@tern-secure/backend 1.2.0-canary.v20251202172616 → 1.2.0-canary.v20251202183844

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/createRedirect.ts","../src/tokens/ternSecureRequest.ts","../src/tokens/ternUrl.ts","../src/tokens/c-authenticateRequestProcessor.ts","../src/utils/mapDecode.ts","../src/tokens/authstate.ts","../src/jwt/verifyJwt.ts","../src/utils/errors.ts","../src/utils/rfc4648.ts","../src/jwt/cryptoKeys.ts","../src/jwt/algorithms.ts","../src/jwt/verifyContent.ts","../src/tokens/keys.ts","../src/tokens/verify.ts","../src/fireRestApi/endpoints/AbstractApi.ts","../src/fireRestApi/endpoints/AppCheckApi.ts","../src/fireRestApi/endpoints/EmailApi.ts","../src/fireRestApi/endpoints/PasswordApi.ts","../src/fireRestApi/endpoints/SignInApi.ts","../src/fireRestApi/endpoints/SignInTokenApi.ts","../src/fireRestApi/endpoints/SignUpApi.ts","../src/fireRestApi/endpoints/TokenApi.ts","../src/fireRestApi/endpoints/UserData.ts","../src/runtime.ts","../src/fireRestApi/emulator.ts","../src/fireRestApi/endpointUrl.ts","../src/fireRestApi/request.ts","../src/fireRestApi/createFireApi.ts","../src/utils/options.ts","../src/tokens/request.ts","../src/jwt/guardReturn.ts","../src/jwt/jwt.ts","../src/jwt/customJwt.ts","../src/jwt/signJwt.ts","../src/utils/fetcher.ts","../src/jwt/types.ts","../src/jwt/crypto-signer.ts","../src/jwt/index.ts","../src/utils/token-generator.ts","../src/app-check/AppCheckApi.ts","../src/app-check/generator.ts","../src/app-check/serverAppCheck.ts","../src/utils/config.ts","../src/app-check/verifier.ts","../src/app-check/index.ts","../src/auth/getauth.ts","../src/auth/credential.ts","../src/tokens/cookie.ts","../src/tokens/factory.ts","../src/instance/backendInstanceEdge.ts","../src/utils/logger.ts","../src/utils/enableDebugLogging.ts","../src/adapters/PostgresAdapter.ts","../src/adapters/RedisAdapter.ts","../src/adapters/index.ts"],"sourcesContent":["export { constants } from './constants';\nexport { createRedirect } from './createRedirect';\nexport type { RedirectFun } from './createRedirect';\n\nexport type { TernSecureRequest } from './tokens/ternSecureRequest';\nexport { createTernSecureRequest } from './tokens/ternSecureRequest';\n\nexport type { AuthenticateRequestOptions } from './tokens/types';\n\nexport type { RequestProcessorContext } from './tokens/c-authenticateRequestProcessor';\nexport { createRequestProcessor } from './tokens/c-authenticateRequestProcessor';\n\nexport type {\n AuthObject,\n RequestState,\n SignedInAuthObject,\n SignedOutAuthObject,\n} from './tokens/authstate';\nexport { signedIn, signedInAuthObject, signedOutAuthObject, AuthStatus } from './tokens/authstate';\nexport { verifyToken } from './tokens/verify';\n\nexport { createBackendInstanceClient } from './instance/backendInstanceEdge';\n\nexport type { BackendInstance, TernSecureBackendOptions } from './instance/backendInstanceEdge';\n\nexport { enableDebugLogging, disableDebugLogging, setLogLevel } from './utils/enableDebugLogging';\n\nexport { LogLevel } from './utils/logger';\n\nexport {\n RedisAdapter,\n PostgresAdapter,\n createAdapter,\n validateCheckRevokedOptions,\n} from './adapters';\n\nexport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n AdapterConfig,\n RedisConfig,\n PostgresConfig,\n AdapterType,\n AdapterConfiguration,\n CheckRevokedOptions,\n} from './adapters';\n","export const GOOGLE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com';\nexport const SESSION_COOKIE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys';\n\nexport const FIREBASE_APP_CHECK_AUDIENCE =\n 'https://firebaseappcheck.googleapis.com/google.firebase.appcheck.v1.TokenExchangeService';\n\nexport const MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;\nexport const DEFAULT_CACHE_DURATION = 3600 * 1000; // 1 hour in milliseconds\nexport const CACHE_CONTROL_REGEX = /max-age=(\\d+)/;\n\nexport const TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1000;\nexport const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token';\nexport const GOOGLE_AUTH_TOKEN_HOST = 'accounts.google.com';\nexport const GOOGLE_AUTH_TOKEN_PATH = '/o/oauth2/token';\nexport const ONE_HOUR_IN_SECONDS = 60 * 60;\n\nexport const ONE_MINUTE_IN_SECONDS = 60;\nexport const ONE_MINUTE_IN_MILLIS = ONE_MINUTE_IN_SECONDS * 1000;\nexport const ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000;\n\nconst Attributes = {\n AuthToken: '__ternsecureAuthToken',\n AuthSignature: '__ternsecureAuthSignature',\n AuthStatus: '__ternsecureAuthStatus',\n AuthReason: '__ternsecureAuthReason',\n AuthMessage: '__ternsecureAuthMessage',\n TernSecureUrl: '__ternsecureUrl',\n} as const;\n\nconst Cookies = {\n Session: '__session',\n CsrfToken: '__terncf',\n IdToken: 'TernSecure_[DEFAULT]',\n Refresh: 'TernSecureID_[DEFAULT]',\n Custom: '__custom',\n TernAut: 'tern_aut',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\n\nconst QueryParameters = {\n TernSynced: '__tern_synced',\n SuffixedCookies: 'suffixed_cookies',\n TernRedirectUrl: '__tern_redirect_url',\n // use the reference to Cookies to indicate that it's the same value\n DevBrowser: Cookies.DevBrowser,\n Handshake: Cookies.Handshake,\n HandshakeHelp: '__tern_help',\n LegacyDevBrowser: '__dev_session',\n HandshakeReason: '__tern_hs_reason',\n HandshakeNonce: Cookies.HandshakeNonce,\n} as const;\n\nconst Headers = {\n Accept: 'accept',\n AppCheckToken: 'x-ternsecure-appcheck',\n AuthMessage: 'x-ternsecure-auth-message',\n Authorization: 'authorization',\n AuthReason: 'x-ternsecure-auth-reason',\n AuthSignature: 'x-ternsecure-auth-signature',\n AuthStatus: 'x-ternsecure-auth-status',\n AuthToken: 'x-ternsecure-auth-token',\n CacheControl: 'cache-control',\n TernSecureRedirectTo: 'x-ternsecure-redirect-to',\n TernSecureRequestData: 'x-ternsecure-request-data',\n TernSecureUrl: 'x-ternsecure-url',\n CloudFrontForwardedProto: 'cloudfront-forwarded-proto',\n ContentType: 'content-type',\n ContentSecurityPolicy: 'content-security-policy',\n ContentSecurityPolicyReportOnly: 'content-security-policy-report-only',\n EnableDebug: 'x-ternsecure-debug',\n ForwardedHost: 'x-forwarded-host',\n ForwardedPort: 'x-forwarded-port',\n ForwardedProto: 'x-forwarded-proto',\n Host: 'host',\n Location: 'location',\n Nonce: 'x-nonce',\n Origin: 'origin',\n Referrer: 'referer',\n SecFetchDest: 'sec-fetch-dest',\n UserAgent: 'user-agent',\n ReportingEndpoints: 'reporting-endpoints',\n} as const;\n\nconst ContentTypes = {\n Json: 'application/json',\n} as const;\n\n/**\n * @internal\n */\nexport const constants = {\n Attributes,\n Cookies,\n Headers,\n ContentTypes,\n QueryParameters,\n} as const;\n\nexport type Constants = typeof constants;\n","const buildUrl = (\n _baseUrl: string | URL,\n _targetUrl: string | URL,\n _returnBackUrl?: string | URL | null,\n) => {\n if (_baseUrl === '') {\n return legacyBuildUrl(_targetUrl.toString(), _returnBackUrl?.toString());\n }\n\n const baseUrl = new URL(_baseUrl);\n const returnBackUrl = _returnBackUrl ? new URL(_returnBackUrl, baseUrl) : undefined;\n const res = new URL(_targetUrl, baseUrl);\n\n if (returnBackUrl) {\n res.searchParams.set('redirect_url', returnBackUrl.toString());\n }\n return res.toString();\n};\n\nconst legacyBuildUrl = (targetUrl: string, redirectUrl?: string) => {\n let url;\n if (!targetUrl.startsWith('http')) {\n if (!redirectUrl || !redirectUrl.startsWith('http')) {\n throw new Error('destination url or return back url should be an absolute path url!');\n }\n\n const baseURL = new URL(redirectUrl);\n url = new URL(targetUrl, baseURL.origin);\n } else {\n url = new URL(targetUrl);\n }\n\n if (redirectUrl) {\n url.searchParams.set('redirect_url', redirectUrl);\n }\n\n return url.toString();\n};\n\ntype RedirectAdapter<RedirectReturn> = (url: string) => RedirectReturn;\ntype RedirectToParams = { returnBackUrl?: string | URL | null };\nexport type RedirectFun<ReturnType> = (params?: RedirectToParams) => ReturnType;\n\n/**\n * @internal\n */\ntype CreateRedirect = <ReturnType>(params: {\n redirectAdapter: RedirectAdapter<ReturnType>;\n baseUrl: URL | string;\n signInUrl?: URL | string;\n signUpUrl?: URL | string;\n}) => {\n redirectToSignIn: RedirectFun<ReturnType>;\n redirectToSignUp: RedirectFun<ReturnType>;\n};\n\nexport const createRedirect: CreateRedirect = params => {\n const { redirectAdapter, signInUrl, signUpUrl, baseUrl } = params;\n\n const redirectToSignUp = ({ returnBackUrl }: RedirectToParams = {}) => {\n if (!signUpUrl) {\n throw new Error('SignUp URL is not defined');\n }\n\n const pathToSignUpUrl = `${baseUrl}/sign-up`;\n\n function buildSignUpUrl(signIn: string | URL | undefined) {\n if (!signIn) {\n return;\n }\n const url = new URL(signIn, baseUrl);\n url.pathname = `${url.pathname}/create`;\n return url.toString();\n }\n\n const targetUrl = signUpUrl || buildSignUpUrl(signInUrl) || pathToSignUpUrl;\n\n return redirectAdapter(buildUrl(baseUrl, targetUrl, returnBackUrl));\n };\n\n const redirectToSignIn = ({ returnBackUrl }: RedirectToParams = {}) => {\n if (!signInUrl) {\n throw new Error('SignIn URL is not defined');\n }\n\n const pathToSignInUrl = `${baseUrl}/sign-in`;\n const targetUrl = signInUrl || pathToSignInUrl;\n\n return redirectAdapter(buildUrl(baseUrl, targetUrl, returnBackUrl));\n };\n\n return { redirectToSignUp, redirectToSignIn };\n};\n","import { parse } from \"cookie\";\n\nimport { constants } from \"../constants\";\nimport type { TernUrl } from \"./ternUrl\";\nimport { createTernUrl } from \"./ternUrl\";\n\nclass TernSecureRequest extends Request {\n readonly ternUrl: TernUrl;\n readonly cookies: Map<string, string | undefined>;\n\n public constructor(\n input: TernSecureRequest | Request | RequestInfo,\n init?: RequestInit\n ) {\n const url =\n typeof input !== \"string\" && \"url\" in input ? input.url : String(input);\n super(url, init || typeof input === \"string\" ? undefined : input);\n this.ternUrl = this.deriveUrlFromHeaders(this);\n this.cookies = this.parseCookies(this);\n }\n\n public toJSON() {\n return {\n url: this.ternUrl.href,\n method: this.method,\n headers: JSON.stringify(Object.fromEntries(this.headers)),\n ternUrl: this.ternUrl.toString(),\n cookies: JSON.stringify(Object.fromEntries(this.cookies)),\n };\n }\n\n private deriveUrlFromHeaders(req: Request) {\n const initialUrl = new URL(req.url);\n const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);\n const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);\n const host = req.headers.get(constants.Headers.Host);\n const protocol = initialUrl.protocol;\n\n const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;\n const resolvedProtocol =\n this.getFirstValueFromHeader(forwardedProto) ??\n protocol?.replace(/[:/]/, \"\");\n const origin =\n resolvedHost && resolvedProtocol\n ? `${resolvedProtocol}://${resolvedHost}`\n : initialUrl.origin;\n\n if (origin === initialUrl.origin) {\n return createTernUrl(initialUrl);\n }\n\n return createTernUrl(initialUrl.pathname + initialUrl.search, origin);\n }\n\n private getFirstValueFromHeader(value?: string | null) {\n return value?.split(\",\")[0];\n }\n\n private parseCookies(req: Request) {\n const cookiesRecord = parse(\n this.decodeCookieValue(req.headers.get(\"cookie\") || \"\")\n );\n return new Map(Object.entries(cookiesRecord));\n }\n\n private decodeCookieValue(str: string) {\n return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;\n }\n}\n\nexport const createTernSecureRequest = (\n ...args: ConstructorParameters<typeof TernSecureRequest>\n): TernSecureRequest => {\n return args[0] instanceof TernSecureRequest\n ? args[0]\n : new TernSecureRequest(...args);\n};\n\nexport type { TernSecureRequest };\n","class TernUrl extends URL {\n public isCrossOrigin(other: URL | string) {\n return this.origin !== new URL(other.toString()).origin;\n }\n}\n\nexport type WithTernUrl<T> = T & {\n /**\n * When a NextJs app is hosted on a platform different from Vercel\n * or inside a container (Netlify, Fly.io, AWS Amplify, docker etc),\n * req.url is always set to `localhost:3000` instead of the actual host of the app.\n *\n */\n ternUrl: TernUrl;\n};\n\nexport const createTernUrl = (\n ...args: ConstructorParameters<typeof TernUrl>\n): TernUrl => {\n return new TernUrl(...args);\n};\n\nexport type { TernUrl };\n","import type { AuthEndpoint, AuthSubEndpoint } from '@tern-secure/types';\n\nimport { constants } from '../constants';\nimport type { TernSecureRequest } from './ternSecureRequest';\nimport type { AuthenticateRequestOptions } from './types';\n\n\n/**\n * Request context for better type safety and clarity\n */\ninterface RequestProcessorContext extends AuthenticateRequestOptions {\n // header-based values\n sessionTokenInHeader: string | undefined;\n origin: string | undefined;\n host: string | undefined;\n forwardedHost: string | undefined;\n forwardedProto: string | undefined;\n referrer: string | undefined;\n userAgent: string | undefined;\n secFetchDest: string | undefined;\n accept: string | undefined;\n appCheckToken: string | undefined;\n\n // cookie-based values\n idTokenInCookie: string | undefined;\n refreshTokenInCookie: string | undefined;\n csrfTokenInCookie: string | undefined;\n sessionTokenInCookie?: string | undefined;\n customTokenInCookie?: string | undefined;\n ternAuth: number;\n\n handshakeNonce: string | undefined;\n handshakeToken: string | undefined;\n\n method: string;\n pathSegments: string[];\n endpoint?: AuthEndpoint;\n subEndpoint?: AuthSubEndpoint;\n\n ternUrl: URL;\n instanceType: string;\n}\n\n/**\n * Request processor utility class for common operations\n */\nclass RequestProcessorContext implements RequestProcessorContext {\n public constructor(\n private ternSecureRequest: TernSecureRequest,\n private options: AuthenticateRequestOptions,\n ) {\n this.initHeaderValues();\n this.initCookieValues();\n this.initHandshakeValues();\n this.initUrlValues();\n Object.assign(this, options);\n this.ternUrl = this.ternSecureRequest.ternUrl;\n }\n\n public get request(): TernSecureRequest {\n return this.ternSecureRequest;\n }\n\n private initHeaderValues() {\n this.sessionTokenInHeader = this.parseAuthorizationHeader(\n this.getHeader(constants.Headers.Authorization),\n );\n this.origin = this.getHeader(constants.Headers.Origin);\n this.host = this.getHeader(constants.Headers.Host);\n this.forwardedHost = this.getHeader(constants.Headers.ForwardedHost);\n this.forwardedProto =\n this.getHeader(constants.Headers.CloudFrontForwardedProto) ||\n this.getHeader(constants.Headers.ForwardedProto);\n this.referrer = this.getHeader(constants.Headers.Referrer);\n this.userAgent = this.getHeader(constants.Headers.UserAgent);\n this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);\n this.accept = this.getHeader(constants.Headers.Accept);\n this.appCheckToken = this.getHeader(constants.Headers.AppCheckToken);\n }\n\n private initCookieValues() {\n const isProduction = process.env.NODE_ENV === 'production';\n const defaultPrefix = isProduction ? '__HOST-' : '__dev_';\n this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);\n\n // System-fixed cookies using backend constants\n this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);\n this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);\n this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);\n this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);\n this.ternAuth = Number.parseInt(this.getCookie(constants.Cookies.TernAut) || '0', 10);\n }\n\n private initHandshakeValues() {\n this.handshakeToken = this.getQueryParam(constants.QueryParameters.Handshake) || this.getCookie(constants.Cookies.Handshake);\n this.handshakeNonce = this.getQueryParam(constants.QueryParameters.HandshakeNonce) || this.getCookie(constants.Cookies.HandshakeNonce);\n }\n\n private initUrlValues() {\n this.method = this.ternSecureRequest.method;\n this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split('/').filter(Boolean);\n this.endpoint = this.pathSegments[2] as AuthEndpoint;\n this.subEndpoint = this.pathSegments[3] as AuthSubEndpoint;\n }\n\n private getQueryParam(name: string) {\n return this.ternSecureRequest.ternUrl.searchParams.get(name);\n }\n\n private getHeader(name: string) {\n return this.ternSecureRequest.headers.get(name) || undefined;\n }\n\n private getCookie(name: string) {\n return this.ternSecureRequest.cookies.get(name) || undefined;\n }\n\n private parseAuthorizationHeader(\n authorizationHeader: string | undefined | null,\n ): string | undefined {\n if (!authorizationHeader) {\n return undefined;\n }\n\n const [scheme, token] = authorizationHeader.split(' ', 2);\n\n if (!token) {\n // No scheme specified, treat the entire value as the token\n return scheme;\n }\n\n if (scheme === 'Bearer') {\n return token;\n }\n\n // Skip all other schemes\n return undefined;\n }\n}\n\nexport type { RequestProcessorContext };\n\nexport const createRequestProcessor = (\n ternSecureRequest: TernSecureRequest,\n options: AuthenticateRequestOptions,\n): RequestProcessorContext => {\n return new RequestProcessorContext(ternSecureRequest, options);\n};\n","import type { DecodedAppCheckToken, DecodedIdToken } from \"@tern-secure/types\";\nimport type {\n JWTPayload,\n} from \"jose\";\n\nexport function mapJwtPayloadToDecodedIdToken(payload: JWTPayload) {\n const decodedIdToken = payload as DecodedIdToken;\n decodedIdToken.uid = decodedIdToken.sub;\n return decodedIdToken;\n}\n\n\nexport function mapJwtPayloadToDecodedAppCheckToken(payload: JWTPayload) {\n const decodedAppCheckToken = payload as DecodedAppCheckToken;\n decodedAppCheckToken.app_id = decodedAppCheckToken.sub;\n return decodedAppCheckToken;\n}","import type { CheckAuthorizationFromSessionClaims, DecodedIdToken } from '@tern-secure/types';\nimport type { JWTPayload } from 'jose';\n\nimport { constants } from '../constants';\nimport type { TokenVerificationErrorReason } from '../utils/errors';\nimport { mapJwtPayloadToDecodedIdToken } from '../utils/mapDecode';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport type { TernSecureRequest } from './ternSecureRequest';\n\nexport const AuthStatus = {\n SignedIn: 'signed-in',\n SignedOut: 'signed-out',\n Handshake: 'handshake',\n} as const;\n\nexport type AuthStatus = (typeof AuthStatus)[keyof typeof AuthStatus];\n\nexport const AuthErrorReason = {\n AuthTimeout: 'auth-timeout',\n SessionTokenAndAuthMissing: 'session-token-and-aut-missing',\n SessionTokenMissing: 'session-token-missing',\n SessionTokenExpired: 'session-token-expired',\n SessionTokenIATBeforeTernAUT: 'session-token-iat-before-tern-aut',\n SessionTokenNBF: 'session-token-nbf',\n SessionTokenIatInTheFuture: 'session-token-iat-in-the-future',\n SessionTokenWithoutTernAUT: 'session-token-but-no-tern-uat',\n TernAutWithoutSessionToken: 'tern-aut-but-no-session-token',\n SyncRequired: 'sync-required',\n UnexpectedError: 'unexpected-error',\n} as const;\n\nexport type AuthErrorReason = (typeof AuthErrorReason)[keyof typeof AuthErrorReason];\n\nexport type AuthReason = AuthErrorReason | TokenVerificationErrorReason;\n\nexport type SignedInAuthObject = {\n sessionClaims: DecodedIdToken;\n userId: string;\n token: string;\n require: CheckAuthorizationFromSessionClaims;\n error: string | null;\n};\n\nexport type SignedOutAuthObject = {\n sessionClaims: null;\n userId: null;\n token: null;\n require: CheckAuthorizationFromSessionClaims;\n error: string | null;\n};\n\nexport type SignedInState = {\n status: typeof AuthStatus.SignedIn;\n message: null;\n reason: null;\n signInUrl: string;\n signUpUrl: string;\n isSignedIn: true;\n auth: () => SignedInAuthObject;\n token: string;\n appCheckToken?: string;\n headers: Headers;\n};\n\nexport type SignedOutState = {\n status: typeof AuthStatus.SignedOut;\n message: string;\n reason: string;\n isSignedIn: false;\n signInUrl: string;\n signUpUrl: string;\n auth: () => SignedOutAuthObject;\n token: null;\n appCheckToken?: string;\n headers: Headers;\n};\n\nexport type HandshakeState = Omit<SignedOutState, 'status' | 'auth'> & {\n status: typeof AuthStatus.Handshake;\n headers: Headers;\n auth: () => null;\n};\n\nexport type RequestState = SignedInState | SignedOutState | HandshakeState;\n\nexport interface BackendInstance {\n ternSecureRequest: TernSecureRequest;\n requestState: RequestState;\n}\n\nexport type AuthObject = SignedInAuthObject | SignedOutAuthObject;\n\nfunction createHasAuthorization(\n decodedIdToken: DecodedIdToken,\n): CheckAuthorizationFromSessionClaims {\n return (authorizationParams: any) => {\n if (\n !authorizationParams ||\n typeof authorizationParams !== 'object' ||\n Array.isArray(authorizationParams)\n ) {\n return false;\n }\n const claims = decodedIdToken as Record<string, any>;\n\n return Object.entries(authorizationParams).every(([key, value]) => {\n const claimValue = claims[key];\n if (typeof claimValue === 'undefined') {\n return false;\n }\n if (Array.isArray(value)) {\n if (Array.isArray(claimValue)) {\n return value.some(v => claimValue.includes(v));\n }\n return value.includes(claimValue);\n }\n\n if (Array.isArray(claimValue)) {\n return claimValue.includes(value);\n }\n return claimValue === value;\n });\n };\n}\n\nexport function signedInAuthObject(\n sessionToken: string,\n sessionClaims: JWTPayload,\n): SignedInAuthObject {\n const decodedIdToken = mapJwtPayloadToDecodedIdToken(sessionClaims);\n return {\n sessionClaims: {\n ...decodedIdToken,\n },\n userId: decodedIdToken.uid,\n token: sessionToken,\n require: createHasAuthorization(decodedIdToken),\n error: null,\n };\n}\n\nexport function signedOutAuthObject(): SignedOutAuthObject {\n return {\n sessionClaims: null,\n userId: null,\n token: null,\n require: () => false,\n error: 'No active session',\n };\n}\n\nexport function signedIn(\n authCtx: RequestProcessorContext,\n sessionClaims: JWTPayload,\n headers: Headers = new Headers(),\n token: string,\n): SignedInState {\n const authObject = signedInAuthObject(token, sessionClaims);\n \n return {\n status: AuthStatus.SignedIn,\n message: null,\n reason: null,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: true,\n auth: () => authObject,\n token,\n headers,\n };\n}\n\nexport function signedOut(\n authCtx: RequestProcessorContext,\n reason: AuthReason,\n message = '',\n headers: Headers = new Headers(),\n): SignedOutState {\n return decorateHeaders({\n status: AuthStatus.SignedOut,\n reason,\n message,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: false,\n auth: () => signedOutAuthObject(),\n token: null,\n appCheckToken: authCtx.appCheckToken,\n headers,\n });\n}\n\nexport function handshake(\n authCtx: RequestProcessorContext,\n reason: AuthReason,\n message = '',\n headers: Headers,\n): HandshakeState {\n return {\n status: AuthStatus.Handshake,\n reason,\n message,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: false,\n headers,\n auth: () => null,\n token: null,\n };\n}\n\nconst decorateHeaders = <T extends RequestState>(requestState: T): T => {\n const headers = new Headers(requestState.headers || {});\n\n if (requestState.message) {\n try {\n headers.set(constants.Headers.AuthMessage, requestState.message);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.reason) {\n try {\n headers.set(constants.Headers.AuthReason, requestState.reason);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.status) {\n try {\n headers.set(constants.Headers.AuthStatus, requestState.status);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.appCheckToken) {\n try {\n headers.set(constants.Headers.AppCheckToken, requestState.appCheckToken);\n } catch {\n // Ignore errors\n }\n }\n\n requestState.headers = headers;\n\n return requestState;\n};\n","import type { DecodedAppCheckToken, DecodedIdToken, Jwt, JWTPayload } from '@tern-secure/types';\nimport {\n decodeJwt,\n decodeProtectedHeader,\n jwtVerify,\n type KeyLike,\n} from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { mapJwtPayloadToDecodedAppCheckToken, mapJwtPayloadToDecodedIdToken } from '../utils/mapDecode';\nimport { base64url } from '../utils/rfc4648';\nimport { importKey } from './cryptoKeys';\nimport type { JwtReturnType } from './types';\nimport {\n verifyExpirationClaim,\n verifyHeaderKid,\n verifyIssuedAtClaim,\n verifySubClaim,\n} from './verifyContent';\n\nconst DEFAULT_CLOCK_SKEW_IN_MS = 5 * 1000;\n\nexport type VerifyJwtOptions = {\n audience?: string | string[];\n clockSkewInMs?: number;\n key: JsonWebKey | string;\n};\n\nexport async function verifySignature(\n jwt: Jwt,\n key: JsonWebKey | string,\n): Promise<JwtReturnType<JWTPayload, Error>> {\n const { header, raw } = jwt;\n const joseAlgorithm = header.alg || 'RS256';\n\n try {\n const publicKey = await importKey(key, joseAlgorithm);\n\n const { payload } = await jwtVerify(raw.text, publicKey);\n\n return { data: payload };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: (error as Error).message,\n }),\n ],\n };\n }\n}\n\nexport function ternDecodeJwt(token: string): JwtReturnType<Jwt, TokenVerificationError> {\n try {\n const header = decodeProtectedHeader(token);\n const payload = decodeJwt(token);\n\n const tokenParts = (token || '').toString().split('.');\n if (tokenParts.length !== 3) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'Invalid JWT format',\n }),\n ],\n };\n }\n\n const [rawHeader, rawPayload, rawSignature] = tokenParts;\n const signature = base64url.parse(rawSignature, { loose: true });\n\n const data = {\n header,\n payload,\n signature,\n raw: {\n header: rawHeader,\n payload: rawPayload,\n signature: rawSignature,\n text: token,\n },\n } satisfies Jwt;\n\n return { data };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `${(error as Error).message || 'Invalid Token or Protected Header formatting'} (Token length: ${token?.length}, First 10 chars: ${token?.substring(0, 10)}...)`,\n }),\n ],\n };\n }\n}\n\nexport async function verifyJwt(\n token: string,\n options: VerifyJwtOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { key } = options;\n const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;\n\n const { data: decoded, errors } = ternDecodeJwt(token);\n if (errors) {\n return { errors };\n }\n\n const { header, payload } = decoded;\n\n try {\n verifyHeaderKid(header.kid);\n verifySubClaim(payload.sub);\n verifyExpirationClaim(payload.exp, clockSkew);\n verifyIssuedAtClaim(payload.iat, clockSkew);\n } catch (error) {\n return { errors: [error as TokenVerificationError] };\n }\n\n const { data: verifiedPayload, errors: signatureErrors } = await verifySignature(decoded, key);\n if (signatureErrors) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: 'Token signature verification failed.',\n }),\n ],\n };\n }\n\n const decodedIdToken = mapJwtPayloadToDecodedIdToken(verifiedPayload);\n\n return { data: decodedIdToken };\n}\n\nexport type VerifyAppCheckJwtOptions = Omit<VerifyJwtOptions, 'key'> & {\n key: () => Promise<KeyLike>;\n};\n\nexport async function verifyAppCheckSignature(\n jwt: Jwt,\n getPublicKey: () => Promise<KeyLike>,\n): Promise<JwtReturnType<JWTPayload, Error>> {\n const { header, raw } = jwt;\n const joseAlgorithm = header.alg || 'RS256';\n\n try {\n const key = await getPublicKey();\n\n const { payload } = await jwtVerify(raw.text, key);\n\n return { data: payload };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: (error as Error).message,\n }),\n ],\n };\n }\n}\n\n\nexport async function verifyAppCheckJwt(\n token: string,\n options: VerifyAppCheckJwtOptions,\n): Promise<JwtReturnType<DecodedAppCheckToken, TokenVerificationError>> {\n const { key: getPublicKey } = options;\n const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;\n\n const { data: decoded, errors } = ternDecodeJwt(token);\n if (errors) {\n return { errors };\n }\n\n const { header, payload } = decoded;\n\n try {\n verifyHeaderKid(header.kid);\n verifySubClaim(payload.sub);\n verifyExpirationClaim(payload.exp, clockSkew);\n verifyIssuedAtClaim(payload.iat, clockSkew);\n } catch (error) {\n return { errors: [error as TokenVerificationError] };\n }\n\n const { data: verifiedPayload, errors: signatureErrors } = await verifyAppCheckSignature(\n decoded,\n getPublicKey,\n );\n if (signatureErrors) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: 'Token signature verification failed.',\n }),\n ],\n };\n }\n\n const decodedAppCheckToken = mapJwtPayloadToDecodedAppCheckToken(verifiedPayload);\n\n return { data: decodedAppCheckToken };\n}","export const RefreshTokenErrorReason = {\n NonEligibleNoCookie: 'non-eligible-no-refresh-cookie',\n NonEligibleNonGet: 'non-eligible-non-get',\n InvalidSessionToken: 'invalid-session-token',\n MissingApiClient: 'missing-api-client',\n MissingIdToken: 'missing-id-token',\n MissingSessionToken: 'missing-session-token',\n MissingRefreshToken: 'missing-refresh-token',\n ExpiredIdTokenDecodeFailed: 'expired-id-token-decode-failed',\n ExpiredSessionTokenDecodeFailed: 'expired-session-token-decode-failed',\n FetchError: 'fetch-error',\n} as const;\n\nexport type TokenCarrier = 'header' | 'cookie';\n\nexport const TokenVerificationErrorReason = {\n TokenExpired: 'token-expired',\n TokenInvalid: 'token-invalid',\n TokenInvalidAlgorithm: 'token-invalid-algorithm',\n TokenInvalidAuthorizedParties: 'token-invalid-authorized-parties',\n TokenInvalidSignature: 'token-invalid-signature',\n TokenNotActiveYet: 'token-not-active-yet',\n TokenIatInTheFuture: 'token-iat-in-the-future',\n TokenVerificationFailed: 'token-verification-failed',\n InvalidSecretKey: 'secret-key-invalid',\n LocalJWKMissing: 'jwk-local-missing',\n RemoteJWKFailedToLoad: 'jwk-remote-failed-to-load',\n RemoteJWKInvalid: 'jwk-remote-invalid',\n RemoteJWKMissing: 'jwk-remote-missing',\n JWKFailedToResolve: 'jwk-failed-to-resolve',\n JWKKidMismatch: 'jwk-kid-mismatch',\n};\n\nexport type TokenVerificationErrorReason =\n (typeof TokenVerificationErrorReason)[keyof typeof TokenVerificationErrorReason];\n\nexport class TokenVerificationError extends Error {\n reason: TokenVerificationErrorReason;\n tokenCarrier?: TokenCarrier;\n\n constructor({\n message,\n reason,\n }: {\n message: string;\n reason: TokenVerificationErrorReason;\n }) {\n super(message);\n\n Object.setPrototypeOf(this, TokenVerificationError.prototype);\n\n this.reason = reason;\n this.message = message;\n }\n\n public getFullMessage() {\n return `${[this.message].filter(m => m).join(' ')} (reason=${this.reason}, token-carrier=${\n this.tokenCarrier\n })`;\n }\n }\n","/**\n * The base64url helper was extracted from the rfc4648 package\n * in order to resolve CSJ/ESM interoperability issues\n *\n * https://github.com/swansontec/rfc4648.js\n *\n * For more context please refer to:\n * - https://github.com/evanw/esbuild/issues/1719\n * - https://github.com/evanw/esbuild/issues/532\n * - https://github.com/swansontec/rollup-plugin-mjs-entry\n */\nexport const base64url = {\n parse(string: string, opts?: ParseOptions): Uint8Array {\n return parse(string, base64UrlEncoding, opts);\n },\n\n stringify(data: ArrayLike<number>, opts?: StringifyOptions): string {\n return stringify(data, base64UrlEncoding, opts);\n },\n};\n\nconst base64UrlEncoding: Encoding = {\n chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',\n bits: 6,\n};\n\ninterface Encoding {\n bits: number;\n chars: string;\n codes?: { [char: string]: number };\n}\n\ninterface ParseOptions {\n loose?: boolean;\n out?: new (size: number) => { [index: number]: number };\n}\n\ninterface StringifyOptions {\n pad?: boolean;\n}\n\nfunction parse(string: string, encoding: Encoding, opts: ParseOptions = {}): Uint8Array {\n // Build the character lookup table:\n if (!encoding.codes) {\n encoding.codes = {};\n for (let i = 0; i < encoding.chars.length; ++i) {\n encoding.codes[encoding.chars[i]] = i;\n }\n }\n\n // The string must have a whole number of bytes:\n if (!opts.loose && (string.length * encoding.bits) & 7) {\n throw new SyntaxError('Invalid padding');\n }\n\n // Count the padding bytes:\n let end = string.length;\n while (string[end - 1] === '=') {\n --end;\n\n // If we get a whole number of bytes, there is too much padding:\n if (!opts.loose && !(((string.length - end) * encoding.bits) & 7)) {\n throw new SyntaxError('Invalid padding');\n }\n }\n\n // Allocate the output:\n const out = new (opts.out ?? Uint8Array)(((end * encoding.bits) / 8) | 0) as Uint8Array;\n\n // Parse the data:\n let bits = 0; // Number of bits currently in the buffer\n let buffer = 0; // Bits waiting to be written out, MSB first\n let written = 0; // Next byte to write\n for (let i = 0; i < end; ++i) {\n // Read one character from the string:\n const value = encoding.codes[string[i]];\n if (value === undefined) {\n throw new SyntaxError('Invalid character ' + string[i]);\n }\n\n // Append the bits to the buffer:\n buffer = (buffer << encoding.bits) | value;\n bits += encoding.bits;\n\n // Write out some bits if the buffer has a byte's worth:\n if (bits >= 8) {\n bits -= 8;\n out[written++] = 0xff & (buffer >> bits);\n }\n }\n\n // Verify that we have received just enough bits:\n if (bits >= encoding.bits || 0xff & (buffer << (8 - bits))) {\n throw new SyntaxError('Unexpected end of data');\n }\n\n return out;\n}\n\nfunction stringify(data: ArrayLike<number>, encoding: Encoding, opts: StringifyOptions = {}): string {\n const { pad = true } = opts;\n const mask = (1 << encoding.bits) - 1;\n let out = '';\n\n let bits = 0; // Number of bits currently in the buffer\n let buffer = 0; // Bits waiting to be written out, MSB first\n for (let i = 0; i < data.length; ++i) {\n // Slurp data into the buffer:\n buffer = (buffer << 8) | (0xff & data[i]);\n bits += 8;\n\n // Write out as much as we can:\n while (bits > encoding.bits) {\n bits -= encoding.bits;\n out += encoding.chars[mask & (buffer >> bits)];\n }\n }\n\n // Partial character:\n if (bits) {\n out += encoding.chars[mask & (buffer << (encoding.bits - bits))];\n }\n\n // Add padding characters until we hit a byte boundary:\n if (pad) {\n while ((out.length * encoding.bits) & 7) {\n out += '=';\n }\n }\n\n return out;\n}\n","import { importJWK, importSPKI,importX509, type KeyLike } from 'jose';\n\nexport async function importKey(key: JsonWebKey | string, algorithm: string): Promise<KeyLike> {\n if (typeof key === 'object') {\n const result = await importJWK(key as Parameters<typeof importJWK>[0], algorithm);\n if (result instanceof Uint8Array) {\n throw new Error('Unexpected Uint8Array result from JWK import');\n }\n return result;\n }\n\n const keyString = key.trim();\n\n if (keyString.includes('-----BEGIN CERTIFICATE-----')) {\n return await importX509(keyString, algorithm);\n }\n\n if (keyString.includes('-----BEGIN PUBLIC KEY-----')) {\n return await importSPKI(keyString, algorithm);\n }\n\n try {\n return await importSPKI(keyString, algorithm);\n } catch (error) {\n throw new Error(\n `Unsupported key format. Supported formats: X.509 certificate (PEM), SPKI (PEM), JWK (JSON object or string). Error: ${error}`,\n );\n }\n}\n","const algToHash: Record<string, string> = {\n RS256: 'SHA-256',\n RS384: 'SHA-384',\n RS512: 'SHA-512',\n};\nconst RSA_ALGORITHM_NAME = 'RSASSA-PKCS1-v1_5';\n\nconst jwksAlgToCryptoAlg: Record<string, string> = {\n RS256: RSA_ALGORITHM_NAME,\n RS384: RSA_ALGORITHM_NAME,\n RS512: RSA_ALGORITHM_NAME,\n};\n\nexport const algs = Object.keys(algToHash);\n\nexport function getCryptoAlgorithm(algorithmName: string): RsaHashedImportParams {\n const hash = algToHash[algorithmName];\n const name = jwksAlgToCryptoAlg[algorithmName];\n\n if (!hash || !name) {\n throw new Error(`Unsupported algorithm ${algorithmName}, expected one of ${algs.join(',')}.`);\n }\n\n return {\n hash: { name: algToHash[algorithmName] },\n name: jwksAlgToCryptoAlg[algorithmName],\n };\n}\n","import { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { algs } from './algorithms';\n\nexport const verifyHeaderType = (typ?: unknown) => {\n if (typeof typ === 'undefined') {\n return;\n }\n\n if (typ !== 'JWT') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `Invalid JWT type ${JSON.stringify(typ)}. Expected \"JWT\".`,\n });\n }\n};\n\nexport const verifyHeaderKid = (kid?: unknown) => {\n if (typeof kid === 'undefined') {\n return;\n }\n\n if (typeof kid !== 'string') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `Invalid JWT kid ${JSON.stringify(kid)}. Expected a string.`,\n });\n }\n};\n\nexport const verifyHeaderAlgorithm = (alg: string) => {\n if (!algs.includes(alg)) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidAlgorithm,\n message: `Invalid JWT algorithm ${JSON.stringify(alg)}. Supported: ${algs}.`,\n });\n }\n};\n\nexport const verifySubClaim = (sub?: string) => {\n if (typeof sub !== 'string') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Subject claim (sub) is required and must be a string. Received ${JSON.stringify(sub)}.`,\n });\n }\n};\n\nexport const verifyExpirationClaim = (exp: number | undefined, clockSkewInMs: number) => {\n if (typeof exp !== 'number') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Invalid JWT expiry date (exp) claim ${JSON.stringify(exp)}. Expected a number.`,\n });\n }\n\n const currentDate = new Date(Date.now());\n const expiryDate = new Date(0);\n expiryDate.setUTCSeconds(exp);\n\n const expired = expiryDate.getTime() <= currentDate.getTime() - clockSkewInMs;\n if (expired) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenExpired,\n message: `JWT is expired. Expiry date: ${expiryDate.toUTCString()}, Current date: ${currentDate.toUTCString()}.`,\n });\n }\n};\n\nexport const verifyIssuedAtClaim = (iat: number | undefined, clockSkewInMs: number) => {\n if (typeof iat === 'undefined') {\n return;\n }\n\n if (typeof iat !== 'number') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Invalid JWT issued at date claim (iat) ${JSON.stringify(iat)}. Expected a number.`,\n });\n }\n\n const currentDate = new Date(Date.now());\n const issuedAtDate = new Date(0);\n issuedAtDate.setUTCSeconds(iat);\n\n const postIssued = issuedAtDate.getTime() > currentDate.getTime() + clockSkewInMs;\n if (postIssued) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenIatInTheFuture,\n message: `JWT issued at date claim (iat) is in the future. Issued at date: ${issuedAtDate.toUTCString()}; Current date: ${currentDate.toUTCString()};`,\n });\n }\n};\n","import { type RemoteJWKSetOptions } from 'jose';\n\nimport {\n CACHE_CONTROL_REGEX,\n DEFAULT_CACHE_DURATION,\n GOOGLE_PUBLIC_KEYS_URL,\n MAX_CACHE_LAST_UPDATED_AT_SECONDS\n} from '../constants';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\n\nexport type PublicKeys = { [key: string]: string };\n\ninterface PublicKeysResponse {\n keys: PublicKeys;\n expiresAt: number;\n}\n\nexport type LoadJWKFromRemoteOptions = RemoteJWKSetOptions & {\n kid: string;\n keyURL?: string;\n skipJwksCache?: boolean;\n};\n\ntype CertificateCache = Record<string, string>;\n\nlet cache: CertificateCache = {};\nlet lastUpdatedAt = 0;\nlet googleExpiresAt = 0;\n\nfunction getFromCache(kid: string) {\n return cache[kid];\n}\n\nfunction getCacheValues() {\n return Object.values(cache);\n}\n\nfunction setInCache(kid: string, certificate: string, shouldExpire = true) {\n cache[kid] = certificate;\n lastUpdatedAt = shouldExpire ? Date.now() : -1;\n}\n\nasync function fetchPublicKeys(keyUrl: string): Promise<PublicKeysResponse> {\n const url = new URL(keyUrl);\n const response = await fetch(url);\n if (!response.ok) {\n throw new TokenVerificationError({\n message: `Error loading public keys from ${url.href} with code=${response.status} `,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n\n const data = await response.json();\n const expiresAt = getExpiresAt(response);\n\n return {\n keys: data,\n expiresAt,\n };\n}\n\nexport async function loadJWKFromRemote({\n keyURL,\n skipJwksCache,\n kid,\n}: LoadJWKFromRemoteOptions): Promise<string> {\n const finalKeyURL = keyURL || GOOGLE_PUBLIC_KEYS_URL;\n if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {\n const { keys, expiresAt } = await fetchPublicKeys(finalKeyURL);\n\n if (!keys || Object.keys(keys).length === 0) {\n throw new TokenVerificationError({\n message: `The JWKS endpoint ${finalKeyURL} returned no keys`,\n reason: TokenVerificationErrorReason.RemoteJWKFailedToLoad,\n });\n }\n googleExpiresAt = expiresAt;\n\n Object.entries(keys).forEach(([keyId, cert]) => {\n setInCache(keyId, cert);\n });\n }\n const cert = getFromCache(kid);\n if (!cert) {\n getCacheValues();\n const availableKids = Object.keys(cache).sort().join(', ');\n\n throw new TokenVerificationError({\n message: `No public key found for kid \"${kid}\". Available kids: [${availableKids}]`,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n return cert;\n}\n\nfunction isCacheExpired() {\n const now = Date.now();\n if (lastUpdatedAt === -1) {\n return false;\n }\n\n const cacheAge = now - lastUpdatedAt;\n const maxCacheAge = MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1000;\n const localCacheExpired = cacheAge >= maxCacheAge;\n const googleCacheExpired = now >= googleExpiresAt;\n\n const isExpired = localCacheExpired || googleCacheExpired;\n\n if (isExpired) {\n cache = {};\n }\n\n return isExpired;\n}\n\nfunction getExpiresAt(res: Response) {\n const cacheControlHeader = res.headers.get('cache-control');\n if (!cacheControlHeader) {\n return Date.now() + DEFAULT_CACHE_DURATION;\n }\n const maxAgeMatch = cacheControlHeader.match(CACHE_CONTROL_REGEX);\n const maxAge = maxAgeMatch ? parseInt(maxAgeMatch[1], 10) : DEFAULT_CACHE_DURATION / 1000;\n\n return Date.now() + maxAge * 1000;\n}\n\nexport const getCacheStats = () => ({\n localExpiry: lastUpdatedAt + MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1000,\n googleExpiry: googleExpiresAt,\n cacheCount: Object.keys(cache).length,\n});\n","import type { DecodedIdToken, TernSecureAdminConfig, TernSecureConfig, TernSecureUserData} from '@tern-secure/types';\n\nimport type { JwtReturnType } from '../jwt/types';\nimport { ternDecodeJwt, verifyJwt, type VerifyJwtOptions } from '../jwt/verifyJwt';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport type { LoadJWKFromRemoteOptions } from './keys';\nimport { loadJWKFromRemote } from './keys';\n\nexport type VerifyTokenVOptions = Omit<VerifyJwtOptions, 'key'> & Omit<LoadJWKFromRemoteOptions, 'kid'> & {\n jwtKey?: string;\n};\n\nexport { TernSecureConfig, TernSecureAdminConfig, TernSecureUserData };\n\nexport async function verifyToken(\n token: string,\n options: VerifyTokenVOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { data: decodedResult, errors } = ternDecodeJwt(token);\n\n if (errors) {\n return { errors };\n }\n\n const { header } = decodedResult;\n const { kid } = header;\n\n if (!kid) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'JWT \"kid\" header is missing.',\n }),\n ],\n };\n }\n\n try {\n const key = options.jwtKey || (await loadJWKFromRemote({ ...options, kid }));\n\n if (!key) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `No public key found for kid \"${kid}\".`,\n }),\n ],\n };\n }\n return await verifyJwt(token, { ...options, key });\n } catch (error) {\n if (error instanceof TokenVerificationError) {\n return { errors: [error] };\n }\n return {\n errors: [error as TokenVerificationError],\n };\n }\n}\n","import type { RequestFunction } from '../request';\n\nexport abstract class AbstractAPI {\n constructor(protected request: RequestFunction) {}\n\n protected requireApiKey(apiKey: string) {\n if (!apiKey) {\n throw new Error('A valid API key is required.');\n }\n }\n}\n","import { AbstractAPI } from './AbstractApi';\n\n\nexport interface AppCheckTokenResponse {\n token: string;\n ttl: string;\n}\n\ntype AppCheckParams = {\n accessToken: string;\n projectId: string;\n appId: string;\n customToken: string;\n limitedUse?: boolean;\n}\n\nexport function getSdkVersion(): string {\n return '12.7.0';\n}\n\nconst FIREBASE_APP_CHECK_CONFIG_HEADERS = {\n 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`\n};\n\n/**\n * App Check API for managing Firebase App Check tokens via REST\n * Firebase REST API endpoint: https://firebaseappcheck.googleapis.com/v1beta/projects/{projectId}/apps/{appId}:exchangeCustomToken\n */\nexport class AppCheckApi extends AbstractAPI {\n public async exchangeCustomToken(params: AppCheckParams): Promise<AppCheckTokenResponse> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeCustomToken`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({customToken, limitedUse}),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n public async exchangeDebugToken(params: AppCheckParams): Promise<AppCheckTokenResponse> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeDebugToken`;\n\n const headers: Record<string, string> = {\n ...FIREBASE_APP_CHECK_CONFIG_HEADERS,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n const body = {\n customToken,\n limitedUse,\n }\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n}\n","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype sendEmailVerificationParams = {\n idToken: string;\n requestType: 'VERIFY_EMAIL';\n};\n\ntype ConfirmEmailVerificationParams = {\n oobCode: string;\n};\n\n\nexport class EmailApi extends AbstractAPI {\n public async verifyEmailVerification(apiKey: string, params: sendEmailVerificationParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"sendOobCode\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async confirmEmailVerification(apiKey: string, params: ConfirmEmailVerificationParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"sendOobCode\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n}","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype ConfirmPasswordResetParams = {\n oobCode: string;\n newPassword: string;\n};\n\ntype VerifyPasswordResetCodeParams = {\n oobCode: string;\n};\n\ntype ChangePasswordParams = {\n idToken: string;\n password: string;\n returnSecureToken?: boolean;\n};\n\nexport class PasswordApi extends AbstractAPI {\n public async verifyPasswordResetCode(apiKey: string, params: VerifyPasswordResetCodeParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async confirmPasswordReset(apiKey: string, params: ConfirmPasswordResetParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async changePassword(apiKey: string, params: ChangePasswordParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n}","import type { ResetPasswordEmail } from '../resources/EmailAddress';\nimport { AbstractAPI } from './AbstractApi';\n\ntype ResetPasswordEmailParams = {\n email: string;\n requestType: 'PASSWORD_RESET';\n};\n\nexport class SignInApi extends AbstractAPI {\n public async resetPasswordEmail(\n apiKey: string,\n params: ResetPasswordEmailParams\n ): Promise<ResetPasswordEmail> {\n try {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n\n const response = await this.request<ResetPasswordEmail>({\n endpoint: 'sendOobCode',\n method: 'POST',\n apiKey,\n bodyParams: restParams,\n });\n\n if (response.errors) {\n const errorMessage = response.errors[0]?.message || 'Failed to send reset password email';\n throw new Error(errorMessage);\n }\n return response.data;\n } catch (error) {\n const contextualMessage = `Failed to send reset password email: ${error instanceof Error ? error.message : 'Unknown error'}`;\n throw new Error(contextualMessage);\n }\n }\n}","import type { IdAndRefreshTokens } from '../resources/Token';\nimport { AbstractAPI } from './AbstractApi';\n\n\ntype CreateSignInTokenParams = {\n token: string;\n returnSecureToken?: boolean;\n};\n\nexport class SignInTokenApi extends AbstractAPI {\n public async createCustomToken(\n apiKey: string,\n params: CreateSignInTokenParams,\n ): Promise<IdAndRefreshTokens> {\n try {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n\n const response = await this.request<IdAndRefreshTokens>({\n endpoint: \"signInWithCustomToken\",\n method: 'POST',\n bodyParams: restParams,\n });\n\n if (response.errors) {\n const errorMessage = response.errors[0]?.message || 'Failed to create custom token';\n throw new Error(errorMessage);\n }\n\n return response.data;\n } catch (error) {\n const contextualMessage = `Failed to create custom token: ${error instanceof Error ? error.message : 'Unknown error'}`;\n throw new Error(contextualMessage);\n }\n }\n}\n","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype CreateSignUpTokenParams = {\n email: string;\n password: string;\n returnSecureToken?: boolean;\n};\n\n\nexport class SignUpApi extends AbstractAPI {\n public async createCustomToken(apiKey: string, params: CreateSignUpTokenParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"signUp\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n}\n","import type { IdAndRefreshTokens } from '../resources/Token';\nimport { AbstractAPI } from './AbstractApi';\n\ntype RefreshTokenParams = {\n expired_token?: string;\n refresh_token: string;\n request_origin?: string;\n request_originating_ip?: string;\n request_headers?: Record<string, string[]>;\n suffixed_cookies?: boolean;\n app_check_token?: string;\n format?: 'token' | 'cookie';\n};\n\ntype IdAndRefreshTokensParams = {\n token: string;\n returnSecureToken?: boolean;\n};\n\ntype IdAndRefreshTokensOptions = {\n referer?: string;\n appCheckToken?: string;\n};\n\nexport class TokenApi extends AbstractAPI {\n public async refreshToken(apiKey: string, params: RefreshTokenParams) {\n this.requireApiKey(apiKey);\n const { refresh_token, request_origin, app_check_token, ...restParams } = params;\n\n const headers: Record<string, string> = {};\n if (request_origin) {\n headers['Referer'] = request_origin;\n }\n\n if (app_check_token) {\n headers['X-Firebase-AppCheck'] = app_check_token;\n }\n\n\n const bodyParams = {\n grant_type: 'refresh_token',\n refresh_token,\n ...restParams,\n };\n\n return this.request({\n endpoint: 'refreshToken',\n method: 'POST',\n apiKey,\n bodyParams,\n headerParams: headers,\n });\n }\n\n public async exchangeCustomForIdAndRefreshTokens(\n apiKey: string,\n params: IdAndRefreshTokensParams,\n options?: IdAndRefreshTokensOptions,\n ): Promise<IdAndRefreshTokens> {\n this.requireApiKey(apiKey);\n\n const headers: Record<string, string> = {};\n if (options?.referer) {\n headers['Referer'] = options.referer;\n }\n if (options?.appCheckToken) {\n headers['X-Firebase-AppCheck'] = options.appCheckToken;\n }\n\n const response = await this.request<IdAndRefreshTokens>({\n endpoint: 'signInWithCustomToken',\n method: 'POST',\n apiKey,\n bodyParams: params,\n headerParams: headers,\n });\n\n if (response.errors) {\n throw new Error(response.errors[0].message);\n }\n\n if (!response.data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n return response.data;\n }\n}\n","import type { User } from '../resources/User';\nimport { AbstractAPI } from './AbstractApi';\n\ntype UserDataParams = {\n localId?: string;\n idToken?: string;\n};\n\ntype UserDataOptions = {\n referer?: string;\n};\n\nexport class UserData extends AbstractAPI {\n public async getUserData(apiKey: string, params: UserDataParams, options?: UserDataOptions) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n\n const headers: Record<string, string> = {};\n if (options?.referer) {\n headers['Referer'] = options.referer;\n }\n return this.request<User>({\n endpoint: 'lookup',\n method: 'POST',\n apiKey,\n bodyParams: restParams,\n headerParams: headers,\n });\n }\n}","/**\n * This file exports APIs that vary across runtimes (i.e. Node & Browser - V8 isolates)\n * as a singleton object.\n *\n * Runtime polyfills are written in VanillaJS for now to avoid TS complication. Moreover,\n * due to this issue https://github.com/microsoft/TypeScript/issues/44848, there is not a good way\n * to tell Typescript which conditional import to use during build type.\n *\n * The Runtime type definition ensures type safety for now.\n * Runtime js modules are copied into dist folder with bash script.\n *\n * TODO: Support TS runtime modules\n */\n\n// @ts-ignore - These are package subpaths\nimport { webcrypto as crypto } from '#crypto';\n\ntype Runtime = {\n crypto: Crypto;\n fetch: typeof globalThis.fetch;\n AbortController: typeof globalThis.AbortController;\n Blob: typeof globalThis.Blob;\n FormData: typeof globalThis.FormData;\n Headers: typeof globalThis.Headers;\n Request: typeof globalThis.Request;\n Response: typeof globalThis.Response;\n};\n\n// Invoking the global.fetch without binding it first to the globalObject fails in\n// Cloudflare Workers with an \"Illegal Invocation\" error.\n//\n// The globalThis object is supported for Node >= 12.0.\n//\n// https://github.com/supabase/supabase/issues/4417\nconst globalFetch = fetch.bind(globalThis);\n\nexport const runtime: Runtime = {\n crypto,\n get fetch() {\n // We need to use the globalFetch for Cloudflare Workers but the fetch for testing\n return process.env.NODE_ENV === 'test' ? fetch : globalFetch;\n },\n AbortController: globalThis.AbortController,\n Blob: globalThis.Blob,\n FormData: globalThis.FormData,\n Headers: globalThis.Headers,\n Request: globalThis.Request,\n Response: globalThis.Response,\n};\n","export const FIREBASE_AUTH_EMULATOR_HOST = process.env.FIREBASE_AUTH_EMULATOR_HOST;\n\nexport function emulatorHost(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n return FIREBASE_AUTH_EMULATOR_HOST;\n}\n\nexport function useEmulator(): boolean {\n return !!emulatorHost();\n}\n","import { FIREBASE_AUTH_EMULATOR_HOST, useEmulator } from './emulator';\n\nexport const topLevelEndpoint = (apiKey: string, projectId: string, version: string) => {\n return `https://identitytoolkit.googleapis.com/${version}/projects/${projectId}${apiKey}`;\n};\n\nexport const lookupEndpoint = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=${apiKey}`;\n};\n\nexport const getRefreshTokenEndpoint = (apiKey: string) => {\n return `https://securetoken.googleapis.com/v1/token?key=${apiKey}`;\n};\n\nexport const signInWithPassword = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${apiKey}`;\n};\n\nexport const signUpEndpoint = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${apiKey}`;\n};\n\nexport const sendOobCode = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${apiKey}`;\n}\n\n\nexport const getCustomTokenEndpoint = (apiKey: string) => {\n if (useEmulator() && FIREBASE_AUTH_EMULATOR_HOST) {\n let protocol = 'http://';\n if (FIREBASE_AUTH_EMULATOR_HOST.startsWith('http://')) {\n protocol = '';\n }\n\n return `${protocol}${FIREBASE_AUTH_EMULATOR_HOST}/identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apiKey}`;\n }\n return `https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apiKey}`;\n};\n\nexport const verifyPasswordResetCode = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=${apiKey}`;\n};\n","import type {\n TernSecureFireRestError,\n TernSecureFireRestErrorJSON,\n} from \"@tern-secure/types\";\n\nimport { constants } from \"../constants\";\nimport { runtime } from \"../runtime\";\nimport {\n getCustomTokenEndpoint,\n getRefreshTokenEndpoint,\n lookupEndpoint,\n sendOobCode,\n signInWithPassword,\n signUpEndpoint,\n} from \"./endpointUrl\";\n\nexport type HTTPMethod = \"DELETE\" | \"GET\" | \"PATCH\" | \"POST\" | \"PUT\";\nexport type FirebaseEndpoint =\n | \"lookup\"\n | \"refreshToken\"\n | \"signInWithPassword\"\n | \"signUp\"\n | \"signInWithCustomToken\"\n | \"passwordReset\"\n | \"sendOobCode\"\n\nexport type BackendApiRequestOptions = {\n endpoint: FirebaseEndpoint;\n method?: HTTPMethod;\n apiKey?: string;\n queryParams?: Record<string, unknown>;\n headerParams?: Record<string, string>;\n bodyParams?: Record<string, unknown>;\n formData?: FormData;\n}\n\nexport type BackendApiResponse<T> =\n | {\n data: T;\n errors: null;\n totalCount?: number;\n }\n | {\n data: null;\n errors: TernSecureFireRestError[];\n totalCount?: never;\n status?: number;\n statusText?: string;\n retryAfter?: number;\n };\n\nexport type RequestFunction = ReturnType<typeof createRequest>;\n\ntype CreateRequestOptions = {\n apiKey?: string;\n apiUrl?: string;\n apiVersion?: string;\n};\n\nconst FIREBASE_ENDPOINT_MAP: Record<FirebaseEndpoint, (apiKey: string) => string> = {\n refreshToken: getRefreshTokenEndpoint,\n signInWithPassword: signInWithPassword,\n signUp: signUpEndpoint,\n signInWithCustomToken: getCustomTokenEndpoint,\n passwordReset: sendOobCode,\n sendOobCode: sendOobCode,\n lookup: lookupEndpoint\n};\n\n\nexport function createRequest(options: CreateRequestOptions) {\n const requestFn = async <T>(\n requestOptions: BackendApiRequestOptions\n ): Promise<BackendApiResponse<T>> => {\n const { endpoint, method, apiKey, queryParams, headerParams, bodyParams, formData } =\n requestOptions;\n\n\n if (!apiKey) {\n return {\n data: null,\n errors: [\n {\n domain: \"none\",\n reason: \"invalid_parameter\",\n message: \"Firebase API key is required\",\n code: \"400\",\n },\n ],\n };\n }\n\n const endpointUrl = FIREBASE_ENDPOINT_MAP[endpoint](apiKey);\n const finalUrl = new URL(endpointUrl);\n\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value) {\n [value].flat().forEach(v => finalUrl.searchParams.append(key, v as string));\n }\n });\n }\n\n const headers: Record<string, any> = {\n ...headerParams,\n };\n let res: Response | undefined;\n\n try {\n if (formData) {\n res = await runtime.fetch(finalUrl.href, {\n method,\n headers,\n body: formData,\n });\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n const hasBody =\n method !== \"GET\" && bodyParams && Object.keys(bodyParams).length > 0;\n const body = hasBody ? { body: JSON.stringify(bodyParams) } : null;\n\n res = await runtime.fetch(finalUrl.href, {\n method,\n headers,\n ...body,\n });\n }\n\n const isJSONResponse =\n res?.headers &&\n res.headers?.get(constants.Headers.ContentType)?.includes(constants.ContentTypes.Json);\n \n let responseBody;\n try {\n const text = await res.text();\n try {\n responseBody = JSON.parse(text);\n } catch {\n responseBody = text;\n }\n } catch (e) {\n responseBody = null;\n }\n\n\n if (!res.ok) {\n return {\n data: null,\n errors: parseErrors(responseBody),\n status: res?.status,\n statusText: res?.statusText,\n };\n }\n\n return {\n data: responseBody,\n errors: null,\n };\n } catch (error) {\n if (error instanceof Error) {\n return {\n data: null,\n errors: [\n {\n domain: \"none\",\n reason: \"request_failed\",\n message: error.message || \"An unexpected error occurred\",\n code: \"500\",\n },\n ],\n };\n }\n\n return {\n data: null,\n errors: parseErrors(error),\n status: res?.status,\n statusText: res?.statusText,\n };\n }\n };\n return requestFn;\n}\n\nfunction parseErrors(data: unknown): TernSecureFireRestError[] {\n let parsedData = data;\n if (typeof data === \"string\") {\n try {\n parsedData = JSON.parse(data);\n } catch (error) {\n return [];\n }\n }\n\n if (!parsedData || typeof parsedData !== \"object\") {\n return [];\n }\n\n if (\"error\" in parsedData && typeof parsedData.error === \"object\" && parsedData.error !== null) {\n const errorObj = parsedData.error as any;\n\n if (\"errors\" in errorObj && Array.isArray(errorObj.errors) && errorObj.errors.length > 0) {\n return errorObj.errors.map((err: any) => parseError({\n code: errorObj.code || \"unknown_error\", \n message: err.message || \"Unknown error\",\n domain: err.domain,\n reason: err.reason\n }));\n }\n\n // Fallback: create single error from main error object\n return [parseError({\n code: errorObj.code?.toString() || \"unknown_error\",\n message: errorObj.message || \"Unknown error\",\n domain: errorObj.domain || \"unknown\",\n reason: errorObj.reason || errorObj.code?.toString() || \"unknown_error\"\n })];\n }\n\n return [];\n}\n\nexport function parseError(error: TernSecureFireRestErrorJSON): TernSecureFireRestError {\n return {\n domain: error.domain,\n reason: error.reason,\n message: error.message,\n code: error.code\n };\n}\n","import { AppCheckApi, EmailApi, PasswordApi, SignInApi, SignInTokenApi, SignUpApi, TokenApi, UserData } from './endpoints';\nimport { createRequest } from './request';\n\nexport type CreateFireApiOptions = Parameters<typeof createRequest>[0];\nexport type ApiClient = ReturnType<typeof createFireApi>;\n\nexport function createFireApi(options: CreateFireApiOptions) {\n const request = createRequest(options);\n return {\n appCheck: new AppCheckApi(request),\n email: new EmailApi(request),\n password: new PasswordApi(request),\n signIn: new SignInApi(request),\n signInToken: new SignInTokenApi(request),\n signUp: new SignUpApi(request),\n tokens: new TokenApi(request),\n userData: new UserData(request),\n };\n}\n","import type { AuthenticateRequestOptions} from \"../tokens/types\";\n\nexport type RuntimeOptions = Omit<AuthenticateRequestOptions, \"apiUrl\">;\n\nexport type buildTimeOptions = Partial<Pick<AuthenticateRequestOptions, \"apiKey\" | \"apiUrl\" | \"apiVersion\">>;\n\nconst defaultOptions: buildTimeOptions = {\n apiKey: undefined,\n apiUrl: undefined,\n apiVersion: undefined,\n};\n\nexport function mergePreDefinedOptions(\n userOptions: buildTimeOptions = {}\n): buildTimeOptions {\n return {\n ...defaultOptions,\n ...userOptions,\n };\n}","import { ms, type StringValue } from '@tern-secure/shared/ms';\nimport type { DecodedIdToken } from '@tern-secure/types';\n\nimport { getAuth } from '../auth';\nimport { constants } from '../constants';\nimport { ternDecodeJwt } from '../jwt/verifyJwt';\nimport type { TokenCarrier } from '../utils/errors';\nimport {\n RefreshTokenErrorReason,\n TokenVerificationError,\n TokenVerificationErrorReason,\n} from '../utils/errors';\nimport type { RequestState, SignedInState, SignedOutState } from './authstate';\nimport { AuthErrorReason, signedIn, signedOut } from './authstate';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createRequestProcessor } from './c-authenticateRequestProcessor';\nimport { getCookieNameEnvironment, getCookiePrefix } from './cookie';\nimport { createTernSecureRequest } from './ternSecureRequest';\nimport type { AuthenticateRequestOptions } from './types';\nimport { verifyToken } from './verify';\n\n\nfunction hasAuthorizationHeader(request: Request): boolean {\n return request.headers.has('Authorization');\n}\n\nfunction convertToSeconds(value: StringValue) {\n return ms(value) / 1000;\n}\n\nfunction isRequestForRefresh(\n error: TokenVerificationError,\n context: { refreshTokenInCookie?: string },\n request: Request,\n) {\n return (\n error.reason === TokenVerificationErrorReason.TokenExpired &&\n !!context.refreshTokenInCookie &&\n request.method === 'GET'\n );\n}\n\nexport async function authenticateRequest(\n request: Request,\n options: AuthenticateRequestOptions,\n): Promise<RequestState> {\n const context = createRequestProcessor(createTernSecureRequest(request), options);\n const { refreshTokenInCookie } = context;\n\n const { refreshExpiredIdToken } = getAuth(options);\n\n\n function checkSessionTimeout(authTimeValue: number): SignedOutState | null {\n const defaultMaxAgeSeconds = convertToSeconds('5 days');\n const REAUTH_PERIOD_SECONDS = context.session?.maxAge\n ? convertToSeconds(context.session.maxAge)\n : defaultMaxAgeSeconds;\n\n const currentTime = Math.floor(Date.now() / 1000);\n const authAge = currentTime - authTimeValue;\n\n\n if (authTimeValue > 0 && authAge > REAUTH_PERIOD_SECONDS) {\n return signedOut(context, AuthErrorReason.AuthTimeout, 'Authentication expired');\n }\n\n return null;\n }\n\n async function refreshToken() {\n if (!refreshTokenInCookie) {\n return {\n data: null,\n error: {\n message: 'No refresh token available',\n reason: AuthErrorReason.SessionTokenMissing,\n },\n };\n }\n return await refreshExpiredIdToken(refreshTokenInCookie, {\n referer: context.ternUrl.origin,\n });\n }\n\n async function handleRefresh(): Promise<\n | { data: { decoded: DecodedIdToken; token: string; headers: Headers }; error: null }\n | { data: null; error: any }\n > {\n const { data: refreshedData, error } = await refreshToken();\n if (!refreshedData) {\n return { data: null, error };\n }\n\n const headers = new Headers();\n const { idToken } = refreshedData;\n\n const maxAge = 365 * 24 * 60 * 60;\n const cookiePrefix = getCookiePrefix();\n const idTokenCookieName = getCookieNameEnvironment(constants.Cookies.IdToken, cookiePrefix);\n const baseCookieAttributes = 'HttpOnly; Secure; SameSite=Strict; Max-Age=' + `${maxAge}; Path=/`;\n\n const idTokenCookie = `${idTokenCookieName}=${idToken}; ${baseCookieAttributes};`;\n headers.append('Set-Cookie', idTokenCookie);\n\n const { data: decoded, errors } = await verifyToken(idToken, options);\n if (errors) {\n return {\n data: null,\n error: errors ? errors[0] : new Error('Failed to verify refreshed token'),\n };\n }\n return { data: { decoded, token: idToken, headers }, error: null };\n }\n\n async function handleLocalHandshakeWithErrorCheck(\n context: RequestProcessorContext,\n reason: string,\n message: string,\n skipSessionCheck: boolean = false,\n ): Promise<SignedInState | SignedOutState> {\n const hasRefreshTokenInCookie = !!context.refreshTokenInCookie;\n if (!hasRefreshTokenInCookie) {\n return signedOut(context, reason, 'Refresh token missing in cookie');\n }\n\n if (reason === AuthErrorReason.TernAutWithoutSessionToken) {\n if (!skipSessionCheck) {\n const sessionTimeoutResult = checkSessionTimeout(context.ternAuth);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n }\n\n const { data, error } = await handleRefresh();\n\n if (data) {\n return signedIn(context, data.decoded, data.headers, data.token);\n }\n\n return signedOut(context, reason, 'Failed to refresh idToken');\n }\n\n\n if (reason === AuthErrorReason.SessionTokenWithoutTernAUT ||\n reason === AuthErrorReason.SessionTokenIATBeforeTernAUT) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = ternDecodeJwt(context.idTokenInCookie!);\n\n if (errors) {\n throw errors[0];\n }\n\n const authTime = data.payload.auth_time;\n\n if (!authTime || typeof authTime !== 'number') {\n return signedOut(context, reason, 'Token missing auth_time');\n }\n\n if (!skipSessionCheck) {\n const sessionTimeoutResult = checkSessionTimeout(authTime);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data: verifiedToken, errors: verifyErrors } = await verifyToken(context.idTokenInCookie!, options);\n\n if (verifyErrors) {\n throw verifyErrors[0];\n }\n\n const headers = new Headers();\n const oneYearInSeconds = 365 * 24 * 60 * 60;\n const ternAutCookie = `${constants.Cookies.TernAut}=${authTime}; Max-Age=${oneYearInSeconds}; Secure; SameSite=Strict; Path=/`;\n headers.append('Set-Cookie', ternAutCookie);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return signedIn(context, verifiedToken, headers, context.idTokenInCookie!);\n }\n\n return signedOut(context, reason, message);\n }\n\n async function authenticateRequestWithTokenInCookie() {\n const hasTernAuth = context.ternAuth\n const hasIdTokenInCookie = !!context.idTokenInCookie;\n\n if (!hasTernAuth && !hasIdTokenInCookie) {\n return signedOut(context, AuthErrorReason.SessionTokenAndAuthMissing);\n }\n\n if (!hasTernAuth && hasIdTokenInCookie) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenWithoutTernAUT, '');\n }\n\n if (hasTernAuth && !hasIdTokenInCookie) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.TernAutWithoutSessionToken, '');\n }\n\n const sessionTimeoutResult = checkSessionTimeout(context.ternAuth);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data: decodedResult, errors: decodeErrors } = ternDecodeJwt(context.idTokenInCookie!);\n\n if (decodeErrors) {\n return handleError(decodeErrors[0], 'cookie');\n }\n\n const tokenIat = decodedResult.payload.iat;\n if (!tokenIat) {\n return signedOut(context, AuthErrorReason.SessionTokenMissing, '');\n }\n\n if (tokenIat < context.ternAuth) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenIATBeforeTernAUT, '', true);\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = await verifyToken(context.idTokenInCookie!, options);\n\n if (errors) {\n throw errors[0];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const signedInRequestState = signedIn(context, data, undefined, context.idTokenInCookie!);\n\n return signedInRequestState;\n } catch (err) {\n return handleError(err, 'cookie');\n }\n\n return signedOut(context, AuthErrorReason.UnexpectedError);\n }\n\n async function authenticateRequestWithTokenInHeader() {\n const { sessionTokenInHeader } = context;\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = await verifyToken(sessionTokenInHeader!, options);\n\n if (errors) {\n throw errors[0];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const signedInRequestState = signedIn(context, data, undefined, sessionTokenInHeader!);\n return signedInRequestState;\n } catch (err) {\n return handleError(err, 'header');\n }\n }\n\n async function handleError(\n err: unknown,\n tokenCarrier: TokenCarrier,\n ): Promise<SignedInState | SignedOutState> {\n if (!(err instanceof TokenVerificationError)) {\n return signedOut(context, AuthErrorReason.UnexpectedError);\n }\n\n let refreshError: string | null;\n if (isRequestForRefresh(err, context, request)) {\n const { data, error } = await handleRefresh();\n if (data) {\n\n const signedInState = signedIn(context, data.decoded, data.headers, data.token);\n return signedInState;\n }\n\n if (error?.cause?.reason) {\n refreshError = error.cause.reason;\n }\n } else {\n if (request.method !== 'GET') {\n refreshError = RefreshTokenErrorReason.NonEligibleNonGet;\n } else if (!context.refreshTokenInCookie) {\n refreshError = RefreshTokenErrorReason.NonEligibleNoCookie;\n } else {\n refreshError = null;\n }\n }\n\n err.tokenCarrier = tokenCarrier;\n\n return signedOut(context, err.reason, err.getFullMessage());\n }\n\n if (hasAuthorizationHeader(request)) {\n return authenticateRequestWithTokenInHeader();\n }\n\n return authenticateRequestWithTokenInCookie();\n}\n","import { type JwtReturnType } from \"./types\";\n\nexport function createJwtGuard<T extends (...args: any[]) => JwtReturnType<any, any>>(decodedFn: T) {\n return (...args: Parameters<T>): NonNullable<Awaited<ReturnType<T>>['data']> | never => {\n const { data, errors } = decodedFn(...args);\n\n if (errors) {\n throw errors[0];\n }\n\n return data;\n };\n}\n","import type {\n DecodedIdToken,\n TernVerificationResult,\n} from \"@tern-secure/types\";\nimport { createRemoteJWKSet, decodeJwt,jwtVerify } from \"jose\";\n\n\nexport type FirebaseIdTokenPayload = DecodedIdToken;\n\n// Firebase public key endpoints\nconst FIREBASE_ID_TOKEN_URL =\n \"https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com\";\nconst FIREBASE_SESSION_CERT_URL =\n \"https://identitytoolkit.googleapis.com/v1/sessionCookiePublicKeys\";\n\n//const FIREBASE_NEW_SESSION_PK = \"https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys\"\n\n// Simple in-memory cache for JWKS\nlet idTokenJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\nlet sessionJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\n\nconst getIdTokenJWKS = () => {\n if (!idTokenJWKS) {\n idTokenJWKS = createRemoteJWKSet(new URL(FIREBASE_ID_TOKEN_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return idTokenJWKS;\n};\n\nconst getSessionJWKS = () => {\n if (!sessionJWKS) {\n sessionJWKS = createRemoteJWKSet(new URL(FIREBASE_SESSION_CERT_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return sessionJWKS;\n};\n\n\n\nexport async function verifyToken(\n token: string,\n isSessionCookie = false\n): Promise<TernVerificationResult> {\n try {\n const projectId = process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;\n if (!projectId) {\n throw new Error(\"Firebase Project ID is not configured\");\n }\n\n const { decoded } = decodeJwt(token);\n if (!decoded) {\n throw new Error(\"Invalid token format\");\n }\n\n let retries = 3;\n let lastError: Error | null = null;\n\n while (retries > 0) {\n try {\n // Use different JWKS based on token type\n const JWKS = isSessionCookie ? getSessionJWKS() : getIdTokenJWKS();\n\n const { payload } = await jwtVerify(token, JWKS, {\n issuer: isSessionCookie\n ? \"https://session.firebase.google.com/\" + projectId\n : \"https://securetoken.google.com/\" + projectId,\n audience: projectId,\n algorithms: [\"RS256\"],\n });\n\n const firebasePayload = payload as unknown as FirebaseIdTokenPayload;\n const now = Math.floor(Date.now() / 1000);\n\n // Verify token claims\n if (firebasePayload.exp <= now) {\n throw new Error(\"Token has expired\");\n }\n\n if (firebasePayload.iat > now) {\n throw new Error(\"Token issued time is in the future\");\n }\n\n if (!firebasePayload.sub) {\n throw new Error(\"Token subject is empty\");\n }\n\n if (firebasePayload.auth_time > now) {\n throw new Error(\"Token auth time is in the future\");\n }\n\n return {\n valid: true,\n uid: firebasePayload.sub,\n sub: firebasePayload.sub,\n email: firebasePayload.email,\n email_verified: firebasePayload.email_verified,\n auth_time: firebasePayload.auth_time,\n iat: firebasePayload.iat,\n exp: firebasePayload.exp,\n aud: firebasePayload.aud,\n iss: firebasePayload.iss,\n firebase: firebasePayload.firebase,\n phone_number: firebasePayload.phone_number,\n picture: firebasePayload.picture,\n };\n } catch (error) {\n lastError = error as Error;\n if (error instanceof Error && error.name === \"JWKSNoMatchingKey\") {\n console.warn(`JWKS retry attempt ${4 - retries}:`, error.message);\n retries--;\n if (retries > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n continue;\n }\n }\n throw error;\n }\n }\n\n throw lastError || new Error(\"Failed to verify token after retries\");\n } catch (error) {\n console.error(\"Token verification details:\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n decoded: decodeJwt(token),\n isSessionCookie,\n });\n\n return {\n valid: false,\n error: {\n success: false,\n message: error instanceof Error ? error.message : \"Invalid token\",\n code: \"INVALID_TOKEN\",\n },\n };\n }\n}\n","import type { JWTPayload } from '@tern-secure/types';\nimport { importPKCS8, SignJWT } from 'jose';\n\nimport type { JwtReturnType } from './types';\n\n\nexport interface CustomTokenClaims {\n [key: string]: unknown;\n}\n\nexport class CustomTokenError extends Error {\n constructor(\n message: string,\n public code?: string,\n ) {\n super(message);\n this.name = 'CustomTokenError';\n }\n}\n\nconst RESERVED_CLAIMS = [\n 'acr',\n 'amr',\n 'at_hash',\n 'aud',\n 'auth_time',\n 'azp',\n 'cnf',\n 'c_hash',\n 'exp',\n 'firebase',\n 'iat',\n 'iss',\n 'jti',\n 'nbf',\n 'nonce',\n 'sub',\n];\n\nasync function createCustomTokenJwt(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<JwtReturnType<string, CustomTokenError>> {\n try {\n const privateKey = process.env.FIREBASE_PRIVATE_KEY;\n const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;\n\n if (!privateKey || !clientEmail) {\n return {\n errors: [\n new CustomTokenError(\n 'Missing FIREBASE_PRIVATE_KEY or FIREBASE_CLIENT_EMAIL environment variables',\n 'MISSING_ENV_VARS',\n ),\n ],\n };\n }\n\n if (!uid || typeof uid !== 'string') {\n return {\n errors: [new CustomTokenError('uid must be a non-empty string', 'INVALID_UID')],\n };\n }\n\n if (uid.length > 128) {\n return {\n errors: [new CustomTokenError('uid must not exceed 128 characters', 'UID_TOO_LONG')],\n };\n }\n\n if (developerClaims) {\n for (const claim of Object.keys(developerClaims)) {\n if (RESERVED_CLAIMS.includes(claim)) {\n return {\n errors: [new CustomTokenError(`Custom claim '${claim}' is reserved`, 'RESERVED_CLAIM')],\n };\n }\n }\n }\n\n // Set expiration (default 1 hour, max 1 hour)\n const expiresIn = 3600;\n const now = Math.floor(Date.now() / 1000);\n\n const parsedPrivateKey = await importPKCS8(privateKey.replace(/\\\\n/g, '\\n'), 'RS256');\n\n const payload: JWTPayload = {\n iss: clientEmail,\n sub: clientEmail,\n aud: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',\n iat: now,\n exp: now + expiresIn,\n uid: uid,\n ...developerClaims,\n };\n\n const jwt = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', typ: 'JWT' })\n .setIssuedAt(now)\n .setExpirationTime(now + expiresIn)\n .setIssuer(clientEmail)\n .setSubject(clientEmail)\n .setAudience(\n 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',\n )\n .sign(parsedPrivateKey);\n\n return {\n data: jwt,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error occurred';\n return {\n errors: [\n new CustomTokenError(`Failed to create custom token: ${message}`, 'TOKEN_CREATION_FAILED'),\n ],\n };\n }\n}\n\nexport async function createCustomToken(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<string> {\n const { data, errors } = await createCustomTokenJwt(uid, developerClaims);\n\n if (errors) {\n throw errors[0];\n }\n\n return data;\n}\n\nexport function createCustomTokenWithResult(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<JwtReturnType<string, CustomTokenError>> {\n return createCustomTokenJwt(uid, developerClaims);\n}","import type { JWTPayload } from '@tern-secure/types';\nimport type { KeyLike } from 'jose';\nimport { base64url,importPKCS8, SignJWT, } from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { fetchAny } from '../utils/fetcher'\nimport { ALGORITHM_RS256 } from './types';\n\nexport interface SignJwtOptions {\n algorithm?: string;\n header?: Record<string, unknown>;\n}\n\n\nexport type SignOptions = {\n readonly payload: JWTPayload;\n readonly privateKey: string;\n readonly keyId?: string;\n};\n\n\nasync function ternSignJwt(opts: SignOptions): Promise<string> {\n const { payload, privateKey, keyId } = opts;\n let key: KeyLike;\n\n try {\n key = await importPKCS8(privateKey, ALGORITHM_RS256);\n } catch (error) {\n throw new TokenVerificationError({\n message: `Failed to import private key: ${(error as Error).message}`,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n\n return new SignJWT(payload)\n .setProtectedHeader({ alg: ALGORITHM_RS256, kid: keyId })\n .sign(key);\n}\n\n\nexport type SignBlobOptions = {\n readonly serviceAccountId: string;\n readonly accessToken: string;\n readonly payload: JWTPayload;\n};\n\n\nfunction formatBase64(value: string) {\n return value.replace(/\\//g, '_').replace(/\\+/g, '-').replace(/=+$/, '');\n}\n\nfunction encodeSegment(segment: Record<string, string> | JWTPayload): string {\n const value = JSON.stringify(segment);\n\n return formatBase64(base64url.encode(value));\n}\n\n\nasync function ternSignBlob({\n payload,\n serviceAccountId,\n accessToken\n}: SignBlobOptions): Promise<string> {\n const url = `https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${serviceAccountId}:signBlob`;\n const header = {\n alg: ALGORITHM_RS256,\n typ: 'JWT'\n };\n const token = `${encodeSegment(header)}.${encodeSegment(payload)}`;\n const request: RequestInit = {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`\n },\n body: JSON.stringify({payload: base64url.encode(token)})\n };\n const response = await fetchAny(url, request);\n const blob = await response.blob();\n const key = await blob.text();\n const {signedBlob} = JSON.parse(key);\n\n return `${token}.${formatBase64(signedBlob)}`;\n}\n\nexport { ternSignJwt, ternSignBlob };\n","async function getDetailFromResponse(response: Response): Promise<string> {\n const json = await response.json();\n\n if (!json) {\n return 'Missing error payload';\n }\n\n let detail =\n typeof json.error === 'string'\n ? json.error\n : (json.error?.message ?? 'Missing error payload');\n\n if (json.error_description) {\n detail += ' (' + json.error_description + ')';\n }\n\n return detail;\n}\n\nexport async function fetchText(url: string, init: RequestInit) {\n return (await fetchAny(url, init)).text();\n}\n\nexport async function fetchJson(url: string, init: RequestInit) {\n return (await fetchAny(url, init)).json();\n}\n\nexport async function fetchAny(url: string, init: RequestInit) {\n const response = await fetch(url, init);\n\n if (!response.ok) {\n throw new Error(await getDetailFromResponse(response));\n }\n\n return response;\n}","import type { JWTPayload } from '@tern-secure/types';\n\n\nexport type JwtReturnType<R, E extends Error> =\n | {\n data: R;\n errors?: undefined;\n }\n | {\n data?: undefined;\n errors: [E];\n };\n\n\nexport const ALGORITHM_RS256 = 'RS256' as const;\n\nexport interface CryptoSigner {\n getAccountId(): Promise<string>;\n sign(payload: JWTPayload): Promise<string>;\n}","import type { JWTPayload } from '@tern-secure/types';\n\nimport type { Credential, ServiceAccountManager } from '../auth';\nimport { fetchText } from '../utils/fetcher'\nimport { ternSignBlob, ternSignJwt } from './signJwt';\nimport { ALGORITHM_RS256, type CryptoSigner } from './types';\n\n\nclass ServiceAccountSigner implements CryptoSigner {\n\n constructor(\n private readonly credential: ServiceAccountManager,\n private tenantId?: string\n ) { }\n\n public async getAccountId(): Promise<string> {\n return Promise.resolve(this.credential.clientEmail);\n }\n\n public async sign(payload: JWTPayload): Promise<string> {\n if (this.tenantId) {\n payload.tenant_id = this.tenantId;\n }\n\n return ternSignJwt({ payload, privateKey: this.credential.privateKey });\n }\n}\n\nclass IAMSigner implements CryptoSigner {\n algorithm = ALGORITHM_RS256;\n\n private credential: Credential;\n private tenantId?: string;\n private serviceAccountId?: string;\n\n constructor(\n credential: Credential,\n tenantId?: string,\n serviceAccountId?: string\n ) {\n this.credential = credential;\n this.tenantId = tenantId;\n this.serviceAccountId = serviceAccountId;\n }\n\n public async sign(payload: JWTPayload): Promise<string> {\n if (this.tenantId) {\n payload.tenant_id = this.tenantId;\n }\n\n const serviceAccount = await this.getAccountId();\n const accessToken = await this.credential.getAccessToken();\n\n return ternSignBlob({\n accessToken: accessToken.accessToken,\n serviceAccountId: serviceAccount,\n payload\n });\n }\n\n public async getAccountId(): Promise<string> {\n if (this.serviceAccountId) {\n return this.serviceAccountId;\n }\n\n const token = await this.credential.getAccessToken();\n const url =\n 'http://metadata/computeMetadata/v1/instance/service-accounts/default/email';\n const request: RequestInit = {\n method: 'GET',\n headers: {\n 'Metadata-Flavor': 'Google',\n Authorization: `Bearer ${token.accessToken}`\n }\n };\n\n return (this.serviceAccountId = await fetchText(url, request));\n }\n}\n\n\nexport { ServiceAccountSigner, IAMSigner };\n\n","import { createJwtGuard } from './guardReturn';\nimport { ternDecodeJwt as _ternDecodeJwt } from './verifyJwt';\n\nexport const ternDecodeJwt = createJwtGuard(_ternDecodeJwt);\nexport { ternDecodeJwt as ternDecodeJwtUnguarded } from './verifyJwt';\n\nexport * from './jwt';\nexport * from './customJwt';\nexport * from './signJwt';\nexport { ServiceAccountSigner, IAMSigner } from './crypto-signer';\nexport type { JwtReturnType, CryptoSigner } from './types';","import type { Credential } from '../auth'\nimport { ServiceAccountManager } from '../auth'\nimport type { CryptoSigner } from '../jwt'\nimport { IAMSigner, ServiceAccountSigner } from '../jwt'\n\nexport function cryptoSignerFromCredential(\n credential: Credential,\n tenantId?: string,\n serviceAccountId?: string\n): CryptoSigner {\n if (credential instanceof ServiceAccountManager) {\n return new ServiceAccountSigner(credential, tenantId);\n }\n\n return new IAMSigner(credential, tenantId, serviceAccountId);\n}","import type { Credential } from '../auth'\nimport type { AppCheckParams, AppCheckToken } from './types'\n\nexport function getSdkVersion(): string {\n return '12.7.0';\n}\n\nconst FIREBASE_APP_CHECK_CONFIG_HEADERS = {\n 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`\n};\n\n/**\n * App Check API for managing Firebase App Check tokens via REST\n * Firebase REST API endpoint: https://firebaseappcheck.googleapis.com/v1beta/projects/{projectId}/apps/{appId}:exchangeCustomToken\n */\nexport class AppCheckApi {\n constructor(private credential: Credential) { }\n\n public async exchangeToken(params: AppCheckParams): Promise<AppCheckToken> {\n const { projectId, appId, customToken, limitedUse = false } = params;\n const token = await this.credential.getAccessToken(false);\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1/projects/${projectId}/apps/${appId}:exchangeCustomToken`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token.accessToken}`,\n };\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ customToken, limitedUse }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n public async exchangeDebugToken(params: AppCheckParams): Promise<AppCheckToken> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeDebugToken`;\n\n const headers: Record<string, string> = {\n ...FIREBASE_APP_CHECK_CONFIG_HEADERS,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n const body = {\n customToken,\n limitedUse,\n }\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n}\n","import {\n FIREBASE_APP_CHECK_AUDIENCE,\n ONE_DAY_IN_MILLIS,\n ONE_MINUTE_IN_MILLIS,\n ONE_MINUTE_IN_SECONDS\n} from '../constants'\nimport type { CryptoSigner } from '../jwt';\nimport type { AppCheckTokenOptions } from './types';\n\n\nfunction transformMillisecondsToSecondsString(milliseconds: number): string {\n let duration: string;\n const seconds = Math.floor(milliseconds / 1000);\n const nanos = Math.floor((milliseconds - seconds * 1000) * 1000000);\n if (nanos > 0) {\n let nanoString = nanos.toString();\n while (nanoString.length < 9) {\n nanoString = '0' + nanoString;\n }\n duration = `${seconds}.${nanoString}s`;\n } else {\n duration = `${seconds}s`;\n }\n return duration;\n}\n\nexport class AppCheckTokenGenerator {\n private readonly signer: CryptoSigner;\n\n constructor(signer: CryptoSigner) {\n this.signer = signer;\n }\n\n public async createCustomToken(\n appId: string,\n options?: AppCheckTokenOptions\n ): Promise<string> {\n if (!appId) {\n throw new Error(\n 'appId is invalid',\n );\n }\n let customOptions = {};\n if (typeof options !== 'undefined') {\n customOptions = this.validateTokenOptions(options);\n }\n\n const account = await this.signer.getAccountId();\n\n const iat = Math.floor(Date.now() / 1000);\n const body = {\n iss: account,\n sub: account,\n app_id: appId,\n aud: FIREBASE_APP_CHECK_AUDIENCE,\n exp: iat + ONE_MINUTE_IN_SECONDS * 5,\n iat,\n ...customOptions\n };\n\n return this.signer.sign(body);\n }\n\n private validateTokenOptions(options: AppCheckTokenOptions): {\n [key: string]: unknown;\n } {\n if (typeof options.ttlMillis !== 'undefined') {\n if (\n options.ttlMillis < ONE_MINUTE_IN_MILLIS * 30 ||\n options.ttlMillis > ONE_DAY_IN_MILLIS * 7\n ) {\n throw new Error(\n 'ttlMillis must be a duration in milliseconds between 30 minutes and 7 days (inclusive).'\n );\n }\n\n return { ttl: transformMillisecondsToSecondsString(options.ttlMillis) };\n }\n return {};\n }\n}\n","import { Redis } from \"@upstash/redis\";\n\nimport type { AppCheckOptions } from '../adapters/types';\nimport { initializeAdminConfig } from '../utils/config';\nimport { getAppCheck } from \"./index\";\n\ninterface CachedToken {\n token: string;\n expiresAt: number;\n}\n\n/**\n * Redis client interface for AppCheck token caching (Upstash Redis or compatible adapter)\n */\ninterface RedisClient {\n get(key: string): Promise<any>;\n set(key: string, value: any, opts?: { px?: number }): Promise<any>;\n del(key: string): Promise<number>;\n}\n\n\nexport class ServerAppCheckManager {\n private static instances: Map<string, ServerAppCheckManager> = new Map();\n private memoryCache: Map<string, CachedToken> = new Map();\n private redisClient: RedisClient | null = null;\n private readonly options: Required<Omit<AppCheckOptions, 'redis' | 'skipInMemoryFirst'>> & {\n redis?: AppCheckOptions['redis'];\n skipInMemoryFirst: boolean;\n };\n private pendingTokens: Map<string, Promise<string | null>> = new Map();\n\n private constructor(options?: AppCheckOptions) {\n const defaultOptions: Required<Omit<AppCheckOptions, 'redis' | 'skipInMemoryFirst'>> & { skipInMemoryFirst: boolean } = {\n strategy: 'memory',\n ttlMillis: 3600000, // 1 hour\n refreshBufferMillis: 300000, // 5 minutes\n keyPrefix: 'appcheck:token:',\n skipInMemoryFirst: false,\n };\n\n this.options = { ...defaultOptions, ...options };\n\n if (this.options.strategy === 'redis' && this.options.redis) {\n void this.initializeRedis(this.options.redis);\n }\n }\n\n private initializeRedis = (config: AppCheckOptions['redis']): void => {\n if (!config) {\n throw new Error('[AppCheck] Redis configuration is required when strategy is \"redis\"');\n }\n\n try {\n this.redisClient = new Redis({\n url: config.url,\n token: config.token,\n });\n\n } catch (error) {\n console.error('[AppCheck] Failed to initialize Redis client:', error);\n throw new Error('[AppCheck] Redis initialization failed.');\n }\n }\n\n public static getInstance(options?: AppCheckOptions): ServerAppCheckManager {\n const key = options?.strategy || 'memory';\n\n if (!ServerAppCheckManager.instances.has(key)) {\n ServerAppCheckManager.instances.set(key, new ServerAppCheckManager(options));\n }\n\n const instance = ServerAppCheckManager.instances.get(key);\n if (!instance) {\n throw new Error('[AppCheck] Failed to get instance');\n }\n\n return instance;\n }\n\n private buildCacheKey(appId: string): string {\n return `${this.options.keyPrefix}${appId}`;\n }\n\n\n private getCachedToken = async (appId: string): Promise<CachedToken | null> => {\n if (this.options.strategy === 'memory') {\n return this.memoryCache.get(appId) || null;\n }\n\n if (this.options.strategy === 'redis') {\n // Check in-memory cache first (unless skipInMemoryFirst is true)\n if (!this.options.skipInMemoryFirst) {\n const memCached = this.memoryCache.get(appId);\n if (memCached) {\n return memCached;\n }\n }\n\n // Fallback to Redis\n if (this.redisClient) {\n try {\n const key = this.buildCacheKey(appId);\n const cached = await this.redisClient.get(key);\n\n if (cached) {\n const parsed: CachedToken = typeof cached === 'string' ? JSON.parse(cached) : cached;\n\n if (!this.options.skipInMemoryFirst) {\n this.memoryCache.set(appId, parsed);\n }\n\n return parsed;\n }\n } catch (error) {\n console.error('[AppCheck] Redis get error:', error);\n }\n }\n }\n\n return null;\n }\n\n\n private setCachedToken = async (appId: string, token: string, expiresAt: number): Promise<void> => {\n const cachedToken: CachedToken = { token, expiresAt };\n\n // Always store in memory cache for both strategies\n this.memoryCache.set(appId, cachedToken);\n\n if (this.options.strategy === 'memory') {\n return;\n }\n\n // For Redis strategy, also persist to Redis\n if (this.options.strategy === 'redis' && this.redisClient) {\n try {\n const key = this.buildCacheKey(appId);\n const ttl = expiresAt - Date.now();\n\n await this.redisClient.set(key, JSON.stringify(cachedToken), {\n px: ttl, // Expiry in milliseconds (lowercase for Upstash)\n });\n } catch (error) {\n console.error('[AppCheck] Redis set error:', error);\n }\n }\n }\n\n getOrGenerateToken = async (appId: string): Promise<string | null> => {\n const cached = await this.getCachedToken(appId);\n const now = Date.now();\n\n if (cached && cached.expiresAt > now + this.options.refreshBufferMillis) {\n return cached.token;\n }\n\n const pending = this.pendingTokens.get(appId);\n if (pending) {\n return pending;\n }\n\n const tokenPromise = this.generateAndCacheToken(appId);\n this.pendingTokens.set(appId, tokenPromise);\n\n try {\n const token = await tokenPromise;\n return token;\n } finally {\n this.pendingTokens.delete(appId);\n }\n }\n\n /**\n * Generate and cache a new token\n */\n private generateAndCacheToken = async (appId: string): Promise<string | null> => {\n try {\n const now = Date.now();\n const config = initializeAdminConfig();\n const appCheck = getAppCheck(config);\n\n const appCheckToken = await appCheck.createToken(config.projectId, appId, {\n ttlMillis: this.options.ttlMillis,\n });\n\n const expiresAt = now + this.options.ttlMillis;\n await this.setCachedToken(appId, appCheckToken.token, expiresAt);\n\n return appCheckToken.token;\n } catch (error) {\n console.error('[AppCheck] Failed to generate token:', error);\n return null;\n }\n }\n\n clearCache = async (appId?: string): Promise<void> => {\n if (appId) {\n this.memoryCache.delete(appId);\n } else {\n this.memoryCache.clear();\n }\n\n if (this.options.strategy === 'redis' && this.redisClient) {\n try {\n if (appId) {\n const key = this.buildCacheKey(appId);\n await this.redisClient.del(key);\n }\n } catch (error) {\n console.error('[AppCheck] Redis delete error:', error);\n }\n }\n }\n\n getCacheStats(): {\n strategy: string;\n memorySize: number;\n entries: Array<{ appId: string; expiresIn: number }>\n } {\n const now = Date.now();\n const entries = Array.from(this.memoryCache.entries()).map(([appId, cached]) => ({\n appId,\n expiresIn: Math.max(0, cached.expiresAt - now),\n }));\n\n return {\n strategy: this.options.strategy,\n memorySize: this.memoryCache.size,\n entries,\n };\n }\n\n /**\n * Close Redis connection\n */\n disconnect(): void {\n if (this.redisClient) {\n this.redisClient = null;\n }\n }\n}","import type { \r\n AdminConfigValidationResult, \r\n ConfigValidationResult, \r\n TernSecureAdminConfig, \r\n TernSecureConfig} from '@tern-secure/types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL || undefined,\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}\r\n\r\n/**\r\n * Loads Firebase Admin configuration from environment variables\r\n * @returns {AdminConfig} Firebase Admin configuration object\r\n */\r\nexport const loadAdminConfig = (): TernSecureAdminConfig => ({\r\n projectId: process.env.FIREBASE_PROJECT_ID || '',\r\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL || '',\r\n privateKey: process.env.FIREBASE_PRIVATE_KEY || '',\r\n})\r\n\r\n/**\r\n * Validates Firebase Admin configuration\r\n * @param {AdminConfig} config - Firebase Admin configuration object\r\n * @returns {ConfigValidationResult} Validation result\r\n */\r\nexport const validateAdminConfig = (config: TernSecureAdminConfig): AdminConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureAdminConfig)[] = [\r\n 'projectId',\r\n 'clientEmail',\r\n 'privateKey'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes admin configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeAdminConfig = (): TernSecureAdminConfig => {\r\n const config = loadAdminConfig()\r\n const validationResult = validateAdminConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase Admin configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}","import type { DecodedAppCheckToken } from '@tern-secure/types';\nimport { createRemoteJWKSet, type KeyLike, type ProtectedHeaderParameters } from 'jose';\n\nimport type { Credential } from '../auth';\nimport type { JwtReturnType } from '../jwt';\nimport { ternDecodeJwt, verifyAppCheckJwt, type VerifyJwtOptions } from '../jwt/verifyJwt';\nimport type { LoadJWKFromRemoteOptions } from '../tokens/keys';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\n\nexport type VerifyAppcheckOptions = Omit<VerifyJwtOptions, 'key'> & Omit<LoadJWKFromRemoteOptions, 'kid'> & {\n currentDate?: Date;\n checkRevoked?: boolean;\n referer?: string;\n experimental_enableTokenRefreshOnExpiredKidHeader?: boolean;\n};\n\nconst getPublicKey = async (header: ProtectedHeaderParameters, keyURL: string): Promise<KeyLike> => {\n const jswksUrl: URL = new URL(keyURL);\n const getKey = createRemoteJWKSet(jswksUrl);\n\n return getKey(header);\n\n}\n\n\nconst verifyAppCheckToken = async (\n token: string,\n options: VerifyAppcheckOptions,\n): Promise<JwtReturnType<DecodedAppCheckToken, TokenVerificationError>> => {\n const { data: decodedResult, errors } = ternDecodeJwt(token);\n\n if (errors) {\n throw errors[0];\n }\n\n const { header } = decodedResult;\n const { kid } = header;\n\n if (!kid) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'JWT \"kid\" header is missing.',\n }),\n ],\n };\n }\n\n try {\n const getPublicKeyForToken = () => getPublicKey(header, options.keyURL || '');\n\n return await verifyAppCheckJwt(token, { ...options, key: getPublicKeyForToken });\n } catch (error) {\n if (error instanceof TokenVerificationError) {\n return { errors: [error] };\n }\n return {\n errors: [error as TokenVerificationError],\n };\n }\n};\n\nexport class AppcheckTokenVerifier {\n constructor(private readonly credential: Credential) { }\n\n public verifyToken = async (\n token: string,\n projectId: string,\n options: VerifyAppcheckOptions,\n ): Promise<DecodedAppCheckToken> => {\n const { data, errors } = await verifyAppCheckToken(token, options);\n if (errors) {\n throw errors[0];\n }\n\n return data;\n };\n}","import type { VerifyAppCheckTokenResponse } from \"@tern-secure/types\";\n\nimport type { Credential, ServiceAccount } from \"../auth\";\nimport { ServiceAccountManager } from \"../auth\";\nimport { cryptoSignerFromCredential } from '../utils/token-generator';\nimport { AppCheckApi } from \"./AppCheckApi\";\nimport { AppCheckTokenGenerator } from \"./generator\";\nimport { ServerAppCheckManager } from \"./serverAppCheck\";\nimport type { AppCheckToken, AppCheckTokenOptions } from \"./types\";\nimport { AppcheckTokenVerifier, type VerifyAppcheckOptions } from \"./verifier\";\n\n\nconst JWKS_URL = 'https://firebaseappcheck.googleapis.com/v1/jwks';\n\nclass AppCheck {\n private readonly client: AppCheckApi;\n private readonly tokenGenerator: AppCheckTokenGenerator;\n private readonly appCheckTokenVerifier: AppcheckTokenVerifier;\n private readonly limitedUse?: boolean;\n\n constructor(credential: Credential, tenantId?: string, limitedUse?: boolean) {\n this.client = new AppCheckApi(credential);\n this.tokenGenerator = new AppCheckTokenGenerator(\n cryptoSignerFromCredential(credential, tenantId)\n );\n this.appCheckTokenVerifier = new AppcheckTokenVerifier(credential);\n this.limitedUse = limitedUse;\n }\n\n public createToken = (projectId: string, appId: string, options?: AppCheckTokenOptions): Promise<AppCheckToken> => {\n return this.tokenGenerator\n .createCustomToken(appId, options)\n .then((customToken) => {\n return this.client.exchangeToken({ customToken, projectId, appId });\n });\n };\n\n public verifyToken = async (appCheckToken: string, projectId: string, options: VerifyAppcheckOptions): Promise<VerifyAppCheckTokenResponse> => {\n return this.appCheckTokenVerifier\n .verifyToken(appCheckToken, projectId, { keyURL: JWKS_URL, ...options })\n .then((decodedToken) => {\n return {\n appId: decodedToken.app_id,\n token: decodedToken,\n };\n });\n\n }\n\n}\n\n\nfunction getAppCheck(serviceAccount: ServiceAccount, tenantId?: string, limitedUse?: boolean): AppCheck {\n return new AppCheck(new ServiceAccountManager(serviceAccount), tenantId, limitedUse);\n}\n\nexport { AppCheck, getAppCheck };\nexport { ServerAppCheckManager };","import { getAppCheck } from '../app-check';\nimport { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions, TernSecureUserData } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\nimport { loadAdminConfig } from '../utils/config';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\n auth_time: number;\n idToken: string;\n refreshToken: string;\n customToken: string;\n}\n\ninterface CustomForIdAndRefreshTokenOptions {\n tenantId?: string;\n appCheckToken?: string;\n referer?: string;\n}\n\ninterface FirebaseRefreshTokenResponse {\n kind: string;\n id_token: string;\n refresh_token: string;\n expires_in: string;\n isNewUser: boolean;\n}\n\ntype AuthResult<T = any> = { data: T; error: null } | { data: null; error: any };\n\nconst API_KEY_ERROR = 'API Key is required';\nconst NO_DATA_ERROR = 'No token data received';\n\nfunction parseFirebaseResponse<T>(data: unknown): T {\n if (typeof data === 'string') {\n try {\n return JSON.parse(data) as T;\n } catch (error) {\n throw new Error(`Failed to parse Firebase response: ${error}`);\n }\n }\n return data as T;\n}\n\nexport function getAuth(options: AuthenticateRequestOptions) {\n const { apiKey } = options;\n const effectiveApiKey = apiKey || process.env.NEXT_PUBLIC_FIREBASE_API_KEY;\n\n\n async function getUserData(idToken?: string, localId?: string): Promise<TernSecureUserData> {\n if (!effectiveApiKey) {\n throw new Error(API_KEY_ERROR);\n }\n const response = await options.apiClient?.userData.getUserData(effectiveApiKey, {\n idToken,\n localId,\n });\n\n if (!response?.data) {\n throw new Error(NO_DATA_ERROR);\n }\n\n const parsedData = parseFirebaseResponse<TernSecureUserData>(response.data);\n return parsedData;\n }\n\n async function refreshExpiredIdToken(\n refreshToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<AuthResult> {\n if (!effectiveApiKey) {\n return { data: null, error: new Error(API_KEY_ERROR) };\n }\n const response = await options.apiClient?.tokens.refreshToken(effectiveApiKey, {\n refresh_token: refreshToken,\n request_origin: opts.referer,\n });\n\n if (!response?.data) {\n return {\n data: null,\n error: new Error(NO_DATA_ERROR),\n };\n }\n\n const parsedData = parseFirebaseResponse<FirebaseRefreshTokenResponse>(response.data);\n\n return {\n data: {\n idToken: parsedData.id_token,\n refreshToken: parsedData.refresh_token,\n },\n error: null,\n };\n }\n\n async function customForIdAndRefreshToken(\n customToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<IdAndRefreshTokens> {\n if (!effectiveApiKey) {\n throw new Error('API Key is required to create custom token');\n }\n const data = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n },\n );\n\n if (!data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n return {\n idToken: data.idToken,\n refreshToken: data.refreshToken,\n };\n }\n\n async function createCustomIdAndRefreshToken(\n idToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<CustomTokens> {\n const decoded = await verifyToken(idToken, options);\n const { data, errors } = decoded;\n if (errors) {\n throw errors[0];\n }\n\n //todo:\n /**\n * For sensitive applications, the auth_time should be checked before issuing the session cookie, minimizing the window of attack in case an ID token is stolen:\n */\n //if (new Date().getTime() / 1000 - data.auth_time < 5 * 60) {\n //proceed\n //}\n\n const customToken = await createCustomToken(data.uid, {\n emailVerified: data.email_verified,\n source_sign_in_provider: data.firebase.sign_in_provider,\n });\n\n const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n });\n\n const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);\n if (decodedCustomIdToken.errors) {\n throw decodedCustomIdToken.errors[0];\n }\n\n return {\n ...idAndRefreshTokens,\n customToken,\n auth_time: decodedCustomIdToken.data.auth_time,\n };\n }\n\n async function createAppCheckToken(): Promise<AuthResult> {\n const adminConfig = loadAdminConfig();\n const appId = process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '';\n const appCheck = getAppCheck(adminConfig, options.tenantId);\n try {\n const appCheckResponse = await appCheck.createToken(adminConfig.projectId, appId);\n\n return {\n data: {\n token: appCheckResponse.token,\n ttl: appCheckResponse.ttl,\n },\n error: null,\n };\n } catch (error) {\n return { data: null, error };\n }\n }\n\n async function verifyAppCheckToken(token: string): Promise<AuthResult> {\n const adminConfig = loadAdminConfig();\n const appCheck = getAppCheck(adminConfig, options.tenantId);\n try {\n const decodedToken = await appCheck.verifyToken(token, adminConfig.projectId, {});\n\n return {\n data: decodedToken,\n error: null,\n };\n } catch (error) {\n return { data: null, error };\n }\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n createAppCheckToken,\n verifyAppCheckToken,\n };\n}\n","import type { JWTPayload } from '@tern-secure/types';\n\nimport {\n GOOGLE_AUTH_TOKEN_HOST,\n GOOGLE_AUTH_TOKEN_PATH,\n GOOGLE_TOKEN_AUDIENCE,\n ONE_HOUR_IN_SECONDS,\n TOKEN_EXPIRY_THRESHOLD_MILLIS\n} from '../constants'\nimport { ternSignJwt } from '../jwt';\nimport { fetchJson } from '../utils/fetcher';\n\n\nexport interface GoogleOAuthAccessToken {\n access_token: string;\n expires_in: number;\n}\n\nexport interface ServiceAccount {\n projectId: string;\n privateKey: string;\n clientEmail: string;\n}\n\nexport interface FirebaseAccessToken {\n accessToken: string;\n expirationTime: number;\n}\n\nconst accessTokenCache: Map<string, FirebaseAccessToken> = new Map();\n\nexport interface Credential {\n getAccessToken: (refresh?: boolean) => Promise<FirebaseAccessToken>;\n}\n\nasync function requestAccessToken(urlString: string, init: RequestInit): Promise<FirebaseAccessToken> {\n const json = await fetchJson(urlString, init);\n\n if (!json.access_token || !json.expires_in) {\n throw new Error('Invalid access token response');\n }\n\n return {\n accessToken: json.access_token,\n expirationTime: Date.now() + (json.expires_in * 1000),\n }\n}\n\nexport class ServiceAccountManager implements Credential {\n public readonly projectId: string;\n public readonly privateKey: string;\n public readonly clientEmail: string;\n\n constructor(serviceAccount: ServiceAccount) {\n this.projectId = serviceAccount.projectId;\n this.privateKey = serviceAccount.privateKey;\n this.clientEmail = serviceAccount.clientEmail;\n }\n\n private fetchAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const token = await this.createJwt();\n const postData =\n 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3A' +\n 'grant-type%3Ajwt-bearer&assertion=' +\n token;\n\n return requestAccessToken(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n body: postData,\n })\n }\n\n private fetchAndCacheAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const accessToken = await this.fetchAccessToken(url);\n accessTokenCache.set(this.projectId, accessToken);\n return accessToken;\n }\n\n public getAccessToken = async (refresh?: boolean): Promise<FirebaseAccessToken> => {\n const url = `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`;\n\n if (refresh) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n const cachedResponse = accessTokenCache.get(this.projectId);\n\n if (!cachedResponse || cachedResponse.expirationTime - Date.now() <= TOKEN_EXPIRY_THRESHOLD_MILLIS) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n return cachedResponse;\n }\n\n private createJwt = async (): Promise<string> => {\n const iat = Math.floor(Date.now() / 1000);\n\n const payload = {\n aud: GOOGLE_TOKEN_AUDIENCE,\n iat,\n exp: iat + ONE_HOUR_IN_SECONDS,\n iss: this.clientEmail,\n sub: this.clientEmail,\n scope: [\n 'https://www.googleapis.com/auth/cloud-platform',\n 'https://www.googleapis.com/auth/firebase.database',\n 'https://www.googleapis.com/auth/firebase.messaging',\n 'https://www.googleapis.com/auth/identitytoolkit',\n 'https://www.googleapis.com/auth/userinfo.email'\n ].join(' ')\n } as JWTPayload;\n\n return ternSignJwt({\n payload,\n privateKey: this.privateKey,\n });\n }\n}\n","import { getCookieName as getCookieNameEnvironment, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nexport const getCookieName = (cookieDirective: string): string => {\n return cookieDirective.split(';')[0]?.split('=')[0];\n};\n\nexport const getCookieValue = (cookieDirective: string): string => {\n return cookieDirective.split(';')[0]?.split('=')[1];\n};\n\nexport { getCookieNameEnvironment, getCookiePrefix };","\nimport type { ApiClient } from '../fireRestApi';\nimport {\n type buildTimeOptions,\n mergePreDefinedOptions,\n type RuntimeOptions,\n} from '../utils/options';\nimport { authenticateRequest } from './request';\n\n/**\n * @internal\n */\nexport type CreateAuthenticateRequestOptions = {\n options: buildTimeOptions;\n apiClient: ApiClient;\n};\n\nexport function createAuthenticateRequest(params: CreateAuthenticateRequestOptions) {\n const buildTimeOptions = mergePreDefinedOptions(params.options);\n const apiClient = params.apiClient;\n\n const handleAuthenticateRequest = (request: Request, options: RuntimeOptions = {}) => {\n const { apiUrl } = buildTimeOptions;\n return authenticateRequest(request, { ...options, apiUrl, apiClient });\n };\n\n return {\n authenticateRequest: handleAuthenticateRequest,\n };\n}","import type { ApiClient,CreateFireApiOptions} from \"../fireRestApi\";\r\nimport { createFireApi } from \"../fireRestApi\";\r\nimport type { RequestState } from \"../tokens/authstate\";\r\nimport type { CreateAuthenticateRequestOptions } from \"../tokens/factory\";\r\nimport { createAuthenticateRequest } from \"../tokens/factory\";\r\nimport type {\r\n TernSecureRequest,\r\n} from \"../tokens/ternSecureRequest\";\r\n\r\nexport type TernSecureBackendOptions = CreateFireApiOptions & CreateAuthenticateRequestOptions['options'];\r\n\r\nexport type TernSecureBackendClient = ApiClient & ReturnType<typeof createAuthenticateRequest>;\r\n\r\nexport interface BackendInstance {\r\n ternSecureRequest: TernSecureRequest;\r\n requestState: RequestState;\r\n}\r\n\r\nexport function createBackendInstanceClient(options: TernSecureBackendOptions): TernSecureBackendClient {\r\n const opts = { ...options };\r\n const apiClient = createFireApi(opts);\r\n const requestState = createAuthenticateRequest({options: opts, apiClient});\r\n\r\n return {\r\n ...apiClient,\r\n ...requestState,\r\n };\r\n}\r\n","export enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n}\n\nexport interface LoggerOptions {\n enabled: boolean\n level: LogLevel\n prefix: string\n}\n\nexport class Logger {\n private options: LoggerOptions\n\n constructor(options: Partial<LoggerOptions> = {}) {\n this.options = {\n enabled: false,\n level: LogLevel.INFO,\n prefix: '[TernSecure-Backend]',\n ...options,\n }\n }\n\n enable(): void {\n this.options.enabled = true\n }\n\n disable(): void {\n this.options.enabled = false\n }\n\n setLevel(level: LogLevel): void {\n this.options.level = level\n }\n\n setPrefix(prefix: string): void {\n this.options.prefix = prefix\n }\n\n private log(level: LogLevel, levelName: string, message: string, ...args: any[]): void {\n if (!this.options.enabled || level > this.options.level) {\n return\n }\n\n const timestamp = new Date().toISOString()\n const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`\n \n switch (level) {\n case LogLevel.ERROR:\n console.error(formattedMessage, ...args)\n break\n case LogLevel.WARN:\n console.warn(formattedMessage, ...args)\n break\n case LogLevel.INFO:\n console.info(formattedMessage, ...args)\n break\n case LogLevel.DEBUG:\n console.debug(formattedMessage, ...args)\n break\n }\n }\n\n error(message: string, ...args: any[]): void {\n this.log(LogLevel.ERROR, 'ERROR', message, ...args)\n }\n\n warn(message: string, ...args: any[]): void {\n this.log(LogLevel.WARN, 'WARN', message, ...args)\n }\n\n info(message: string, ...args: any[]): void {\n this.log(LogLevel.INFO, 'INFO', message, ...args)\n }\n\n debug(message: string, ...args: any[]): void {\n this.log(LogLevel.DEBUG, 'DEBUG', message, ...args)\n }\n}\n\nexport const createLogger = (options?: Partial<LoggerOptions>): Logger => {\n return new Logger(options)\n}\n\nexport const redisLogger = createLogger({ prefix: '[TernSecure-Redis]' })\nexport const authLogger = createLogger({ prefix: '[TernSecure-Auth]' })","import { authLogger, LogLevel,redisLogger } from \"./logger\"\n\nexport function enableDebugLogging(): void {\n authLogger.enable()\n authLogger.setLevel(LogLevel.DEBUG)\n \n redisLogger.enable()\n redisLogger.setLevel(LogLevel.DEBUG)\n}\n\nexport function disableDebugLogging(): void {\n authLogger.disable()\n redisLogger.disable()\n}\n\nexport function setLogLevel(level: LogLevel): void {\n authLogger.setLevel(level)\n redisLogger.setLevel(level)\n}","import { authLogger } from \"../utils/logger\";\nimport type { DisabledUserAdapter, DisabledUserRecord, PostgresConfig } from \"./types\";\n\nexport class PostgresAdapter implements DisabledUserAdapter {\n private config: PostgresConfig;\n private tableName: string;\n\n constructor(config: PostgresConfig) {\n this.config = config;\n this.tableName = config.table || 'disabled_users';\n }\n\n getDisabledUser = async(uid: string): Promise<DisabledUserRecord | null> => {\n try {\n // For edge runtime, we'll use fetch to call a REST API endpoint\n // This avoids the need for full postgres client libraries in edge\n const response = await fetch(this.config.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.token}`,\n },\n body: JSON.stringify({\n query: `SELECT uid, email, disabled_time as \"disabledTime\" FROM ${this.tableName} WHERE uid = $1`,\n params: [uid],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n \n if (result.rows && result.rows.length > 0) {\n const row = result.rows[0];\n const disabledUser: DisabledUserRecord = {\n uid: row.uid,\n email: row.email,\n disabledTime: row.disabledTime,\n };\n \n authLogger.debug(`Found disabled user: ${uid}`);\n return disabledUser;\n }\n\n authLogger.debug(`No disabled user found: ${uid}`);\n return null;\n } catch (error) {\n authLogger.error('Failed to fetch disabled user from Postgres:', error);\n return null;\n }\n }\n}","import { Redis } from \"@upstash/redis\";\n\nimport { authLogger } from \"../utils/logger\";\nimport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n RedisConfig,\n} from \"./types\";\n\ninterface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nclass TTLCache<T> {\n private cache = new Map<string, CacheEntry<T>>();\n private readonly defaultTTL: number;\n\n constructor(defaultTTLMs: number = 60000) {\n this.defaultTTL = defaultTTLMs;\n }\n\n set(key: string, value: T, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTTL);\n this.cache.set(key, { value, expiresAt });\n console.log(`TTLCache.set: key=${key}, value=${JSON.stringify(value)}, expiresAt=${expiresAt}, cacheSize=${this.cache.size}`);\n }\n\n private getEntry(key: string): CacheEntry<T> | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n console.log(`TTLCache: key=${key} expired (now=${now}, expiresAt=${entry.expiresAt})`);\n this.cache.delete(key);\n return undefined;\n }\n\n return entry;\n }\n\n get(key: string): T | undefined {\n const entry = this.getEntry(key);\n const hasEntry = entry !== undefined;\n const cacheHasKey = this.cache.has(key);\n const rawEntry = this.cache.get(key);\n \n console.log(`TTLCache.get: key=${key}, hasEntry=${hasEntry}, cacheHasKey=${cacheHasKey}`);\n console.log(`TTLCache.get: rawEntry=${JSON.stringify(rawEntry)}, entry=${JSON.stringify(entry)}`);\n \n if (!entry) {\n console.log(`TTLCache.get: no entry found for key=${key}, returning undefined`);\n return undefined;\n }\n\n console.log(`TTLCache.get: returning value=${JSON.stringify(entry.value)} for key=${key}`);\n return entry.value;\n }\n\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n cleanup(): void {\n const now = Date.now();\n for (const [key, entry] of this.cache.entries()) {\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n }\n }\n }\n}\n\nexport class RedisAdapter implements DisabledUserAdapter {\n private redis: Redis;\n private cache: TTLCache<DisabledUserRecord | null>;\n private keyPrefix: string;\n\n constructor(config: RedisConfig) {\n this.redis = new Redis({\n url: config.url,\n token: config.token,\n });\n\n this.keyPrefix = config.keyPrefix || \"disabled_user:\";\n const cacheTTL = config.ttl || 30000; // Default 30 seconds\n this.cache = new TTLCache<DisabledUserRecord | null>(cacheTTL);\n\n setInterval(() => this.cache.cleanup(), 5 * 60 * 1000);\n }\n\n getDisabledUser = async (uid: string): Promise<DisabledUserRecord | null> => {\n const cacheKey = `${this.keyPrefix}${uid}`;\n \n authLogger.debug(`RedisAdapter: Checking cache for key: ${cacheKey}`);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n authLogger.debug(`RedisAdapter: Cache get result for ${cacheKey}:`, {\n cachedResult: JSON.stringify(cachedResult),\n isUndefined: cachedResult === undefined,\n type: typeof cachedResult\n });\n \n if (cachedResult !== undefined) {\n authLogger.debug(`Cache hit for disabled user: ${uid}`, { \n cacheKey,\n cachedResult: JSON.stringify(cachedResult)\n });\n return cachedResult;\n }\n\n authLogger.debug(\n `Cache miss for disabled user: ${uid}, fetching from Redis with key: ${cacheKey}`\n );\n\n try {\n const disabledUser: DisabledUserRecord | null =\n await this.redis.get(cacheKey);\n\n authLogger.debug(`Redis returned for key ${cacheKey}:`, { \n disabledUser: JSON.stringify(disabledUser),\n type: typeof disabledUser\n });\n\n // Cache the result (including null values to prevent repeated Redis calls)\n this.cache.set(cacheKey, disabledUser);\n \n authLogger.debug(`Cached disabled user result for: ${uid}`, {\n cacheKey,\n isDisabled: !!disabledUser,\n cachedValue: JSON.stringify(disabledUser)\n });\n\n return disabledUser;\n } catch (error) {\n authLogger.error(\"Failed to fetch disabled user from Redis:\", error);\n return null;\n }\n };\n\n invalidateCache(uid: string): void {\n const cacheKey = `${this.keyPrefix}${uid}`;\n this.cache.delete(cacheKey);\n }\n}\n","import { PostgresAdapter } from \"./PostgresAdapter\";\nimport { RedisAdapter } from \"./RedisAdapter\";\nimport type { AdapterConfiguration,DisabledUserAdapter } from \"./types\";\n\nexport function createAdapter(\n config: AdapterConfiguration\n): DisabledUserAdapter {\n switch (config.type) {\n case \"redis\":\n return new RedisAdapter(config.config as any);\n case \"postgres\":\n return new PostgresAdapter(config.config as any);\n default:\n throw new Error(`Unsupported adapter type: ${(config as any).type}`);\n }\n}\n\nexport function validateCheckRevokedOptions(options?: {\n enabled: boolean;\n adapter?: AdapterConfiguration;\n}): { isValid: boolean; error?: string } {\n if (options?.enabled && !options.adapter) {\n return {\n isValid: false,\n error: \"When checkRevoked.enabled is true, an adapter must be provided\",\n };\n }\n return { isValid: true };\n}\n\n\nexport { RedisAdapter } from './RedisAdapter';\nexport { PostgresAdapter } from './PostgresAdapter';\nexport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n AdapterConfig,\n RedisConfig,\n PostgresConfig,\n AdapterType,\n AdapterConfiguration,\n CheckRevokedOptions,\n AppCheckOptions,\n} from './types';\n"],"mappings":"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","names":["Headers","import_jose","parse","getPublicKey","cert","crypto","import_jose","import_jose","import_jose","ternDecodeJwt","getSdkVersion","FIREBASE_APP_CHECK_CONFIG_HEADERS","AppCheckApi","import_jose","AppCheckApi","verifyAppCheckToken","import_cookie","getCookieNameEnvironment","context","LogLevel","import_redis"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/createRedirect.ts","../src/tokens/ternSecureRequest.ts","../src/tokens/ternUrl.ts","../src/tokens/c-authenticateRequestProcessor.ts","../src/utils/mapDecode.ts","../src/tokens/authstate.ts","../src/jwt/verifyJwt.ts","../src/utils/errors.ts","../src/utils/rfc4648.ts","../src/jwt/cryptoKeys.ts","../src/jwt/algorithms.ts","../src/jwt/verifyContent.ts","../src/tokens/keys.ts","../src/tokens/verify.ts","../src/fireRestApi/endpoints/AbstractApi.ts","../src/fireRestApi/endpoints/AppCheckApi.ts","../src/fireRestApi/endpoints/EmailApi.ts","../src/fireRestApi/endpoints/PasswordApi.ts","../src/fireRestApi/endpoints/SignInApi.ts","../src/fireRestApi/endpoints/SignInTokenApi.ts","../src/fireRestApi/endpoints/SignUpApi.ts","../src/fireRestApi/endpoints/TokenApi.ts","../src/fireRestApi/endpoints/UserData.ts","../src/runtime.ts","../src/fireRestApi/emulator.ts","../src/fireRestApi/endpointUrl.ts","../src/fireRestApi/request.ts","../src/fireRestApi/createFireApi.ts","../src/utils/options.ts","../src/tokens/request.ts","../src/jwt/guardReturn.ts","../src/jwt/jwt.ts","../src/jwt/customJwt.ts","../src/jwt/signJwt.ts","../src/utils/fetcher.ts","../src/jwt/types.ts","../src/jwt/crypto-signer.ts","../src/jwt/index.ts","../src/utils/token-generator.ts","../src/app-check/AppCheckApi.ts","../src/app-check/generator.ts","../src/app-check/serverAppCheck.ts","../src/utils/config.ts","../src/app-check/verifier.ts","../src/app-check/index.ts","../src/auth/getauth.ts","../src/auth/credential.ts","../src/tokens/cookie.ts","../src/tokens/factory.ts","../src/instance/backendInstanceEdge.ts","../src/utils/logger.ts","../src/utils/enableDebugLogging.ts","../src/adapters/PostgresAdapter.ts","../src/adapters/RedisAdapter.ts","../src/adapters/index.ts"],"sourcesContent":["export { constants } from './constants';\nexport { createRedirect } from './createRedirect';\nexport type { RedirectFun } from './createRedirect';\n\nexport type { TernSecureRequest } from './tokens/ternSecureRequest';\nexport { createTernSecureRequest } from './tokens/ternSecureRequest';\n\nexport type { AuthenticateRequestOptions } from './tokens/types';\n\nexport type { RequestProcessorContext } from './tokens/c-authenticateRequestProcessor';\nexport { createRequestProcessor } from './tokens/c-authenticateRequestProcessor';\n\nexport type {\n AuthObject,\n RequestState,\n SignedInAuthObject,\n SignedOutAuthObject,\n} from './tokens/authstate';\nexport { signedIn, signedInAuthObject, signedOutAuthObject, AuthStatus } from './tokens/authstate';\nexport { verifyToken } from './tokens/verify';\n\nexport { createBackendInstanceClient } from './instance/backendInstanceEdge';\n\nexport type { BackendInstance, TernSecureBackendOptions } from './instance/backendInstanceEdge';\n\nexport { enableDebugLogging, disableDebugLogging, setLogLevel } from './utils/enableDebugLogging';\n\nexport { LogLevel } from './utils/logger';\n\nexport {\n RedisAdapter,\n PostgresAdapter,\n createAdapter,\n validateCheckRevokedOptions,\n} from './adapters';\n\nexport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n AdapterConfig,\n RedisConfig,\n PostgresConfig,\n AdapterType,\n AdapterConfiguration,\n CheckRevokedOptions,\n} from './adapters';\n","export const GOOGLE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com';\nexport const SESSION_COOKIE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys';\n\nexport const FIREBASE_APP_CHECK_AUDIENCE =\n 'https://firebaseappcheck.googleapis.com/google.firebase.appcheck.v1.TokenExchangeService';\n\nexport const MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;\nexport const DEFAULT_CACHE_DURATION = 3600 * 1000; // 1 hour in milliseconds\nexport const CACHE_CONTROL_REGEX = /max-age=(\\d+)/;\n\nexport const TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1000;\nexport const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token';\nexport const GOOGLE_AUTH_TOKEN_HOST = 'accounts.google.com';\nexport const GOOGLE_AUTH_TOKEN_PATH = '/o/oauth2/token';\nexport const ONE_HOUR_IN_SECONDS = 60 * 60;\n\nexport const ONE_MINUTE_IN_SECONDS = 60;\nexport const ONE_MINUTE_IN_MILLIS = ONE_MINUTE_IN_SECONDS * 1000;\nexport const ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000;\n\nconst Attributes = {\n AuthToken: '__ternsecureAuthToken',\n AuthSignature: '__ternsecureAuthSignature',\n AuthStatus: '__ternsecureAuthStatus',\n AuthReason: '__ternsecureAuthReason',\n AuthMessage: '__ternsecureAuthMessage',\n TernSecureUrl: '__ternsecureUrl',\n} as const;\n\nconst Cookies = {\n Session: '__session',\n CsrfToken: '__terncf',\n IdToken: 'TernSecure_[DEFAULT]',\n Refresh: 'TernSecureID_[DEFAULT]',\n Custom: '__custom',\n TernAut: 'tern_aut',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\n\nconst QueryParameters = {\n TernSynced: '__tern_synced',\n SuffixedCookies: 'suffixed_cookies',\n TernRedirectUrl: '__tern_redirect_url',\n // use the reference to Cookies to indicate that it's the same value\n DevBrowser: Cookies.DevBrowser,\n Handshake: Cookies.Handshake,\n HandshakeHelp: '__tern_help',\n LegacyDevBrowser: '__dev_session',\n HandshakeReason: '__tern_hs_reason',\n HandshakeNonce: Cookies.HandshakeNonce,\n} as const;\n\nconst Headers = {\n Accept: 'accept',\n AppCheckToken: 'x-ternsecure-appcheck',\n AuthMessage: 'x-ternsecure-auth-message',\n Authorization: 'authorization',\n AuthReason: 'x-ternsecure-auth-reason',\n AuthSignature: 'x-ternsecure-auth-signature',\n AuthStatus: 'x-ternsecure-auth-status',\n AuthToken: 'x-ternsecure-auth-token',\n CacheControl: 'cache-control',\n TernSecureRedirectTo: 'x-ternsecure-redirect-to',\n TernSecureRequestData: 'x-ternsecure-request-data',\n TernSecureUrl: 'x-ternsecure-url',\n CloudFrontForwardedProto: 'cloudfront-forwarded-proto',\n ContentType: 'content-type',\n ContentSecurityPolicy: 'content-security-policy',\n ContentSecurityPolicyReportOnly: 'content-security-policy-report-only',\n EnableDebug: 'x-ternsecure-debug',\n ForwardedHost: 'x-forwarded-host',\n ForwardedPort: 'x-forwarded-port',\n ForwardedProto: 'x-forwarded-proto',\n Host: 'host',\n Location: 'location',\n Nonce: 'x-nonce',\n Origin: 'origin',\n Referrer: 'referer',\n SecFetchDest: 'sec-fetch-dest',\n UserAgent: 'user-agent',\n ReportingEndpoints: 'reporting-endpoints',\n} as const;\n\nconst ContentTypes = {\n Json: 'application/json',\n} as const;\n\n/**\n * @internal\n */\nexport const constants = {\n Attributes,\n Cookies,\n Headers,\n ContentTypes,\n QueryParameters,\n} as const;\n\nexport type Constants = typeof constants;\n","const buildUrl = (\n _baseUrl: string | URL,\n _targetUrl: string | URL,\n _returnBackUrl?: string | URL | null,\n) => {\n if (_baseUrl === '') {\n return legacyBuildUrl(_targetUrl.toString(), _returnBackUrl?.toString());\n }\n\n const baseUrl = new URL(_baseUrl);\n const returnBackUrl = _returnBackUrl ? new URL(_returnBackUrl, baseUrl) : undefined;\n const res = new URL(_targetUrl, baseUrl);\n\n if (returnBackUrl) {\n res.searchParams.set('redirect_url', returnBackUrl.toString());\n }\n return res.toString();\n};\n\nconst legacyBuildUrl = (targetUrl: string, redirectUrl?: string) => {\n let url;\n if (!targetUrl.startsWith('http')) {\n if (!redirectUrl || !redirectUrl.startsWith('http')) {\n throw new Error('destination url or return back url should be an absolute path url!');\n }\n\n const baseURL = new URL(redirectUrl);\n url = new URL(targetUrl, baseURL.origin);\n } else {\n url = new URL(targetUrl);\n }\n\n if (redirectUrl) {\n url.searchParams.set('redirect_url', redirectUrl);\n }\n\n return url.toString();\n};\n\ntype RedirectAdapter<RedirectReturn> = (url: string) => RedirectReturn;\ntype RedirectToParams = { returnBackUrl?: string | URL | null };\nexport type RedirectFun<ReturnType> = (params?: RedirectToParams) => ReturnType;\n\n/**\n * @internal\n */\ntype CreateRedirect = <ReturnType>(params: {\n redirectAdapter: RedirectAdapter<ReturnType>;\n baseUrl: URL | string;\n signInUrl?: URL | string;\n signUpUrl?: URL | string;\n}) => {\n redirectToSignIn: RedirectFun<ReturnType>;\n redirectToSignUp: RedirectFun<ReturnType>;\n};\n\nexport const createRedirect: CreateRedirect = params => {\n const { redirectAdapter, signInUrl, signUpUrl, baseUrl } = params;\n\n const redirectToSignUp = ({ returnBackUrl }: RedirectToParams = {}) => {\n if (!signUpUrl) {\n throw new Error('SignUp URL is not defined');\n }\n\n const pathToSignUpUrl = `${baseUrl}/sign-up`;\n\n function buildSignUpUrl(signIn: string | URL | undefined) {\n if (!signIn) {\n return;\n }\n const url = new URL(signIn, baseUrl);\n url.pathname = `${url.pathname}/create`;\n return url.toString();\n }\n\n const targetUrl = signUpUrl || buildSignUpUrl(signInUrl) || pathToSignUpUrl;\n\n return redirectAdapter(buildUrl(baseUrl, targetUrl, returnBackUrl));\n };\n\n const redirectToSignIn = ({ returnBackUrl }: RedirectToParams = {}) => {\n if (!signInUrl) {\n throw new Error('SignIn URL is not defined');\n }\n\n const pathToSignInUrl = `${baseUrl}/sign-in`;\n const targetUrl = signInUrl || pathToSignInUrl;\n\n return redirectAdapter(buildUrl(baseUrl, targetUrl, returnBackUrl));\n };\n\n return { redirectToSignUp, redirectToSignIn };\n};\n","import { parse } from \"cookie\";\n\nimport { constants } from \"../constants\";\nimport type { TernUrl } from \"./ternUrl\";\nimport { createTernUrl } from \"./ternUrl\";\n\nclass TernSecureRequest extends Request {\n readonly ternUrl: TernUrl;\n readonly cookies: Map<string, string | undefined>;\n\n public constructor(\n input: TernSecureRequest | Request | RequestInfo,\n init?: RequestInit\n ) {\n const url =\n typeof input !== \"string\" && \"url\" in input ? input.url : String(input);\n super(url, init || typeof input === \"string\" ? undefined : input);\n this.ternUrl = this.deriveUrlFromHeaders(this);\n this.cookies = this.parseCookies(this);\n }\n\n public toJSON() {\n return {\n url: this.ternUrl.href,\n method: this.method,\n headers: JSON.stringify(Object.fromEntries(this.headers)),\n ternUrl: this.ternUrl.toString(),\n cookies: JSON.stringify(Object.fromEntries(this.cookies)),\n };\n }\n\n private deriveUrlFromHeaders(req: Request) {\n const initialUrl = new URL(req.url);\n const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);\n const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);\n const host = req.headers.get(constants.Headers.Host);\n const protocol = initialUrl.protocol;\n\n const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;\n const resolvedProtocol =\n this.getFirstValueFromHeader(forwardedProto) ??\n protocol?.replace(/[:/]/, \"\");\n const origin =\n resolvedHost && resolvedProtocol\n ? `${resolvedProtocol}://${resolvedHost}`\n : initialUrl.origin;\n\n if (origin === initialUrl.origin) {\n return createTernUrl(initialUrl);\n }\n\n return createTernUrl(initialUrl.pathname + initialUrl.search, origin);\n }\n\n private getFirstValueFromHeader(value?: string | null) {\n return value?.split(\",\")[0];\n }\n\n private parseCookies(req: Request) {\n const cookiesRecord = parse(\n this.decodeCookieValue(req.headers.get(\"cookie\") || \"\")\n );\n return new Map(Object.entries(cookiesRecord));\n }\n\n private decodeCookieValue(str: string) {\n return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;\n }\n}\n\nexport const createTernSecureRequest = (\n ...args: ConstructorParameters<typeof TernSecureRequest>\n): TernSecureRequest => {\n return args[0] instanceof TernSecureRequest\n ? args[0]\n : new TernSecureRequest(...args);\n};\n\nexport type { TernSecureRequest };\n","class TernUrl extends URL {\n public isCrossOrigin(other: URL | string) {\n return this.origin !== new URL(other.toString()).origin;\n }\n}\n\nexport type WithTernUrl<T> = T & {\n /**\n * When a NextJs app is hosted on a platform different from Vercel\n * or inside a container (Netlify, Fly.io, AWS Amplify, docker etc),\n * req.url is always set to `localhost:3000` instead of the actual host of the app.\n *\n */\n ternUrl: TernUrl;\n};\n\nexport const createTernUrl = (\n ...args: ConstructorParameters<typeof TernUrl>\n): TernUrl => {\n return new TernUrl(...args);\n};\n\nexport type { TernUrl };\n","import type { AuthEndpoint, AuthSubEndpoint } from '@tern-secure/types';\n\nimport { constants } from '../constants';\nimport type { TernSecureRequest } from './ternSecureRequest';\nimport type { AuthenticateRequestOptions } from './types';\n\n\n/**\n * Request context for better type safety and clarity\n */\ninterface RequestProcessorContext extends AuthenticateRequestOptions {\n // header-based values\n sessionTokenInHeader: string | undefined;\n origin: string | undefined;\n host: string | undefined;\n forwardedHost: string | undefined;\n forwardedProto: string | undefined;\n referrer: string | undefined;\n userAgent: string | undefined;\n secFetchDest: string | undefined;\n accept: string | undefined;\n appCheckToken: string | undefined;\n\n // cookie-based values\n idTokenInCookie: string | undefined;\n refreshTokenInCookie: string | undefined;\n csrfTokenInCookie: string | undefined;\n sessionTokenInCookie?: string | undefined;\n customTokenInCookie?: string | undefined;\n ternAuth: number;\n\n handshakeNonce: string | undefined;\n handshakeToken: string | undefined;\n\n method: string;\n pathSegments: string[];\n endpoint?: AuthEndpoint;\n subEndpoint?: AuthSubEndpoint;\n\n ternUrl: URL;\n instanceType: string;\n}\n\n/**\n * Request processor utility class for common operations\n */\nclass RequestProcessorContext implements RequestProcessorContext {\n public constructor(\n private ternSecureRequest: TernSecureRequest,\n private options: AuthenticateRequestOptions,\n ) {\n this.initHeaderValues();\n this.initCookieValues();\n this.initHandshakeValues();\n this.initUrlValues();\n Object.assign(this, options);\n this.ternUrl = this.ternSecureRequest.ternUrl;\n }\n\n public get request(): TernSecureRequest {\n return this.ternSecureRequest;\n }\n\n private initHeaderValues() {\n this.sessionTokenInHeader = this.parseAuthorizationHeader(\n this.getHeader(constants.Headers.Authorization),\n );\n this.origin = this.getHeader(constants.Headers.Origin);\n this.host = this.getHeader(constants.Headers.Host);\n this.forwardedHost = this.getHeader(constants.Headers.ForwardedHost);\n this.forwardedProto =\n this.getHeader(constants.Headers.CloudFrontForwardedProto) ||\n this.getHeader(constants.Headers.ForwardedProto);\n this.referrer = this.getHeader(constants.Headers.Referrer);\n this.userAgent = this.getHeader(constants.Headers.UserAgent);\n this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);\n this.accept = this.getHeader(constants.Headers.Accept);\n this.appCheckToken = this.getHeader(constants.Headers.AppCheckToken);\n }\n\n private initCookieValues() {\n const isProduction = process.env.NODE_ENV === 'production';\n const defaultPrefix = isProduction ? '__HOST-' : '__dev_';\n this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);\n\n // System-fixed cookies using backend constants\n this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);\n this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);\n this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);\n this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);\n this.ternAuth = Number.parseInt(this.getCookie(constants.Cookies.TernAut) || '0', 10);\n }\n\n private initHandshakeValues() {\n this.handshakeToken = this.getQueryParam(constants.QueryParameters.Handshake) || this.getCookie(constants.Cookies.Handshake);\n this.handshakeNonce = this.getQueryParam(constants.QueryParameters.HandshakeNonce) || this.getCookie(constants.Cookies.HandshakeNonce);\n }\n\n private initUrlValues() {\n this.method = this.ternSecureRequest.method;\n this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split('/').filter(Boolean);\n this.endpoint = this.pathSegments[2] as AuthEndpoint;\n this.subEndpoint = this.pathSegments[3] as AuthSubEndpoint;\n }\n\n private getQueryParam(name: string) {\n return this.ternSecureRequest.ternUrl.searchParams.get(name);\n }\n\n private getHeader(name: string) {\n return this.ternSecureRequest.headers.get(name) || undefined;\n }\n\n private getCookie(name: string) {\n return this.ternSecureRequest.cookies.get(name) || undefined;\n }\n\n private parseAuthorizationHeader(\n authorizationHeader: string | undefined | null,\n ): string | undefined {\n if (!authorizationHeader) {\n return undefined;\n }\n\n const [scheme, token] = authorizationHeader.split(' ', 2);\n\n if (!token) {\n // No scheme specified, treat the entire value as the token\n return scheme;\n }\n\n if (scheme === 'Bearer') {\n return token;\n }\n\n // Skip all other schemes\n return undefined;\n }\n}\n\nexport type { RequestProcessorContext };\n\nexport const createRequestProcessor = (\n ternSecureRequest: TernSecureRequest,\n options: AuthenticateRequestOptions,\n): RequestProcessorContext => {\n return new RequestProcessorContext(ternSecureRequest, options);\n};\n","import type { DecodedAppCheckToken, DecodedIdToken } from \"@tern-secure/types\";\nimport type {\n JWTPayload,\n} from \"jose\";\n\nexport function mapJwtPayloadToDecodedIdToken(payload: JWTPayload) {\n const decodedIdToken = payload as DecodedIdToken;\n decodedIdToken.uid = decodedIdToken.sub;\n return decodedIdToken;\n}\n\n\nexport function mapJwtPayloadToDecodedAppCheckToken(payload: JWTPayload) {\n const decodedAppCheckToken = payload as DecodedAppCheckToken;\n decodedAppCheckToken.app_id = decodedAppCheckToken.sub;\n return decodedAppCheckToken;\n}","import type { CheckAuthorizationFromSessionClaims, DecodedIdToken } from '@tern-secure/types';\nimport type { JWTPayload } from 'jose';\n\nimport { constants } from '../constants';\nimport type { TokenVerificationErrorReason } from '../utils/errors';\nimport { mapJwtPayloadToDecodedIdToken } from '../utils/mapDecode';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport type { TernSecureRequest } from './ternSecureRequest';\n\nexport const AuthStatus = {\n SignedIn: 'signed-in',\n SignedOut: 'signed-out',\n Handshake: 'handshake',\n} as const;\n\nexport type AuthStatus = (typeof AuthStatus)[keyof typeof AuthStatus];\n\nexport const AuthErrorReason = {\n AuthTimeout: 'auth-timeout',\n SessionTokenAndAuthMissing: 'session-token-and-aut-missing',\n SessionTokenMissing: 'session-token-missing',\n SessionTokenExpired: 'session-token-expired',\n SessionTokenIATBeforeTernAUT: 'session-token-iat-before-tern-aut',\n SessionTokenNBF: 'session-token-nbf',\n SessionTokenIatInTheFuture: 'session-token-iat-in-the-future',\n SessionTokenWithoutTernAUT: 'session-token-but-no-tern-uat',\n TernAutWithoutSessionToken: 'tern-aut-but-no-session-token',\n SyncRequired: 'sync-required',\n UnexpectedError: 'unexpected-error',\n} as const;\n\nexport type AuthErrorReason = (typeof AuthErrorReason)[keyof typeof AuthErrorReason];\n\nexport type AuthReason = AuthErrorReason | TokenVerificationErrorReason;\n\nexport type SignedInAuthObject = {\n sessionClaims: DecodedIdToken;\n userId: string;\n token: string;\n require: CheckAuthorizationFromSessionClaims;\n error: string | null;\n};\n\nexport type SignedOutAuthObject = {\n sessionClaims: null;\n userId: null;\n token: null;\n require: CheckAuthorizationFromSessionClaims;\n error: string | null;\n};\n\nexport type SignedInState = {\n status: typeof AuthStatus.SignedIn;\n message: null;\n reason: null;\n signInUrl: string;\n signUpUrl: string;\n isSignedIn: true;\n auth: () => SignedInAuthObject;\n token: string;\n appCheckToken?: string;\n headers: Headers;\n};\n\nexport type SignedOutState = {\n status: typeof AuthStatus.SignedOut;\n message: string;\n reason: string;\n isSignedIn: false;\n signInUrl: string;\n signUpUrl: string;\n auth: () => SignedOutAuthObject;\n token: null;\n appCheckToken?: string;\n headers: Headers;\n};\n\nexport type HandshakeState = Omit<SignedOutState, 'status' | 'auth'> & {\n status: typeof AuthStatus.Handshake;\n headers: Headers;\n auth: () => null;\n};\n\nexport type RequestState = SignedInState | SignedOutState | HandshakeState;\n\nexport interface BackendInstance {\n ternSecureRequest: TernSecureRequest;\n requestState: RequestState;\n}\n\nexport type AuthObject = SignedInAuthObject | SignedOutAuthObject;\n\nfunction createHasAuthorization(\n decodedIdToken: DecodedIdToken,\n): CheckAuthorizationFromSessionClaims {\n return (authorizationParams: any) => {\n if (\n !authorizationParams ||\n typeof authorizationParams !== 'object' ||\n Array.isArray(authorizationParams)\n ) {\n return false;\n }\n const claims = decodedIdToken as Record<string, any>;\n\n return Object.entries(authorizationParams).every(([key, value]) => {\n const claimValue = claims[key];\n if (typeof claimValue === 'undefined') {\n return false;\n }\n if (Array.isArray(value)) {\n if (Array.isArray(claimValue)) {\n return value.some(v => claimValue.includes(v));\n }\n return value.includes(claimValue);\n }\n\n if (Array.isArray(claimValue)) {\n return claimValue.includes(value);\n }\n return claimValue === value;\n });\n };\n}\n\nexport function signedInAuthObject(\n sessionToken: string,\n sessionClaims: JWTPayload,\n): SignedInAuthObject {\n const decodedIdToken = mapJwtPayloadToDecodedIdToken(sessionClaims);\n return {\n sessionClaims: {\n ...decodedIdToken,\n },\n userId: decodedIdToken.uid,\n token: sessionToken,\n require: createHasAuthorization(decodedIdToken),\n error: null,\n };\n}\n\nexport function signedOutAuthObject(): SignedOutAuthObject {\n return {\n sessionClaims: null,\n userId: null,\n token: null,\n require: () => false,\n error: 'No active session',\n };\n}\n\nexport function signedIn(\n authCtx: RequestProcessorContext,\n sessionClaims: JWTPayload,\n headers: Headers = new Headers(),\n token: string,\n): SignedInState {\n const authObject = signedInAuthObject(token, sessionClaims);\n \n return {\n status: AuthStatus.SignedIn,\n message: null,\n reason: null,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: true,\n auth: () => authObject,\n token,\n headers,\n };\n}\n\nexport function signedOut(\n authCtx: RequestProcessorContext,\n reason: AuthReason,\n message = '',\n headers: Headers = new Headers(),\n): SignedOutState {\n return decorateHeaders({\n status: AuthStatus.SignedOut,\n reason,\n message,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: false,\n auth: () => signedOutAuthObject(),\n token: null,\n appCheckToken: authCtx.appCheckToken,\n headers,\n });\n}\n\nexport function handshake(\n authCtx: RequestProcessorContext,\n reason: AuthReason,\n message = '',\n headers: Headers,\n): HandshakeState {\n return {\n status: AuthStatus.Handshake,\n reason,\n message,\n signInUrl: authCtx.signInUrl || '',\n signUpUrl: authCtx.signUpUrl || '',\n isSignedIn: false,\n headers,\n auth: () => null,\n token: null,\n };\n}\n\nconst decorateHeaders = <T extends RequestState>(requestState: T): T => {\n const headers = new Headers(requestState.headers || {});\n\n if (requestState.message) {\n try {\n headers.set(constants.Headers.AuthMessage, requestState.message);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.reason) {\n try {\n headers.set(constants.Headers.AuthReason, requestState.reason);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.status) {\n try {\n headers.set(constants.Headers.AuthStatus, requestState.status);\n } catch {\n // Ignore errors\n }\n }\n\n if (requestState.appCheckToken) {\n try {\n headers.set(constants.Headers.AppCheckToken, requestState.appCheckToken);\n } catch {\n // Ignore errors\n }\n }\n\n requestState.headers = headers;\n\n return requestState;\n};\n","import type { DecodedAppCheckToken, DecodedIdToken, Jwt, JWTPayload } from '@tern-secure/types';\nimport {\n decodeJwt,\n decodeProtectedHeader,\n jwtVerify,\n type KeyLike,\n} from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { mapJwtPayloadToDecodedAppCheckToken, mapJwtPayloadToDecodedIdToken } from '../utils/mapDecode';\nimport { base64url } from '../utils/rfc4648';\nimport { importKey } from './cryptoKeys';\nimport type { JwtReturnType } from './types';\nimport {\n verifyExpirationClaim,\n verifyHeaderKid,\n verifyIssuedAtClaim,\n verifySubClaim,\n} from './verifyContent';\n\nconst DEFAULT_CLOCK_SKEW_IN_MS = 5 * 1000;\n\nexport type VerifyJwtOptions = {\n audience?: string | string[];\n clockSkewInMs?: number;\n key: JsonWebKey | string;\n};\n\nexport async function verifySignature(\n jwt: Jwt,\n key: JsonWebKey | string,\n): Promise<JwtReturnType<JWTPayload, Error>> {\n const { header, raw } = jwt;\n const joseAlgorithm = header.alg || 'RS256';\n\n try {\n const publicKey = await importKey(key, joseAlgorithm);\n\n const { payload } = await jwtVerify(raw.text, publicKey);\n\n return { data: payload };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: (error as Error).message,\n }),\n ],\n };\n }\n}\n\nexport function ternDecodeJwt(token: string): JwtReturnType<Jwt, TokenVerificationError> {\n try {\n const header = decodeProtectedHeader(token);\n const payload = decodeJwt(token);\n\n const tokenParts = (token || '').toString().split('.');\n if (tokenParts.length !== 3) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'Invalid JWT format',\n }),\n ],\n };\n }\n\n const [rawHeader, rawPayload, rawSignature] = tokenParts;\n const signature = base64url.parse(rawSignature, { loose: true });\n\n const data = {\n header,\n payload,\n signature,\n raw: {\n header: rawHeader,\n payload: rawPayload,\n signature: rawSignature,\n text: token,\n },\n } satisfies Jwt;\n\n return { data };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `${(error as Error).message || 'Invalid Token or Protected Header formatting'} (Token length: ${token?.length}, First 10 chars: ${token?.substring(0, 10)}...)`,\n }),\n ],\n };\n }\n}\n\nexport async function verifyJwt(\n token: string,\n options: VerifyJwtOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { key } = options;\n const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;\n\n const { data: decoded, errors } = ternDecodeJwt(token);\n if (errors) {\n return { errors };\n }\n\n const { header, payload } = decoded;\n\n try {\n verifyHeaderKid(header.kid);\n verifySubClaim(payload.sub);\n verifyExpirationClaim(payload.exp, clockSkew);\n verifyIssuedAtClaim(payload.iat, clockSkew);\n } catch (error) {\n return { errors: [error as TokenVerificationError] };\n }\n\n const { data: verifiedPayload, errors: signatureErrors } = await verifySignature(decoded, key);\n if (signatureErrors) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: 'Token signature verification failed.',\n }),\n ],\n };\n }\n\n const decodedIdToken = mapJwtPayloadToDecodedIdToken(verifiedPayload);\n\n return { data: decodedIdToken };\n}\n\nexport type VerifyAppCheckJwtOptions = Omit<VerifyJwtOptions, 'key'> & {\n key: () => Promise<KeyLike>;\n};\n\nexport async function verifyAppCheckSignature(\n jwt: Jwt,\n getPublicKey: () => Promise<KeyLike>,\n): Promise<JwtReturnType<JWTPayload, Error>> {\n const { header, raw } = jwt;\n const joseAlgorithm = header.alg || 'RS256';\n\n try {\n const key = await getPublicKey();\n\n const { payload } = await jwtVerify(raw.text, key);\n\n return { data: payload };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: (error as Error).message,\n }),\n ],\n };\n }\n}\n\n\nexport async function verifyAppCheckJwt(\n token: string,\n options: VerifyAppCheckJwtOptions,\n): Promise<JwtReturnType<DecodedAppCheckToken, TokenVerificationError>> {\n const { key: getPublicKey } = options;\n const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;\n\n const { data: decoded, errors } = ternDecodeJwt(token);\n if (errors) {\n return { errors };\n }\n\n const { header, payload } = decoded;\n\n try {\n verifyHeaderKid(header.kid);\n verifySubClaim(payload.sub);\n verifyExpirationClaim(payload.exp, clockSkew);\n verifyIssuedAtClaim(payload.iat, clockSkew);\n } catch (error) {\n return { errors: [error as TokenVerificationError] };\n }\n\n const { data: verifiedPayload, errors: signatureErrors } = await verifyAppCheckSignature(\n decoded,\n getPublicKey,\n );\n if (signatureErrors) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: 'Token signature verification failed.',\n }),\n ],\n };\n }\n\n const decodedAppCheckToken = mapJwtPayloadToDecodedAppCheckToken(verifiedPayload);\n\n return { data: decodedAppCheckToken };\n}","export const RefreshTokenErrorReason = {\n NonEligibleNoCookie: 'non-eligible-no-refresh-cookie',\n NonEligibleNonGet: 'non-eligible-non-get',\n InvalidSessionToken: 'invalid-session-token',\n MissingApiClient: 'missing-api-client',\n MissingIdToken: 'missing-id-token',\n MissingSessionToken: 'missing-session-token',\n MissingRefreshToken: 'missing-refresh-token',\n ExpiredIdTokenDecodeFailed: 'expired-id-token-decode-failed',\n ExpiredSessionTokenDecodeFailed: 'expired-session-token-decode-failed',\n FetchError: 'fetch-error',\n} as const;\n\nexport type TokenCarrier = 'header' | 'cookie';\n\nexport const TokenVerificationErrorReason = {\n TokenExpired: 'token-expired',\n TokenInvalid: 'token-invalid',\n TokenInvalidAlgorithm: 'token-invalid-algorithm',\n TokenInvalidAuthorizedParties: 'token-invalid-authorized-parties',\n TokenInvalidSignature: 'token-invalid-signature',\n TokenNotActiveYet: 'token-not-active-yet',\n TokenIatInTheFuture: 'token-iat-in-the-future',\n TokenVerificationFailed: 'token-verification-failed',\n InvalidSecretKey: 'secret-key-invalid',\n LocalJWKMissing: 'jwk-local-missing',\n RemoteJWKFailedToLoad: 'jwk-remote-failed-to-load',\n RemoteJWKInvalid: 'jwk-remote-invalid',\n RemoteJWKMissing: 'jwk-remote-missing',\n JWKFailedToResolve: 'jwk-failed-to-resolve',\n JWKKidMismatch: 'jwk-kid-mismatch',\n};\n\nexport type TokenVerificationErrorReason =\n (typeof TokenVerificationErrorReason)[keyof typeof TokenVerificationErrorReason];\n\nexport class TokenVerificationError extends Error {\n reason: TokenVerificationErrorReason;\n tokenCarrier?: TokenCarrier;\n\n constructor({\n message,\n reason,\n }: {\n message: string;\n reason: TokenVerificationErrorReason;\n }) {\n super(message);\n\n Object.setPrototypeOf(this, TokenVerificationError.prototype);\n\n this.reason = reason;\n this.message = message;\n }\n\n public getFullMessage() {\n return `${[this.message].filter(m => m).join(' ')} (reason=${this.reason}, token-carrier=${\n this.tokenCarrier\n })`;\n }\n }\n","/**\n * The base64url helper was extracted from the rfc4648 package\n * in order to resolve CSJ/ESM interoperability issues\n *\n * https://github.com/swansontec/rfc4648.js\n *\n * For more context please refer to:\n * - https://github.com/evanw/esbuild/issues/1719\n * - https://github.com/evanw/esbuild/issues/532\n * - https://github.com/swansontec/rollup-plugin-mjs-entry\n */\nexport const base64url = {\n parse(string: string, opts?: ParseOptions): Uint8Array {\n return parse(string, base64UrlEncoding, opts);\n },\n\n stringify(data: ArrayLike<number>, opts?: StringifyOptions): string {\n return stringify(data, base64UrlEncoding, opts);\n },\n};\n\nconst base64UrlEncoding: Encoding = {\n chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',\n bits: 6,\n};\n\ninterface Encoding {\n bits: number;\n chars: string;\n codes?: { [char: string]: number };\n}\n\ninterface ParseOptions {\n loose?: boolean;\n out?: new (size: number) => { [index: number]: number };\n}\n\ninterface StringifyOptions {\n pad?: boolean;\n}\n\nfunction parse(string: string, encoding: Encoding, opts: ParseOptions = {}): Uint8Array {\n // Build the character lookup table:\n if (!encoding.codes) {\n encoding.codes = {};\n for (let i = 0; i < encoding.chars.length; ++i) {\n encoding.codes[encoding.chars[i]] = i;\n }\n }\n\n // The string must have a whole number of bytes:\n if (!opts.loose && (string.length * encoding.bits) & 7) {\n throw new SyntaxError('Invalid padding');\n }\n\n // Count the padding bytes:\n let end = string.length;\n while (string[end - 1] === '=') {\n --end;\n\n // If we get a whole number of bytes, there is too much padding:\n if (!opts.loose && !(((string.length - end) * encoding.bits) & 7)) {\n throw new SyntaxError('Invalid padding');\n }\n }\n\n // Allocate the output:\n const out = new (opts.out ?? Uint8Array)(((end * encoding.bits) / 8) | 0) as Uint8Array;\n\n // Parse the data:\n let bits = 0; // Number of bits currently in the buffer\n let buffer = 0; // Bits waiting to be written out, MSB first\n let written = 0; // Next byte to write\n for (let i = 0; i < end; ++i) {\n // Read one character from the string:\n const value = encoding.codes[string[i]];\n if (value === undefined) {\n throw new SyntaxError('Invalid character ' + string[i]);\n }\n\n // Append the bits to the buffer:\n buffer = (buffer << encoding.bits) | value;\n bits += encoding.bits;\n\n // Write out some bits if the buffer has a byte's worth:\n if (bits >= 8) {\n bits -= 8;\n out[written++] = 0xff & (buffer >> bits);\n }\n }\n\n // Verify that we have received just enough bits:\n if (bits >= encoding.bits || 0xff & (buffer << (8 - bits))) {\n throw new SyntaxError('Unexpected end of data');\n }\n\n return out;\n}\n\nfunction stringify(data: ArrayLike<number>, encoding: Encoding, opts: StringifyOptions = {}): string {\n const { pad = true } = opts;\n const mask = (1 << encoding.bits) - 1;\n let out = '';\n\n let bits = 0; // Number of bits currently in the buffer\n let buffer = 0; // Bits waiting to be written out, MSB first\n for (let i = 0; i < data.length; ++i) {\n // Slurp data into the buffer:\n buffer = (buffer << 8) | (0xff & data[i]);\n bits += 8;\n\n // Write out as much as we can:\n while (bits > encoding.bits) {\n bits -= encoding.bits;\n out += encoding.chars[mask & (buffer >> bits)];\n }\n }\n\n // Partial character:\n if (bits) {\n out += encoding.chars[mask & (buffer << (encoding.bits - bits))];\n }\n\n // Add padding characters until we hit a byte boundary:\n if (pad) {\n while ((out.length * encoding.bits) & 7) {\n out += '=';\n }\n }\n\n return out;\n}\n","import { importJWK, importSPKI,importX509, type KeyLike } from 'jose';\n\nexport async function importKey(key: JsonWebKey | string, algorithm: string): Promise<KeyLike> {\n if (typeof key === 'object') {\n const result = await importJWK(key as Parameters<typeof importJWK>[0], algorithm);\n if (result instanceof Uint8Array) {\n throw new Error('Unexpected Uint8Array result from JWK import');\n }\n return result;\n }\n\n const keyString = key.trim();\n\n if (keyString.includes('-----BEGIN CERTIFICATE-----')) {\n return await importX509(keyString, algorithm);\n }\n\n if (keyString.includes('-----BEGIN PUBLIC KEY-----')) {\n return await importSPKI(keyString, algorithm);\n }\n\n try {\n return await importSPKI(keyString, algorithm);\n } catch (error) {\n throw new Error(\n `Unsupported key format. Supported formats: X.509 certificate (PEM), SPKI (PEM), JWK (JSON object or string). Error: ${error}`,\n );\n }\n}\n","const algToHash: Record<string, string> = {\n RS256: 'SHA-256',\n RS384: 'SHA-384',\n RS512: 'SHA-512',\n};\nconst RSA_ALGORITHM_NAME = 'RSASSA-PKCS1-v1_5';\n\nconst jwksAlgToCryptoAlg: Record<string, string> = {\n RS256: RSA_ALGORITHM_NAME,\n RS384: RSA_ALGORITHM_NAME,\n RS512: RSA_ALGORITHM_NAME,\n};\n\nexport const algs = Object.keys(algToHash);\n\nexport function getCryptoAlgorithm(algorithmName: string): RsaHashedImportParams {\n const hash = algToHash[algorithmName];\n const name = jwksAlgToCryptoAlg[algorithmName];\n\n if (!hash || !name) {\n throw new Error(`Unsupported algorithm ${algorithmName}, expected one of ${algs.join(',')}.`);\n }\n\n return {\n hash: { name: algToHash[algorithmName] },\n name: jwksAlgToCryptoAlg[algorithmName],\n };\n}\n","import { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { algs } from './algorithms';\n\nexport const verifyHeaderType = (typ?: unknown) => {\n if (typeof typ === 'undefined') {\n return;\n }\n\n if (typ !== 'JWT') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `Invalid JWT type ${JSON.stringify(typ)}. Expected \"JWT\".`,\n });\n }\n};\n\nexport const verifyHeaderKid = (kid?: unknown) => {\n if (typeof kid === 'undefined') {\n return;\n }\n\n if (typeof kid !== 'string') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `Invalid JWT kid ${JSON.stringify(kid)}. Expected a string.`,\n });\n }\n};\n\nexport const verifyHeaderAlgorithm = (alg: string) => {\n if (!algs.includes(alg)) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidAlgorithm,\n message: `Invalid JWT algorithm ${JSON.stringify(alg)}. Supported: ${algs}.`,\n });\n }\n};\n\nexport const verifySubClaim = (sub?: string) => {\n if (typeof sub !== 'string') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Subject claim (sub) is required and must be a string. Received ${JSON.stringify(sub)}.`,\n });\n }\n};\n\nexport const verifyExpirationClaim = (exp: number | undefined, clockSkewInMs: number) => {\n if (typeof exp !== 'number') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Invalid JWT expiry date (exp) claim ${JSON.stringify(exp)}. Expected a number.`,\n });\n }\n\n const currentDate = new Date(Date.now());\n const expiryDate = new Date(0);\n expiryDate.setUTCSeconds(exp);\n\n const expired = expiryDate.getTime() <= currentDate.getTime() - clockSkewInMs;\n if (expired) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenExpired,\n message: `JWT is expired. Expiry date: ${expiryDate.toUTCString()}, Current date: ${currentDate.toUTCString()}.`,\n });\n }\n};\n\nexport const verifyIssuedAtClaim = (iat: number | undefined, clockSkewInMs: number) => {\n if (typeof iat === 'undefined') {\n return;\n }\n\n if (typeof iat !== 'number') {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenVerificationFailed,\n message: `Invalid JWT issued at date claim (iat) ${JSON.stringify(iat)}. Expected a number.`,\n });\n }\n\n const currentDate = new Date(Date.now());\n const issuedAtDate = new Date(0);\n issuedAtDate.setUTCSeconds(iat);\n\n const postIssued = issuedAtDate.getTime() > currentDate.getTime() + clockSkewInMs;\n if (postIssued) {\n throw new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenIatInTheFuture,\n message: `JWT issued at date claim (iat) is in the future. Issued at date: ${issuedAtDate.toUTCString()}; Current date: ${currentDate.toUTCString()};`,\n });\n }\n};\n","import { type RemoteJWKSetOptions } from 'jose';\n\nimport {\n CACHE_CONTROL_REGEX,\n DEFAULT_CACHE_DURATION,\n GOOGLE_PUBLIC_KEYS_URL,\n MAX_CACHE_LAST_UPDATED_AT_SECONDS\n} from '../constants';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\n\nexport type PublicKeys = { [key: string]: string };\n\ninterface PublicKeysResponse {\n keys: PublicKeys;\n expiresAt: number;\n}\n\nexport type LoadJWKFromRemoteOptions = RemoteJWKSetOptions & {\n kid: string;\n keyURL?: string;\n skipJwksCache?: boolean;\n};\n\ntype CertificateCache = Record<string, string>;\n\nlet cache: CertificateCache = {};\nlet lastUpdatedAt = 0;\nlet googleExpiresAt = 0;\n\nfunction getFromCache(kid: string) {\n return cache[kid];\n}\n\nfunction getCacheValues() {\n return Object.values(cache);\n}\n\nfunction setInCache(kid: string, certificate: string, shouldExpire = true) {\n cache[kid] = certificate;\n lastUpdatedAt = shouldExpire ? Date.now() : -1;\n}\n\nasync function fetchPublicKeys(keyUrl: string): Promise<PublicKeysResponse> {\n const url = new URL(keyUrl);\n const response = await fetch(url);\n if (!response.ok) {\n throw new TokenVerificationError({\n message: `Error loading public keys from ${url.href} with code=${response.status} `,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n\n const data = await response.json();\n const expiresAt = getExpiresAt(response);\n\n return {\n keys: data,\n expiresAt,\n };\n}\n\nexport async function loadJWKFromRemote({\n keyURL,\n skipJwksCache,\n kid,\n}: LoadJWKFromRemoteOptions): Promise<string> {\n const finalKeyURL = keyURL || GOOGLE_PUBLIC_KEYS_URL;\n if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {\n const { keys, expiresAt } = await fetchPublicKeys(finalKeyURL);\n\n if (!keys || Object.keys(keys).length === 0) {\n throw new TokenVerificationError({\n message: `The JWKS endpoint ${finalKeyURL} returned no keys`,\n reason: TokenVerificationErrorReason.RemoteJWKFailedToLoad,\n });\n }\n googleExpiresAt = expiresAt;\n\n Object.entries(keys).forEach(([keyId, cert]) => {\n setInCache(keyId, cert);\n });\n }\n const cert = getFromCache(kid);\n if (!cert) {\n getCacheValues();\n const availableKids = Object.keys(cache).sort().join(', ');\n\n throw new TokenVerificationError({\n message: `No public key found for kid \"${kid}\". Available kids: [${availableKids}]`,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n return cert;\n}\n\nfunction isCacheExpired() {\n const now = Date.now();\n if (lastUpdatedAt === -1) {\n return false;\n }\n\n const cacheAge = now - lastUpdatedAt;\n const maxCacheAge = MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1000;\n const localCacheExpired = cacheAge >= maxCacheAge;\n const googleCacheExpired = now >= googleExpiresAt;\n\n const isExpired = localCacheExpired || googleCacheExpired;\n\n if (isExpired) {\n cache = {};\n }\n\n return isExpired;\n}\n\nfunction getExpiresAt(res: Response) {\n const cacheControlHeader = res.headers.get('cache-control');\n if (!cacheControlHeader) {\n return Date.now() + DEFAULT_CACHE_DURATION;\n }\n const maxAgeMatch = cacheControlHeader.match(CACHE_CONTROL_REGEX);\n const maxAge = maxAgeMatch ? parseInt(maxAgeMatch[1], 10) : DEFAULT_CACHE_DURATION / 1000;\n\n return Date.now() + maxAge * 1000;\n}\n\nexport const getCacheStats = () => ({\n localExpiry: lastUpdatedAt + MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1000,\n googleExpiry: googleExpiresAt,\n cacheCount: Object.keys(cache).length,\n});\n","import type { DecodedIdToken, TernSecureAdminConfig, TernSecureConfig, TernSecureUserData} from '@tern-secure/types';\n\nimport type { JwtReturnType } from '../jwt/types';\nimport { ternDecodeJwt, verifyJwt, type VerifyJwtOptions } from '../jwt/verifyJwt';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport type { LoadJWKFromRemoteOptions } from './keys';\nimport { loadJWKFromRemote } from './keys';\n\nexport type VerifyTokenVOptions = Omit<VerifyJwtOptions, 'key'> & Omit<LoadJWKFromRemoteOptions, 'kid'> & {\n jwtKey?: string;\n};\n\nexport { TernSecureConfig, TernSecureAdminConfig, TernSecureUserData };\n\nexport async function verifyToken(\n token: string,\n options: VerifyTokenVOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { data: decodedResult, errors } = ternDecodeJwt(token);\n\n if (errors) {\n return { errors };\n }\n\n const { header } = decodedResult;\n const { kid } = header;\n\n if (!kid) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'JWT \"kid\" header is missing.',\n }),\n ],\n };\n }\n\n try {\n const key = options.jwtKey || (await loadJWKFromRemote({ ...options, kid }));\n\n if (!key) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `No public key found for kid \"${kid}\".`,\n }),\n ],\n };\n }\n return await verifyJwt(token, { ...options, key });\n } catch (error) {\n if (error instanceof TokenVerificationError) {\n return { errors: [error] };\n }\n return {\n errors: [error as TokenVerificationError],\n };\n }\n}\n","import type { RequestFunction } from '../request';\n\nexport abstract class AbstractAPI {\n constructor(protected request: RequestFunction) {}\n\n protected requireApiKey(apiKey: string) {\n if (!apiKey) {\n throw new Error('A valid API key is required.');\n }\n }\n}\n","import { AbstractAPI } from './AbstractApi';\n\n\nexport interface AppCheckTokenResponse {\n token: string;\n ttl: string;\n}\n\ntype AppCheckParams = {\n accessToken: string;\n projectId: string;\n appId: string;\n customToken: string;\n limitedUse?: boolean;\n}\n\nexport function getSdkVersion(): string {\n return '12.7.0';\n}\n\nconst FIREBASE_APP_CHECK_CONFIG_HEADERS = {\n 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`\n};\n\n/**\n * App Check API for managing Firebase App Check tokens via REST\n * Firebase REST API endpoint: https://firebaseappcheck.googleapis.com/v1beta/projects/{projectId}/apps/{appId}:exchangeCustomToken\n */\nexport class AppCheckApi extends AbstractAPI {\n public async exchangeCustomToken(params: AppCheckParams): Promise<AppCheckTokenResponse> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeCustomToken`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({customToken, limitedUse}),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n public async exchangeDebugToken(params: AppCheckParams): Promise<AppCheckTokenResponse> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeDebugToken`;\n\n const headers: Record<string, string> = {\n ...FIREBASE_APP_CHECK_CONFIG_HEADERS,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n const body = {\n customToken,\n limitedUse,\n }\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n}\n","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype sendEmailVerificationParams = {\n idToken: string;\n requestType: 'VERIFY_EMAIL';\n};\n\ntype ConfirmEmailVerificationParams = {\n oobCode: string;\n};\n\n\nexport class EmailApi extends AbstractAPI {\n public async verifyEmailVerification(apiKey: string, params: sendEmailVerificationParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"sendOobCode\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async confirmEmailVerification(apiKey: string, params: ConfirmEmailVerificationParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"sendOobCode\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n}","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype ConfirmPasswordResetParams = {\n oobCode: string;\n newPassword: string;\n};\n\ntype VerifyPasswordResetCodeParams = {\n oobCode: string;\n};\n\ntype ChangePasswordParams = {\n idToken: string;\n password: string;\n returnSecureToken?: boolean;\n};\n\nexport class PasswordApi extends AbstractAPI {\n public async verifyPasswordResetCode(apiKey: string, params: VerifyPasswordResetCodeParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async confirmPasswordReset(apiKey: string, params: ConfirmPasswordResetParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n public async changePassword(apiKey: string, params: ChangePasswordParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"passwordReset\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n}","import type { ResetPasswordEmail } from '../resources/EmailAddress';\nimport { AbstractAPI } from './AbstractApi';\n\ntype ResetPasswordEmailParams = {\n email: string;\n requestType: 'PASSWORD_RESET';\n};\n\ntype opts = {\n appCheckToken?: string;\n}\n\nexport class SignInApi extends AbstractAPI {\n public async resetPasswordEmail(\n apiKey: string,\n params: ResetPasswordEmailParams,\n options?: opts,\n ): Promise<ResetPasswordEmail> {\n try {\n this.requireApiKey(apiKey);\n const headers: Record<string, string> = {};\n if (options?.appCheckToken) {\n headers['X-Firebase-AppCheck'] = options.appCheckToken;\n }\n const { ...restParams } = params;\n\n const response = await this.request<ResetPasswordEmail>({\n endpoint: 'sendOobCode',\n method: 'POST',\n apiKey,\n bodyParams: restParams,\n headerParams: headers,\n });\n\n if (response.errors) {\n const errorMessage = response.errors[0]?.message || 'Failed to send reset password email';\n throw new Error(errorMessage);\n }\n return response.data;\n } catch (error) {\n const contextualMessage = `Failed to send reset password email: ${error instanceof Error ? error.message : 'Unknown error'}`;\n throw new Error(contextualMessage);\n }\n }\n}","import type { IdAndRefreshTokens } from '../resources/Token';\nimport { AbstractAPI } from './AbstractApi';\n\n\ntype CreateSignInTokenParams = {\n token: string;\n returnSecureToken?: boolean;\n};\n\nexport class SignInTokenApi extends AbstractAPI {\n public async createCustomToken(\n apiKey: string,\n params: CreateSignInTokenParams,\n ): Promise<IdAndRefreshTokens> {\n try {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n\n const response = await this.request<IdAndRefreshTokens>({\n endpoint: \"signInWithCustomToken\",\n method: 'POST',\n bodyParams: restParams,\n });\n\n if (response.errors) {\n const errorMessage = response.errors[0]?.message || 'Failed to create custom token';\n throw new Error(errorMessage);\n }\n\n return response.data;\n } catch (error) {\n const contextualMessage = `Failed to create custom token: ${error instanceof Error ? error.message : 'Unknown error'}`;\n throw new Error(contextualMessage);\n }\n }\n}\n","import { AbstractAPI } from \"./AbstractApi\";\n\n\ntype CreateSignUpTokenParams = {\n email: string;\n password: string;\n returnSecureToken?: boolean;\n};\n\n\nexport class SignUpApi extends AbstractAPI {\n public async createCustomToken(apiKey: string, params: CreateSignUpTokenParams) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n return this.request({\n endpoint: \"signUp\",\n method: \"POST\",\n bodyParams: restParams,\n });\n }\n\n}\n","import type { IdAndRefreshTokens } from '../resources/Token';\nimport { AbstractAPI } from './AbstractApi';\n\ntype RefreshTokenParams = {\n expired_token?: string;\n refresh_token: string;\n request_origin?: string;\n request_originating_ip?: string;\n request_headers?: Record<string, string[]>;\n suffixed_cookies?: boolean;\n app_check_token?: string;\n format?: 'token' | 'cookie';\n};\n\ntype IdAndRefreshTokensParams = {\n token: string;\n returnSecureToken?: boolean;\n};\n\ntype IdAndRefreshTokensOptions = {\n referer?: string;\n appCheckToken?: string;\n};\n\nexport class TokenApi extends AbstractAPI {\n public async refreshToken(apiKey: string, params: RefreshTokenParams) {\n this.requireApiKey(apiKey);\n const { refresh_token, request_origin, app_check_token, ...restParams } = params;\n\n const headers: Record<string, string> = {};\n if (request_origin) {\n headers['Referer'] = request_origin;\n }\n\n if (app_check_token) {\n headers['X-Firebase-AppCheck'] = app_check_token;\n }\n\n\n const bodyParams = {\n grant_type: 'refresh_token',\n refresh_token,\n ...restParams,\n };\n\n return this.request({\n endpoint: 'refreshToken',\n method: 'POST',\n apiKey,\n bodyParams,\n headerParams: headers,\n });\n }\n\n public async exchangeCustomForIdAndRefreshTokens(\n apiKey: string,\n params: IdAndRefreshTokensParams,\n options?: IdAndRefreshTokensOptions,\n ): Promise<IdAndRefreshTokens> {\n this.requireApiKey(apiKey);\n\n const headers: Record<string, string> = {};\n if (options?.referer) {\n headers['Referer'] = options.referer;\n }\n if (options?.appCheckToken) {\n headers['X-Firebase-AppCheck'] = options.appCheckToken;\n }\n\n const response = await this.request<IdAndRefreshTokens>({\n endpoint: 'signInWithCustomToken',\n method: 'POST',\n apiKey,\n bodyParams: params,\n headerParams: headers,\n });\n\n if (response.errors) {\n throw new Error(response.errors[0].message);\n }\n\n if (!response.data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n return response.data;\n }\n}\n","import type { User } from '../resources/User';\nimport { AbstractAPI } from './AbstractApi';\n\ntype UserDataParams = {\n localId?: string;\n idToken?: string;\n};\n\ntype UserDataOptions = {\n referer?: string;\n};\n\nexport class UserData extends AbstractAPI {\n public async getUserData(apiKey: string, params: UserDataParams, options?: UserDataOptions) {\n this.requireApiKey(apiKey);\n const { ...restParams } = params;\n\n const headers: Record<string, string> = {};\n if (options?.referer) {\n headers['Referer'] = options.referer;\n }\n return this.request<User>({\n endpoint: 'lookup',\n method: 'POST',\n apiKey,\n bodyParams: restParams,\n headerParams: headers,\n });\n }\n}","/**\n * This file exports APIs that vary across runtimes (i.e. Node & Browser - V8 isolates)\n * as a singleton object.\n *\n * Runtime polyfills are written in VanillaJS for now to avoid TS complication. Moreover,\n * due to this issue https://github.com/microsoft/TypeScript/issues/44848, there is not a good way\n * to tell Typescript which conditional import to use during build type.\n *\n * The Runtime type definition ensures type safety for now.\n * Runtime js modules are copied into dist folder with bash script.\n *\n * TODO: Support TS runtime modules\n */\n\n// @ts-ignore - These are package subpaths\nimport { webcrypto as crypto } from '#crypto';\n\ntype Runtime = {\n crypto: Crypto;\n fetch: typeof globalThis.fetch;\n AbortController: typeof globalThis.AbortController;\n Blob: typeof globalThis.Blob;\n FormData: typeof globalThis.FormData;\n Headers: typeof globalThis.Headers;\n Request: typeof globalThis.Request;\n Response: typeof globalThis.Response;\n};\n\n// Invoking the global.fetch without binding it first to the globalObject fails in\n// Cloudflare Workers with an \"Illegal Invocation\" error.\n//\n// The globalThis object is supported for Node >= 12.0.\n//\n// https://github.com/supabase/supabase/issues/4417\nconst globalFetch = fetch.bind(globalThis);\n\nexport const runtime: Runtime = {\n crypto,\n get fetch() {\n // We need to use the globalFetch for Cloudflare Workers but the fetch for testing\n return process.env.NODE_ENV === 'test' ? fetch : globalFetch;\n },\n AbortController: globalThis.AbortController,\n Blob: globalThis.Blob,\n FormData: globalThis.FormData,\n Headers: globalThis.Headers,\n Request: globalThis.Request,\n Response: globalThis.Response,\n};\n","export const FIREBASE_AUTH_EMULATOR_HOST = process.env.FIREBASE_AUTH_EMULATOR_HOST;\n\nexport function emulatorHost(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n return FIREBASE_AUTH_EMULATOR_HOST;\n}\n\nexport function useEmulator(): boolean {\n return !!emulatorHost();\n}\n","import { FIREBASE_AUTH_EMULATOR_HOST, useEmulator } from './emulator';\n\nexport const topLevelEndpoint = (apiKey: string, projectId: string, version: string) => {\n return `https://identitytoolkit.googleapis.com/${version}/projects/${projectId}${apiKey}`;\n};\n\nexport const lookupEndpoint = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=${apiKey}`;\n};\n\nexport const getRefreshTokenEndpoint = (apiKey: string) => {\n return `https://securetoken.googleapis.com/v1/token?key=${apiKey}`;\n};\n\nexport const signInWithPassword = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${apiKey}`;\n};\n\nexport const signUpEndpoint = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${apiKey}`;\n};\n\nexport const sendOobCode = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${apiKey}`;\n}\n\n\nexport const getCustomTokenEndpoint = (apiKey: string) => {\n if (useEmulator() && FIREBASE_AUTH_EMULATOR_HOST) {\n let protocol = 'http://';\n if (FIREBASE_AUTH_EMULATOR_HOST.startsWith('http://')) {\n protocol = '';\n }\n\n return `${protocol}${FIREBASE_AUTH_EMULATOR_HOST}/identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apiKey}`;\n }\n return `https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apiKey}`;\n};\n\nexport const verifyPasswordResetCode = (apiKey: string) => {\n return `https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=${apiKey}`;\n};\n","import type {\n TernSecureFireRestError,\n TernSecureFireRestErrorJSON,\n} from \"@tern-secure/types\";\n\nimport { constants } from \"../constants\";\nimport { runtime } from \"../runtime\";\nimport {\n getCustomTokenEndpoint,\n getRefreshTokenEndpoint,\n lookupEndpoint,\n sendOobCode,\n signInWithPassword,\n signUpEndpoint,\n} from \"./endpointUrl\";\n\nexport type HTTPMethod = \"DELETE\" | \"GET\" | \"PATCH\" | \"POST\" | \"PUT\";\nexport type FirebaseEndpoint =\n | \"lookup\"\n | \"refreshToken\"\n | \"signInWithPassword\"\n | \"signUp\"\n | \"signInWithCustomToken\"\n | \"passwordReset\"\n | \"sendOobCode\"\n\nexport type BackendApiRequestOptions = {\n endpoint: FirebaseEndpoint;\n method?: HTTPMethod;\n apiKey?: string;\n queryParams?: Record<string, unknown>;\n headerParams?: Record<string, string>;\n bodyParams?: Record<string, unknown>;\n formData?: FormData;\n}\n\nexport type BackendApiResponse<T> =\n | {\n data: T;\n errors: null;\n totalCount?: number;\n }\n | {\n data: null;\n errors: TernSecureFireRestError[];\n totalCount?: never;\n status?: number;\n statusText?: string;\n retryAfter?: number;\n };\n\nexport type RequestFunction = ReturnType<typeof createRequest>;\n\ntype CreateRequestOptions = {\n apiKey?: string;\n apiUrl?: string;\n apiVersion?: string;\n};\n\nconst FIREBASE_ENDPOINT_MAP: Record<FirebaseEndpoint, (apiKey: string) => string> = {\n refreshToken: getRefreshTokenEndpoint,\n signInWithPassword: signInWithPassword,\n signUp: signUpEndpoint,\n signInWithCustomToken: getCustomTokenEndpoint,\n passwordReset: sendOobCode,\n sendOobCode: sendOobCode,\n lookup: lookupEndpoint\n};\n\n\nexport function createRequest(options: CreateRequestOptions) {\n const requestFn = async <T>(\n requestOptions: BackendApiRequestOptions\n ): Promise<BackendApiResponse<T>> => {\n const { endpoint, method, apiKey, queryParams, headerParams, bodyParams, formData } =\n requestOptions;\n\n\n if (!apiKey) {\n return {\n data: null,\n errors: [\n {\n domain: \"none\",\n reason: \"invalid_parameter\",\n message: \"Firebase API key is required\",\n code: \"400\",\n },\n ],\n };\n }\n\n const endpointUrl = FIREBASE_ENDPOINT_MAP[endpoint](apiKey);\n const finalUrl = new URL(endpointUrl);\n\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value) {\n [value].flat().forEach(v => finalUrl.searchParams.append(key, v as string));\n }\n });\n }\n\n const headers: Record<string, any> = {\n ...headerParams,\n };\n let res: Response | undefined;\n\n try {\n if (formData) {\n res = await runtime.fetch(finalUrl.href, {\n method,\n headers,\n body: formData,\n });\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n const hasBody =\n method !== \"GET\" && bodyParams && Object.keys(bodyParams).length > 0;\n const body = hasBody ? { body: JSON.stringify(bodyParams) } : null;\n\n res = await runtime.fetch(finalUrl.href, {\n method,\n headers,\n ...body,\n });\n }\n\n const isJSONResponse =\n res?.headers &&\n res.headers?.get(constants.Headers.ContentType)?.includes(constants.ContentTypes.Json);\n \n let responseBody;\n try {\n const text = await res.text();\n try {\n responseBody = JSON.parse(text);\n } catch {\n responseBody = text;\n }\n } catch (e) {\n responseBody = null;\n }\n\n\n if (!res.ok) {\n return {\n data: null,\n errors: parseErrors(responseBody),\n status: res?.status,\n statusText: res?.statusText,\n };\n }\n\n return {\n data: responseBody,\n errors: null,\n };\n } catch (error) {\n if (error instanceof Error) {\n return {\n data: null,\n errors: [\n {\n domain: \"none\",\n reason: \"request_failed\",\n message: error.message || \"An unexpected error occurred\",\n code: \"500\",\n },\n ],\n };\n }\n\n return {\n data: null,\n errors: parseErrors(error),\n status: res?.status,\n statusText: res?.statusText,\n };\n }\n };\n return requestFn;\n}\n\nfunction parseErrors(data: unknown): TernSecureFireRestError[] {\n let parsedData = data;\n if (typeof data === \"string\") {\n try {\n parsedData = JSON.parse(data);\n } catch (error) {\n return [];\n }\n }\n\n if (!parsedData || typeof parsedData !== \"object\") {\n return [];\n }\n\n if (\"error\" in parsedData && typeof parsedData.error === \"object\" && parsedData.error !== null) {\n const errorObj = parsedData.error as any;\n\n if (\"errors\" in errorObj && Array.isArray(errorObj.errors) && errorObj.errors.length > 0) {\n return errorObj.errors.map((err: any) => parseError({\n code: errorObj.code || \"unknown_error\", \n message: err.message || \"Unknown error\",\n domain: err.domain,\n reason: err.reason\n }));\n }\n\n // Fallback: create single error from main error object\n return [parseError({\n code: errorObj.code?.toString() || \"unknown_error\",\n message: errorObj.message || \"Unknown error\",\n domain: errorObj.domain || \"unknown\",\n reason: errorObj.reason || errorObj.code?.toString() || \"unknown_error\"\n })];\n }\n\n return [];\n}\n\nexport function parseError(error: TernSecureFireRestErrorJSON): TernSecureFireRestError {\n return {\n domain: error.domain,\n reason: error.reason,\n message: error.message,\n code: error.code\n };\n}\n","import { AppCheckApi, EmailApi, PasswordApi, SignInApi, SignInTokenApi, SignUpApi, TokenApi, UserData } from './endpoints';\nimport { createRequest } from './request';\n\nexport type CreateFireApiOptions = Parameters<typeof createRequest>[0];\nexport type ApiClient = ReturnType<typeof createFireApi>;\n\nexport function createFireApi(options: CreateFireApiOptions) {\n const request = createRequest(options);\n return {\n appCheck: new AppCheckApi(request),\n email: new EmailApi(request),\n password: new PasswordApi(request),\n signIn: new SignInApi(request),\n signInToken: new SignInTokenApi(request),\n signUp: new SignUpApi(request),\n tokens: new TokenApi(request),\n userData: new UserData(request),\n };\n}\n","import type { AuthenticateRequestOptions} from \"../tokens/types\";\n\nexport type RuntimeOptions = Omit<AuthenticateRequestOptions, \"apiUrl\">;\n\nexport type buildTimeOptions = Partial<Pick<AuthenticateRequestOptions, \"apiKey\" | \"apiUrl\" | \"apiVersion\">>;\n\nconst defaultOptions: buildTimeOptions = {\n apiKey: undefined,\n apiUrl: undefined,\n apiVersion: undefined,\n};\n\nexport function mergePreDefinedOptions(\n userOptions: buildTimeOptions = {}\n): buildTimeOptions {\n return {\n ...defaultOptions,\n ...userOptions,\n };\n}","import { ms, type StringValue } from '@tern-secure/shared/ms';\nimport type { DecodedIdToken } from '@tern-secure/types';\n\nimport { getAuth } from '../auth';\nimport { constants } from '../constants';\nimport { ternDecodeJwt } from '../jwt/verifyJwt';\nimport type { TokenCarrier } from '../utils/errors';\nimport {\n RefreshTokenErrorReason,\n TokenVerificationError,\n TokenVerificationErrorReason,\n} from '../utils/errors';\nimport type { RequestState, SignedInState, SignedOutState } from './authstate';\nimport { AuthErrorReason, signedIn, signedOut } from './authstate';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createRequestProcessor } from './c-authenticateRequestProcessor';\nimport { getCookieNameEnvironment, getCookiePrefix } from './cookie';\nimport { createTernSecureRequest } from './ternSecureRequest';\nimport type { AuthenticateRequestOptions } from './types';\nimport { verifyToken } from './verify';\n\n\nfunction hasAuthorizationHeader(request: Request): boolean {\n return request.headers.has('Authorization');\n}\n\nfunction convertToSeconds(value: StringValue) {\n return ms(value) / 1000;\n}\n\nfunction isRequestForRefresh(\n error: TokenVerificationError,\n context: { refreshTokenInCookie?: string },\n request: Request,\n) {\n return (\n error.reason === TokenVerificationErrorReason.TokenExpired &&\n !!context.refreshTokenInCookie &&\n request.method === 'GET'\n );\n}\n\nexport async function authenticateRequest(\n request: Request,\n options: AuthenticateRequestOptions,\n): Promise<RequestState> {\n const context = createRequestProcessor(createTernSecureRequest(request), options);\n const { refreshTokenInCookie } = context;\n\n const { refreshExpiredIdToken } = getAuth(options);\n\n\n function checkSessionTimeout(authTimeValue: number): SignedOutState | null {\n const defaultMaxAgeSeconds = convertToSeconds('5 days');\n const REAUTH_PERIOD_SECONDS = context.session?.maxAge\n ? convertToSeconds(context.session.maxAge)\n : defaultMaxAgeSeconds;\n\n const currentTime = Math.floor(Date.now() / 1000);\n const authAge = currentTime - authTimeValue;\n\n\n if (authTimeValue > 0 && authAge > REAUTH_PERIOD_SECONDS) {\n return signedOut(context, AuthErrorReason.AuthTimeout, 'Authentication expired');\n }\n\n return null;\n }\n\n async function refreshToken() {\n if (!refreshTokenInCookie) {\n return {\n data: null,\n error: {\n message: 'No refresh token available',\n reason: AuthErrorReason.SessionTokenMissing,\n },\n };\n }\n return await refreshExpiredIdToken(refreshTokenInCookie, {\n referer: context.ternUrl.origin,\n });\n }\n\n async function handleRefresh(): Promise<\n | { data: { decoded: DecodedIdToken; token: string; headers: Headers }; error: null }\n | { data: null; error: any }\n > {\n const { data: refreshedData, error } = await refreshToken();\n if (!refreshedData) {\n return { data: null, error };\n }\n\n const headers = new Headers();\n const { idToken } = refreshedData;\n\n const maxAge = 365 * 24 * 60 * 60;\n const cookiePrefix = getCookiePrefix();\n const idTokenCookieName = getCookieNameEnvironment(constants.Cookies.IdToken, cookiePrefix);\n const baseCookieAttributes = 'HttpOnly; Secure; SameSite=Strict; Max-Age=' + `${maxAge}; Path=/`;\n\n const idTokenCookie = `${idTokenCookieName}=${idToken}; ${baseCookieAttributes};`;\n headers.append('Set-Cookie', idTokenCookie);\n\n const { data: decoded, errors } = await verifyToken(idToken, options);\n if (errors) {\n return {\n data: null,\n error: errors ? errors[0] : new Error('Failed to verify refreshed token'),\n };\n }\n return { data: { decoded, token: idToken, headers }, error: null };\n }\n\n async function handleLocalHandshakeWithErrorCheck(\n context: RequestProcessorContext,\n reason: string,\n message: string,\n skipSessionCheck: boolean = false,\n ): Promise<SignedInState | SignedOutState> {\n const hasRefreshTokenInCookie = !!context.refreshTokenInCookie;\n if (!hasRefreshTokenInCookie) {\n return signedOut(context, reason, 'Refresh token missing in cookie');\n }\n\n if (reason === AuthErrorReason.TernAutWithoutSessionToken) {\n if (!skipSessionCheck) {\n const sessionTimeoutResult = checkSessionTimeout(context.ternAuth);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n }\n\n const { data, error } = await handleRefresh();\n\n if (data) {\n return signedIn(context, data.decoded, data.headers, data.token);\n }\n\n return signedOut(context, reason, 'Failed to refresh idToken');\n }\n\n\n if (reason === AuthErrorReason.SessionTokenWithoutTernAUT ||\n reason === AuthErrorReason.SessionTokenIATBeforeTernAUT) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = ternDecodeJwt(context.idTokenInCookie!);\n\n if (errors) {\n throw errors[0];\n }\n\n const authTime = data.payload.auth_time;\n\n if (!authTime || typeof authTime !== 'number') {\n return signedOut(context, reason, 'Token missing auth_time');\n }\n\n if (!skipSessionCheck) {\n const sessionTimeoutResult = checkSessionTimeout(authTime);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data: verifiedToken, errors: verifyErrors } = await verifyToken(context.idTokenInCookie!, options);\n\n if (verifyErrors) {\n throw verifyErrors[0];\n }\n\n const headers = new Headers();\n const oneYearInSeconds = 365 * 24 * 60 * 60;\n const ternAutCookie = `${constants.Cookies.TernAut}=${authTime}; Max-Age=${oneYearInSeconds}; Secure; SameSite=Strict; Path=/`;\n headers.append('Set-Cookie', ternAutCookie);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return signedIn(context, verifiedToken, headers, context.idTokenInCookie!);\n }\n\n return signedOut(context, reason, message);\n }\n\n async function authenticateRequestWithTokenInCookie() {\n const hasTernAuth = context.ternAuth\n const hasIdTokenInCookie = !!context.idTokenInCookie;\n\n if (!hasTernAuth && !hasIdTokenInCookie) {\n return signedOut(context, AuthErrorReason.SessionTokenAndAuthMissing);\n }\n\n if (!hasTernAuth && hasIdTokenInCookie) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenWithoutTernAUT, '');\n }\n\n if (hasTernAuth && !hasIdTokenInCookie) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.TernAutWithoutSessionToken, '');\n }\n\n const sessionTimeoutResult = checkSessionTimeout(context.ternAuth);\n if (sessionTimeoutResult) {\n return sessionTimeoutResult;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data: decodedResult, errors: decodeErrors } = ternDecodeJwt(context.idTokenInCookie!);\n\n if (decodeErrors) {\n return handleError(decodeErrors[0], 'cookie');\n }\n\n const tokenIat = decodedResult.payload.iat;\n if (!tokenIat) {\n return signedOut(context, AuthErrorReason.SessionTokenMissing, '');\n }\n\n if (tokenIat < context.ternAuth) {\n return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenIATBeforeTernAUT, '', true);\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = await verifyToken(context.idTokenInCookie!, options);\n\n if (errors) {\n throw errors[0];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const signedInRequestState = signedIn(context, data, undefined, context.idTokenInCookie!);\n\n return signedInRequestState;\n } catch (err) {\n return handleError(err, 'cookie');\n }\n\n return signedOut(context, AuthErrorReason.UnexpectedError);\n }\n\n async function authenticateRequestWithTokenInHeader() {\n const { sessionTokenInHeader } = context;\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { data, errors } = await verifyToken(sessionTokenInHeader!, options);\n\n if (errors) {\n throw errors[0];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const signedInRequestState = signedIn(context, data, undefined, sessionTokenInHeader!);\n return signedInRequestState;\n } catch (err) {\n return handleError(err, 'header');\n }\n }\n\n async function handleError(\n err: unknown,\n tokenCarrier: TokenCarrier,\n ): Promise<SignedInState | SignedOutState> {\n if (!(err instanceof TokenVerificationError)) {\n return signedOut(context, AuthErrorReason.UnexpectedError);\n }\n\n let refreshError: string | null;\n if (isRequestForRefresh(err, context, request)) {\n const { data, error } = await handleRefresh();\n if (data) {\n\n const signedInState = signedIn(context, data.decoded, data.headers, data.token);\n return signedInState;\n }\n\n if (error?.cause?.reason) {\n refreshError = error.cause.reason;\n }\n } else {\n if (request.method !== 'GET') {\n refreshError = RefreshTokenErrorReason.NonEligibleNonGet;\n } else if (!context.refreshTokenInCookie) {\n refreshError = RefreshTokenErrorReason.NonEligibleNoCookie;\n } else {\n refreshError = null;\n }\n }\n\n err.tokenCarrier = tokenCarrier;\n\n return signedOut(context, err.reason, err.getFullMessage());\n }\n\n if (hasAuthorizationHeader(request)) {\n return authenticateRequestWithTokenInHeader();\n }\n\n return authenticateRequestWithTokenInCookie();\n}\n","import { type JwtReturnType } from \"./types\";\n\nexport function createJwtGuard<T extends (...args: any[]) => JwtReturnType<any, any>>(decodedFn: T) {\n return (...args: Parameters<T>): NonNullable<Awaited<ReturnType<T>>['data']> | never => {\n const { data, errors } = decodedFn(...args);\n\n if (errors) {\n throw errors[0];\n }\n\n return data;\n };\n}\n","import type {\n DecodedIdToken,\n TernVerificationResult,\n} from \"@tern-secure/types\";\nimport { createRemoteJWKSet, decodeJwt,jwtVerify } from \"jose\";\n\n\nexport type FirebaseIdTokenPayload = DecodedIdToken;\n\n// Firebase public key endpoints\nconst FIREBASE_ID_TOKEN_URL =\n \"https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com\";\nconst FIREBASE_SESSION_CERT_URL =\n \"https://identitytoolkit.googleapis.com/v1/sessionCookiePublicKeys\";\n\n//const FIREBASE_NEW_SESSION_PK = \"https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys\"\n\n// Simple in-memory cache for JWKS\nlet idTokenJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\nlet sessionJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\n\nconst getIdTokenJWKS = () => {\n if (!idTokenJWKS) {\n idTokenJWKS = createRemoteJWKSet(new URL(FIREBASE_ID_TOKEN_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return idTokenJWKS;\n};\n\nconst getSessionJWKS = () => {\n if (!sessionJWKS) {\n sessionJWKS = createRemoteJWKSet(new URL(FIREBASE_SESSION_CERT_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return sessionJWKS;\n};\n\n\n\nexport async function verifyToken(\n token: string,\n isSessionCookie = false\n): Promise<TernVerificationResult> {\n try {\n const projectId = process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;\n if (!projectId) {\n throw new Error(\"Firebase Project ID is not configured\");\n }\n\n const { decoded } = decodeJwt(token);\n if (!decoded) {\n throw new Error(\"Invalid token format\");\n }\n\n let retries = 3;\n let lastError: Error | null = null;\n\n while (retries > 0) {\n try {\n // Use different JWKS based on token type\n const JWKS = isSessionCookie ? getSessionJWKS() : getIdTokenJWKS();\n\n const { payload } = await jwtVerify(token, JWKS, {\n issuer: isSessionCookie\n ? \"https://session.firebase.google.com/\" + projectId\n : \"https://securetoken.google.com/\" + projectId,\n audience: projectId,\n algorithms: [\"RS256\"],\n });\n\n const firebasePayload = payload as unknown as FirebaseIdTokenPayload;\n const now = Math.floor(Date.now() / 1000);\n\n // Verify token claims\n if (firebasePayload.exp <= now) {\n throw new Error(\"Token has expired\");\n }\n\n if (firebasePayload.iat > now) {\n throw new Error(\"Token issued time is in the future\");\n }\n\n if (!firebasePayload.sub) {\n throw new Error(\"Token subject is empty\");\n }\n\n if (firebasePayload.auth_time > now) {\n throw new Error(\"Token auth time is in the future\");\n }\n\n return {\n valid: true,\n uid: firebasePayload.sub,\n sub: firebasePayload.sub,\n email: firebasePayload.email,\n email_verified: firebasePayload.email_verified,\n auth_time: firebasePayload.auth_time,\n iat: firebasePayload.iat,\n exp: firebasePayload.exp,\n aud: firebasePayload.aud,\n iss: firebasePayload.iss,\n firebase: firebasePayload.firebase,\n phone_number: firebasePayload.phone_number,\n picture: firebasePayload.picture,\n };\n } catch (error) {\n lastError = error as Error;\n if (error instanceof Error && error.name === \"JWKSNoMatchingKey\") {\n console.warn(`JWKS retry attempt ${4 - retries}:`, error.message);\n retries--;\n if (retries > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n continue;\n }\n }\n throw error;\n }\n }\n\n throw lastError || new Error(\"Failed to verify token after retries\");\n } catch (error) {\n console.error(\"Token verification details:\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n decoded: decodeJwt(token),\n isSessionCookie,\n });\n\n return {\n valid: false,\n error: {\n success: false,\n message: error instanceof Error ? error.message : \"Invalid token\",\n code: \"INVALID_TOKEN\",\n },\n };\n }\n}\n","import type { JWTPayload } from '@tern-secure/types';\nimport { importPKCS8, SignJWT } from 'jose';\n\nimport type { JwtReturnType } from './types';\n\n\nexport interface CustomTokenClaims {\n [key: string]: unknown;\n}\n\nexport class CustomTokenError extends Error {\n constructor(\n message: string,\n public code?: string,\n ) {\n super(message);\n this.name = 'CustomTokenError';\n }\n}\n\nconst RESERVED_CLAIMS = [\n 'acr',\n 'amr',\n 'at_hash',\n 'aud',\n 'auth_time',\n 'azp',\n 'cnf',\n 'c_hash',\n 'exp',\n 'firebase',\n 'iat',\n 'iss',\n 'jti',\n 'nbf',\n 'nonce',\n 'sub',\n];\n\nasync function createCustomTokenJwt(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<JwtReturnType<string, CustomTokenError>> {\n try {\n const privateKey = process.env.FIREBASE_PRIVATE_KEY;\n const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;\n\n if (!privateKey || !clientEmail) {\n return {\n errors: [\n new CustomTokenError(\n 'Missing FIREBASE_PRIVATE_KEY or FIREBASE_CLIENT_EMAIL environment variables',\n 'MISSING_ENV_VARS',\n ),\n ],\n };\n }\n\n if (!uid || typeof uid !== 'string') {\n return {\n errors: [new CustomTokenError('uid must be a non-empty string', 'INVALID_UID')],\n };\n }\n\n if (uid.length > 128) {\n return {\n errors: [new CustomTokenError('uid must not exceed 128 characters', 'UID_TOO_LONG')],\n };\n }\n\n if (developerClaims) {\n for (const claim of Object.keys(developerClaims)) {\n if (RESERVED_CLAIMS.includes(claim)) {\n return {\n errors: [new CustomTokenError(`Custom claim '${claim}' is reserved`, 'RESERVED_CLAIM')],\n };\n }\n }\n }\n\n // Set expiration (default 1 hour, max 1 hour)\n const expiresIn = 3600;\n const now = Math.floor(Date.now() / 1000);\n\n const parsedPrivateKey = await importPKCS8(privateKey.replace(/\\\\n/g, '\\n'), 'RS256');\n\n const payload: JWTPayload = {\n iss: clientEmail,\n sub: clientEmail,\n aud: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',\n iat: now,\n exp: now + expiresIn,\n uid: uid,\n ...developerClaims,\n };\n\n const jwt = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', typ: 'JWT' })\n .setIssuedAt(now)\n .setExpirationTime(now + expiresIn)\n .setIssuer(clientEmail)\n .setSubject(clientEmail)\n .setAudience(\n 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',\n )\n .sign(parsedPrivateKey);\n\n return {\n data: jwt,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error occurred';\n return {\n errors: [\n new CustomTokenError(`Failed to create custom token: ${message}`, 'TOKEN_CREATION_FAILED'),\n ],\n };\n }\n}\n\nexport async function createCustomToken(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<string> {\n const { data, errors } = await createCustomTokenJwt(uid, developerClaims);\n\n if (errors) {\n throw errors[0];\n }\n\n return data;\n}\n\nexport function createCustomTokenWithResult(\n uid: string,\n developerClaims?: CustomTokenClaims,\n): Promise<JwtReturnType<string, CustomTokenError>> {\n return createCustomTokenJwt(uid, developerClaims);\n}","import type { JWTPayload } from '@tern-secure/types';\nimport type { KeyLike } from 'jose';\nimport { base64url,importPKCS8, SignJWT, } from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { fetchAny } from '../utils/fetcher'\nimport { ALGORITHM_RS256 } from './types';\n\nexport interface SignJwtOptions {\n algorithm?: string;\n header?: Record<string, unknown>;\n}\n\n\nexport type SignOptions = {\n readonly payload: JWTPayload;\n readonly privateKey: string;\n readonly keyId?: string;\n};\n\n\nasync function ternSignJwt(opts: SignOptions): Promise<string> {\n const { payload, privateKey, keyId } = opts;\n let key: KeyLike;\n\n try {\n key = await importPKCS8(privateKey, ALGORITHM_RS256);\n } catch (error) {\n throw new TokenVerificationError({\n message: `Failed to import private key: ${(error as Error).message}`,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n\n return new SignJWT(payload)\n .setProtectedHeader({ alg: ALGORITHM_RS256, kid: keyId })\n .sign(key);\n}\n\n\nexport type SignBlobOptions = {\n readonly serviceAccountId: string;\n readonly accessToken: string;\n readonly payload: JWTPayload;\n};\n\n\nfunction formatBase64(value: string) {\n return value.replace(/\\//g, '_').replace(/\\+/g, '-').replace(/=+$/, '');\n}\n\nfunction encodeSegment(segment: Record<string, string> | JWTPayload): string {\n const value = JSON.stringify(segment);\n\n return formatBase64(base64url.encode(value));\n}\n\n\nasync function ternSignBlob({\n payload,\n serviceAccountId,\n accessToken\n}: SignBlobOptions): Promise<string> {\n const url = `https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${serviceAccountId}:signBlob`;\n const header = {\n alg: ALGORITHM_RS256,\n typ: 'JWT'\n };\n const token = `${encodeSegment(header)}.${encodeSegment(payload)}`;\n const request: RequestInit = {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`\n },\n body: JSON.stringify({payload: base64url.encode(token)})\n };\n const response = await fetchAny(url, request);\n const blob = await response.blob();\n const key = await blob.text();\n const {signedBlob} = JSON.parse(key);\n\n return `${token}.${formatBase64(signedBlob)}`;\n}\n\nexport { ternSignJwt, ternSignBlob };\n","async function getDetailFromResponse(response: Response): Promise<string> {\n const json = await response.json();\n\n if (!json) {\n return 'Missing error payload';\n }\n\n let detail =\n typeof json.error === 'string'\n ? json.error\n : (json.error?.message ?? 'Missing error payload');\n\n if (json.error_description) {\n detail += ' (' + json.error_description + ')';\n }\n\n return detail;\n}\n\nexport async function fetchText(url: string, init: RequestInit) {\n return (await fetchAny(url, init)).text();\n}\n\nexport async function fetchJson(url: string, init: RequestInit) {\n return (await fetchAny(url, init)).json();\n}\n\nexport async function fetchAny(url: string, init: RequestInit) {\n const response = await fetch(url, init);\n\n if (!response.ok) {\n throw new Error(await getDetailFromResponse(response));\n }\n\n return response;\n}","import type { JWTPayload } from '@tern-secure/types';\n\n\nexport type JwtReturnType<R, E extends Error> =\n | {\n data: R;\n errors?: undefined;\n }\n | {\n data?: undefined;\n errors: [E];\n };\n\n\nexport const ALGORITHM_RS256 = 'RS256' as const;\n\nexport interface CryptoSigner {\n getAccountId(): Promise<string>;\n sign(payload: JWTPayload): Promise<string>;\n}","import type { JWTPayload } from '@tern-secure/types';\n\nimport type { Credential, ServiceAccountManager } from '../auth';\nimport { fetchText } from '../utils/fetcher'\nimport { ternSignBlob, ternSignJwt } from './signJwt';\nimport { ALGORITHM_RS256, type CryptoSigner } from './types';\n\n\nclass ServiceAccountSigner implements CryptoSigner {\n\n constructor(\n private readonly credential: ServiceAccountManager,\n private tenantId?: string\n ) { }\n\n public async getAccountId(): Promise<string> {\n return Promise.resolve(this.credential.clientEmail);\n }\n\n public async sign(payload: JWTPayload): Promise<string> {\n if (this.tenantId) {\n payload.tenant_id = this.tenantId;\n }\n\n return ternSignJwt({ payload, privateKey: this.credential.privateKey });\n }\n}\n\nclass IAMSigner implements CryptoSigner {\n algorithm = ALGORITHM_RS256;\n\n private credential: Credential;\n private tenantId?: string;\n private serviceAccountId?: string;\n\n constructor(\n credential: Credential,\n tenantId?: string,\n serviceAccountId?: string\n ) {\n this.credential = credential;\n this.tenantId = tenantId;\n this.serviceAccountId = serviceAccountId;\n }\n\n public async sign(payload: JWTPayload): Promise<string> {\n if (this.tenantId) {\n payload.tenant_id = this.tenantId;\n }\n\n const serviceAccount = await this.getAccountId();\n const accessToken = await this.credential.getAccessToken();\n\n return ternSignBlob({\n accessToken: accessToken.accessToken,\n serviceAccountId: serviceAccount,\n payload\n });\n }\n\n public async getAccountId(): Promise<string> {\n if (this.serviceAccountId) {\n return this.serviceAccountId;\n }\n\n const token = await this.credential.getAccessToken();\n const url =\n 'http://metadata/computeMetadata/v1/instance/service-accounts/default/email';\n const request: RequestInit = {\n method: 'GET',\n headers: {\n 'Metadata-Flavor': 'Google',\n Authorization: `Bearer ${token.accessToken}`\n }\n };\n\n return (this.serviceAccountId = await fetchText(url, request));\n }\n}\n\n\nexport { ServiceAccountSigner, IAMSigner };\n\n","import { createJwtGuard } from './guardReturn';\nimport { ternDecodeJwt as _ternDecodeJwt } from './verifyJwt';\n\nexport const ternDecodeJwt = createJwtGuard(_ternDecodeJwt);\nexport { ternDecodeJwt as ternDecodeJwtUnguarded } from './verifyJwt';\n\nexport * from './jwt';\nexport * from './customJwt';\nexport * from './signJwt';\nexport { ServiceAccountSigner, IAMSigner } from './crypto-signer';\nexport type { JwtReturnType, CryptoSigner } from './types';","import type { Credential } from '../auth'\nimport { ServiceAccountManager } from '../auth'\nimport type { CryptoSigner } from '../jwt'\nimport { IAMSigner, ServiceAccountSigner } from '../jwt'\n\nexport function cryptoSignerFromCredential(\n credential: Credential,\n tenantId?: string,\n serviceAccountId?: string\n): CryptoSigner {\n if (credential instanceof ServiceAccountManager) {\n return new ServiceAccountSigner(credential, tenantId);\n }\n\n return new IAMSigner(credential, tenantId, serviceAccountId);\n}","import type { Credential } from '../auth'\nimport type { AppCheckParams, AppCheckToken } from './types'\n\nexport function getSdkVersion(): string {\n return '12.7.0';\n}\n\nconst FIREBASE_APP_CHECK_CONFIG_HEADERS = {\n 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`\n};\n\n/**\n * App Check API for managing Firebase App Check tokens via REST\n * Firebase REST API endpoint: https://firebaseappcheck.googleapis.com/v1beta/projects/{projectId}/apps/{appId}:exchangeCustomToken\n */\nexport class AppCheckApi {\n constructor(private credential: Credential) { }\n\n public async exchangeToken(params: AppCheckParams): Promise<AppCheckToken> {\n const { projectId, appId, customToken, limitedUse = false } = params;\n const token = await this.credential.getAccessToken(false);\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1/projects/${projectId}/apps/${appId}:exchangeCustomToken`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token.accessToken}`,\n };\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ customToken, limitedUse }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n public async exchangeDebugToken(params: AppCheckParams): Promise<AppCheckToken> {\n const { projectId, appId, customToken, accessToken, limitedUse = false } = params;\n if (!projectId || !appId) {\n throw new Error('Project ID and App ID are required for App Check token exchange');\n }\n\n const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeDebugToken`;\n\n const headers: Record<string, string> = {\n ...FIREBASE_APP_CHECK_CONFIG_HEADERS,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n const body = {\n customToken,\n limitedUse,\n }\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n return {\n token: data.token,\n ttl: data.ttl,\n };\n } catch (error) {\n console.warn('[ternsecure - appcheck api]unexpected error:', error);\n throw error;\n }\n }\n}\n","import {\n FIREBASE_APP_CHECK_AUDIENCE,\n ONE_DAY_IN_MILLIS,\n ONE_MINUTE_IN_MILLIS,\n ONE_MINUTE_IN_SECONDS\n} from '../constants'\nimport type { CryptoSigner } from '../jwt';\nimport type { AppCheckTokenOptions } from './types';\n\n\nfunction transformMillisecondsToSecondsString(milliseconds: number): string {\n let duration: string;\n const seconds = Math.floor(milliseconds / 1000);\n const nanos = Math.floor((milliseconds - seconds * 1000) * 1000000);\n if (nanos > 0) {\n let nanoString = nanos.toString();\n while (nanoString.length < 9) {\n nanoString = '0' + nanoString;\n }\n duration = `${seconds}.${nanoString}s`;\n } else {\n duration = `${seconds}s`;\n }\n return duration;\n}\n\nexport class AppCheckTokenGenerator {\n private readonly signer: CryptoSigner;\n\n constructor(signer: CryptoSigner) {\n this.signer = signer;\n }\n\n public async createCustomToken(\n appId: string,\n options?: AppCheckTokenOptions\n ): Promise<string> {\n if (!appId) {\n throw new Error(\n 'appId is invalid',\n );\n }\n let customOptions = {};\n if (typeof options !== 'undefined') {\n customOptions = this.validateTokenOptions(options);\n }\n\n const account = await this.signer.getAccountId();\n\n const iat = Math.floor(Date.now() / 1000);\n const body = {\n iss: account,\n sub: account,\n app_id: appId,\n aud: FIREBASE_APP_CHECK_AUDIENCE,\n exp: iat + ONE_MINUTE_IN_SECONDS * 5,\n iat,\n ...customOptions\n };\n\n return this.signer.sign(body);\n }\n\n private validateTokenOptions(options: AppCheckTokenOptions): {\n [key: string]: unknown;\n } {\n if (typeof options.ttlMillis !== 'undefined') {\n if (\n options.ttlMillis < ONE_MINUTE_IN_MILLIS * 30 ||\n options.ttlMillis > ONE_DAY_IN_MILLIS * 7\n ) {\n throw new Error(\n 'ttlMillis must be a duration in milliseconds between 30 minutes and 7 days (inclusive).'\n );\n }\n\n return { ttl: transformMillisecondsToSecondsString(options.ttlMillis) };\n }\n return {};\n }\n}\n","import { Redis } from \"@upstash/redis\";\n\nimport type { AppCheckOptions } from '../adapters/types';\nimport { initializeAdminConfig } from '../utils/config';\nimport { getAppCheck } from \"./index\";\n\ninterface CachedToken {\n token: string;\n expiresAt: number;\n}\n\n/**\n * Redis client interface for AppCheck token caching (Upstash Redis or compatible adapter)\n */\ninterface RedisClient {\n get(key: string): Promise<any>;\n set(key: string, value: any, opts?: { px?: number }): Promise<any>;\n del(key: string): Promise<number>;\n}\n\n\nexport class ServerAppCheckManager {\n private static instances: Map<string, ServerAppCheckManager> = new Map();\n private memoryCache: Map<string, CachedToken> = new Map();\n private redisClient: RedisClient | null = null;\n private readonly options: Required<Omit<AppCheckOptions, 'redis' | 'skipInMemoryFirst'>> & {\n redis?: AppCheckOptions['redis'];\n skipInMemoryFirst: boolean;\n };\n private pendingTokens: Map<string, Promise<string | null>> = new Map();\n\n private constructor(options?: AppCheckOptions) {\n const defaultOptions: Required<Omit<AppCheckOptions, 'redis' | 'skipInMemoryFirst'>> & { skipInMemoryFirst: boolean } = {\n strategy: 'memory',\n ttlMillis: 3600000, // 1 hour\n refreshBufferMillis: 300000, // 5 minutes\n keyPrefix: 'appcheck:token:',\n skipInMemoryFirst: false,\n };\n\n this.options = { ...defaultOptions, ...options };\n\n if (this.options.strategy === 'redis' && this.options.redis) {\n void this.initializeRedis(this.options.redis);\n }\n }\n\n private initializeRedis = (config: AppCheckOptions['redis']): void => {\n if (!config) {\n throw new Error('[AppCheck] Redis configuration is required when strategy is \"redis\"');\n }\n\n try {\n this.redisClient = new Redis({\n url: config.url,\n token: config.token,\n });\n\n } catch (error) {\n console.error('[AppCheck] Failed to initialize Redis client:', error);\n throw new Error('[AppCheck] Redis initialization failed.');\n }\n }\n\n public static getInstance(options?: AppCheckOptions): ServerAppCheckManager {\n const key = options?.strategy || 'memory';\n\n if (!ServerAppCheckManager.instances.has(key)) {\n ServerAppCheckManager.instances.set(key, new ServerAppCheckManager(options));\n }\n\n const instance = ServerAppCheckManager.instances.get(key);\n if (!instance) {\n throw new Error('[AppCheck] Failed to get instance');\n }\n\n return instance;\n }\n\n private buildCacheKey(appId: string): string {\n return `${this.options.keyPrefix}${appId}`;\n }\n\n\n private getCachedToken = async (appId: string): Promise<CachedToken | null> => {\n if (this.options.strategy === 'memory') {\n return this.memoryCache.get(appId) || null;\n }\n\n if (this.options.strategy === 'redis') {\n // Check in-memory cache first (unless skipInMemoryFirst is true)\n if (!this.options.skipInMemoryFirst) {\n const memCached = this.memoryCache.get(appId);\n if (memCached) {\n return memCached;\n }\n }\n\n // Fallback to Redis\n if (this.redisClient) {\n try {\n const key = this.buildCacheKey(appId);\n const cached = await this.redisClient.get(key);\n\n if (cached) {\n const parsed: CachedToken = typeof cached === 'string' ? JSON.parse(cached) : cached;\n\n if (!this.options.skipInMemoryFirst) {\n this.memoryCache.set(appId, parsed);\n }\n\n return parsed;\n }\n } catch (error) {\n console.error('[AppCheck] Redis get error:', error);\n }\n }\n }\n\n return null;\n }\n\n\n private setCachedToken = async (appId: string, token: string, expiresAt: number): Promise<void> => {\n const cachedToken: CachedToken = { token, expiresAt };\n\n // Always store in memory cache for both strategies\n this.memoryCache.set(appId, cachedToken);\n\n if (this.options.strategy === 'memory') {\n return;\n }\n\n // For Redis strategy, also persist to Redis\n if (this.options.strategy === 'redis' && this.redisClient) {\n try {\n const key = this.buildCacheKey(appId);\n const ttl = expiresAt - Date.now();\n\n await this.redisClient.set(key, JSON.stringify(cachedToken), {\n px: ttl, // Expiry in milliseconds (lowercase for Upstash)\n });\n } catch (error) {\n console.error('[AppCheck] Redis set error:', error);\n }\n }\n }\n\n getOrGenerateToken = async (appId: string): Promise<string | null> => {\n const cached = await this.getCachedToken(appId);\n const now = Date.now();\n\n if (cached && cached.expiresAt > now + this.options.refreshBufferMillis) {\n return cached.token;\n }\n\n const pending = this.pendingTokens.get(appId);\n if (pending) {\n return pending;\n }\n\n const tokenPromise = this.generateAndCacheToken(appId);\n this.pendingTokens.set(appId, tokenPromise);\n\n try {\n const token = await tokenPromise;\n return token;\n } finally {\n this.pendingTokens.delete(appId);\n }\n }\n\n /**\n * Generate and cache a new token\n */\n private generateAndCacheToken = async (appId: string): Promise<string | null> => {\n try {\n const now = Date.now();\n const config = initializeAdminConfig();\n const appCheck = getAppCheck(config);\n\n const appCheckToken = await appCheck.createToken(config.projectId, appId, {\n ttlMillis: this.options.ttlMillis,\n });\n\n const expiresAt = now + this.options.ttlMillis;\n await this.setCachedToken(appId, appCheckToken.token, expiresAt);\n\n return appCheckToken.token;\n } catch (error) {\n console.error('[AppCheck] Failed to generate token:', error);\n return null;\n }\n }\n\n clearCache = async (appId?: string): Promise<void> => {\n if (appId) {\n this.memoryCache.delete(appId);\n } else {\n this.memoryCache.clear();\n }\n\n if (this.options.strategy === 'redis' && this.redisClient) {\n try {\n if (appId) {\n const key = this.buildCacheKey(appId);\n await this.redisClient.del(key);\n }\n } catch (error) {\n console.error('[AppCheck] Redis delete error:', error);\n }\n }\n }\n\n getCacheStats(): {\n strategy: string;\n memorySize: number;\n entries: Array<{ appId: string; expiresIn: number }>\n } {\n const now = Date.now();\n const entries = Array.from(this.memoryCache.entries()).map(([appId, cached]) => ({\n appId,\n expiresIn: Math.max(0, cached.expiresAt - now),\n }));\n\n return {\n strategy: this.options.strategy,\n memorySize: this.memoryCache.size,\n entries,\n };\n }\n\n /**\n * Close Redis connection\n */\n disconnect(): void {\n if (this.redisClient) {\n this.redisClient = null;\n }\n }\n}","import type { \r\n AdminConfigValidationResult, \r\n ConfigValidationResult, \r\n TernSecureAdminConfig, \r\n TernSecureConfig} from '@tern-secure/types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL || undefined,\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}\r\n\r\n/**\r\n * Loads Firebase Admin configuration from environment variables\r\n * @returns {AdminConfig} Firebase Admin configuration object\r\n */\r\nexport const loadAdminConfig = (): TernSecureAdminConfig => ({\r\n projectId: process.env.FIREBASE_PROJECT_ID || '',\r\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL || '',\r\n privateKey: process.env.FIREBASE_PRIVATE_KEY || '',\r\n})\r\n\r\n/**\r\n * Validates Firebase Admin configuration\r\n * @param {AdminConfig} config - Firebase Admin configuration object\r\n * @returns {ConfigValidationResult} Validation result\r\n */\r\nexport const validateAdminConfig = (config: TernSecureAdminConfig): AdminConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureAdminConfig)[] = [\r\n 'projectId',\r\n 'clientEmail',\r\n 'privateKey'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes admin configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeAdminConfig = (): TernSecureAdminConfig => {\r\n const config = loadAdminConfig()\r\n const validationResult = validateAdminConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase Admin configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}","import type { DecodedAppCheckToken } from '@tern-secure/types';\nimport { createRemoteJWKSet, type KeyLike, type ProtectedHeaderParameters } from 'jose';\n\nimport type { Credential } from '../auth';\nimport type { JwtReturnType } from '../jwt';\nimport { ternDecodeJwt, verifyAppCheckJwt, type VerifyJwtOptions } from '../jwt/verifyJwt';\nimport type { LoadJWKFromRemoteOptions } from '../tokens/keys';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\n\nexport type VerifyAppcheckOptions = Omit<VerifyJwtOptions, 'key'> & Omit<LoadJWKFromRemoteOptions, 'kid'> & {\n currentDate?: Date;\n checkRevoked?: boolean;\n referer?: string;\n experimental_enableTokenRefreshOnExpiredKidHeader?: boolean;\n};\n\nconst getPublicKey = async (header: ProtectedHeaderParameters, keyURL: string): Promise<KeyLike> => {\n const jswksUrl: URL = new URL(keyURL);\n const getKey = createRemoteJWKSet(jswksUrl);\n\n return getKey(header);\n\n}\n\n\nconst verifyAppCheckToken = async (\n token: string,\n options: VerifyAppcheckOptions,\n): Promise<JwtReturnType<DecodedAppCheckToken, TokenVerificationError>> => {\n const { data: decodedResult, errors } = ternDecodeJwt(token);\n\n if (errors) {\n throw errors[0];\n }\n\n const { header } = decodedResult;\n const { kid } = header;\n\n if (!kid) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'JWT \"kid\" header is missing.',\n }),\n ],\n };\n }\n\n try {\n const getPublicKeyForToken = () => getPublicKey(header, options.keyURL || '');\n\n return await verifyAppCheckJwt(token, { ...options, key: getPublicKeyForToken });\n } catch (error) {\n if (error instanceof TokenVerificationError) {\n return { errors: [error] };\n }\n return {\n errors: [error as TokenVerificationError],\n };\n }\n};\n\nexport class AppcheckTokenVerifier {\n constructor(private readonly credential: Credential) { }\n\n public verifyToken = async (\n token: string,\n projectId: string,\n options: VerifyAppcheckOptions,\n ): Promise<DecodedAppCheckToken> => {\n const { data, errors } = await verifyAppCheckToken(token, options);\n if (errors) {\n throw errors[0];\n }\n\n return data;\n };\n}","import type { VerifyAppCheckTokenResponse } from \"@tern-secure/types\";\n\nimport type { Credential, ServiceAccount } from \"../auth\";\nimport { ServiceAccountManager } from \"../auth\";\nimport { cryptoSignerFromCredential } from '../utils/token-generator';\nimport { AppCheckApi } from \"./AppCheckApi\";\nimport { AppCheckTokenGenerator } from \"./generator\";\nimport { ServerAppCheckManager } from \"./serverAppCheck\";\nimport type { AppCheckToken, AppCheckTokenOptions } from \"./types\";\nimport { AppcheckTokenVerifier, type VerifyAppcheckOptions } from \"./verifier\";\n\n\nconst JWKS_URL = 'https://firebaseappcheck.googleapis.com/v1/jwks';\n\nclass AppCheck {\n private readonly client: AppCheckApi;\n private readonly tokenGenerator: AppCheckTokenGenerator;\n private readonly appCheckTokenVerifier: AppcheckTokenVerifier;\n private readonly limitedUse?: boolean;\n\n constructor(credential: Credential, tenantId?: string, limitedUse?: boolean) {\n this.client = new AppCheckApi(credential);\n this.tokenGenerator = new AppCheckTokenGenerator(\n cryptoSignerFromCredential(credential, tenantId)\n );\n this.appCheckTokenVerifier = new AppcheckTokenVerifier(credential);\n this.limitedUse = limitedUse;\n }\n\n public createToken = (projectId: string, appId: string, options?: AppCheckTokenOptions): Promise<AppCheckToken> => {\n return this.tokenGenerator\n .createCustomToken(appId, options)\n .then((customToken) => {\n return this.client.exchangeToken({ customToken, projectId, appId });\n });\n };\n\n public verifyToken = async (appCheckToken: string, projectId: string, options: VerifyAppcheckOptions): Promise<VerifyAppCheckTokenResponse> => {\n return this.appCheckTokenVerifier\n .verifyToken(appCheckToken, projectId, { keyURL: JWKS_URL, ...options })\n .then((decodedToken) => {\n return {\n appId: decodedToken.app_id,\n token: decodedToken,\n };\n });\n\n }\n\n}\n\n\nfunction getAppCheck(serviceAccount: ServiceAccount, tenantId?: string, limitedUse?: boolean): AppCheck {\n return new AppCheck(new ServiceAccountManager(serviceAccount), tenantId, limitedUse);\n}\n\nexport { AppCheck, getAppCheck };\nexport { ServerAppCheckManager };","import { getAppCheck } from '../app-check';\nimport { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions, TernSecureUserData } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\nimport { loadAdminConfig } from '../utils/config';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\n auth_time: number;\n idToken: string;\n refreshToken: string;\n customToken: string;\n}\n\ninterface CustomForIdAndRefreshTokenOptions {\n tenantId?: string;\n appCheckToken?: string;\n referer?: string;\n}\n\ninterface FirebaseRefreshTokenResponse {\n kind: string;\n id_token: string;\n refresh_token: string;\n expires_in: string;\n isNewUser: boolean;\n}\n\ntype AuthResult<T = any> = { data: T; error: null } | { data: null; error: any };\n\nconst API_KEY_ERROR = 'API Key is required';\nconst NO_DATA_ERROR = 'No token data received';\n\nfunction parseFirebaseResponse<T>(data: unknown): T {\n if (typeof data === 'string') {\n try {\n return JSON.parse(data) as T;\n } catch (error) {\n throw new Error(`Failed to parse Firebase response: ${error}`);\n }\n }\n return data as T;\n}\n\nexport function getAuth(options: AuthenticateRequestOptions) {\n const { apiKey } = options;\n const effectiveApiKey = apiKey || process.env.NEXT_PUBLIC_FIREBASE_API_KEY;\n\n\n async function getUserData(idToken?: string, localId?: string): Promise<TernSecureUserData> {\n if (!effectiveApiKey) {\n throw new Error(API_KEY_ERROR);\n }\n const response = await options.apiClient?.userData.getUserData(effectiveApiKey, {\n idToken,\n localId,\n });\n\n if (!response?.data) {\n throw new Error(NO_DATA_ERROR);\n }\n\n const parsedData = parseFirebaseResponse<TernSecureUserData>(response.data);\n return parsedData;\n }\n\n async function refreshExpiredIdToken(\n refreshToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<AuthResult> {\n if (!effectiveApiKey) {\n return { data: null, error: new Error(API_KEY_ERROR) };\n }\n const response = await options.apiClient?.tokens.refreshToken(effectiveApiKey, {\n refresh_token: refreshToken,\n request_origin: opts.referer,\n });\n\n if (!response?.data) {\n return {\n data: null,\n error: new Error(NO_DATA_ERROR),\n };\n }\n\n const parsedData = parseFirebaseResponse<FirebaseRefreshTokenResponse>(response.data);\n\n return {\n data: {\n idToken: parsedData.id_token,\n refreshToken: parsedData.refresh_token,\n },\n error: null,\n };\n }\n\n async function customForIdAndRefreshToken(\n customToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<IdAndRefreshTokens> {\n if (!effectiveApiKey) {\n throw new Error('API Key is required to create custom token');\n }\n const data = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n },\n );\n\n if (!data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n return {\n idToken: data.idToken,\n refreshToken: data.refreshToken,\n };\n }\n\n async function createCustomIdAndRefreshToken(\n idToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<CustomTokens> {\n const decoded = await verifyToken(idToken, options);\n const { data, errors } = decoded;\n if (errors) {\n throw errors[0];\n }\n\n //todo:\n /**\n * For sensitive applications, the auth_time should be checked before issuing the session cookie, minimizing the window of attack in case an ID token is stolen:\n */\n //if (new Date().getTime() / 1000 - data.auth_time < 5 * 60) {\n //proceed\n //}\n\n const customToken = await createCustomToken(data.uid, {\n emailVerified: data.email_verified,\n source_sign_in_provider: data.firebase.sign_in_provider,\n });\n\n const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n });\n\n const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);\n if (decodedCustomIdToken.errors) {\n throw decodedCustomIdToken.errors[0];\n }\n\n return {\n ...idAndRefreshTokens,\n customToken,\n auth_time: decodedCustomIdToken.data.auth_time,\n };\n }\n\n async function createAppCheckToken(): Promise<AuthResult> {\n const adminConfig = loadAdminConfig();\n const appId = process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '';\n const appCheck = getAppCheck(adminConfig, options.tenantId);\n try {\n const appCheckResponse = await appCheck.createToken(adminConfig.projectId, appId);\n\n return {\n data: {\n token: appCheckResponse.token,\n ttl: appCheckResponse.ttl,\n },\n error: null,\n };\n } catch (error) {\n return { data: null, error };\n }\n }\n\n async function verifyAppCheckToken(token: string): Promise<AuthResult> {\n const adminConfig = loadAdminConfig();\n const appCheck = getAppCheck(adminConfig, options.tenantId);\n try {\n const decodedToken = await appCheck.verifyToken(token, adminConfig.projectId, {});\n\n return {\n data: decodedToken,\n error: null,\n };\n } catch (error) {\n return { data: null, error };\n }\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n createAppCheckToken,\n verifyAppCheckToken,\n };\n}\n","import type { JWTPayload } from '@tern-secure/types';\n\nimport {\n GOOGLE_AUTH_TOKEN_HOST,\n GOOGLE_AUTH_TOKEN_PATH,\n GOOGLE_TOKEN_AUDIENCE,\n ONE_HOUR_IN_SECONDS,\n TOKEN_EXPIRY_THRESHOLD_MILLIS\n} from '../constants'\nimport { ternSignJwt } from '../jwt';\nimport { fetchJson } from '../utils/fetcher';\n\n\nexport interface GoogleOAuthAccessToken {\n access_token: string;\n expires_in: number;\n}\n\nexport interface ServiceAccount {\n projectId: string;\n privateKey: string;\n clientEmail: string;\n}\n\nexport interface FirebaseAccessToken {\n accessToken: string;\n expirationTime: number;\n}\n\nconst accessTokenCache: Map<string, FirebaseAccessToken> = new Map();\n\nexport interface Credential {\n getAccessToken: (refresh?: boolean) => Promise<FirebaseAccessToken>;\n}\n\nasync function requestAccessToken(urlString: string, init: RequestInit): Promise<FirebaseAccessToken> {\n const json = await fetchJson(urlString, init);\n\n if (!json.access_token || !json.expires_in) {\n throw new Error('Invalid access token response');\n }\n\n return {\n accessToken: json.access_token,\n expirationTime: Date.now() + (json.expires_in * 1000),\n }\n}\n\nexport class ServiceAccountManager implements Credential {\n public readonly projectId: string;\n public readonly privateKey: string;\n public readonly clientEmail: string;\n\n constructor(serviceAccount: ServiceAccount) {\n this.projectId = serviceAccount.projectId;\n this.privateKey = serviceAccount.privateKey;\n this.clientEmail = serviceAccount.clientEmail;\n }\n\n private fetchAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const token = await this.createJwt();\n const postData =\n 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3A' +\n 'grant-type%3Ajwt-bearer&assertion=' +\n token;\n\n return requestAccessToken(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n body: postData,\n })\n }\n\n private fetchAndCacheAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const accessToken = await this.fetchAccessToken(url);\n accessTokenCache.set(this.projectId, accessToken);\n return accessToken;\n }\n\n public getAccessToken = async (refresh?: boolean): Promise<FirebaseAccessToken> => {\n const url = `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`;\n\n if (refresh) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n const cachedResponse = accessTokenCache.get(this.projectId);\n\n if (!cachedResponse || cachedResponse.expirationTime - Date.now() <= TOKEN_EXPIRY_THRESHOLD_MILLIS) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n return cachedResponse;\n }\n\n private createJwt = async (): Promise<string> => {\n const iat = Math.floor(Date.now() / 1000);\n\n const payload = {\n aud: GOOGLE_TOKEN_AUDIENCE,\n iat,\n exp: iat + ONE_HOUR_IN_SECONDS,\n iss: this.clientEmail,\n sub: this.clientEmail,\n scope: [\n 'https://www.googleapis.com/auth/cloud-platform',\n 'https://www.googleapis.com/auth/firebase.database',\n 'https://www.googleapis.com/auth/firebase.messaging',\n 'https://www.googleapis.com/auth/identitytoolkit',\n 'https://www.googleapis.com/auth/userinfo.email'\n ].join(' ')\n } as JWTPayload;\n\n return ternSignJwt({\n payload,\n privateKey: this.privateKey,\n });\n }\n}\n","import { getCookieName as getCookieNameEnvironment, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nexport const getCookieName = (cookieDirective: string): string => {\n return cookieDirective.split(';')[0]?.split('=')[0];\n};\n\nexport const getCookieValue = (cookieDirective: string): string => {\n return cookieDirective.split(';')[0]?.split('=')[1];\n};\n\nexport { getCookieNameEnvironment, getCookiePrefix };","\nimport type { ApiClient } from '../fireRestApi';\nimport {\n type buildTimeOptions,\n mergePreDefinedOptions,\n type RuntimeOptions,\n} from '../utils/options';\nimport { authenticateRequest } from './request';\n\n/**\n * @internal\n */\nexport type CreateAuthenticateRequestOptions = {\n options: buildTimeOptions;\n apiClient: ApiClient;\n};\n\nexport function createAuthenticateRequest(params: CreateAuthenticateRequestOptions) {\n const buildTimeOptions = mergePreDefinedOptions(params.options);\n const apiClient = params.apiClient;\n\n const handleAuthenticateRequest = (request: Request, options: RuntimeOptions = {}) => {\n const { apiUrl } = buildTimeOptions;\n return authenticateRequest(request, { ...options, apiUrl, apiClient });\n };\n\n return {\n authenticateRequest: handleAuthenticateRequest,\n };\n}","import type { ApiClient,CreateFireApiOptions} from \"../fireRestApi\";\r\nimport { createFireApi } from \"../fireRestApi\";\r\nimport type { RequestState } from \"../tokens/authstate\";\r\nimport type { CreateAuthenticateRequestOptions } from \"../tokens/factory\";\r\nimport { createAuthenticateRequest } from \"../tokens/factory\";\r\nimport type {\r\n TernSecureRequest,\r\n} from \"../tokens/ternSecureRequest\";\r\n\r\nexport type TernSecureBackendOptions = CreateFireApiOptions & CreateAuthenticateRequestOptions['options'];\r\n\r\nexport type TernSecureBackendClient = ApiClient & ReturnType<typeof createAuthenticateRequest>;\r\n\r\nexport interface BackendInstance {\r\n ternSecureRequest: TernSecureRequest;\r\n requestState: RequestState;\r\n}\r\n\r\nexport function createBackendInstanceClient(options: TernSecureBackendOptions): TernSecureBackendClient {\r\n const opts = { ...options };\r\n const apiClient = createFireApi(opts);\r\n const requestState = createAuthenticateRequest({options: opts, apiClient});\r\n\r\n return {\r\n ...apiClient,\r\n ...requestState,\r\n };\r\n}\r\n","export enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n}\n\nexport interface LoggerOptions {\n enabled: boolean\n level: LogLevel\n prefix: string\n}\n\nexport class Logger {\n private options: LoggerOptions\n\n constructor(options: Partial<LoggerOptions> = {}) {\n this.options = {\n enabled: false,\n level: LogLevel.INFO,\n prefix: '[TernSecure-Backend]',\n ...options,\n }\n }\n\n enable(): void {\n this.options.enabled = true\n }\n\n disable(): void {\n this.options.enabled = false\n }\n\n setLevel(level: LogLevel): void {\n this.options.level = level\n }\n\n setPrefix(prefix: string): void {\n this.options.prefix = prefix\n }\n\n private log(level: LogLevel, levelName: string, message: string, ...args: any[]): void {\n if (!this.options.enabled || level > this.options.level) {\n return\n }\n\n const timestamp = new Date().toISOString()\n const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`\n \n switch (level) {\n case LogLevel.ERROR:\n console.error(formattedMessage, ...args)\n break\n case LogLevel.WARN:\n console.warn(formattedMessage, ...args)\n break\n case LogLevel.INFO:\n console.info(formattedMessage, ...args)\n break\n case LogLevel.DEBUG:\n console.debug(formattedMessage, ...args)\n break\n }\n }\n\n error(message: string, ...args: any[]): void {\n this.log(LogLevel.ERROR, 'ERROR', message, ...args)\n }\n\n warn(message: string, ...args: any[]): void {\n this.log(LogLevel.WARN, 'WARN', message, ...args)\n }\n\n info(message: string, ...args: any[]): void {\n this.log(LogLevel.INFO, 'INFO', message, ...args)\n }\n\n debug(message: string, ...args: any[]): void {\n this.log(LogLevel.DEBUG, 'DEBUG', message, ...args)\n }\n}\n\nexport const createLogger = (options?: Partial<LoggerOptions>): Logger => {\n return new Logger(options)\n}\n\nexport const redisLogger = createLogger({ prefix: '[TernSecure-Redis]' })\nexport const authLogger = createLogger({ prefix: '[TernSecure-Auth]' })","import { authLogger, LogLevel,redisLogger } from \"./logger\"\n\nexport function enableDebugLogging(): void {\n authLogger.enable()\n authLogger.setLevel(LogLevel.DEBUG)\n \n redisLogger.enable()\n redisLogger.setLevel(LogLevel.DEBUG)\n}\n\nexport function disableDebugLogging(): void {\n authLogger.disable()\n redisLogger.disable()\n}\n\nexport function setLogLevel(level: LogLevel): void {\n authLogger.setLevel(level)\n redisLogger.setLevel(level)\n}","import { authLogger } from \"../utils/logger\";\nimport type { DisabledUserAdapter, DisabledUserRecord, PostgresConfig } from \"./types\";\n\nexport class PostgresAdapter implements DisabledUserAdapter {\n private config: PostgresConfig;\n private tableName: string;\n\n constructor(config: PostgresConfig) {\n this.config = config;\n this.tableName = config.table || 'disabled_users';\n }\n\n getDisabledUser = async(uid: string): Promise<DisabledUserRecord | null> => {\n try {\n // For edge runtime, we'll use fetch to call a REST API endpoint\n // This avoids the need for full postgres client libraries in edge\n const response = await fetch(this.config.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.token}`,\n },\n body: JSON.stringify({\n query: `SELECT uid, email, disabled_time as \"disabledTime\" FROM ${this.tableName} WHERE uid = $1`,\n params: [uid],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n \n if (result.rows && result.rows.length > 0) {\n const row = result.rows[0];\n const disabledUser: DisabledUserRecord = {\n uid: row.uid,\n email: row.email,\n disabledTime: row.disabledTime,\n };\n \n authLogger.debug(`Found disabled user: ${uid}`);\n return disabledUser;\n }\n\n authLogger.debug(`No disabled user found: ${uid}`);\n return null;\n } catch (error) {\n authLogger.error('Failed to fetch disabled user from Postgres:', error);\n return null;\n }\n }\n}","import { Redis } from \"@upstash/redis\";\n\nimport { authLogger } from \"../utils/logger\";\nimport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n RedisConfig,\n} from \"./types\";\n\ninterface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nclass TTLCache<T> {\n private cache = new Map<string, CacheEntry<T>>();\n private readonly defaultTTL: number;\n\n constructor(defaultTTLMs: number = 60000) {\n this.defaultTTL = defaultTTLMs;\n }\n\n set(key: string, value: T, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTTL);\n this.cache.set(key, { value, expiresAt });\n console.log(`TTLCache.set: key=${key}, value=${JSON.stringify(value)}, expiresAt=${expiresAt}, cacheSize=${this.cache.size}`);\n }\n\n private getEntry(key: string): CacheEntry<T> | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n console.log(`TTLCache: key=${key} expired (now=${now}, expiresAt=${entry.expiresAt})`);\n this.cache.delete(key);\n return undefined;\n }\n\n return entry;\n }\n\n get(key: string): T | undefined {\n const entry = this.getEntry(key);\n const hasEntry = entry !== undefined;\n const cacheHasKey = this.cache.has(key);\n const rawEntry = this.cache.get(key);\n \n console.log(`TTLCache.get: key=${key}, hasEntry=${hasEntry}, cacheHasKey=${cacheHasKey}`);\n console.log(`TTLCache.get: rawEntry=${JSON.stringify(rawEntry)}, entry=${JSON.stringify(entry)}`);\n \n if (!entry) {\n console.log(`TTLCache.get: no entry found for key=${key}, returning undefined`);\n return undefined;\n }\n\n console.log(`TTLCache.get: returning value=${JSON.stringify(entry.value)} for key=${key}`);\n return entry.value;\n }\n\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n cleanup(): void {\n const now = Date.now();\n for (const [key, entry] of this.cache.entries()) {\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n }\n }\n }\n}\n\nexport class RedisAdapter implements DisabledUserAdapter {\n private redis: Redis;\n private cache: TTLCache<DisabledUserRecord | null>;\n private keyPrefix: string;\n\n constructor(config: RedisConfig) {\n this.redis = new Redis({\n url: config.url,\n token: config.token,\n });\n\n this.keyPrefix = config.keyPrefix || \"disabled_user:\";\n const cacheTTL = config.ttl || 30000; // Default 30 seconds\n this.cache = new TTLCache<DisabledUserRecord | null>(cacheTTL);\n\n setInterval(() => this.cache.cleanup(), 5 * 60 * 1000);\n }\n\n getDisabledUser = async (uid: string): Promise<DisabledUserRecord | null> => {\n const cacheKey = `${this.keyPrefix}${uid}`;\n \n authLogger.debug(`RedisAdapter: Checking cache for key: ${cacheKey}`);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n authLogger.debug(`RedisAdapter: Cache get result for ${cacheKey}:`, {\n cachedResult: JSON.stringify(cachedResult),\n isUndefined: cachedResult === undefined,\n type: typeof cachedResult\n });\n \n if (cachedResult !== undefined) {\n authLogger.debug(`Cache hit for disabled user: ${uid}`, { \n cacheKey,\n cachedResult: JSON.stringify(cachedResult)\n });\n return cachedResult;\n }\n\n authLogger.debug(\n `Cache miss for disabled user: ${uid}, fetching from Redis with key: ${cacheKey}`\n );\n\n try {\n const disabledUser: DisabledUserRecord | null =\n await this.redis.get(cacheKey);\n\n authLogger.debug(`Redis returned for key ${cacheKey}:`, { \n disabledUser: JSON.stringify(disabledUser),\n type: typeof disabledUser\n });\n\n // Cache the result (including null values to prevent repeated Redis calls)\n this.cache.set(cacheKey, disabledUser);\n \n authLogger.debug(`Cached disabled user result for: ${uid}`, {\n cacheKey,\n isDisabled: !!disabledUser,\n cachedValue: JSON.stringify(disabledUser)\n });\n\n return disabledUser;\n } catch (error) {\n authLogger.error(\"Failed to fetch disabled user from Redis:\", error);\n return null;\n }\n };\n\n invalidateCache(uid: string): void {\n const cacheKey = `${this.keyPrefix}${uid}`;\n this.cache.delete(cacheKey);\n }\n}\n","import { PostgresAdapter } from \"./PostgresAdapter\";\nimport { RedisAdapter } from \"./RedisAdapter\";\nimport type { AdapterConfiguration,DisabledUserAdapter } from \"./types\";\n\nexport function createAdapter(\n config: AdapterConfiguration\n): DisabledUserAdapter {\n switch (config.type) {\n case \"redis\":\n return new RedisAdapter(config.config as any);\n case \"postgres\":\n return new PostgresAdapter(config.config as any);\n default:\n throw new Error(`Unsupported adapter type: ${(config as any).type}`);\n }\n}\n\nexport function validateCheckRevokedOptions(options?: {\n enabled: boolean;\n adapter?: AdapterConfiguration;\n}): { isValid: boolean; error?: string } {\n if (options?.enabled && !options.adapter) {\n return {\n isValid: false,\n error: \"When checkRevoked.enabled is true, an adapter must be provided\",\n };\n }\n return { isValid: true };\n}\n\n\nexport { RedisAdapter } from './RedisAdapter';\nexport { PostgresAdapter } from './PostgresAdapter';\nexport type {\n DisabledUserAdapter,\n DisabledUserRecord,\n AdapterConfig,\n RedisConfig,\n PostgresConfig,\n AdapterType,\n AdapterConfiguration,\n CheckRevokedOptions,\n AppCheckOptions,\n} from './types';\n"],"mappings":"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","names":["Headers","import_jose","parse","getPublicKey","cert","crypto","import_jose","import_jose","import_jose","ternDecodeJwt","getSdkVersion","FIREBASE_APP_CHECK_CONFIG_HEADERS","AppCheckApi","import_jose","AppCheckApi","verifyAppCheckToken","import_cookie","getCookieNameEnvironment","context","LogLevel","import_redis"]}