UNPKG

next-firebase-auth-edge

Version:

Next.js Firebase Authentication for Edge and server runtimes. Compatible with latest Next.js features.

59 lines (58 loc) 2.19 kB
import { FirebaseAppCheckError } from './api-client.js'; const ONE_MINUTE_IN_SECONDS = 60; const ONE_MINUTE_IN_MILLIS = ONE_MINUTE_IN_SECONDS * 1000; const ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000; const FIREBASE_APP_CHECK_AUDIENCE = 'https://firebaseappcheck.googleapis.com/google.firebase.appcheck.v1.TokenExchangeService'; function transformMillisecondsToSecondsString(milliseconds) { let duration; const seconds = Math.floor(milliseconds / 1000); const nanos = Math.floor((milliseconds - seconds * 1000) * 1000000); if (nanos > 0) { let nanoString = nanos.toString(); while (nanoString.length < 9) { nanoString = '0' + nanoString; } duration = `${seconds}.${nanoString}s`; } else { duration = `${seconds}s`; } return duration; } export class AppCheckTokenGenerator { signer; constructor(signer) { this.signer = signer; } async createCustomToken(appId, options) { if (!appId) { throw new FirebaseAppCheckError('invalid-argument', '`appId` must be a non-empty string.'); } let customOptions = {}; if (typeof options !== 'undefined') { customOptions = this.validateTokenOptions(options); } const account = await this.signer.getAccountId(); const iat = Math.floor(Date.now() / 1000); const body = { iss: account, sub: account, app_id: appId, aud: FIREBASE_APP_CHECK_AUDIENCE, exp: iat + ONE_MINUTE_IN_SECONDS * 5, iat, ...customOptions }; return this.signer.sign(body); } validateTokenOptions(options) { if (typeof options.ttlMillis !== 'undefined') { if (options.ttlMillis < ONE_MINUTE_IN_MILLIS * 30 || options.ttlMillis > ONE_DAY_IN_MILLIS * 7) { throw new FirebaseAppCheckError('invalid-argument', 'ttlMillis must be a duration in milliseconds between 30 minutes and 7 days (inclusive).'); } return { ttl: transformMillisecondsToSecondsString(options.ttlMillis) }; } return {}; } }