Small Node.js server that exchanges OAuth authorization codes (Google & Microsoft) for Firebase custom tokens. Used by the secMail Flutter desktop app (Linux/Windows) so client secrets stay on the server and all desktop users appear in Firebase.
- Flutter app opens the browser for Google or Microsoft sign-in; redirect URI is
http://localhost:8086/__/auth/callback. - User signs in; provider redirects back with an authorization code in the URL.
- The app sends the code (and
redirect_uri) to this backend. - Backend exchanges the code for tokens (using client_secret), verifies the user, creates or gets the Firebase user, and returns a Firebase custom token.
- The app calls
FirebaseAuth.instance.signInWithCustomToken(customToken)and continues as normal.
See secMail/docs/DESKTOP_AUTH_BACKEND_PLAN.md for the full plan.
cd auth-backend
npm installCopy the example and fill in your values:
cp .env.example .envEdit .env:
| Variable | Description |
|---|---|
PORT |
Server port (default 3000). |
GOOGLE_CLIENT_ID |
Google OAuth Web client ID (same as in Firebase Console → Google sign-in). |
GOOGLE_CLIENT_SECRET |
Google OAuth Web client secret. |
MS_CLIENT_ID |
Microsoft Azure app (client) ID. |
MS_CLIENT_SECRET |
Microsoft Azure client secret. |
MS_TENANT_ID |
Optional; default consumers for personal accounts. |
GOOGLE_APPLICATION_CREDENTIALS |
Path to Firebase service account JSON file. |
FIREBASE_SERVICE_ACCOUNT_JSON |
Alternative: full JSON string (e.g. for Cloud Run). |
Firebase service account: In Firebase Console → Project settings → Service accounts → Generate new private key. Save as serviceAccountKey.json in this folder (and add to .gitignore; do not commit).
Redirect URI: Ensure http://localhost:8086/__/auth/callback is added in:
- Google Cloud Console → APIs & Services → Credentials → your OAuth 2.0 Client ID → Authorized redirect URIs.
- Azure Portal → App registration → Authentication → Redirect URIs.
npm startServer listens on http://localhost:3000 (or your PORT).
Request body:
{
"code": "<authorization_code>",
"redirect_uri": "http://localhost:8086/__/auth/callback"
}Success (200):
{
"customToken": "<firebase_custom_token>",
"user": {
"uid": "google:123...",
"email": "user@example.com",
"name": "Display Name",
"photo": "https://..."
}
}Same request shape; use redirect_uri that matches Azure (e.g. http://localhost:8086/__/auth/callback).
Success (200): same shape; uid is like microsoft:....
Returns { "status": "ok", "service": "secmail-auth-backend" }.
In the secMail app, set the backend URL (e.g. in app_constants.dart or .env) so the desktop flow POSTs to this server:
- Local:
http://localhost:3000 - Production: your deployed URL (e.g.
https://your-auth-backend.run.app)
See DESKTOP_AUTH_BACKEND_PLAN.md Phase 2 and 3 for wiring the app to this API.
- Cloud Run: Build a Docker image from this directory (add a
Dockerfilethat runsnode server.js), set env vars or Secret Manager, deploy. Use the same redirect URIs; for production you may allow an additional redirect URI if the app uses one. - Firebase Cloud Functions: Wrap the Express app in
functions.https.onRequest(app)or implement the same logic in HTTP functions and set the same env.
Do not commit .env or serviceAccountKey.json.