@tern-secure/backend 1.2.0-canary.v20251125170702 → 1.2.0-canary.v20251127221555

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 (62) hide show
  1. package/dist/admin/index.js +3 -0
  2. package/dist/admin/index.js.map +1 -1
  3. package/dist/admin/index.mjs +4 -2
  4. package/dist/admin/index.mjs.map +1 -1
  5. package/dist/auth/constants.d.ts +6 -0
  6. package/dist/auth/constants.d.ts.map +1 -0
  7. package/dist/auth/credential.d.ts +27 -0
  8. package/dist/auth/credential.d.ts.map +1 -0
  9. package/dist/auth/getauth.d.ts +1 -0
  10. package/dist/auth/getauth.d.ts.map +1 -1
  11. package/dist/auth/index.js +234 -28
  12. package/dist/auth/index.js.map +1 -1
  13. package/dist/auth/index.mjs +3 -3
  14. package/dist/auth/utils.d.ts +3 -0
  15. package/dist/auth/utils.d.ts.map +1 -0
  16. package/dist/{chunk-MS6L7M3C.mjs → chunk-DJLDUW7J.mjs} +174 -12
  17. package/dist/chunk-DJLDUW7J.mjs.map +1 -0
  18. package/dist/{chunk-ASGV4MFO.mjs → chunk-GFH5CXQR.mjs} +2 -2
  19. package/dist/{chunk-DDUNOEIM.mjs → chunk-NXYWC6YO.mjs} +278 -116
  20. package/dist/chunk-NXYWC6YO.mjs.map +1 -0
  21. package/dist/{chunk-DFAJCSBJ.mjs → chunk-WIVOBOZR.mjs} +2 -1
  22. package/dist/chunk-WIVOBOZR.mjs.map +1 -0
  23. package/dist/constants.d.ts +1 -0
  24. package/dist/constants.d.ts.map +1 -1
  25. package/dist/fireRestApi/createFireApi.d.ts +2 -1
  26. package/dist/fireRestApi/createFireApi.d.ts.map +1 -1
  27. package/dist/fireRestApi/endpoints/AppCheckApi.d.ts +23 -0
  28. package/dist/fireRestApi/endpoints/AppCheckApi.d.ts.map +1 -0
  29. package/dist/fireRestApi/endpoints/TokenApi.d.ts +3 -1
  30. package/dist/fireRestApi/endpoints/TokenApi.d.ts.map +1 -1
  31. package/dist/fireRestApi/endpoints/UserData.d.ts.map +1 -1
  32. package/dist/fireRestApi/endpoints/index.d.ts +1 -0
  33. package/dist/fireRestApi/endpoints/index.d.ts.map +1 -1
  34. package/dist/fireRestApi/request.d.ts.map +1 -1
  35. package/dist/index.js +390 -36
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +159 -12
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/jwt/index.d.ts +1 -0
  40. package/dist/jwt/index.d.ts.map +1 -1
  41. package/dist/jwt/index.js +51 -19
  42. package/dist/jwt/index.js.map +1 -1
  43. package/dist/jwt/index.mjs +8 -132
  44. package/dist/jwt/index.mjs.map +1 -1
  45. package/dist/jwt/signJwt.d.ts +8 -0
  46. package/dist/jwt/signJwt.d.ts.map +1 -1
  47. package/dist/jwt/verifyJwt.d.ts.map +1 -1
  48. package/dist/tokens/authstate.d.ts.map +1 -1
  49. package/dist/tokens/c-authenticateRequestProcessor.d.ts +1 -0
  50. package/dist/tokens/c-authenticateRequestProcessor.d.ts.map +1 -1
  51. package/dist/tokens/request.d.ts.map +1 -1
  52. package/dist/tokens/types.d.ts +2 -1
  53. package/dist/tokens/types.d.ts.map +1 -1
  54. package/dist/tokens/verify.d.ts +2 -2
  55. package/dist/tokens/verify.d.ts.map +1 -1
  56. package/dist/utils/admin-init.d.ts +1 -0
  57. package/dist/utils/admin-init.d.ts.map +1 -1
  58. package/package.json +3 -3
  59. package/dist/chunk-DDUNOEIM.mjs.map +0 -1
  60. package/dist/chunk-DFAJCSBJ.mjs.map +0 -1
  61. package/dist/chunk-MS6L7M3C.mjs.map +0 -1
  62. /package/dist/{chunk-ASGV4MFO.mjs.map → chunk-GFH5CXQR.mjs.map} +0 -0
@@ -355,33 +355,44 @@ async function verifySignature(jwt, key) {
355
355
  }
356
356
  }
357
357
  function ternDecodeJwt(token) {
358
- const header = (0, import_jose3.decodeProtectedHeader)(token);
359
- const payload = (0, import_jose3.decodeJwt)(token);
360
- const tokenParts = (token || "").toString().split(".");
361
- if (tokenParts.length !== 3) {
358
+ try {
359
+ const header = (0, import_jose3.decodeProtectedHeader)(token);
360
+ const payload = (0, import_jose3.decodeJwt)(token);
361
+ const tokenParts = (token || "").toString().split(".");
362
+ if (tokenParts.length !== 3) {
363
+ return {
364
+ errors: [
365
+ new TokenVerificationError({
366
+ reason: TokenVerificationErrorReason.TokenInvalid,
367
+ message: "Invalid JWT format"
368
+ })
369
+ ]
370
+ };
371
+ }
372
+ const [rawHeader, rawPayload, rawSignature] = tokenParts;
373
+ const signature = base64url.parse(rawSignature, { loose: true });
374
+ const data = {
375
+ header,
376
+ payload,
377
+ signature,
378
+ raw: {
379
+ header: rawHeader,
380
+ payload: rawPayload,
381
+ signature: rawSignature,
382
+ text: token
383
+ }
384
+ };
385
+ return { data };
386
+ } catch (error) {
362
387
  return {
363
388
  errors: [
364
389
  new TokenVerificationError({
365
390
  reason: TokenVerificationErrorReason.TokenInvalid,
366
- message: "Invalid JWT format"
391
+ message: `${error.message || "Invalid Token or Protected Header formatting"} (Token length: ${token?.length}, First 10 chars: ${token?.substring(0, 10)}...)`
367
392
  })
368
393
  ]
369
394
  };
370
395
  }
371
- const [rawHeader, rawPayload, rawSignature] = tokenParts;
372
- const signature = base64url.parse(rawSignature, { loose: true });
373
- const data = {
374
- header,
375
- payload,
376
- signature,
377
- raw: {
378
- header: rawHeader,
379
- payload: rawPayload,
380
- signature: rawSignature,
381
- text: token
382
- }
383
- };
384
- return { data };
385
396
  }
386
397
  async function verifyJwt(token, options) {
387
398
  const { key } = options;
@@ -569,6 +580,143 @@ async function verifyToken(token, options) {
569
580
  }
570
581
  }
571
582
 
583
+ // src/jwt/guardReturn.ts
584
+ function createJwtGuard(decodedFn) {
585
+ return (...args) => {
586
+ const { data, errors } = decodedFn(...args);
587
+ if (errors) {
588
+ throw errors[0];
589
+ }
590
+ return data;
591
+ };
592
+ }
593
+
594
+ // src/jwt/jwt.ts
595
+ var import_jose4 = require("jose");
596
+
597
+ // src/jwt/signJwt.ts
598
+ var import_jose5 = require("jose");
599
+ var ALGORITHM_RS256 = "RS256";
600
+ async function ternSignJwt(opts) {
601
+ const { payload, privateKey, keyId } = opts;
602
+ let key;
603
+ try {
604
+ key = await (0, import_jose5.importPKCS8)(privateKey, ALGORITHM_RS256);
605
+ } catch (error) {
606
+ throw new TokenVerificationError({
607
+ message: `Failed to import private key: ${error.message}`,
608
+ reason: TokenVerificationErrorReason.TokenInvalid
609
+ });
610
+ }
611
+ return new import_jose5.SignJWT(payload).setProtectedHeader({ alg: ALGORITHM_RS256, kid: keyId }).sign(key);
612
+ }
613
+
614
+ // src/jwt/index.ts
615
+ var ternDecodeJwt2 = createJwtGuard(ternDecodeJwt);
616
+
617
+ // src/auth/constants.ts
618
+ var TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1e3;
619
+ var GOOGLE_TOKEN_AUDIENCE = "https://accounts.google.com/o/oauth2/token";
620
+ var GOOGLE_AUTH_TOKEN_HOST = "accounts.google.com";
621
+ var GOOGLE_AUTH_TOKEN_PATH = "/o/oauth2/token";
622
+ var ONE_HOUR_IN_SECONDS = 60 * 60;
623
+
624
+ // src/auth/utils.ts
625
+ async function getDetailFromResponse(response) {
626
+ const json = await response.json();
627
+ if (!json) {
628
+ return "Missing error payload";
629
+ }
630
+ let detail = typeof json.error === "string" ? json.error : json.error?.message ?? "Missing error payload";
631
+ if (json.error_description) {
632
+ detail += " (" + json.error_description + ")";
633
+ }
634
+ return detail;
635
+ }
636
+ async function fetchJson(url, init) {
637
+ return (await fetchAny(url, init)).json();
638
+ }
639
+ async function fetchAny(url, init) {
640
+ const response = await fetch(url, init);
641
+ if (!response.ok) {
642
+ throw new Error(await getDetailFromResponse(response));
643
+ }
644
+ return response;
645
+ }
646
+
647
+ // src/auth/credential.ts
648
+ var accessTokenCache = /* @__PURE__ */ new Map();
649
+ async function requestAccessToken(urlString, init) {
650
+ const json = await fetchJson(urlString, init);
651
+ if (!json.access_token || !json.expires_in) {
652
+ throw new Error("Invalid access token response");
653
+ }
654
+ return {
655
+ accessToken: json.access_token,
656
+ expirationTime: Date.now() + json.expires_in * 1e3
657
+ };
658
+ }
659
+ var ServiceAccountTokenManager = class {
660
+ projectId;
661
+ privateKey;
662
+ clientEmail;
663
+ constructor(serviceAccount) {
664
+ this.projectId = serviceAccount.projectId;
665
+ this.privateKey = serviceAccount.privateKey;
666
+ this.clientEmail = serviceAccount.clientEmail;
667
+ }
668
+ fetchAccessToken = async (url) => {
669
+ const token = await this.createJwt();
670
+ const postData = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + token;
671
+ return requestAccessToken(url, {
672
+ method: "POST",
673
+ headers: {
674
+ "Content-Type": "application/x-www-form-urlencoded",
675
+ Authorization: `Bearer ${token}`,
676
+ Accept: "application/json"
677
+ },
678
+ body: postData
679
+ });
680
+ };
681
+ fetchAndCacheAccessToken = async (url) => {
682
+ const accessToken = await this.fetchAccessToken(url);
683
+ accessTokenCache.set(this.projectId, accessToken);
684
+ return accessToken;
685
+ };
686
+ getAccessToken = async (refresh) => {
687
+ const url = `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`;
688
+ if (refresh) {
689
+ return this.fetchAndCacheAccessToken(url);
690
+ }
691
+ const cachedResponse = accessTokenCache.get(this.projectId);
692
+ if (!cachedResponse || cachedResponse.expirationTime - Date.now() <= TOKEN_EXPIRY_THRESHOLD_MILLIS) {
693
+ return this.fetchAndCacheAccessToken(url);
694
+ }
695
+ return cachedResponse;
696
+ };
697
+ createJwt = async () => {
698
+ const iat = Math.floor(Date.now() / 1e3);
699
+ const payload = {
700
+ aud: GOOGLE_TOKEN_AUDIENCE,
701
+ iat,
702
+ exp: iat + ONE_HOUR_IN_SECONDS,
703
+ iss: this.clientEmail,
704
+ sub: this.clientEmail,
705
+ scope: [
706
+ "https://www.googleapis.com/auth/cloud-platform",
707
+ "https://www.googleapis.com/auth/firebase.database",
708
+ "https://www.googleapis.com/auth/firebase.messaging",
709
+ "https://www.googleapis.com/auth/identitytoolkit",
710
+ "https://www.googleapis.com/auth/userinfo.email"
711
+ ].join(" ")
712
+ };
713
+ return ternSignJwt({
714
+ payload,
715
+ privateKey: this.privateKey
716
+ });
717
+ };
718
+ };
719
+
572
720
  // src/auth/getauth.ts
573
721
  var API_KEY_ERROR = "API Key is required";
574
722
  var NO_DATA_ERROR = "No token data received";
@@ -583,9 +731,17 @@ function parseFirebaseResponse(data) {
583
731
  return data;
584
732
  }
585
733
  function getAuth(options) {
586
- const { apiKey } = options;
734
+ const { apiKey, firebaseAdminConfig } = options;
587
735
  const firebaseApiKey = options.firebaseConfig?.apiKey;
588
736
  const effectiveApiKey = apiKey || firebaseApiKey;
737
+ let credential = null;
738
+ if (firebaseAdminConfig?.projectId && firebaseAdminConfig?.privateKey && firebaseAdminConfig?.clientEmail) {
739
+ credential = new ServiceAccountTokenManager({
740
+ projectId: firebaseAdminConfig.projectId,
741
+ privateKey: firebaseAdminConfig.privateKey,
742
+ clientEmail: firebaseAdminConfig.clientEmail
743
+ });
744
+ }
589
745
  async function getUserData(idToken, localId) {
590
746
  if (!effectiveApiKey) {
591
747
  throw new Error(API_KEY_ERROR);
@@ -627,23 +783,23 @@ function getAuth(options) {
627
783
  if (!effectiveApiKey) {
628
784
  throw new Error("API Key is required to create custom token");
629
785
  }
630
- const response = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(
786
+ const data = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(
631
787
  effectiveApiKey,
632
788
  {
633
789
  token: customToken,
634
790
  returnSecureToken: true
635
791
  },
636
792
  {
637
- referer: opts.referer
793
+ referer: opts.referer,
794
+ appCheckToken: opts.appCheckToken
638
795
  }
639
796
  );
640
- if (!response?.data) {
797
+ if (!data) {
641
798
  throw new Error("No data received from Firebase token exchange");
642
799
  }
643
- const parsedData = parseFirebaseResponse(response.data);
644
800
  return {
645
- idToken: parsedData.idToken,
646
- refreshToken: parsedData.refreshToken
801
+ idToken: data.idToken,
802
+ refreshToken: data.refreshToken
647
803
  };
648
804
  }
649
805
  async function createCustomIdAndRefreshToken(idToken, opts) {
@@ -657,7 +813,8 @@ function getAuth(options) {
657
813
  source_sign_in_provider: data.firebase.sign_in_provider
658
814
  });
659
815
  const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {
660
- referer: opts.referer
816
+ referer: opts.referer,
817
+ appCheckToken: opts.appCheckToken
661
818
  });
662
819
  const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);
663
820
  if (decodedCustomIdToken.errors) {
@@ -669,11 +826,60 @@ function getAuth(options) {
669
826
  auth_time: decodedCustomIdToken.data.auth_time
670
827
  };
671
828
  }
829
+ async function exchangeAppCheckToken(idToken) {
830
+ if (!credential) {
831
+ return {
832
+ data: null,
833
+ error: new Error(
834
+ "Firebase Admin config must be provided to exchange App Check tokens."
835
+ )
836
+ };
837
+ }
838
+ if (!effectiveApiKey) {
839
+ return { data: null, error: new Error(API_KEY_ERROR) };
840
+ }
841
+ try {
842
+ const decoded = await verifyToken(idToken, options);
843
+ if (decoded.errors) {
844
+ return { data: null, error: decoded.errors[0] };
845
+ }
846
+ const customToken = await createCustomToken(decoded.data.uid, {
847
+ emailVerified: decoded.data.email_verified,
848
+ source_sign_in_provider: decoded.data.firebase.sign_in_provider
849
+ });
850
+ const projectId = options.firebaseConfig?.projectId;
851
+ const appId = options.firebaseConfig?.appId;
852
+ if (!projectId || !appId) {
853
+ return { data: null, error: new Error("Project ID and App ID are required for App Check") };
854
+ }
855
+ const { accessToken } = await credential.getAccessToken();
856
+ const appCheckResponse = await options.apiClient?.appCheck.exchangeCustomToken({
857
+ accessToken,
858
+ projectId,
859
+ appId,
860
+ customToken,
861
+ limitedUse: false
862
+ });
863
+ if (!appCheckResponse?.token) {
864
+ return { data: null, error: new Error("Failed to exchange for App Check token") };
865
+ }
866
+ return {
867
+ data: {
868
+ token: appCheckResponse.token,
869
+ ttl: appCheckResponse.ttl
870
+ },
871
+ error: null
872
+ };
873
+ } catch (error) {
874
+ return { data: null, error };
875
+ }
876
+ }
672
877
  return {
673
878
  getUserData,
674
879
  customForIdAndRefreshToken,
675
880
  createCustomIdAndRefreshToken,
676
- refreshExpiredIdToken
881
+ refreshExpiredIdToken,
882
+ exchangeAppCheckToken
677
883
  };
678
884
  }
679
885
  // Annotate the CommonJS export names for ESM import in node:
@@ -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 const header = decodeProtectedHeader(token);\n const payload = decodeJwt(token);\n\n const tokenParts = (token || '').toString().split('.');\n if (tokenParts.length !== 3) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'Invalid JWT format',\n }),\n ],\n };\n }\n\n const [rawHeader, rawPayload, rawSignature] = tokenParts;\n const signature = base64url.parse(rawSignature, { loose: true });\n\n const data = {\n header,\n payload,\n signature,\n raw: {\n header: rawHeader,\n payload: rawPayload,\n signature: rawSignature,\n text: token,\n },\n } satisfies Jwt;\n\n return { data };\n}\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: '__terncf',\n IdToken: 'TernSecure_[DEFAULT]',\n Refresh: 'TernSecureID_[DEFAULT]',\n Custom: '__custom',\n TernAut: 'tern_aut',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\n\nconst QueryParameters = {\n TernSynced: '__tern_synced',\n SuffixedCookies: 'suffixed_cookies',\n TernRedirectUrl: '__tern_redirect_url',\n // use the reference to Cookies to indicate that it's the same value\n DevBrowser: Cookies.DevBrowser,\n Handshake: Cookies.Handshake,\n HandshakeHelp: '__tern_help',\n LegacyDevBrowser: '__dev_session',\n HandshakeReason: '__tern_hs_reason',\n HandshakeNonce: Cookies.HandshakeNonce,\n} as const;\n\nconst Headers = {\n Accept: 'accept',\n AuthMessage: 'x-ternsecure-auth-message',\n Authorization: 'authorization',\n AuthReason: 'x-ternsecure-auth-reason',\n AuthSignature: 'x-ternsecure-auth-signature',\n AuthStatus: 'x-ternsecure-auth-status',\n AuthToken: 'x-ternsecure-auth-token',\n CacheControl: 'cache-control',\n TernSecureRedirectTo: 'x-ternsecure-redirect-to',\n TernSecureRequestData: 'x-ternsecure-request-data',\n TernSecureUrl: 'x-ternsecure-url',\n CloudFrontForwardedProto: 'cloudfront-forwarded-proto',\n ContentType: 'content-type',\n ContentSecurityPolicy: 'content-security-policy',\n ContentSecurityPolicyReportOnly: 'content-security-policy-report-only',\n EnableDebug: 'x-ternsecure-debug',\n ForwardedHost: 'x-forwarded-host',\n ForwardedPort: 'x-forwarded-port',\n ForwardedProto: 'x-forwarded-proto',\n Host: 'host',\n Location: 'location',\n Nonce: 'x-nonce',\n Origin: 'origin',\n Referrer: 'referer',\n SecFetchDest: 'sec-fetch-dest',\n UserAgent: 'user-agent',\n ReportingEndpoints: 'reporting-endpoints',\n} as const;\n\nconst ContentTypes = {\n Json: 'application/json',\n} as const;\n\n/**\n * @internal\n */\nexport const constants = {\n Attributes,\n Cookies,\n Headers,\n ContentTypes,\n QueryParameters,\n} as const;\n\nexport type Constants = typeof constants;\n","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 auth_time: number;\n idToken: string;\n refreshToken: string;\n customToken: string;\n}\n\ninterface CustomForIdAndRefreshTokenOptions {\n tenantId?: string;\n appCheckToken?: string;\n referer?: string;\n}\n\ninterface FirebaseRefreshTokenResponse {\n kind: string;\n id_token: string;\n refresh_token: string;\n expires_in: string;\n isNewUser: boolean;\n}\n\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 //todo:\n /**\n * For sensitive applications, the auth_time should be checked before issuing the session cookie, minimizing the window of attack in case an ID token is stolen:\n */\n //if (new Date().getTime() / 1000 - data.auth_time < 5 * 60) {\n //proceed\n //}\n\n const customToken = await createCustomToken(data.uid, {\n emailVerified: data.email_verified,\n source_sign_in_provider: data.firebase.sign_in_provider,\n });\n\n const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {\n referer: opts.referer,\n });\n\n const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);\n if (decodedCustomIdToken.errors) {\n throw decodedCustomIdToken.errors[0];\n }\n\n return {\n ...idAndRefreshTokens,\n customToken,\n auth_time: decodedCustomIdToken.data.auth_time,\n };\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAAqC;AAS9B,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACE,SACO,MACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAe,qBACb,KACA,iBACkD;AAClD,MAAI;AACF,UAAM,aAAa,QAAQ,IAAI;AAC/B,UAAM,cAAc,QAAQ,IAAI;AAEhC,QAAI,CAAC,cAAc,CAAC,aAAa;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,aAAO;AAAA,QACL,QAAQ,CAAC,IAAI,iBAAiB,kCAAkC,aAAa,CAAC;AAAA,MAChF;AAAA,IACF;AAEA,QAAI,IAAI,SAAS,KAAK;AACpB,aAAO;AAAA,QACL,QAAQ,CAAC,IAAI,iBAAiB,sCAAsC,cAAc,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,QAAI,iBAAiB;AACnB,iBAAW,SAAS,OAAO,KAAK,eAAe,GAAG;AAChD,YAAI,gBAAgB,SAAS,KAAK,GAAG;AACnC,iBAAO;AAAA,YACL,QAAQ,CAAC,IAAI,iBAAiB,iBAAiB,KAAK,iBAAiB,gBAAgB,CAAC;AAAA,UACxF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY;AAClB,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAExC,UAAM,mBAAmB,UAAM,yBAAY,WAAW,QAAQ,QAAQ,IAAI,GAAG,OAAO;AAEpF,UAAM,UAAsB;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,MAAM;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AAEA,UAAM,MAAM,MAAM,IAAI,oBAAQ,OAAO,EAClC,mBAAmB,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,EAC/C,YAAY,GAAG,EACf,kBAAkB,MAAM,SAAS,EACjC,UAAU,WAAW,EACrB,WAAW,WAAW,EACtB;AAAA,MACC;AAAA,IACF,EACC,KAAK,gBAAgB;AAExB,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,iBAAiB,kCAAkC,OAAO,IAAI,uBAAuB;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,kBACpB,KACA,iBACiB;AACjB,QAAM,EAAE,MAAM,OAAO,IAAI,MAAM,qBAAqB,KAAK,eAAe;AAExE,MAAI,QAAQ;AACV,UAAM,OAAO,CAAC;AAAA,EAChB;AAEA,SAAO;AACT;;;AClIA,IAAAA,eAIO;;;ACUA,IAAM,+BAA+B;AAAA,EAC1C,cAAc;AAAA,EACd,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,+BAA+B;AAAA,EAC/B,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,gBAAgB;AAClB;AAKO,IAAM,yBAAN,MAAM,gCAA+B,MAAM;AAAA,EAChD;AAAA,EACA;AAAA,EAEA,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AAEb,WAAO,eAAe,MAAM,wBAAuB,SAAS;AAE5D,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,iBAAiB;AACtB,WAAO,GAAG,CAAC,KAAK,OAAO,EAAE,OAAO,OAAK,CAAC,EAAE,KAAK,GAAG,CAAC,YAAY,KAAK,MAAM,mBACtE,KAAK,YACP;AAAA,EACF;AACA;;;ACvDK,SAAS,8BAA8B,SAAqB;AACjE,QAAM,iBAAiB;AACvB,iBAAe,MAAM,eAAe;AACpC,SAAO;AACT;;;ACEO,IAAM,YAAY;AAAA,EACvB,MAAM,QAAgB,MAAiC;AACrD,WAAO,MAAM,QAAQ,mBAAmB,IAAI;AAAA,EAC9C;AAAA,EAEA,UAAU,MAAyB,MAAiC;AAClE,WAAO,UAAU,MAAM,mBAAmB,IAAI;AAAA,EAChD;AACF;AAEA,IAAM,oBAA8B;AAAA,EAClC,OAAO;AAAA,EACP,MAAM;AACR;AAiBA,SAAS,MAAM,QAAgB,UAAoB,OAAqB,CAAC,GAAe;AAEtF,MAAI,CAAC,SAAS,OAAO;AACnB,aAAS,QAAQ,CAAC;AAClB,aAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,EAAE,GAAG;AAC9C,eAAS,MAAM,SAAS,MAAM,CAAC,CAAC,IAAI;AAAA,IACtC;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,SAAU,OAAO,SAAS,SAAS,OAAQ,GAAG;AACtD,UAAM,IAAI,YAAY,iBAAiB;AAAA,EACzC;AAGA,MAAI,MAAM,OAAO;AACjB,SAAO,OAAO,MAAM,CAAC,MAAM,KAAK;AAC9B,MAAE;AAGF,QAAI,CAAC,KAAK,SAAS,GAAI,OAAO,SAAS,OAAO,SAAS,OAAQ,IAAI;AACjE,YAAM,IAAI,YAAY,iBAAiB;AAAA,IACzC;AAAA,EACF;AAGA,QAAM,MAAM,KAAK,KAAK,OAAO,YAAc,MAAM,SAAS,OAAQ,IAAK,CAAC;AAGxE,MAAI,OAAO;AACX,MAAI,SAAS;AACb,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG;AAE5B,UAAM,QAAQ,SAAS,MAAM,OAAO,CAAC,CAAC;AACtC,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,YAAY,uBAAuB,OAAO,CAAC,CAAC;AAAA,IACxD;AAGA,aAAU,UAAU,SAAS,OAAQ;AACrC,YAAQ,SAAS;AAGjB,QAAI,QAAQ,GAAG;AACb,cAAQ;AACR,UAAI,SAAS,IAAI,MAAQ,UAAU;AAAA,IACrC;AAAA,EACF;AAGA,MAAI,QAAQ,SAAS,QAAQ,MAAQ,UAAW,IAAI,MAAQ;AAC1D,UAAM,IAAI,YAAY,wBAAwB;AAAA,EAChD;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,MAAyB,UAAoB,OAAyB,CAAC,GAAW;AACnG,QAAM,EAAE,MAAM,KAAK,IAAI;AACvB,QAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,MAAI,MAAM;AAEV,MAAI,OAAO;AACX,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE,GAAG;AAEpC,aAAU,UAAU,IAAM,MAAO,KAAK,CAAC;AACvC,YAAQ;AAGR,WAAO,OAAO,SAAS,MAAM;AAC3B,cAAQ,SAAS;AACjB,aAAO,SAAS,MAAM,OAAQ,UAAU,IAAK;AAAA,IAC/C;AAAA,EACF;AAGA,MAAI,MAAM;AACR,WAAO,SAAS,MAAM,OAAQ,UAAW,SAAS,OAAO,IAAM;AAAA,EACjE;AAGA,MAAI,KAAK;AACP,WAAQ,IAAI,SAAS,SAAS,OAAQ,GAAG;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;ACnIA,IAAAC,eAA+D;AAE/D,eAAsB,UAAU,KAA0B,WAAqC;AAC7F,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,SAAS,UAAM,wBAAU,KAAwC,SAAS;AAChF,QAAI,kBAAkB,YAAY;AAChC,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,KAAK;AAE3B,MAAI,UAAU,SAAS,6BAA6B,GAAG;AACrD,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C;AAEA,MAAI,UAAU,SAAS,4BAA4B,GAAG;AACpD,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C;AAEA,MAAI;AACF,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,uHAAuH,KAAK;AAAA,IAC9H;AAAA,EACF;AACF;;;AC5BA,IAAM,YAAoC;AAAA,EACxC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;AASO,IAAM,OAAO,OAAO,KAAK,SAAS;;;ACGlC,IAAM,kBAAkB,CAAC,QAAkB;AAChD,MAAI,OAAO,QAAQ,aAAa;AAC9B;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,mBAAmB,KAAK,UAAU,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AACF;AAWO,IAAM,iBAAiB,CAAC,QAAiB;AAC9C,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,kEAAkE,KAAK,UAAU,GAAG,CAAC;AAAA,IAChG,CAAC;AAAA,EACH;AACF;AAEO,IAAM,wBAAwB,CAAC,KAAyB,kBAA0B;AACvF,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,uCAAuC,KAAK,UAAU,GAAG,CAAC;AAAA,IACrE,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC;AACvC,QAAM,aAAa,oBAAI,KAAK,CAAC;AAC7B,aAAW,cAAc,GAAG;AAE5B,QAAM,UAAU,WAAW,QAAQ,KAAK,YAAY,QAAQ,IAAI;AAChE,MAAI,SAAS;AACX,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,gCAAgC,WAAW,YAAY,CAAC,mBAAmB,YAAY,YAAY,CAAC;AAAA,IAC/G,CAAC;AAAA,EACH;AACF;AAEO,IAAM,sBAAsB,CAAC,KAAyB,kBAA0B;AACrF,MAAI,OAAO,QAAQ,aAAa;AAC9B;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,0CAA0C,KAAK,UAAU,GAAG,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC;AACvC,QAAM,eAAe,oBAAI,KAAK,CAAC;AAC/B,eAAa,cAAc,GAAG;AAE9B,QAAM,aAAa,aAAa,QAAQ,IAAI,YAAY,QAAQ,IAAI;AACpE,MAAI,YAAY;AACd,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,oEAAoE,aAAa,YAAY,CAAC,mBAAmB,YAAY,YAAY,CAAC;AAAA,IACrJ,CAAC;AAAA,EACH;AACF;;;ANxEA,IAAM,2BAA2B,IAAI;AAQrC,eAAsB,gBACpB,KACA,KAC2C;AAC3C,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,gBAAgB,OAAO,OAAO;AAEpC,MAAI;AACF,UAAM,YAAY,MAAM,UAAU,KAAK,aAAa;AAEpD,UAAM,EAAE,QAAQ,IAAI,UAAM,wBAAU,IAAI,MAAM,SAAS;AAEvD,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAU,MAAgB;AAAA,QAC5B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,cAAc,OAA2D;AACvF,QAAM,aAAS,oCAAsB,KAAK;AAC1C,QAAM,cAAU,wBAAU,KAAK;AAE/B,QAAM,cAAc,SAAS,IAAI,SAAS,EAAE,MAAM,GAAG;AACrD,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,CAAC,WAAW,YAAY,YAAY,IAAI;AAC9C,QAAM,YAAY,UAAU,MAAM,cAAc,EAAE,OAAO,KAAK,CAAC;AAE/D,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,MACH,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,MACX,MAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO,EAAE,KAAK;AAChB;AAEA,eAAsB,UACpB,OACA,SACgE;AAChE,QAAM,EAAE,IAAI,IAAI;AAChB,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,QAAM,EAAE,MAAM,SAAS,OAAO,IAAI,cAAc,KAAK;AACrD,MAAI,QAAQ;AACV,WAAO,EAAE,OAAO;AAAA,EAClB;AAEA,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,MAAI;AACF,oBAAgB,OAAO,GAAG;AAC1B,mBAAe,QAAQ,GAAG;AAC1B,0BAAsB,QAAQ,KAAK,SAAS;AAC5C,wBAAoB,QAAQ,KAAK,SAAS;AAAA,EAC5C,SAAS,OAAO;AACd,WAAO,EAAE,QAAQ,CAAC,KAA+B,EAAE;AAAA,EACrD;AAEA,QAAM,EAAE,MAAM,iBAAiB,QAAQ,gBAAgB,IAAI,MAAM,gBAAgB,SAAS,GAAG;AAC7F,MAAI,iBAAiB;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,8BAA8B,eAAe;AAEpE,SAAO,EAAE,MAAM,eAAe;AAChC;;;AO5HO,IAAM,yBACX;AAIK,IAAM,oCAAoC,IAAI;AAC9C,IAAM,yBAAyB,OAAO;AACtC,IAAM,sBAAsB;AAWnC,IAAM,UAAU;AAAA,EACd,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,gBAAgB;AAClB;AAGA,IAAM,kBAAkB;AAAA,EACtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,iBAAiB;AAAA;AAAA,EAEjB,YAAY,QAAQ;AAAA,EACpB,WAAW,QAAQ;AAAA,EACnB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,gBAAgB,QAAQ;AAC1B;;;AClBA,IAAI,QAA0B,CAAC;AAC/B,IAAI,gBAAgB;AACpB,IAAI,kBAAkB;AAEtB,SAAS,aAAa,KAAa;AACjC,SAAO,MAAM,GAAG;AAClB;AAEA,SAAS,iBAAiB;AACxB,SAAO,OAAO,OAAO,KAAK;AAC5B;AAEA,SAAS,WAAW,KAAa,aAAqB,eAAe,MAAM;AACzE,QAAM,GAAG,IAAI;AACb,kBAAgB,eAAe,KAAK,IAAI,IAAI;AAC9C;AAEA,eAAe,gBAAgB,QAA6C;AAC1E,QAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,uBAAuB;AAAA,MAC/B,SAAS,kCAAkC,IAAI,IAAI,cAAc,SAAS,MAAM;AAAA,MAChF,QAAQ,6BAA6B;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAM,YAAY,aAAa,QAAQ;AAEvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAEA,eAAsB,kBAAkB;AAAA,EACtC,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAA8C;AAC5C,MAAI,iBAAiB,eAAe,KAAK,CAAC,aAAa,GAAG,GAAG;AAC3D,UAAM,EAAE,MAAM,UAAU,IAAI,MAAM,gBAAgB,MAAM;AAExD,QAAI,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAC3C,YAAM,IAAI,uBAAuB;AAAA,QAC/B,SAAS,qBAAqB,MAAM;AAAA,QACpC,QAAQ,6BAA6B;AAAA,MACvC,CAAC;AAAA,IACH;AACA,sBAAkB;AAElB,WAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAOC,KAAI,MAAM;AAC9C,iBAAW,OAAOA,KAAI;AAAA,IACxB,CAAC;AAAA,EACH;AACA,QAAM,OAAO,aAAa,GAAG;AAC7B,MAAI,CAAC,MAAM;AACT,mBAAe;AACf,UAAM,gBAAgB,OAAO,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI;AAEzD,UAAM,IAAI,uBAAuB;AAAA,MAC/B,SAAS,gCAAgC,GAAG,uBAAuB,aAAa;AAAA,MAChF,QAAQ,6BAA6B;AAAA,IACvC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB;AACxB,QAAM,MAAM,KAAK,IAAI;AACrB,MAAI,kBAAkB,IAAI;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM;AACvB,QAAM,cAAc,oCAAoC;AACxD,QAAM,oBAAoB,YAAY;AACtC,QAAM,qBAAqB,OAAO;AAElC,QAAM,YAAY,qBAAqB;AAEvC,MAAI,WAAW;AACb,YAAQ,CAAC;AAAA,EACX;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,KAAe;AACnC,QAAM,qBAAqB,IAAI,QAAQ,IAAI,eAAe;AAC1D,MAAI,CAAC,oBAAoB;AACvB,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AACA,QAAM,cAAc,mBAAmB,MAAM,mBAAmB;AAChE,QAAM,SAAS,cAAc,SAAS,YAAY,CAAC,GAAG,EAAE,IAAI,yBAAyB;AAErF,SAAO,KAAK,IAAI,IAAI,SAAS;AAC/B;;;AC7GA,eAAsB,YACpB,OACA,SACgE;AAChE,QAAM,EAAE,MAAM,eAAe,OAAO,IAAI,cAAc,KAAK;AAE3D,MAAI,QAAQ;AACV,WAAO,EAAE,OAAO;AAAA,EAClB;AAEA,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,EAAE,IAAI,IAAI;AAEhB,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,QAAQ,UAAW,MAAM,kBAAkB,EAAE,GAAG,SAAS,IAAI,CAAC;AAE1E,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI,uBAAuB;AAAA,YACzB,QAAQ,6BAA6B;AAAA,YACrC,SAAS,gCAAgC,GAAG;AAAA,UAC9C,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,SAAS,IAAI,CAAC;AAAA,EACnD,SAAS,OAAO;AACd,QAAI,iBAAiB,wBAAwB;AAC3C,aAAO,EAAE,QAAQ,CAAC,KAAK,EAAE;AAAA,IAC3B;AACA,WAAO;AAAA,MACL,QAAQ,CAAC,KAA+B;AAAA,IAC1C;AAAA,EACF;AACF;;;ACpBA,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AAEtB,SAAS,sBAAyB,MAAkB;AAClD,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,QAAQ,SAAqC;AAC3D,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,iBAAiB,QAAQ,gBAAgB;AAC/C,QAAM,kBAAkB,UAAU;AAElC,iBAAe,YAAY,SAAkB,SAA+C;AAC1F,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AACA,UAAM,WAAW,MAAM,QAAQ,WAAW,SAAS,YAAY,iBAAiB;AAAA,MAC9E;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AAEA,UAAM,aAAa,sBAA0C,SAAS,IAAI;AAC1E,WAAO;AAAA,EACT;AAEA,iBAAe,sBACb,cACA,MACqB;AACrB,QAAI,CAAC,iBAAiB;AACpB,aAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,aAAa,EAAE;AAAA,IACvD;AACA,UAAM,WAAW,MAAM,QAAQ,WAAW,OAAO,aAAa,iBAAiB;AAAA,MAC7E,eAAe;AAAA,MACf,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAED,QAAI,CAAC,UAAU,MAAM;AACnB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI,MAAM,aAAa;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,aAAa,sBAAoD,SAAS,IAAI;AAEpF,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,SAAS,WAAW;AAAA,QACpB,cAAc,WAAW;AAAA,MAC3B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAEA,iBAAe,2BACb,aACA,MAC6B;AAC7B,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AACA,UAAM,WAAW,MAAM,QAAQ,WAAW,OAAO;AAAA,MAC/C;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,mBAAmB;AAAA,MACrB;AAAA,MACA;AAAA,QACE,SAAS,KAAK;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,CAAC,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAEA,UAAM,aAAa,sBAAmD,SAAS,IAAI;AAEnF,WAAO;AAAA,MACL,SAAS,WAAW;AAAA,MACpB,cAAc,WAAW;AAAA,IAC3B;AAAA,EACF;AAEA,iBAAe,8BACb,SACA,MACuB;AACvB,UAAM,UAAU,MAAM,YAAY,SAAS,OAAO;AAClD,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,QAAI,QAAQ;AACV,YAAM,OAAO,CAAC;AAAA,IAChB;AAUA,UAAM,cAAc,MAAM,kBAAkB,KAAK,KAAK;AAAA,MACpD,eAAe,KAAK;AAAA,MACpB,yBAAyB,KAAK,SAAS;AAAA,IACzC,CAAC;AAED,UAAM,qBAAqB,MAAM,2BAA2B,aAAa;AAAA,MACvE,SAAS,KAAK;AAAA,IAChB,CAAC;AAED,UAAM,uBAAuB,MAAM,YAAY,mBAAmB,SAAS,OAAO;AAClF,QAAI,qBAAqB,QAAQ;AAC/B,YAAM,qBAAqB,OAAO,CAAC;AAAA,IACrC;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,WAAW,qBAAqB,KAAK;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","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/jwt/guardReturn.ts","../../src/jwt/jwt.ts","../../src/jwt/signJwt.ts","../../src/jwt/index.ts","../../src/auth/constants.ts","../../src/auth/utils.ts","../../src/auth/credential.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 } satisfies Jwt;\n\n return { data };\n } catch (error) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `${(error as Error).message || 'Invalid Token or Protected Header formatting'} (Token length: ${token?.length}, First 10 chars: ${token?.substring(0, 10)}...)`,\n }),\n ],\n };\n }\n}\n\nexport async function verifyJwt(\n token: string,\n options: VerifyJwtOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { key } = options;\n const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;\n\n const { data: decoded, errors } = ternDecodeJwt(token);\n if (errors) {\n return { errors };\n }\n\n const { header, payload } = decoded;\n\n try {\n verifyHeaderKid(header.kid);\n verifySubClaim(payload.sub);\n verifyExpirationClaim(payload.exp, clockSkew);\n verifyIssuedAtClaim(payload.iat, clockSkew);\n } catch (error) {\n return { errors: [error as TokenVerificationError] };\n }\n\n const { data: verifiedPayload, errors: signatureErrors } = await verifySignature(decoded, key);\n if (signatureErrors) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalidSignature,\n message: 'Token signature verification failed.',\n }),\n ],\n };\n }\n\n const decodedIdToken = mapJwtPayloadToDecodedIdToken(verifiedPayload);\n\n return { data: decodedIdToken };\n}\n","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: '__terncf',\n IdToken: 'TernSecure_[DEFAULT]',\n Refresh: 'TernSecureID_[DEFAULT]',\n Custom: '__custom',\n TernAut: 'tern_aut',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\n\nconst QueryParameters = {\n TernSynced: '__tern_synced',\n SuffixedCookies: 'suffixed_cookies',\n TernRedirectUrl: '__tern_redirect_url',\n // use the reference to Cookies to indicate that it's the same value\n DevBrowser: Cookies.DevBrowser,\n Handshake: Cookies.Handshake,\n HandshakeHelp: '__tern_help',\n LegacyDevBrowser: '__dev_session',\n HandshakeReason: '__tern_hs_reason',\n HandshakeNonce: Cookies.HandshakeNonce,\n} as const;\n\nconst Headers = {\n Accept: 'accept',\n AppCheckToken: 'x-firebase-appcheck',\n AuthMessage: 'x-ternsecure-auth-message',\n Authorization: 'authorization',\n AuthReason: 'x-ternsecure-auth-reason',\n AuthSignature: 'x-ternsecure-auth-signature',\n AuthStatus: 'x-ternsecure-auth-status',\n AuthToken: 'x-ternsecure-auth-token',\n CacheControl: 'cache-control',\n TernSecureRedirectTo: 'x-ternsecure-redirect-to',\n TernSecureRequestData: 'x-ternsecure-request-data',\n TernSecureUrl: 'x-ternsecure-url',\n CloudFrontForwardedProto: 'cloudfront-forwarded-proto',\n ContentType: 'content-type',\n ContentSecurityPolicy: 'content-security-policy',\n ContentSecurityPolicyReportOnly: 'content-security-policy-report-only',\n EnableDebug: 'x-ternsecure-debug',\n ForwardedHost: 'x-forwarded-host',\n ForwardedPort: 'x-forwarded-port',\n ForwardedProto: 'x-forwarded-proto',\n Host: 'host',\n Location: 'location',\n Nonce: 'x-nonce',\n Origin: 'origin',\n Referrer: 'referer',\n SecFetchDest: 'sec-fetch-dest',\n UserAgent: 'user-agent',\n ReportingEndpoints: 'reporting-endpoints',\n} as const;\n\nconst ContentTypes = {\n Json: 'application/json',\n} as const;\n\n/**\n * @internal\n */\nexport const constants = {\n Attributes,\n Cookies,\n Headers,\n ContentTypes,\n QueryParameters,\n} as const;\n\nexport type Constants = typeof constants;\n","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, TernSecureAdminConfig, TernSecureConfig, TernSecureUserData} from '@tern-secure/types';\n\nimport type { JwtReturnType } from '../jwt/types';\nimport { ternDecodeJwt, verifyJwt, type VerifyJwtOptions } from '../jwt/verifyJwt';\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\nimport type { LoadJWKFromRemoteOptions } from './keys';\nimport { loadJWKFromRemote } from './keys';\n\nexport type VerifyTokenVOptions = Omit<VerifyJwtOptions, 'key'> & Omit<LoadJWKFromRemoteOptions, 'kid'> & {\n jwtKey?: string;\n};\n\nexport { TernSecureConfig, TernSecureAdminConfig, TernSecureUserData };\n\nexport async function verifyToken(\n token: string,\n options: VerifyTokenVOptions,\n): Promise<JwtReturnType<DecodedIdToken, TokenVerificationError>> {\n const { data: decodedResult, errors } = ternDecodeJwt(token);\n\n if (errors) {\n return { errors };\n }\n\n const { header } = decodedResult;\n const { kid } = header;\n\n if (!kid) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: 'JWT \"kid\" header is missing.',\n }),\n ],\n };\n }\n\n try {\n const key = options.jwtKey || (await loadJWKFromRemote({ ...options, kid }));\n\n if (!key) {\n return {\n errors: [\n new TokenVerificationError({\n reason: TokenVerificationErrorReason.TokenInvalid,\n message: `No public key found for kid \"${kid}\".`,\n }),\n ],\n };\n }\n return await verifyJwt(token, { ...options, key });\n } catch (error) {\n if (error instanceof TokenVerificationError) {\n return { errors: [error] };\n }\n return {\n errors: [error as TokenVerificationError],\n };\n }\n}\n","import { type JwtReturnType } from \"./types\";\n\nexport function createJwtGuard<T extends (...args: any[]) => JwtReturnType<any, any>>(decodedFn: T) {\n return (...args: Parameters<T>): NonNullable<Awaited<ReturnType<T>>['data']> | never => {\n const { data, errors } = decodedFn(...args);\n\n if (errors) {\n throw errors[0];\n }\n\n return data;\n };\n}\n","import type {\n DecodedIdToken,\n TernVerificationResult,\n} from \"@tern-secure/types\";\nimport { createRemoteJWKSet, decodeJwt,jwtVerify } from \"jose\";\n\n\nexport type FirebaseIdTokenPayload = DecodedIdToken;\n\n// Firebase public key endpoints\nconst FIREBASE_ID_TOKEN_URL =\n \"https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com\";\nconst FIREBASE_SESSION_CERT_URL =\n \"https://identitytoolkit.googleapis.com/v1/sessionCookiePublicKeys\";\n\n//const FIREBASE_NEW_SESSION_PK = \"https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys\"\n\n// Simple in-memory cache for JWKS\nlet idTokenJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\nlet sessionJWKS: ReturnType<typeof createRemoteJWKSet> | null = null;\n\nconst getIdTokenJWKS = () => {\n if (!idTokenJWKS) {\n idTokenJWKS = createRemoteJWKSet(new URL(FIREBASE_ID_TOKEN_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return idTokenJWKS;\n};\n\nconst getSessionJWKS = () => {\n if (!sessionJWKS) {\n sessionJWKS = createRemoteJWKSet(new URL(FIREBASE_SESSION_CERT_URL), {\n cacheMaxAge: 3600000, // 1 hour\n timeoutDuration: 5000, // 5 seconds\n cooldownDuration: 30000, // 30 seconds between retries\n });\n }\n return sessionJWKS;\n};\n\n\n\nexport async function verifyToken(\n token: string,\n isSessionCookie = false\n): Promise<TernVerificationResult> {\n try {\n const projectId = process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;\n if (!projectId) {\n throw new Error(\"Firebase Project ID is not configured\");\n }\n\n const { decoded } = decodeJwt(token);\n if (!decoded) {\n throw new Error(\"Invalid token format\");\n }\n\n let retries = 3;\n let lastError: Error | null = null;\n\n while (retries > 0) {\n try {\n // Use different JWKS based on token type\n const JWKS = isSessionCookie ? getSessionJWKS() : getIdTokenJWKS();\n\n const { payload } = await jwtVerify(token, JWKS, {\n issuer: isSessionCookie\n ? \"https://session.firebase.google.com/\" + projectId\n : \"https://securetoken.google.com/\" + projectId,\n audience: projectId,\n algorithms: [\"RS256\"],\n });\n\n const firebasePayload = payload as unknown as FirebaseIdTokenPayload;\n const now = Math.floor(Date.now() / 1000);\n\n // Verify token claims\n if (firebasePayload.exp <= now) {\n throw new Error(\"Token has expired\");\n }\n\n if (firebasePayload.iat > now) {\n throw new Error(\"Token issued time is in the future\");\n }\n\n if (!firebasePayload.sub) {\n throw new Error(\"Token subject is empty\");\n }\n\n if (firebasePayload.auth_time > now) {\n throw new Error(\"Token auth time is in the future\");\n }\n\n return {\n valid: true,\n uid: firebasePayload.sub,\n sub: firebasePayload.sub,\n email: firebasePayload.email,\n email_verified: firebasePayload.email_verified,\n auth_time: firebasePayload.auth_time,\n iat: firebasePayload.iat,\n exp: firebasePayload.exp,\n aud: firebasePayload.aud,\n iss: firebasePayload.iss,\n firebase: firebasePayload.firebase,\n phone_number: firebasePayload.phone_number,\n picture: firebasePayload.picture,\n };\n } catch (error) {\n lastError = error as Error;\n if (error instanceof Error && error.name === \"JWKSNoMatchingKey\") {\n console.warn(`JWKS retry attempt ${4 - retries}:`, error.message);\n retries--;\n if (retries > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n continue;\n }\n }\n throw error;\n }\n }\n\n throw lastError || new Error(\"Failed to verify token after retries\");\n } catch (error) {\n console.error(\"Token verification details:\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n decoded: decodeJwt(token),\n isSessionCookie,\n });\n\n return {\n valid: false,\n error: {\n success: false,\n message: error instanceof Error ? error.message : \"Invalid token\",\n code: \"INVALID_TOKEN\",\n },\n };\n }\n}\n","import type { JWTPayload } from '@tern-secure/types';\nimport type { KeyLike } from 'jose';\nimport { importPKCS8, SignJWT } from 'jose';\n\nimport { TokenVerificationError, TokenVerificationErrorReason } from '../utils/errors';\n\nexport interface SignJwtOptions {\n algorithm?: string;\n header?: Record<string, unknown>;\n}\n\nexport const ALGORITHM_RS256 = 'RS256' as const;\n\n\nexport type SignOptions = {\n readonly payload: JWTPayload;\n readonly privateKey: string;\n readonly keyId?: string;\n};\n\n\nexport async function ternSignJwt(opts: SignOptions): Promise<string> {\n const { payload, privateKey, keyId } = opts;\n let key: KeyLike;\n\n try {\n key = await importPKCS8(privateKey, ALGORITHM_RS256);\n } catch (error) {\n throw new TokenVerificationError({\n message: `Failed to import private key: ${(error as Error).message}`,\n reason: TokenVerificationErrorReason.TokenInvalid,\n });\n }\n\n return new SignJWT(payload)\n .setProtectedHeader({ alg: ALGORITHM_RS256, kid: keyId })\n .sign(key);\n}\n","import { createJwtGuard } from './guardReturn';\nimport { ternDecodeJwt as _ternDecodeJwt } from './verifyJwt';\n\nexport const ternDecodeJwt = createJwtGuard(_ternDecodeJwt);\nexport { ternDecodeJwt as ternDecodeJwtUnguarded } from './verifyJwt';\n\nexport * from './jwt';\nexport * from './customJwt';\nexport * from './signJwt';\nexport type { JwtReturnType } from './types';","export const TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1000;\nexport const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token';\nexport const GOOGLE_AUTH_TOKEN_HOST = 'accounts.google.com';\nexport const GOOGLE_AUTH_TOKEN_PATH = '/o/oauth2/token';\nexport const ONE_HOUR_IN_SECONDS = 60 * 60;","async function getDetailFromResponse(response: Response): Promise<string> {\n const json = await response.json();\n\n if (!json) {\n return 'Missing error payload';\n }\n\n let detail =\n typeof json.error === 'string'\n ? json.error\n : (json.error?.message ?? 'Missing error payload');\n\n if (json.error_description) {\n detail += ' (' + json.error_description + ')';\n }\n\n return detail;\n}\n\nexport async function fetchJson(url: string, init: RequestInit) {\n return (await fetchAny(url, init)).json();\n}\n\nexport async function fetchAny(url: string, init: RequestInit) {\n const response = await fetch(url, init);\n\n if (!response.ok) {\n throw new Error(await getDetailFromResponse(response));\n }\n\n return response;\n}","import type { JWTPayload } from '@tern-secure/types';\n\nimport { ternSignJwt } from '../jwt';\nimport {\n GOOGLE_AUTH_TOKEN_HOST,\n GOOGLE_AUTH_TOKEN_PATH,\n GOOGLE_TOKEN_AUDIENCE,\n ONE_HOUR_IN_SECONDS,\n TOKEN_EXPIRY_THRESHOLD_MILLIS\n} from './constants'\nimport { fetchJson } from './utils';\n\n\nexport interface GoogleOAuthAccessToken {\n access_token: string;\n expires_in: number;\n}\n\nexport interface ServiceAccount {\n projectId: string;\n privateKey: string;\n clientEmail: string;\n}\n\nexport interface FirebaseAccessToken {\n accessToken: string;\n expirationTime: number;\n}\n\nconst accessTokenCache: Map<string, FirebaseAccessToken> = new Map();\n\nexport interface ServiceAccountCredential {\n getAccessToken: (refresh?: boolean) => Promise<FirebaseAccessToken>;\n}\n\nasync function requestAccessToken(urlString: string, init: RequestInit): Promise<FirebaseAccessToken> {\n const json = await fetchJson(urlString, init);\n\n if (!json.access_token || !json.expires_in) {\n throw new Error('Invalid access token response');\n }\n\n return {\n accessToken: json.access_token,\n expirationTime: Date.now() + (json.expires_in * 1000),\n }\n}\n\nexport class ServiceAccountTokenManager implements ServiceAccountCredential {\n private readonly projectId: string;\n private readonly privateKey: string;\n private readonly clientEmail: string;\n\n constructor(serviceAccount: ServiceAccount) {\n this.projectId = serviceAccount.projectId;\n this.privateKey = serviceAccount.privateKey;\n this.clientEmail = serviceAccount.clientEmail;\n }\n\n private fetchAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const token = await this.createJwt();\n const postData =\n 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3A' +\n 'grant-type%3Ajwt-bearer&assertion=' +\n token;\n\n return requestAccessToken(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n body: postData,\n })\n }\n\n private fetchAndCacheAccessToken = async (url: string): Promise<FirebaseAccessToken> => {\n const accessToken = await this.fetchAccessToken(url);\n accessTokenCache.set(this.projectId, accessToken);\n return accessToken;\n }\n\n public getAccessToken = async (refresh?: boolean): Promise<FirebaseAccessToken> => {\n const url = `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`;\n\n if (refresh) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n const cachedResponse = accessTokenCache.get(this.projectId);\n\n if (!cachedResponse || cachedResponse.expirationTime - Date.now() <= TOKEN_EXPIRY_THRESHOLD_MILLIS) {\n return this.fetchAndCacheAccessToken(url);\n }\n\n return cachedResponse;\n }\n\n private createJwt = async (): Promise<string> => {\n const iat = Math.floor(Date.now() / 1000);\n\n const payload = {\n aud: GOOGLE_TOKEN_AUDIENCE,\n iat,\n exp: iat + ONE_HOUR_IN_SECONDS,\n iss: this.clientEmail,\n sub: this.clientEmail,\n scope: [\n 'https://www.googleapis.com/auth/cloud-platform',\n 'https://www.googleapis.com/auth/firebase.database',\n 'https://www.googleapis.com/auth/firebase.messaging',\n 'https://www.googleapis.com/auth/identitytoolkit',\n 'https://www.googleapis.com/auth/userinfo.email'\n ].join(' ')\n } as JWTPayload;\n\n return ternSignJwt({\n payload,\n privateKey: this.privateKey,\n });\n }\n}\n","import { createCustomToken } from '../jwt/customJwt';\nimport type { AuthenticateRequestOptions, TernSecureUserData } from '../tokens/types';\nimport { verifyToken } from '../tokens/verify';\nimport { ServiceAccountTokenManager } from './credential';\n\nexport interface IdAndRefreshTokens {\n idToken: string;\n refreshToken: string;\n}\n\nexport interface CustomTokens {\n auth_time: number;\n idToken: string;\n refreshToken: string;\n customToken: string;\n}\n\ninterface CustomForIdAndRefreshTokenOptions {\n tenantId?: string;\n appCheckToken?: string;\n referer?: string;\n}\n\ninterface FirebaseRefreshTokenResponse {\n kind: string;\n id_token: string;\n refresh_token: string;\n expires_in: string;\n isNewUser: boolean;\n}\n\ntype AuthResult<T = any> = { data: T; error: null } | { data: null; error: any };\n\nconst API_KEY_ERROR = 'API Key is required';\nconst NO_DATA_ERROR = 'No token data received';\n\nfunction parseFirebaseResponse<T>(data: unknown): T {\n if (typeof data === 'string') {\n try {\n return JSON.parse(data) as T;\n } catch (error) {\n throw new Error(`Failed to parse Firebase response: ${error}`);\n }\n }\n return data as T;\n}\n\nexport function getAuth(options: AuthenticateRequestOptions) {\n const { apiKey, firebaseAdminConfig } = options;\n const firebaseApiKey = options.firebaseConfig?.apiKey;\n const effectiveApiKey = apiKey || firebaseApiKey;\n\n let credential: ServiceAccountTokenManager | null = null;\n if (\n firebaseAdminConfig?.projectId &&\n firebaseAdminConfig?.privateKey &&\n firebaseAdminConfig?.clientEmail\n ) {\n credential = new ServiceAccountTokenManager({\n projectId: firebaseAdminConfig.projectId,\n privateKey: firebaseAdminConfig.privateKey,\n clientEmail: firebaseAdminConfig.clientEmail,\n });\n }\n\n async function getUserData(idToken?: string, localId?: string): Promise<TernSecureUserData> {\n if (!effectiveApiKey) {\n throw new Error(API_KEY_ERROR);\n }\n const response = await options.apiClient?.userData.getUserData(effectiveApiKey, {\n idToken,\n localId,\n });\n\n if (!response?.data) {\n throw new Error(NO_DATA_ERROR);\n }\n\n const parsedData = parseFirebaseResponse<TernSecureUserData>(response.data);\n return parsedData;\n }\n\n async function refreshExpiredIdToken(\n refreshToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<AuthResult> {\n if (!effectiveApiKey) {\n return { data: null, error: new Error(API_KEY_ERROR) };\n }\n const response = await options.apiClient?.tokens.refreshToken(effectiveApiKey, {\n refresh_token: refreshToken,\n request_origin: opts.referer,\n });\n\n if (!response?.data) {\n return {\n data: null,\n error: new Error(NO_DATA_ERROR),\n };\n }\n\n const parsedData = parseFirebaseResponse<FirebaseRefreshTokenResponse>(response.data);\n\n return {\n data: {\n idToken: parsedData.id_token,\n refreshToken: parsedData.refresh_token,\n },\n error: null,\n };\n }\n\n async function customForIdAndRefreshToken(\n customToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<IdAndRefreshTokens> {\n if (!effectiveApiKey) {\n throw new Error('API Key is required to create custom token');\n }\n const data = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(\n effectiveApiKey,\n {\n token: customToken,\n returnSecureToken: true,\n },\n {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n },\n );\n\n if (!data) {\n throw new Error('No data received from Firebase token exchange');\n }\n\n return {\n idToken: data.idToken,\n refreshToken: data.refreshToken,\n };\n }\n\n async function createCustomIdAndRefreshToken(\n idToken: string,\n opts: CustomForIdAndRefreshTokenOptions,\n ): Promise<CustomTokens> {\n const decoded = await verifyToken(idToken, options);\n const { data, errors } = decoded;\n if (errors) {\n throw errors[0];\n }\n\n //todo:\n /**\n * For sensitive applications, the auth_time should be checked before issuing the session cookie, minimizing the window of attack in case an ID token is stolen:\n */\n //if (new Date().getTime() / 1000 - data.auth_time < 5 * 60) {\n //proceed\n //}\n\n const customToken = await createCustomToken(data.uid, {\n emailVerified: data.email_verified,\n source_sign_in_provider: data.firebase.sign_in_provider,\n });\n\n const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {\n referer: opts.referer,\n appCheckToken: opts.appCheckToken,\n });\n\n const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);\n if (decodedCustomIdToken.errors) {\n throw decodedCustomIdToken.errors[0];\n }\n\n return {\n ...idAndRefreshTokens,\n customToken,\n auth_time: decodedCustomIdToken.data.auth_time,\n };\n }\n\n async function exchangeAppCheckToken(idToken: string): Promise<AuthResult> {\n if (!credential) {\n return {\n data: null,\n error: new Error(\n 'Firebase Admin config must be provided to exchange App Check tokens.',\n ),\n };\n }\n if (!effectiveApiKey) {\n return { data: null, error: new Error(API_KEY_ERROR) };\n }\n\n try {\n const decoded = await verifyToken(idToken, options);\n if (decoded.errors) {\n return { data: null, error: decoded.errors[0] };\n }\n\n const customToken = await createCustomToken(decoded.data.uid, {\n emailVerified: decoded.data.email_verified,\n source_sign_in_provider: decoded.data.firebase.sign_in_provider,\n });\n\n const projectId = options.firebaseConfig?.projectId;\n const appId = options.firebaseConfig?.appId;\n\n if (!projectId || !appId) {\n return { data: null, error: new Error('Project ID and App ID are required for App Check') };\n }\n\n const { accessToken } = await credential.getAccessToken();\n\n const appCheckResponse = await options.apiClient?.appCheck.exchangeCustomToken({\n accessToken,\n projectId,\n appId,\n customToken,\n limitedUse: false,\n });\n\n if (!appCheckResponse?.token) {\n return { data: null, error: new Error('Failed to exchange for App Check token') };\n }\n\n return {\n data: {\n token: appCheckResponse.token,\n ttl: appCheckResponse.ttl\n },\n error: null,\n };\n } catch (error) {\n return { data: null, error };\n }\n }\n\n return {\n getUserData,\n customForIdAndRefreshToken,\n createCustomIdAndRefreshToken,\n refreshExpiredIdToken,\n exchangeAppCheckToken,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAAqC;AAS9B,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACE,SACO,MACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAe,qBACb,KACA,iBACkD;AAClD,MAAI;AACF,UAAM,aAAa,QAAQ,IAAI;AAC/B,UAAM,cAAc,QAAQ,IAAI;AAEhC,QAAI,CAAC,cAAc,CAAC,aAAa;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,aAAO;AAAA,QACL,QAAQ,CAAC,IAAI,iBAAiB,kCAAkC,aAAa,CAAC;AAAA,MAChF;AAAA,IACF;AAEA,QAAI,IAAI,SAAS,KAAK;AACpB,aAAO;AAAA,QACL,QAAQ,CAAC,IAAI,iBAAiB,sCAAsC,cAAc,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,QAAI,iBAAiB;AACnB,iBAAW,SAAS,OAAO,KAAK,eAAe,GAAG;AAChD,YAAI,gBAAgB,SAAS,KAAK,GAAG;AACnC,iBAAO;AAAA,YACL,QAAQ,CAAC,IAAI,iBAAiB,iBAAiB,KAAK,iBAAiB,gBAAgB,CAAC;AAAA,UACxF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY;AAClB,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAExC,UAAM,mBAAmB,UAAM,yBAAY,WAAW,QAAQ,QAAQ,IAAI,GAAG,OAAO;AAEpF,UAAM,UAAsB;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,MAAM;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AAEA,UAAM,MAAM,MAAM,IAAI,oBAAQ,OAAO,EAClC,mBAAmB,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,EAC/C,YAAY,GAAG,EACf,kBAAkB,MAAM,SAAS,EACjC,UAAU,WAAW,EACrB,WAAW,WAAW,EACtB;AAAA,MACC;AAAA,IACF,EACC,KAAK,gBAAgB;AAExB,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,iBAAiB,kCAAkC,OAAO,IAAI,uBAAuB;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,kBACpB,KACA,iBACiB;AACjB,QAAM,EAAE,MAAM,OAAO,IAAI,MAAM,qBAAqB,KAAK,eAAe;AAExE,MAAI,QAAQ;AACV,UAAM,OAAO,CAAC;AAAA,EAChB;AAEA,SAAO;AACT;;;AClIA,IAAAA,eAIO;;;ACUA,IAAM,+BAA+B;AAAA,EAC1C,cAAc;AAAA,EACd,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,+BAA+B;AAAA,EAC/B,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,gBAAgB;AAClB;AAKO,IAAM,yBAAN,MAAM,gCAA+B,MAAM;AAAA,EAChD;AAAA,EACA;AAAA,EAEA,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AAEb,WAAO,eAAe,MAAM,wBAAuB,SAAS;AAE5D,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,iBAAiB;AACtB,WAAO,GAAG,CAAC,KAAK,OAAO,EAAE,OAAO,OAAK,CAAC,EAAE,KAAK,GAAG,CAAC,YAAY,KAAK,MAAM,mBACtE,KAAK,YACP;AAAA,EACF;AACA;;;ACvDK,SAAS,8BAA8B,SAAqB;AACjE,QAAM,iBAAiB;AACvB,iBAAe,MAAM,eAAe;AACpC,SAAO;AACT;;;ACEO,IAAM,YAAY;AAAA,EACvB,MAAM,QAAgB,MAAiC;AACrD,WAAO,MAAM,QAAQ,mBAAmB,IAAI;AAAA,EAC9C;AAAA,EAEA,UAAU,MAAyB,MAAiC;AAClE,WAAO,UAAU,MAAM,mBAAmB,IAAI;AAAA,EAChD;AACF;AAEA,IAAM,oBAA8B;AAAA,EAClC,OAAO;AAAA,EACP,MAAM;AACR;AAiBA,SAAS,MAAM,QAAgB,UAAoB,OAAqB,CAAC,GAAe;AAEtF,MAAI,CAAC,SAAS,OAAO;AACnB,aAAS,QAAQ,CAAC;AAClB,aAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,EAAE,GAAG;AAC9C,eAAS,MAAM,SAAS,MAAM,CAAC,CAAC,IAAI;AAAA,IACtC;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,SAAU,OAAO,SAAS,SAAS,OAAQ,GAAG;AACtD,UAAM,IAAI,YAAY,iBAAiB;AAAA,EACzC;AAGA,MAAI,MAAM,OAAO;AACjB,SAAO,OAAO,MAAM,CAAC,MAAM,KAAK;AAC9B,MAAE;AAGF,QAAI,CAAC,KAAK,SAAS,GAAI,OAAO,SAAS,OAAO,SAAS,OAAQ,IAAI;AACjE,YAAM,IAAI,YAAY,iBAAiB;AAAA,IACzC;AAAA,EACF;AAGA,QAAM,MAAM,KAAK,KAAK,OAAO,YAAc,MAAM,SAAS,OAAQ,IAAK,CAAC;AAGxE,MAAI,OAAO;AACX,MAAI,SAAS;AACb,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG;AAE5B,UAAM,QAAQ,SAAS,MAAM,OAAO,CAAC,CAAC;AACtC,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,YAAY,uBAAuB,OAAO,CAAC,CAAC;AAAA,IACxD;AAGA,aAAU,UAAU,SAAS,OAAQ;AACrC,YAAQ,SAAS;AAGjB,QAAI,QAAQ,GAAG;AACb,cAAQ;AACR,UAAI,SAAS,IAAI,MAAQ,UAAU;AAAA,IACrC;AAAA,EACF;AAGA,MAAI,QAAQ,SAAS,QAAQ,MAAQ,UAAW,IAAI,MAAQ;AAC1D,UAAM,IAAI,YAAY,wBAAwB;AAAA,EAChD;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,MAAyB,UAAoB,OAAyB,CAAC,GAAW;AACnG,QAAM,EAAE,MAAM,KAAK,IAAI;AACvB,QAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,MAAI,MAAM;AAEV,MAAI,OAAO;AACX,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE,GAAG;AAEpC,aAAU,UAAU,IAAM,MAAO,KAAK,CAAC;AACvC,YAAQ;AAGR,WAAO,OAAO,SAAS,MAAM;AAC3B,cAAQ,SAAS;AACjB,aAAO,SAAS,MAAM,OAAQ,UAAU,IAAK;AAAA,IAC/C;AAAA,EACF;AAGA,MAAI,MAAM;AACR,WAAO,SAAS,MAAM,OAAQ,UAAW,SAAS,OAAO,IAAM;AAAA,EACjE;AAGA,MAAI,KAAK;AACP,WAAQ,IAAI,SAAS,SAAS,OAAQ,GAAG;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;ACnIA,IAAAC,eAA+D;AAE/D,eAAsB,UAAU,KAA0B,WAAqC;AAC7F,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,SAAS,UAAM,wBAAU,KAAwC,SAAS;AAChF,QAAI,kBAAkB,YAAY;AAChC,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,KAAK;AAE3B,MAAI,UAAU,SAAS,6BAA6B,GAAG;AACrD,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C;AAEA,MAAI,UAAU,SAAS,4BAA4B,GAAG;AACpD,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C;AAEA,MAAI;AACF,WAAO,UAAM,yBAAW,WAAW,SAAS;AAAA,EAC9C,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,uHAAuH,KAAK;AAAA,IAC9H;AAAA,EACF;AACF;;;AC5BA,IAAM,YAAoC;AAAA,EACxC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;AASO,IAAM,OAAO,OAAO,KAAK,SAAS;;;ACGlC,IAAM,kBAAkB,CAAC,QAAkB;AAChD,MAAI,OAAO,QAAQ,aAAa;AAC9B;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,mBAAmB,KAAK,UAAU,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AACF;AAWO,IAAM,iBAAiB,CAAC,QAAiB;AAC9C,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,kEAAkE,KAAK,UAAU,GAAG,CAAC;AAAA,IAChG,CAAC;AAAA,EACH;AACF;AAEO,IAAM,wBAAwB,CAAC,KAAyB,kBAA0B;AACvF,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,uCAAuC,KAAK,UAAU,GAAG,CAAC;AAAA,IACrE,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC;AACvC,QAAM,aAAa,oBAAI,KAAK,CAAC;AAC7B,aAAW,cAAc,GAAG;AAE5B,QAAM,UAAU,WAAW,QAAQ,KAAK,YAAY,QAAQ,IAAI;AAChE,MAAI,SAAS;AACX,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,gCAAgC,WAAW,YAAY,CAAC,mBAAmB,YAAY,YAAY,CAAC;AAAA,IAC/G,CAAC;AAAA,EACH;AACF;AAEO,IAAM,sBAAsB,CAAC,KAAyB,kBAA0B;AACrF,MAAI,OAAO,QAAQ,aAAa;AAC9B;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,0CAA0C,KAAK,UAAU,GAAG,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC;AACvC,QAAM,eAAe,oBAAI,KAAK,CAAC;AAC/B,eAAa,cAAc,GAAG;AAE9B,QAAM,aAAa,aAAa,QAAQ,IAAI,YAAY,QAAQ,IAAI;AACpE,MAAI,YAAY;AACd,UAAM,IAAI,uBAAuB;AAAA,MAC/B,QAAQ,6BAA6B;AAAA,MACrC,SAAS,oEAAoE,aAAa,YAAY,CAAC,mBAAmB,YAAY,YAAY,CAAC;AAAA,IACrJ,CAAC;AAAA,EACH;AACF;;;ANxEA,IAAM,2BAA2B,IAAI;AAQrC,eAAsB,gBACpB,KACA,KAC2C;AAC3C,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,gBAAgB,OAAO,OAAO;AAEpC,MAAI;AACF,UAAM,YAAY,MAAM,UAAU,KAAK,aAAa;AAEpD,UAAM,EAAE,QAAQ,IAAI,UAAM,wBAAU,IAAI,MAAM,SAAS;AAEvD,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAU,MAAgB;AAAA,QAC5B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,cAAc,OAA2D;AACvF,MAAI;AACF,UAAM,aAAS,oCAAsB,KAAK;AAC1C,UAAM,cAAU,wBAAU,KAAK;AAE/B,UAAM,cAAc,SAAS,IAAI,SAAS,EAAE,MAAM,GAAG;AACrD,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI,uBAAuB;AAAA,YACzB,QAAQ,6BAA6B;AAAA,YACrC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,CAAC,WAAW,YAAY,YAAY,IAAI;AAC9C,UAAM,YAAY,UAAU,MAAM,cAAc,EAAE,OAAO,KAAK,CAAC;AAE/D,UAAM,OAAO;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,QACH,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAM;AAAA,MACR;AAAA,IACF;AAEA,WAAO,EAAE,KAAK;AAAA,EAChB,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS,GAAI,MAAgB,WAAW,8CAA8C,mBAAmB,OAAO,MAAM,qBAAqB,OAAO,UAAU,GAAG,EAAE,CAAC;AAAA,QACpK,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,UACpB,OACA,SACgE;AAChE,QAAM,EAAE,IAAI,IAAI;AAChB,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,QAAM,EAAE,MAAM,SAAS,OAAO,IAAI,cAAc,KAAK;AACrD,MAAI,QAAQ;AACV,WAAO,EAAE,OAAO;AAAA,EAClB;AAEA,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,MAAI;AACF,oBAAgB,OAAO,GAAG;AAC1B,mBAAe,QAAQ,GAAG;AAC1B,0BAAsB,QAAQ,KAAK,SAAS;AAC5C,wBAAoB,QAAQ,KAAK,SAAS;AAAA,EAC5C,SAAS,OAAO;AACd,WAAO,EAAE,QAAQ,CAAC,KAA+B,EAAE;AAAA,EACrD;AAEA,QAAM,EAAE,MAAM,iBAAiB,QAAQ,gBAAgB,IAAI,MAAM,gBAAgB,SAAS,GAAG;AAC7F,MAAI,iBAAiB;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,8BAA8B,eAAe;AAEpE,SAAO,EAAE,MAAM,eAAe;AAChC;;;AOvIO,IAAM,yBACX;AAIK,IAAM,oCAAoC,IAAI;AAC9C,IAAM,yBAAyB,OAAO;AACtC,IAAM,sBAAsB;AAWnC,IAAM,UAAU;AAAA,EACd,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,gBAAgB;AAClB;AAGA,IAAM,kBAAkB;AAAA,EACtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,iBAAiB;AAAA;AAAA,EAEjB,YAAY,QAAQ;AAAA,EACpB,WAAW,QAAQ;AAAA,EACnB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,gBAAgB,QAAQ;AAC1B;;;AClBA,IAAI,QAA0B,CAAC;AAC/B,IAAI,gBAAgB;AACpB,IAAI,kBAAkB;AAEtB,SAAS,aAAa,KAAa;AACjC,SAAO,MAAM,GAAG;AAClB;AAEA,SAAS,iBAAiB;AACxB,SAAO,OAAO,OAAO,KAAK;AAC5B;AAEA,SAAS,WAAW,KAAa,aAAqB,eAAe,MAAM;AACzE,QAAM,GAAG,IAAI;AACb,kBAAgB,eAAe,KAAK,IAAI,IAAI;AAC9C;AAEA,eAAe,gBAAgB,QAA6C;AAC1E,QAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,uBAAuB;AAAA,MAC/B,SAAS,kCAAkC,IAAI,IAAI,cAAc,SAAS,MAAM;AAAA,MAChF,QAAQ,6BAA6B;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAM,YAAY,aAAa,QAAQ;AAEvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAEA,eAAsB,kBAAkB;AAAA,EACtC,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAA8C;AAC5C,MAAI,iBAAiB,eAAe,KAAK,CAAC,aAAa,GAAG,GAAG;AAC3D,UAAM,EAAE,MAAM,UAAU,IAAI,MAAM,gBAAgB,MAAM;AAExD,QAAI,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAC3C,YAAM,IAAI,uBAAuB;AAAA,QAC/B,SAAS,qBAAqB,MAAM;AAAA,QACpC,QAAQ,6BAA6B;AAAA,MACvC,CAAC;AAAA,IACH;AACA,sBAAkB;AAElB,WAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAOC,KAAI,MAAM;AAC9C,iBAAW,OAAOA,KAAI;AAAA,IACxB,CAAC;AAAA,EACH;AACA,QAAM,OAAO,aAAa,GAAG;AAC7B,MAAI,CAAC,MAAM;AACT,mBAAe;AACf,UAAM,gBAAgB,OAAO,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI;AAEzD,UAAM,IAAI,uBAAuB;AAAA,MAC/B,SAAS,gCAAgC,GAAG,uBAAuB,aAAa;AAAA,MAChF,QAAQ,6BAA6B;AAAA,IACvC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB;AACxB,QAAM,MAAM,KAAK,IAAI;AACrB,MAAI,kBAAkB,IAAI;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM;AACvB,QAAM,cAAc,oCAAoC;AACxD,QAAM,oBAAoB,YAAY;AACtC,QAAM,qBAAqB,OAAO;AAElC,QAAM,YAAY,qBAAqB;AAEvC,MAAI,WAAW;AACb,YAAQ,CAAC;AAAA,EACX;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,KAAe;AACnC,QAAM,qBAAqB,IAAI,QAAQ,IAAI,eAAe;AAC1D,MAAI,CAAC,oBAAoB;AACvB,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AACA,QAAM,cAAc,mBAAmB,MAAM,mBAAmB;AAChE,QAAM,SAAS,cAAc,SAAS,YAAY,CAAC,GAAG,EAAE,IAAI,yBAAyB;AAErF,SAAO,KAAK,IAAI,IAAI,SAAS;AAC/B;;;AC7GA,eAAsB,YACpB,OACA,SACgE;AAChE,QAAM,EAAE,MAAM,eAAe,OAAO,IAAI,cAAc,KAAK;AAE3D,MAAI,QAAQ;AACV,WAAO,EAAE,OAAO;AAAA,EAClB;AAEA,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,EAAE,IAAI,IAAI;AAEhB,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,IAAI,uBAAuB;AAAA,UACzB,QAAQ,6BAA6B;AAAA,UACrC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,QAAQ,UAAW,MAAM,kBAAkB,EAAE,GAAG,SAAS,IAAI,CAAC;AAE1E,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI,uBAAuB;AAAA,YACzB,QAAQ,6BAA6B;AAAA,YACrC,SAAS,gCAAgC,GAAG;AAAA,UAC9C,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,SAAS,IAAI,CAAC;AAAA,EACnD,SAAS,OAAO;AACd,QAAI,iBAAiB,wBAAwB;AAC3C,aAAO,EAAE,QAAQ,CAAC,KAAK,EAAE;AAAA,IAC3B;AACA,WAAO;AAAA,MACL,QAAQ,CAAC,KAA+B;AAAA,IAC1C;AAAA,EACF;AACF;;;AC1DO,SAAS,eAAsE,WAAc;AAClG,SAAO,IAAI,SAA6E;AACtF,UAAM,EAAE,MAAM,OAAO,IAAI,UAAU,GAAG,IAAI;AAE1C,QAAI,QAAQ;AACV,YAAM,OAAO,CAAC;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AACF;;;ACRA,IAAAC,eAAwD;;;ACFxD,IAAAC,eAAqC;AAS9B,IAAM,kBAAkB;AAU/B,eAAsB,YAAY,MAAoC;AACpE,QAAM,EAAE,SAAS,YAAY,MAAM,IAAI;AACvC,MAAI;AAEJ,MAAI;AACF,UAAM,UAAM,0BAAY,YAAY,eAAe;AAAA,EACrD,SAAS,OAAO;AACd,UAAM,IAAI,uBAAuB;AAAA,MAC/B,SAAS,iCAAkC,MAAgB,OAAO;AAAA,MAClE,QAAQ,6BAA6B;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,qBAAQ,OAAO,EACvB,mBAAmB,EAAE,KAAK,iBAAiB,KAAK,MAAM,CAAC,EACvD,KAAK,GAAG;AACb;;;AClCO,IAAMC,iBAAgB,eAAe,aAAc;;;ACHnD,IAAM,gCAAgC,IAAI,KAAK;AAC/C,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB,KAAK;;;ACJxC,eAAe,sBAAsB,UAAqC;AACtE,QAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,MAAI,CAAC,MAAM;AACP,WAAO;AAAA,EACX;AAEA,MAAI,SACA,OAAO,KAAK,UAAU,WAChB,KAAK,QACJ,KAAK,OAAO,WAAW;AAElC,MAAI,KAAK,mBAAmB;AACxB,cAAU,OAAO,KAAK,oBAAoB;AAAA,EAC9C;AAEA,SAAO;AACX;AAEA,eAAsB,UAAU,KAAa,MAAmB;AAC5D,UAAQ,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK;AAC5C;AAEA,eAAsB,SAAS,KAAa,MAAmB;AAC3D,QAAM,WAAW,MAAM,MAAM,KAAK,IAAI;AAEtC,MAAI,CAAC,SAAS,IAAI;AACd,UAAM,IAAI,MAAM,MAAM,sBAAsB,QAAQ,CAAC;AAAA,EACzD;AAEA,SAAO;AACX;;;ACFA,IAAM,mBAAqD,oBAAI,IAAI;AAMnE,eAAe,mBAAmB,WAAmB,MAAiD;AAClG,QAAM,OAAO,MAAM,UAAU,WAAW,IAAI;AAE5C,MAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,YAAY;AACxC,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACnD;AAEA,SAAO;AAAA,IACH,aAAa,KAAK;AAAA,IAClB,gBAAgB,KAAK,IAAI,IAAK,KAAK,aAAa;AAAA,EACpD;AACJ;AAEO,IAAM,6BAAN,MAAqE;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,gBAAgC;AACxC,SAAK,YAAY,eAAe;AAChC,SAAK,aAAa,eAAe;AACjC,SAAK,cAAc,eAAe;AAAA,EACtC;AAAA,EAEQ,mBAAmB,OAAO,QAA8C;AAC5E,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,WACF,gFAEA;AAEJ,WAAO,mBAAmB,KAAK;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,QAC9B,QAAQ;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,EACL;AAAA,EAEQ,2BAA2B,OAAO,QAA8C;AACpF,UAAM,cAAc,MAAM,KAAK,iBAAiB,GAAG;AACnD,qBAAiB,IAAI,KAAK,WAAW,WAAW;AAChD,WAAO;AAAA,EACX;AAAA,EAEO,iBAAiB,OAAO,YAAoD;AAC/E,UAAM,MAAM,WAAW,sBAAsB,GAAG,sBAAsB;AAEtE,QAAI,SAAS;AACT,aAAO,KAAK,yBAAyB,GAAG;AAAA,IAC5C;AAEA,UAAM,iBAAiB,iBAAiB,IAAI,KAAK,SAAS;AAE1D,QAAI,CAAC,kBAAkB,eAAe,iBAAiB,KAAK,IAAI,KAAK,+BAA+B;AAChG,aAAO,KAAK,yBAAyB,GAAG;AAAA,IAC5C;AAEA,WAAO;AAAA,EACX;AAAA,EAEQ,YAAY,YAA6B;AAC7C,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAExC,UAAM,UAAU;AAAA,MACZ,KAAK;AAAA,MACL;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK,KAAK;AAAA,MACV,KAAK,KAAK;AAAA,MACV,OAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACJ,EAAE,KAAK,GAAG;AAAA,IACd;AAEA,WAAO,YAAY;AAAA,MACf;AAAA,MACA,YAAY,KAAK;AAAA,IACrB,CAAC;AAAA,EACL;AACJ;;;ACzFA,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AAEtB,SAAS,sBAAyB,MAAkB;AAClD,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,QAAQ,SAAqC;AAC3D,QAAM,EAAE,QAAQ,oBAAoB,IAAI;AACxC,QAAM,iBAAiB,QAAQ,gBAAgB;AAC/C,QAAM,kBAAkB,UAAU;AAElC,MAAI,aAAgD;AACpD,MACE,qBAAqB,aACrB,qBAAqB,cACrB,qBAAqB,aACrB;AACA,iBAAa,IAAI,2BAA2B;AAAA,MAC1C,WAAW,oBAAoB;AAAA,MAC/B,YAAY,oBAAoB;AAAA,MAChC,aAAa,oBAAoB;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,iBAAe,YAAY,SAAkB,SAA+C;AAC1F,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AACA,UAAM,WAAW,MAAM,QAAQ,WAAW,SAAS,YAAY,iBAAiB;AAAA,MAC9E;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AAEA,UAAM,aAAa,sBAA0C,SAAS,IAAI;AAC1E,WAAO;AAAA,EACT;AAEA,iBAAe,sBACb,cACA,MACqB;AACrB,QAAI,CAAC,iBAAiB;AACpB,aAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,aAAa,EAAE;AAAA,IACvD;AACA,UAAM,WAAW,MAAM,QAAQ,WAAW,OAAO,aAAa,iBAAiB;AAAA,MAC7E,eAAe;AAAA,MACf,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAED,QAAI,CAAC,UAAU,MAAM;AACnB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI,MAAM,aAAa;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,aAAa,sBAAoD,SAAS,IAAI;AAEpF,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,SAAS,WAAW;AAAA,QACpB,cAAc,WAAW;AAAA,MAC3B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAEA,iBAAe,2BACb,aACA,MAC6B;AAC7B,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AACA,UAAM,OAAO,MAAM,QAAQ,WAAW,OAAO;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,mBAAmB;AAAA,MACrB;AAAA,MACA;AAAA,QACE,SAAS,KAAK;AAAA,QACd,eAAe,KAAK;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAEA,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,iBAAe,8BACb,SACA,MACuB;AACvB,UAAM,UAAU,MAAM,YAAY,SAAS,OAAO;AAClD,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,QAAI,QAAQ;AACV,YAAM,OAAO,CAAC;AAAA,IAChB;AAUA,UAAM,cAAc,MAAM,kBAAkB,KAAK,KAAK;AAAA,MACpD,eAAe,KAAK;AAAA,MACpB,yBAAyB,KAAK,SAAS;AAAA,IACzC,CAAC;AAED,UAAM,qBAAqB,MAAM,2BAA2B,aAAa;AAAA,MACvE,SAAS,KAAK;AAAA,MACd,eAAe,KAAK;AAAA,IACtB,CAAC;AAED,UAAM,uBAAuB,MAAM,YAAY,mBAAmB,SAAS,OAAO;AAClF,QAAI,qBAAqB,QAAQ;AAC/B,YAAM,qBAAqB,OAAO,CAAC;AAAA,IACrC;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,WAAW,qBAAqB,KAAK;AAAA,IACvC;AAAA,EACF;AAEA,iBAAe,sBAAsB,SAAsC;AACzE,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,iBAAiB;AACpB,aAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,aAAa,EAAE;AAAA,IACvD;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,YAAY,SAAS,OAAO;AAClD,UAAI,QAAQ,QAAQ;AAClB,eAAO,EAAE,MAAM,MAAM,OAAO,QAAQ,OAAO,CAAC,EAAE;AAAA,MAChD;AAEA,YAAM,cAAc,MAAM,kBAAkB,QAAQ,KAAK,KAAK;AAAA,QAC5D,eAAe,QAAQ,KAAK;AAAA,QAC5B,yBAAyB,QAAQ,KAAK,SAAS;AAAA,MACjD,CAAC;AAED,YAAM,YAAY,QAAQ,gBAAgB;AAC1C,YAAM,QAAQ,QAAQ,gBAAgB;AAEtC,UAAI,CAAC,aAAa,CAAC,OAAO;AACxB,eAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,kDAAkD,EAAE;AAAA,MAC5F;AAEA,YAAM,EAAE,YAAY,IAAI,MAAM,WAAW,eAAe;AAExD,YAAM,mBAAmB,MAAM,QAAQ,WAAW,SAAS,oBAAoB;AAAA,QAC7E;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd,CAAC;AAED,UAAI,CAAC,kBAAkB,OAAO;AAC5B,eAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,wCAAwC,EAAE;AAAA,MAClF;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,UACJ,OAAO,iBAAiB;AAAA,UACxB,KAAK,iBAAiB;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AACd,aAAO,EAAE,MAAM,MAAM,MAAM;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["import_jose","import_jose","cert","import_jose","import_jose","ternDecodeJwt"]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  getAuth
3
- } from "../chunk-MS6L7M3C.mjs";
4
- import "../chunk-DFAJCSBJ.mjs";
5
- import "../chunk-DDUNOEIM.mjs";
3
+ } from "../chunk-DJLDUW7J.mjs";
4
+ import "../chunk-WIVOBOZR.mjs";
5
+ import "../chunk-NXYWC6YO.mjs";
6
6
  export {
7
7
  getAuth
8
8
  };
@@ -0,0 +1,3 @@
1
+ export declare function fetchJson(url: string, init: RequestInit): Promise<any>;
2
+ export declare function fetchAny(url: string, init: RequestInit): Promise<Response>;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAmBA,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,gBAE7D;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,qBAQ5D"}