feat(api): TokenVerifier-gränssnitt + FirebaseTokenVerifier (AUTH-2)
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
"drizzle-orm": "^0.45.0",
|
||||
"fastify": "^5.6.0",
|
||||
"fastify-plugin": "^5.0.0",
|
||||
"firebase-admin": "^14.2.0",
|
||||
"ioredis": "^6.0.0",
|
||||
"nodemailer": "^9.0.3",
|
||||
"pg": "^8.13.0",
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { initializeApp, cert, getApps, type App, type ServiceAccount } from "firebase-admin/app";
|
||||
import { getAuth } from "firebase-admin/auth";
|
||||
|
||||
/**
|
||||
* Leverantörsneutralt resultat av en verifierad ID-token.
|
||||
* App-koden/rutterna använder DETTA – aldrig firebase-admin direkt.
|
||||
*/
|
||||
export interface VerifiedIdentity {
|
||||
/** Stabil identitet från leverantören (Firebase-UID). */
|
||||
uid: string;
|
||||
email: string | null;
|
||||
emailVerified: boolean;
|
||||
name: string | null;
|
||||
/** t.ex. "password" | "google.com" | "apple.com". */
|
||||
provider: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enda gränssnittet mot token-verifiering. En framtida ZitadelTokenVerifier
|
||||
* (introspektion/JWKS) implementerar samma interface – då byts bara denna fil.
|
||||
*/
|
||||
export interface TokenVerifier {
|
||||
verify(idToken: string): Promise<VerifiedIdentity>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Firebase-implementation. ENDA serverfilen som importerar firebase-admin.
|
||||
* Admin-appen initieras lat (först vid första verify) så att build/typecheck
|
||||
* aldrig kräver tjänstekontot.
|
||||
*/
|
||||
export function createFirebaseTokenVerifier(serviceAccount: ServiceAccount): TokenVerifier {
|
||||
let app: App | undefined;
|
||||
const ensureApp = (): App => {
|
||||
if (app) return app;
|
||||
app = getApps()[0] ?? initializeApp({ credential: cert(serviceAccount) });
|
||||
return app;
|
||||
};
|
||||
return {
|
||||
async verify(idToken: string): Promise<VerifiedIdentity> {
|
||||
const decoded = await getAuth(ensureApp()).verifyIdToken(idToken);
|
||||
return {
|
||||
uid: decoded.uid,
|
||||
email: decoded.email ?? null,
|
||||
emailVerified: decoded.email_verified ?? false,
|
||||
name: (decoded.name as string | undefined) ?? null,
|
||||
provider: decoded.firebase?.sign_in_provider ?? null,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user