Authorized administrator portal. Authenticate with secure credentials.
Your authenticated identity does not possess administrative privileges. Only wingesindre@gmail.com is authorized here.
Real-time central users stream.
Choose a user from the directory to review session auditing logs, modify profile details, or manage app access permissions.
Connect your other apps to this centralized single-sign-on (SSO) engine using standard JavaScript or API requests.
Feed this exact prompt to an Antigravity AI coding session in any other app workspace (e.g., arcade.winge.app) to let the AI fully implement central Winge SSO integration automatically!
You are Antigravity, an expert coding assistant. We are going to integrate my centralized Single Sign-On (SSO) identity system into this application.
Identity Architecture Details:
- Centralized Auth portal is hosted at: https://accounts.winge.app
- Centralized Firebase configuration (Winge central applications):
* authDomain: "winge-applications.firebaseapp.com"
* projectId: "winge-applications"
(Use these centralized credentials and ensure the standard Firebase Web SDK is imported or referenced).
SSO Integration Logic to Implement:
1. Session Listener: On application load, monitor Firebase auth state (using onAuthStateChanged).
2. Unauthorized Redirection: If the user is NOT logged in, redirect them to accounts.winge.app to sign in. The redirection URL must pass this app's current location as a secure redirect parameter:
window.location.href = "https://accounts.winge.app?redirect_uri=" + encodeURIComponent(window.location.href);
3. Token Capture & Login: When accounts.winge.app successfully authenticates a user, it redirects back to our application with a secure Firebase token parameter in the URL query string: ?token=<ID_TOKEN>.
We must detect this "token" parameter in the URL, extract it, and sign the user into our Firebase instance securely using standard custom token or credential login methods.
After successful login, clean up the URL by stripping the ?token= query parameter to keep the navigation bar pristine.
4. Role Entitlement Check: Once the user is signed in, load their profile document from Firestore at "/users/{uid}" from the winge-applications database.
Read the user's assigned role for this app from the `roles` map. For example: `roles["this-app-slug"]`.
If their role is "none" or they do not have an entitlement, show a beautiful, glassmorphic "Access Denied" error message indicating they must ask Sindre (admin.winge.app) for access.
Otherwise, grant them full access to the app based on their role (e.g. staff, admin, developer)!
Please implement this entire flow securely and elegantly in my application's entrypoint, adding smooth glassmorphic loading overlays during the SSO transfer process.
Initialize the central Firebase project in your other app (e.g. `arcade.winge.app`) using the **same** firebase configuration. When a user logs in, they are immediately identified across origins! Fetch their roles from Firestore to authorize page access.
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import { getFirestore, doc, getDoc } from 'firebase/firestore';
// 1. Initialize using your Winge central keys
const firebaseConfig = {
apiKey: "YOUR_CENTRAL_API_KEY",
authDomain: "winge-applications.firebaseapp.com",
projectId: "winge-applications"
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
// 2. Monitor session and fetch permissions on load
onAuthStateChanged(auth, async (user) => {
if (user) {
// User is authenticated. Fetch roles securely from the central users collection!
const userDoc = await getDoc(doc(db, 'users', user.uid));
if (userDoc.exists()) {
const roles = userDoc.data().roles;
console.log("Central Identity Active:", user.email);
console.log("Permissions entitlement:", roles);
// Authorize client access dynamically using registry keys
if (roles['dronetjenester-shop'] === 'staff' || roles['dronetjenester-shop'] === 'admin') {
initializeApplication(user);
} else {
showAccessDeniedBanner("Requires entitlement.");
}
}
} else {
// Redirect to central SSO login!
window.location.href = "https://accounts.winge.app?redirect_uri=" + encodeURIComponent(window.location.href);
}
});
If your apps or servers need a secure HTTP API endpoint to verify a user's logged-in token, they can pass the user's `ID Token` to a **Cloudflare Worker** (hosted on your Cloudflare domains). The Worker securely decodes and validates the Firebase JWT token and returns their profile and permissions.
// Cloudflare Worker validating centralized Winge tokens
export default {
async fetch(request, env) {
const authHeader = request.headers.get("Authorization");
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return new Response("Unauthorized header format", { status: 401 });
}
const idToken = authHeader.split("Bearer ")[1];
try {
const tokenPayload = await verifyFirebaseToken(idToken, "winge-applications");
const uid = tokenPayload.sub;
const firestoreUrl = `https://firestore.googleapis.com/v1/projects/winge-applications/databases/(default)/documents/users/${uid}`;
const firestoreResp = await fetch(firestoreUrl);
if (!firestoreResp.ok) {
return new Response("User Profile Not Found in Firestore", { status: 404 });
}
const docData = await firestoreResp.json();
const fields = docData.fields;
const rolesMap = fields.roles.mapValue.fields;
// Build dynamic roles object from Firestore REST values
const roles = {};
Object.keys(rolesMap).forEach(key => {
const val = rolesMap[key];
roles[key] = val.booleanValue !== undefined ? val.booleanValue : val.stringValue;
});
const responsePayload = {
authenticated: true,
uid: uid,
email: fields.email.stringValue,
displayName: fields.displayName.stringValue,
roles: roles
};
return new Response(JSON.stringify(responsePayload), {
headers: { "Content-Type": "application/json" }
});
} catch (err) {
return new Response("Token signature verification failed: " + err.message, { status: 403 });
}
}
};
Directly seed user profiles and roles into the Firestore database.