@tern-secure/backend 1.2.0-canary.v20251008165428 → 1.2.0-canary.v20251020032343

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.
Files changed (44) hide show
  1. package/dist/admin/index.js +8 -8
  2. package/dist/admin/index.js.map +1 -1
  3. package/dist/admin/index.mjs +8 -8
  4. package/dist/admin/index.mjs.map +1 -1
  5. package/dist/admin/nextSessionTernSecure.d.ts.map +1 -1
  6. package/dist/auth/getauth.d.ts +2 -1
  7. package/dist/auth/getauth.d.ts.map +1 -1
  8. package/dist/auth/index.js +15 -0
  9. package/dist/auth/index.js.map +1 -1
  10. package/dist/auth/index.mjs +2 -2
  11. package/dist/{chunk-SVZUAXAW.mjs → chunk-5AP2WM3W.mjs} +1 -1
  12. package/dist/chunk-5AP2WM3W.mjs.map +1 -0
  13. package/dist/{chunk-YGNTGJTP.mjs → chunk-ZLFJV4IK.mjs} +17 -2
  14. package/dist/chunk-ZLFJV4IK.mjs.map +1 -0
  15. package/dist/fireRestApi/createFireApi.d.ts +2 -1
  16. package/dist/fireRestApi/createFireApi.d.ts.map +1 -1
  17. package/dist/fireRestApi/endpointUrl.d.ts +2 -0
  18. package/dist/fireRestApi/endpointUrl.d.ts.map +1 -1
  19. package/dist/fireRestApi/endpoints/UserData.d.ts +14 -0
  20. package/dist/fireRestApi/endpoints/UserData.d.ts.map +1 -0
  21. package/dist/fireRestApi/endpoints/index.d.ts +1 -0
  22. package/dist/fireRestApi/endpoints/index.d.ts.map +1 -1
  23. package/dist/fireRestApi/request.d.ts +1 -1
  24. package/dist/fireRestApi/request.d.ts.map +1 -1
  25. package/dist/fireRestApi/resources/JSON.d.ts +19 -0
  26. package/dist/fireRestApi/resources/JSON.d.ts.map +1 -1
  27. package/dist/fireRestApi/resources/User.d.ts +8 -0
  28. package/dist/fireRestApi/resources/User.d.ts.map +1 -0
  29. package/dist/index.js +42 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +29 -4
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/jwt/index.js.map +1 -1
  34. package/dist/jwt/index.mjs +1 -1
  35. package/dist/jwt/verifyJwt.d.ts.map +1 -1
  36. package/dist/tokens/authstate.d.ts +1 -0
  37. package/dist/tokens/authstate.d.ts.map +1 -1
  38. package/dist/tokens/types.d.ts +2 -1
  39. package/dist/tokens/types.d.ts.map +1 -1
  40. package/dist/tokens/verify.d.ts +2 -2
  41. package/dist/tokens/verify.d.ts.map +1 -1
  42. package/package.json +3 -3
  43. package/dist/chunk-SVZUAXAW.mjs.map +0 -1
  44. package/dist/chunk-YGNTGJTP.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/index.ts","../../src/jwt/customJwt.ts","../../src/jwt/verifyJwt.ts","../../src/utils/errors.ts","../../src/utils/mapDecode.ts","../../src/utils/rfc4648.ts","../../src/jwt/cryptoKeys.ts","../../src/jwt/algorithms.ts","../../src/jwt/verifyContent.ts","../../src/constants.ts","../../src/tokens/keys.ts","../../src/tokens/verify.ts","../../src/auth/getauth.ts"],"sourcesContent":["export * from './getauth';","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 { DecodedIdToken, Jwt,JWTPayload } from '@tern-secure/types';\nimport {\n decodeJwt,\n decodeProtectedHeader,\n jwtVerify,\n} from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { 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 };\n\n return { data };\n } catch (error: any) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: error.message,\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","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","import type { 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 * 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","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 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\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: '__session_terncf',\n IdToken: 'FIREBASE_[DEFAULT]',\n Refresh: 'FIREBASEID_[DEFAULT]',\n Custom: '__custom',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\nconst Headers = {\n Accept: 'accept',\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} as const;\n\nexport type Constants = typeof constants;\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 = GOOGLE_PUBLIC_KEYS_URL,\n skipJwksCache,\n kid,\n}: LoadJWKFromRemoteOptions): Promise<string> {\n if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {\n const { keys, expiresAt } = await fetchPublicKeys(keyURL);\n\n if (!keys || Object.keys(keys).length === 0) {\n throw new TokenVerificationError({\n message: `The JWKS endpoint ${keyURL} 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, TernSecureConfig } 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 };\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 { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\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\ninterface FirebaseCustomTokenResponse {\n kind: string;\n idToken: string;\n refreshToken: string;\n expiresIn: 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 firebaseApiKey = options.firebaseConfig?.apiKey;\n const effectiveApiKey = apiKey || firebaseApiKey;\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 response = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n },\n );\n\n if (!response?.data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n const parsedData = parseFirebaseResponse<FirebaseCustomTokenResponse>(response.data);\n\n return {\n idToken: parsedData.idToken,\n refreshToken: parsedData.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 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 });\n\n return {\n ...idAndRefreshTokens,\n customToken,\n };\n }\n\n return {\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n };\n}\n"],"mappings":"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","names":["import_jose","import_jose","cert"]}
1
+ {"version":3,"sources":["../../src/auth/index.ts","../../src/jwt/customJwt.ts","../../src/jwt/verifyJwt.ts","../../src/utils/errors.ts","../../src/utils/mapDecode.ts","../../src/utils/rfc4648.ts","../../src/jwt/cryptoKeys.ts","../../src/jwt/algorithms.ts","../../src/jwt/verifyContent.ts","../../src/constants.ts","../../src/tokens/keys.ts","../../src/tokens/verify.ts","../../src/auth/getauth.ts"],"sourcesContent":["export * from './getauth';","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 { DecodedIdToken, Jwt, JWTPayload } from '@tern-secure/types';\nimport {\n decodeJwt,\n decodeProtectedHeader,\n jwtVerify,\n} from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { 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 };\n\n return { data };\n } catch (error: any) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: error.message,\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","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","import type { 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 * 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","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 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\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: '__session_terncf',\n IdToken: 'FIREBASE_[DEFAULT]',\n Refresh: 'FIREBASEID_[DEFAULT]',\n Custom: '__custom',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\nconst Headers = {\n Accept: 'accept',\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} as const;\n\nexport type Constants = typeof constants;\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 = GOOGLE_PUBLIC_KEYS_URL,\n skipJwksCache,\n kid,\n}: LoadJWKFromRemoteOptions): Promise<string> {\n if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {\n const { keys, expiresAt } = await fetchPublicKeys(keyURL);\n\n if (!keys || Object.keys(keys).length === 0) {\n throw new TokenVerificationError({\n message: `The JWKS endpoint ${keyURL} 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, 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, 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 { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions, TernSecureUserData } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\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\ninterface FirebaseCustomTokenResponse {\n kind: string;\n idToken: string;\n refreshToken: string;\n expiresIn: 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 firebaseApiKey = options.firebaseConfig?.apiKey;\n const effectiveApiKey = apiKey || firebaseApiKey;\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 response = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n },\n );\n\n if (!response?.data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n const parsedData = parseFirebaseResponse<FirebaseCustomTokenResponse>(response.data);\n\n return {\n idToken: parsedData.idToken,\n refreshToken: parsedData.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 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 });\n\n return {\n ...idAndRefreshTokens,\n customToken,\n };\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n };\n}\n"],"mappings":"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","names":["import_jose","import_jose","cert"]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  getAuth
3
- } from "../chunk-YGNTGJTP.mjs";
3
+ } from "../chunk-ZLFJV4IK.mjs";
4
4
  import "../chunk-VSYYHCUV.mjs";
5
- import "../chunk-SVZUAXAW.mjs";
5
+ import "../chunk-5AP2WM3W.mjs";
6
6
  export {
7
7
  getAuth
8
8
  };
@@ -429,4 +429,4 @@ export {
429
429
  ternDecodeJwt,
430
430
  verifyJwt
431
431
  };
432
- //# sourceMappingURL=chunk-SVZUAXAW.mjs.map
432
+ //# sourceMappingURL=chunk-5AP2WM3W.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/jwt/customJwt.ts","../src/jwt/verifyJwt.ts","../src/utils/errors.ts","../src/utils/mapDecode.ts","../src/utils/rfc4648.ts","../src/jwt/cryptoKeys.ts","../src/jwt/algorithms.ts","../src/jwt/verifyContent.ts"],"sourcesContent":["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 { DecodedIdToken, Jwt, JWTPayload } from '@tern-secure/types';\nimport {\n decodeJwt,\n decodeProtectedHeader,\n jwtVerify,\n} from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport { 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 };\n\n return { data };\n } catch (error: any) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: error.message,\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","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","import type { 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 * 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"],"mappings":"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","names":[]}
@@ -10,7 +10,7 @@ import {
10
10
  createCustomToken,
11
11
  ternDecodeJwt,
12
12
  verifyJwt
13
- } from "./chunk-SVZUAXAW.mjs";
13
+ } from "./chunk-5AP2WM3W.mjs";
14
14
 
15
15
  // src/tokens/keys.ts
16
16
  var cache = {};
@@ -154,6 +154,20 @@ function getAuth(options) {
154
154
  const { apiKey } = options;
155
155
  const firebaseApiKey = options.firebaseConfig?.apiKey;
156
156
  const effectiveApiKey = apiKey || firebaseApiKey;
157
+ async function getUserData(idToken, localId) {
158
+ if (!effectiveApiKey) {
159
+ throw new Error(API_KEY_ERROR);
160
+ }
161
+ const response = await options.apiClient?.userData.getUserData(effectiveApiKey, {
162
+ idToken,
163
+ localId
164
+ });
165
+ if (!response?.data) {
166
+ throw new Error(NO_DATA_ERROR);
167
+ }
168
+ const parsedData = parseFirebaseResponse(response.data);
169
+ return parsedData;
170
+ }
157
171
  async function refreshExpiredIdToken(refreshToken, opts) {
158
172
  if (!effectiveApiKey) {
159
173
  return { data: null, error: new Error(API_KEY_ERROR) };
@@ -219,6 +233,7 @@ function getAuth(options) {
219
233
  };
220
234
  }
221
235
  return {
236
+ getUserData,
222
237
  customForIdAndRefreshToken,
223
238
  createCustomIdAndRefreshToken,
224
239
  refreshExpiredIdToken
@@ -229,4 +244,4 @@ export {
229
244
  verifyToken,
230
245
  getAuth
231
246
  };
232
- //# sourceMappingURL=chunk-YGNTGJTP.mjs.map
247
+ //# sourceMappingURL=chunk-ZLFJV4IK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tokens/keys.ts","../src/tokens/verify.ts","../src/auth/getauth.ts"],"sourcesContent":["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 = GOOGLE_PUBLIC_KEYS_URL,\n skipJwksCache,\n kid,\n}: LoadJWKFromRemoteOptions): Promise<string> {\n if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {\n const { keys, expiresAt } = await fetchPublicKeys(keyURL);\n\n if (!keys || Object.keys(keys).length === 0) {\n throw new TokenVerificationError({\n message: `The JWKS endpoint ${keyURL} 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, 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, 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 { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions, TernSecureUserData } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\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\ninterface FirebaseCustomTokenResponse {\n kind: string;\n idToken: string;\n refreshToken: string;\n expiresIn: 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 firebaseApiKey = options.firebaseConfig?.apiKey;\n const effectiveApiKey = apiKey || firebaseApiKey;\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 response = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n },\n );\n\n if (!response?.data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n const parsedData = parseFirebaseResponse<FirebaseCustomTokenResponse>(response.data);\n\n return {\n idToken: parsedData.idToken,\n refreshToken: parsedData.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 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 });\n\n return {\n ...idAndRefreshTokens,\n customToken,\n };\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n };\n}\n"],"mappings":"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","names":["cert"]}
@@ -1,4 +1,4 @@
1
- import { EmailApi, PasswordApi, SignInTokenApi, SignUpApi, TokenApi } from './endpoints';
1
+ import { EmailApi, PasswordApi, SignInTokenApi, SignUpApi, TokenApi, UserData } from './endpoints';
2
2
  import { createRequest } from './request';
3
3
  export type CreateFireApiOptions = Parameters<typeof createRequest>[0];
4
4
  export type ApiClient = ReturnType<typeof createFireApi>;
@@ -8,5 +8,6 @@ export declare function createFireApi(options: CreateFireApiOptions): {
8
8
  signIn: SignInTokenApi;
9
9
  signUp: SignUpApi;
10
10
  tokens: TokenApi;
11
+ userData: UserData;
11
12
  };
12
13
  //# sourceMappingURL=createFireApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createFireApi.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/createFireApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEzD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB;;;;;;EAS1D"}
1
+ {"version":3,"file":"createFireApi.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/createFireApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEzD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB;;;;;;;EAU1D"}
@@ -1,3 +1,5 @@
1
+ export declare const topLevelEndpoint: (apiKey: string, projectId: string, version: string) => string;
2
+ export declare const lookupEndpoint: (apiKey: string) => string;
1
3
  export declare const getRefreshTokenEndpoint: (apiKey: string) => string;
2
4
  export declare const signInWithPassword: (apiKey: string) => string;
3
5
  export declare const signUpEndpoint: (apiKey: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"endpointUrl.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/endpointUrl.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,WAErD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,WAEhD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,WAE5C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,WAUpD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,WAEnD,CAAC"}
1
+ {"version":3,"file":"endpointUrl.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/endpointUrl.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,EAAE,WAAW,MAAM,EAAE,SAAS,MAAM,WAElF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,WAE5C,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,WAErD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,WAEhD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,WAE5C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,WAUpD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,WAEnD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { User } from '../resources/User';
2
+ import { AbstractAPI } from './AbstractApi';
3
+ type UserDataParams = {
4
+ localId?: string;
5
+ idToken?: string;
6
+ };
7
+ type UserDataOptions = {
8
+ referer?: string;
9
+ };
10
+ export declare class UserData extends AbstractAPI {
11
+ getUserData(apiKey: string, params: UserDataParams, options?: UserDataOptions): Promise<import("../request").BackendApiResponse<User>>;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=UserData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserData.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/endpoints/UserData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,qBAAa,QAAS,SAAQ,WAAW;IACxB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,eAAe;CAgB7F"}
@@ -3,4 +3,5 @@ export * from './PasswordApi';
3
3
  export * from './SignInTokenApi';
4
4
  export * from './SignUpApi';
5
5
  export * from './TokenApi';
6
+ export * from './UserData';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/endpoints/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/endpoints/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { TernSecureFireRestError, TernSecureFireRestErrorJSON } from "@tern-secure/types";
2
2
  export type HTTPMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
3
- export type FirebaseEndpoint = "refreshToken" | "signInWithPassword" | "signUp" | "signInWithCustomToken" | "passwordReset" | "sendOobCode";
3
+ export type FirebaseEndpoint = "lookup" | "refreshToken" | "signInWithPassword" | "signUp" | "signInWithCustomToken" | "passwordReset" | "sendOobCode";
4
4
  export type BackendApiRequestOptions = {
5
5
  endpoint: FirebaseEndpoint;
6
6
  method?: HTTPMethod;
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAY5B,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AACrE,MAAM,MAAM,gBAAgB,GACxB,cAAc,GACd,oBAAoB,GACpB,QAAQ,GACR,uBAAuB,GACvB,eAAe,GACf,aAAa,CAAA;AAEjB,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAA;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IACE,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,IAAI,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAE/D,KAAK,oBAAoB,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAYF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,IAChC,CAAC,kBACR,wBAAwB,KACvC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAmGlC;AAwCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,2BAA2B,GAAG,uBAAuB,CAOtF"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/fireRestApi/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAa5B,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AACrE,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,cAAc,GACd,oBAAoB,GACpB,QAAQ,GACR,uBAAuB,GACvB,eAAe,GACf,aAAa,CAAA;AAEjB,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAA;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IACE,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,IAAI,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAE/D,KAAK,oBAAoB,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAaF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,IAChC,CAAC,kBACR,wBAAwB,KACvC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAmGlC;AAwCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,2BAA2B,GAAG,uBAAuB,CAOtF"}
@@ -1,3 +1,4 @@
1
+ import type { ProviderUserInfo } from "@tern-secure/types";
1
2
  export declare const ObjectType: {
2
3
  readonly Client: "client";
3
4
  readonly Cookies: "cookies";
@@ -47,4 +48,22 @@ export interface IdAndRefreshTokenJSON {
47
48
  idToken: string;
48
49
  refreshToken: string;
49
50
  }
51
+ export interface UserJson {
52
+ object: typeof ObjectType.User;
53
+ localId: string;
54
+ email: string;
55
+ emailVerified: boolean;
56
+ displayName: string;
57
+ providerUserInfo: ProviderUserInfo[];
58
+ photoUrl: string;
59
+ passwordHash: string;
60
+ passwordUpdatedAt: number;
61
+ validSince: string;
62
+ disabled: boolean;
63
+ lastLoginAt: string;
64
+ createdAt: string;
65
+ phoneNumber?: string;
66
+ customAuth: boolean;
67
+ tenantId?: string;
68
+ }
50
69
  //# sourceMappingURL=JSON.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSON.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/resources/JSON.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;CAuBb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAGtE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,UAAU,CAAC,OAAO,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,UAAU,CAAC,kBAAkB,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"JSON.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/resources/JSON.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;CAuBb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAGtE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,UAAU,CAAC,OAAO,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,UAAU,CAAC,kBAAkB,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,8 @@
1
+ import type { TernSecureUserData } from '@tern-secure/types';
2
+ import type { UserJson } from './JSON';
3
+ export declare class User {
4
+ readonly data: TernSecureUserData;
5
+ constructor(data: TernSecureUserData);
6
+ static fromJSON(data: UserJson): User;
7
+ }
8
+ //# sourceMappingURL=User.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../../../src/fireRestApi/resources/User.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,qBAAa,IAAI;IACH,QAAQ,CAAC,IAAI,EAAE,kBAAkB;gBAAxB,IAAI,EAAE,kBAAkB;IAE7C,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;CAgBtC"}
package/dist/index.js CHANGED
@@ -227,6 +227,7 @@ function signedOutAuthObject() {
227
227
  return {
228
228
  sessionClaims: null,
229
229
  userId: null,
230
+ token: null,
230
231
  require: () => false,
231
232
  error: "No active session"
232
233
  };
@@ -410,6 +411,25 @@ var TokenApi = class extends AbstractAPI {
410
411
  }
411
412
  };
412
413
 
414
+ // src/fireRestApi/endpoints/UserData.ts
415
+ var UserData = class extends AbstractAPI {
416
+ async getUserData(apiKey, params, options) {
417
+ this.requireApiKey(apiKey);
418
+ const { ...restParams } = params;
419
+ const headers = {};
420
+ if (options?.referer) {
421
+ headers["Referer"] = options.referer;
422
+ }
423
+ return this.request({
424
+ endpoint: "lookup",
425
+ method: "POST",
426
+ apiKey,
427
+ bodyParams: restParams,
428
+ headerParams: headers
429
+ });
430
+ }
431
+ };
432
+
413
433
  // src/runtime.ts
414
434
  var import_crypto = require("#crypto");
415
435
  var globalFetch = fetch.bind(globalThis);
@@ -437,6 +457,9 @@ function useEmulator() {
437
457
  }
438
458
 
439
459
  // src/fireRestApi/endpointUrl.ts
460
+ var lookupEndpoint = (apiKey) => {
461
+ return `https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=${apiKey}`;
462
+ };
440
463
  var getRefreshTokenEndpoint = (apiKey) => {
441
464
  return `https://securetoken.googleapis.com/v1/token?key=${apiKey}`;
442
465
  };
@@ -467,7 +490,8 @@ var FIREBASE_ENDPOINT_MAP = {
467
490
  signUp: signUpEndpoint,
468
491
  signInWithCustomToken: getCustomTokenEndpoint,
469
492
  passwordReset: passwordResetEndpoint,
470
- sendOobCode: signInWithPassword
493
+ sendOobCode: signInWithPassword,
494
+ lookup: lookupEndpoint
471
495
  };
472
496
  function createRequest(options) {
473
497
  const requestFn = async (requestOptions) => {
@@ -601,7 +625,8 @@ function createFireApi(options) {
601
625
  password: new PasswordApi(request),
602
626
  signIn: new SignInTokenApi(request),
603
627
  signUp: new SignUpApi(request),
604
- tokens: new TokenApi(request)
628
+ tokens: new TokenApi(request),
629
+ userData: new UserData(request)
605
630
  };
606
631
  }
607
632
 
@@ -1153,6 +1178,20 @@ function getAuth(options) {
1153
1178
  const { apiKey } = options;
1154
1179
  const firebaseApiKey = options.firebaseConfig?.apiKey;
1155
1180
  const effectiveApiKey = apiKey || firebaseApiKey;
1181
+ async function getUserData(idToken, localId) {
1182
+ if (!effectiveApiKey) {
1183
+ throw new Error(API_KEY_ERROR);
1184
+ }
1185
+ const response = await options.apiClient?.userData.getUserData(effectiveApiKey, {
1186
+ idToken,
1187
+ localId
1188
+ });
1189
+ if (!response?.data) {
1190
+ throw new Error(NO_DATA_ERROR);
1191
+ }
1192
+ const parsedData = parseFirebaseResponse(response.data);
1193
+ return parsedData;
1194
+ }
1156
1195
  async function refreshExpiredIdToken(refreshToken, opts) {
1157
1196
  if (!effectiveApiKey) {
1158
1197
  return { data: null, error: new Error(API_KEY_ERROR) };
@@ -1218,6 +1257,7 @@ function getAuth(options) {
1218
1257
  };
1219
1258
  }
1220
1259
  return {
1260
+ getUserData,
1221
1261
  customForIdAndRefreshToken,
1222
1262
  createCustomIdAndRefreshToken,
1223
1263
  refreshExpiredIdToken