@tern-secure/backend 1.2.0-canary.v20251003134325 → 1.2.0-canary.v20251008131428

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 (54) hide show
  1. package/dist/admin/index.js +7 -3
  2. package/dist/admin/index.js.map +1 -1
  3. package/dist/admin/index.mjs +531 -22
  4. package/dist/admin/index.mjs.map +1 -1
  5. package/dist/admin/nextSessionTernSecure.d.ts.map +1 -1
  6. package/dist/auth/getauth.d.ts +16 -2
  7. package/dist/auth/getauth.d.ts.map +1 -1
  8. package/dist/auth/index.js +166 -213
  9. package/dist/auth/index.js.map +1 -1
  10. package/dist/auth/index.mjs +4 -51
  11. package/dist/auth/index.mjs.map +1 -1
  12. package/dist/{chunk-4SGWLAJG.mjs → chunk-3ZLDOHI2.mjs} +4 -68
  13. package/dist/chunk-3ZLDOHI2.mjs.map +1 -0
  14. package/dist/{chunk-WZYVAHZ3.mjs → chunk-SVZUAXAW.mjs} +115 -1
  15. package/dist/chunk-SVZUAXAW.mjs.map +1 -0
  16. package/dist/chunk-VSYYHCUV.mjs +71 -0
  17. package/dist/chunk-VSYYHCUV.mjs.map +1 -0
  18. package/dist/{chunk-YKIA5EBF.mjs → chunk-YGNTGJTP.mjs} +94 -4
  19. package/dist/chunk-YGNTGJTP.mjs.map +1 -0
  20. package/dist/fireRestApi/endpoints/TokenApi.d.ts +6 -3
  21. package/dist/fireRestApi/endpoints/TokenApi.d.ts.map +1 -1
  22. package/dist/fireRestApi/request.d.ts +3 -3
  23. package/dist/fireRestApi/request.d.ts.map +1 -1
  24. package/dist/index.d.ts +12 -12
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +405 -103
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +130 -18
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/jwt/customJwt.d.ts +11 -0
  31. package/dist/jwt/customJwt.d.ts.map +1 -0
  32. package/dist/jwt/index.d.ts +1 -0
  33. package/dist/jwt/index.d.ts.map +1 -1
  34. package/dist/jwt/index.js +104 -0
  35. package/dist/jwt/index.js.map +1 -1
  36. package/dist/jwt/index.mjs +7 -1
  37. package/dist/jwt/index.mjs.map +1 -1
  38. package/dist/tokens/cookie.d.ts +5 -0
  39. package/dist/tokens/cookie.d.ts.map +1 -0
  40. package/dist/tokens/request.d.ts.map +1 -1
  41. package/dist/tokens/types.d.ts +1 -12
  42. package/dist/tokens/types.d.ts.map +1 -1
  43. package/dist/utils/errors.d.ts +12 -0
  44. package/dist/utils/errors.d.ts.map +1 -1
  45. package/dist/utils/options.d.ts +3 -3
  46. package/dist/utils/options.d.ts.map +1 -1
  47. package/package.json +3 -3
  48. package/dist/chunk-4SGWLAJG.mjs.map +0 -1
  49. package/dist/chunk-NEPV6OWI.mjs +0 -550
  50. package/dist/chunk-NEPV6OWI.mjs.map +0 -1
  51. package/dist/chunk-WZYVAHZ3.mjs.map +0 -1
  52. package/dist/chunk-YKIA5EBF.mjs.map +0 -1
  53. package/dist/tokens/sessionConfig.d.ts +0 -14
  54. package/dist/tokens/sessionConfig.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -376,20 +376,36 @@ var SignUpApi = class extends AbstractAPI {
376
376
  var TokenApi = class extends AbstractAPI {
377
377
  async refreshToken(apiKey, params) {
378
378
  this.requireApiKey(apiKey);
379
- const { ...restParams } = params;
379
+ const { refresh_token, request_origin, ...restParams } = params;
380
+ const headers = {};
381
+ if (request_origin) {
382
+ headers["Referer"] = request_origin;
383
+ }
384
+ const bodyParams = {
385
+ grant_type: "refresh_token",
386
+ refresh_token,
387
+ ...restParams
388
+ };
380
389
  return this.request({
381
390
  endpoint: "refreshToken",
382
391
  method: "POST",
383
- bodyParams: restParams
392
+ apiKey,
393
+ bodyParams,
394
+ headerParams: headers
384
395
  });
385
396
  }
386
- async exchangeCustomForIdAndRefreshTokens(apiKey, params) {
397
+ async exchangeCustomForIdAndRefreshTokens(apiKey, params, options) {
387
398
  this.requireApiKey(apiKey);
399
+ const headers = {};
400
+ if (options?.referer) {
401
+ headers["Referer"] = options.referer;
402
+ }
388
403
  return this.request({
389
404
  endpoint: "signInWithCustomToken",
390
405
  method: "POST",
391
406
  apiKey,
392
- bodyParams: params
407
+ bodyParams: params,
408
+ headerParams: headers
393
409
  });
394
410
  }
395
411
  };
@@ -461,8 +477,10 @@ function createRequest(options) {
461
477
  data: null,
462
478
  errors: [
463
479
  {
464
- code: "missing_api_key",
465
- message: "Firebase API key is required"
480
+ domain: "none",
481
+ reason: "invalid_parameter",
482
+ message: "Firebase API key is required",
483
+ code: "400"
466
484
  }
467
485
  ]
468
486
  };
@@ -517,8 +535,10 @@ function createRequest(options) {
517
535
  data: null,
518
536
  errors: [
519
537
  {
520
- code: "unexpected_error",
521
- message: error.message || "An unexpected error occurred"
538
+ domain: "none",
539
+ reason: "request_failed",
540
+ message: error.message || "An unexpected error occurred",
541
+ code: "500"
522
542
  }
523
543
  ]
524
544
  };
@@ -534,16 +554,42 @@ function createRequest(options) {
534
554
  return requestFn;
535
555
  }
536
556
  function parseErrors(data) {
537
- if (!!data && typeof data === "object" && "errors" in data) {
538
- const errors = data.errors;
539
- return errors.length > 0 ? errors.map(parseError) : [];
557
+ let parsedData = data;
558
+ if (typeof data === "string") {
559
+ try {
560
+ parsedData = JSON.parse(data);
561
+ } catch (error) {
562
+ return [];
563
+ }
564
+ }
565
+ if (!parsedData || typeof parsedData !== "object") {
566
+ return [];
567
+ }
568
+ if ("error" in parsedData && typeof parsedData.error === "object" && parsedData.error !== null) {
569
+ const errorObj = parsedData.error;
570
+ if ("errors" in errorObj && Array.isArray(errorObj.errors) && errorObj.errors.length > 0) {
571
+ return errorObj.errors.map((err) => parseError({
572
+ code: errorObj.code || "unknown_error",
573
+ message: err.message || "Unknown error",
574
+ domain: err.domain,
575
+ reason: err.reason
576
+ }));
577
+ }
578
+ return [parseError({
579
+ code: errorObj.code?.toString() || "unknown_error",
580
+ message: errorObj.message || "Unknown error",
581
+ domain: errorObj.domain || "unknown",
582
+ reason: errorObj.reason || errorObj.code?.toString() || "unknown_error"
583
+ })];
540
584
  }
541
585
  return [];
542
586
  }
543
587
  function parseError(error) {
544
588
  return {
545
- code: error.code,
546
- message: error.message
589
+ domain: error.domain,
590
+ reason: error.reason,
591
+ message: error.message,
592
+ code: error.code
547
593
  };
548
594
  }
549
595
 
@@ -559,7 +605,117 @@ function createFireApi(options) {
559
605
  };
560
606
  }
561
607
 
608
+ // src/jwt/customJwt.ts
609
+ var import_jose = require("jose");
610
+ var CustomTokenError = class extends Error {
611
+ constructor(message, code) {
612
+ super(message);
613
+ this.code = code;
614
+ this.name = "CustomTokenError";
615
+ }
616
+ };
617
+ var RESERVED_CLAIMS = [
618
+ "acr",
619
+ "amr",
620
+ "at_hash",
621
+ "aud",
622
+ "auth_time",
623
+ "azp",
624
+ "cnf",
625
+ "c_hash",
626
+ "exp",
627
+ "firebase",
628
+ "iat",
629
+ "iss",
630
+ "jti",
631
+ "nbf",
632
+ "nonce",
633
+ "sub"
634
+ ];
635
+ async function createCustomTokenJwt(uid, developerClaims) {
636
+ try {
637
+ const privateKey = process.env.FIREBASE_PRIVATE_KEY;
638
+ const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;
639
+ if (!privateKey || !clientEmail) {
640
+ return {
641
+ errors: [
642
+ new CustomTokenError(
643
+ "Missing FIREBASE_PRIVATE_KEY or FIREBASE_CLIENT_EMAIL environment variables",
644
+ "MISSING_ENV_VARS"
645
+ )
646
+ ]
647
+ };
648
+ }
649
+ if (!uid || typeof uid !== "string") {
650
+ return {
651
+ errors: [new CustomTokenError("uid must be a non-empty string", "INVALID_UID")]
652
+ };
653
+ }
654
+ if (uid.length > 128) {
655
+ return {
656
+ errors: [new CustomTokenError("uid must not exceed 128 characters", "UID_TOO_LONG")]
657
+ };
658
+ }
659
+ if (developerClaims) {
660
+ for (const claim of Object.keys(developerClaims)) {
661
+ if (RESERVED_CLAIMS.includes(claim)) {
662
+ return {
663
+ errors: [new CustomTokenError(`Custom claim '${claim}' is reserved`, "RESERVED_CLAIM")]
664
+ };
665
+ }
666
+ }
667
+ }
668
+ const expiresIn = 3600;
669
+ const now = Math.floor(Date.now() / 1e3);
670
+ const parsedPrivateKey = await (0, import_jose.importPKCS8)(privateKey.replace(/\\n/g, "\n"), "RS256");
671
+ const payload = {
672
+ iss: clientEmail,
673
+ sub: clientEmail,
674
+ aud: "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
675
+ iat: now,
676
+ exp: now + expiresIn,
677
+ uid,
678
+ ...developerClaims
679
+ };
680
+ const jwt = await new import_jose.SignJWT(payload).setProtectedHeader({ alg: "RS256", typ: "JWT" }).setIssuedAt(now).setExpirationTime(now + expiresIn).setIssuer(clientEmail).setSubject(clientEmail).setAudience(
681
+ "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
682
+ ).sign(parsedPrivateKey);
683
+ return {
684
+ data: jwt
685
+ };
686
+ } catch (error) {
687
+ const message = error instanceof Error ? error.message : "Unknown error occurred";
688
+ return {
689
+ errors: [
690
+ new CustomTokenError(`Failed to create custom token: ${message}`, "TOKEN_CREATION_FAILED")
691
+ ]
692
+ };
693
+ }
694
+ }
695
+ async function createCustomToken(uid, developerClaims) {
696
+ const { data, errors } = await createCustomTokenJwt(uid, developerClaims);
697
+ if (errors) {
698
+ throw errors[0];
699
+ }
700
+ return data;
701
+ }
702
+
703
+ // src/jwt/verifyJwt.ts
704
+ var import_jose3 = require("jose");
705
+
562
706
  // src/utils/errors.ts
707
+ var RefreshTokenErrorReason = {
708
+ NonEligibleNoCookie: "non-eligible-no-refresh-cookie",
709
+ NonEligibleNonGet: "non-eligible-non-get",
710
+ InvalidSessionToken: "invalid-session-token",
711
+ MissingApiClient: "missing-api-client",
712
+ MissingIdToken: "missing-id-token",
713
+ MissingSessionToken: "missing-session-token",
714
+ MissingRefreshToken: "missing-refresh-token",
715
+ ExpiredIdTokenDecodeFailed: "expired-id-token-decode-failed",
716
+ ExpiredSessionTokenDecodeFailed: "expired-session-token-decode-failed",
717
+ FetchError: "fetch-error"
718
+ };
563
719
  var TokenVerificationErrorReason = {
564
720
  TokenExpired: "token-expired",
565
721
  TokenInvalid: "token-invalid",
@@ -594,88 +750,6 @@ var TokenVerificationError = class _TokenVerificationError extends Error {
594
750
  }
595
751
  };
596
752
 
597
- // src/utils/options.ts
598
- var defaultOptions = {
599
- apiKey: void 0,
600
- apiUrl: void 0,
601
- apiVersion: void 0
602
- };
603
- function mergePreDefinedOptions(userOptions = {}) {
604
- return {
605
- ...defaultOptions,
606
- ...userOptions
607
- };
608
- }
609
-
610
- // src/tokens/c-authenticateRequestProcessor.ts
611
- var RequestProcessorContext = class {
612
- constructor(ternSecureRequest, options) {
613
- this.ternSecureRequest = ternSecureRequest;
614
- this.options = options;
615
- this.initHeaderValues();
616
- this.initCookieValues();
617
- this.initUrlValues();
618
- Object.assign(this, options);
619
- this.ternUrl = this.ternSecureRequest.ternUrl;
620
- }
621
- get request() {
622
- return this.ternSecureRequest;
623
- }
624
- initHeaderValues() {
625
- this.sessionTokenInHeader = this.parseAuthorizationHeader(
626
- this.getHeader(constants.Headers.Authorization)
627
- );
628
- this.origin = this.getHeader(constants.Headers.Origin);
629
- this.host = this.getHeader(constants.Headers.Host);
630
- this.forwardedHost = this.getHeader(constants.Headers.ForwardedHost);
631
- this.forwardedProto = this.getHeader(constants.Headers.CloudFrontForwardedProto) || this.getHeader(constants.Headers.ForwardedProto);
632
- this.referrer = this.getHeader(constants.Headers.Referrer);
633
- this.userAgent = this.getHeader(constants.Headers.UserAgent);
634
- this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);
635
- this.accept = this.getHeader(constants.Headers.Accept);
636
- }
637
- initCookieValues() {
638
- const isProduction = process.env.NODE_ENV === "production";
639
- const defaultPrefix = isProduction ? "__HOST-" : "__dev_";
640
- this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);
641
- this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);
642
- this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);
643
- this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);
644
- this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);
645
- }
646
- initUrlValues() {
647
- this.method = this.ternSecureRequest.method;
648
- this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split("/").filter(Boolean);
649
- this.endpoint = this.pathSegments[2];
650
- this.subEndpoint = this.pathSegments[3];
651
- }
652
- getHeader(name) {
653
- return this.ternSecureRequest.headers.get(name) || void 0;
654
- }
655
- getCookie(name) {
656
- return this.ternSecureRequest.cookies.get(name) || void 0;
657
- }
658
- parseAuthorizationHeader(authorizationHeader) {
659
- if (!authorizationHeader) {
660
- return void 0;
661
- }
662
- const [scheme, token] = authorizationHeader.split(" ", 2);
663
- if (!token) {
664
- return scheme;
665
- }
666
- if (scheme === "Bearer") {
667
- return token;
668
- }
669
- return void 0;
670
- }
671
- };
672
- var createRequestProcessor = (ternSecureRequest, options) => {
673
- return new RequestProcessorContext(ternSecureRequest, options);
674
- };
675
-
676
- // src/jwt/verifyJwt.ts
677
- var import_jose2 = require("jose");
678
-
679
753
  // src/utils/rfc4648.ts
680
754
  var base64url = {
681
755
  parse(string, opts) {
@@ -753,10 +827,10 @@ function stringify(data, encoding, opts = {}) {
753
827
  }
754
828
 
755
829
  // src/jwt/cryptoKeys.ts
756
- var import_jose = require("jose");
830
+ var import_jose2 = require("jose");
757
831
  async function importKey(key, algorithm) {
758
832
  if (typeof key === "object") {
759
- const result = await (0, import_jose.importJWK)(key, algorithm);
833
+ const result = await (0, import_jose2.importJWK)(key, algorithm);
760
834
  if (result instanceof Uint8Array) {
761
835
  throw new Error("Unexpected Uint8Array result from JWK import");
762
836
  }
@@ -764,13 +838,13 @@ async function importKey(key, algorithm) {
764
838
  }
765
839
  const keyString = key.trim();
766
840
  if (keyString.includes("-----BEGIN CERTIFICATE-----")) {
767
- return await (0, import_jose.importX509)(keyString, algorithm);
841
+ return await (0, import_jose2.importX509)(keyString, algorithm);
768
842
  }
769
843
  if (keyString.includes("-----BEGIN PUBLIC KEY-----")) {
770
- return await (0, import_jose.importSPKI)(keyString, algorithm);
844
+ return await (0, import_jose2.importSPKI)(keyString, algorithm);
771
845
  }
772
846
  try {
773
- return await (0, import_jose.importSPKI)(keyString, algorithm);
847
+ return await (0, import_jose2.importSPKI)(keyString, algorithm);
774
848
  } catch (error) {
775
849
  throw new Error(
776
850
  `Unsupported key format. Supported formats: X.509 certificate (PEM), SPKI (PEM), JWK (JSON object or string). Error: ${error}`
@@ -853,7 +927,7 @@ async function verifySignature(jwt, key) {
853
927
  const joseAlgorithm = header.alg || "RS256";
854
928
  try {
855
929
  const publicKey = await importKey(key, joseAlgorithm);
856
- const { payload } = await (0, import_jose2.jwtVerify)(raw.text, publicKey);
930
+ const { payload } = await (0, import_jose3.jwtVerify)(raw.text, publicKey);
857
931
  return { data: payload };
858
932
  } catch (error) {
859
933
  return {
@@ -868,8 +942,8 @@ async function verifySignature(jwt, key) {
868
942
  }
869
943
  function ternDecodeJwt(token) {
870
944
  try {
871
- const header = (0, import_jose2.decodeProtectedHeader)(token);
872
- const payload = (0, import_jose2.decodeJwt)(token);
945
+ const header = (0, import_jose3.decodeProtectedHeader)(token);
946
+ const payload = (0, import_jose3.decodeJwt)(token);
873
947
  const tokenParts = (token || "").toString().split(".");
874
948
  if (tokenParts.length !== 3) {
875
949
  return {
@@ -1062,12 +1136,223 @@ async function verifyToken(token, options) {
1062
1136
  }
1063
1137
  }
1064
1138
 
1139
+ // src/auth/getauth.ts
1140
+ var API_KEY_ERROR = "API Key is required";
1141
+ var NO_DATA_ERROR = "No token data received";
1142
+ function parseFirebaseResponse(data) {
1143
+ if (typeof data === "string") {
1144
+ try {
1145
+ return JSON.parse(data);
1146
+ } catch (error) {
1147
+ throw new Error(`Failed to parse Firebase response: ${error}`);
1148
+ }
1149
+ }
1150
+ return data;
1151
+ }
1152
+ function getAuth(options) {
1153
+ const { apiKey } = options;
1154
+ const firebaseApiKey = options.firebaseConfig?.apiKey;
1155
+ const effectiveApiKey = apiKey || firebaseApiKey;
1156
+ async function refreshExpiredIdToken(refreshToken, opts) {
1157
+ if (!effectiveApiKey) {
1158
+ return { data: null, error: new Error(API_KEY_ERROR) };
1159
+ }
1160
+ const response = await options.apiClient?.tokens.refreshToken(effectiveApiKey, {
1161
+ refresh_token: refreshToken,
1162
+ request_origin: opts.referer
1163
+ });
1164
+ if (!response?.data) {
1165
+ return {
1166
+ data: null,
1167
+ error: new Error(NO_DATA_ERROR)
1168
+ };
1169
+ }
1170
+ const parsedData = parseFirebaseResponse(response.data);
1171
+ return {
1172
+ data: {
1173
+ idToken: parsedData.id_token,
1174
+ refreshToken: parsedData.refresh_token
1175
+ },
1176
+ error: null
1177
+ };
1178
+ }
1179
+ async function customForIdAndRefreshToken(customToken, opts) {
1180
+ if (!effectiveApiKey) {
1181
+ throw new Error("API Key is required to create custom token");
1182
+ }
1183
+ const response = await options.apiClient?.tokens.exchangeCustomForIdAndRefreshTokens(
1184
+ effectiveApiKey,
1185
+ {
1186
+ token: customToken,
1187
+ returnSecureToken: true
1188
+ },
1189
+ {
1190
+ referer: opts.referer
1191
+ }
1192
+ );
1193
+ if (!response?.data) {
1194
+ throw new Error("No data received from Firebase token exchange");
1195
+ }
1196
+ const parsedData = parseFirebaseResponse(response.data);
1197
+ return {
1198
+ idToken: parsedData.idToken,
1199
+ refreshToken: parsedData.refreshToken
1200
+ };
1201
+ }
1202
+ async function createCustomIdAndRefreshToken(idToken, opts) {
1203
+ const decoded = await verifyToken(idToken, options);
1204
+ const { data, errors } = decoded;
1205
+ if (errors) {
1206
+ throw errors[0];
1207
+ }
1208
+ const customToken = await createCustomToken(data.uid, {
1209
+ emailVerified: data.email_verified,
1210
+ source_sign_in_provider: data.firebase.sign_in_provider
1211
+ });
1212
+ const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {
1213
+ referer: opts.referer
1214
+ });
1215
+ return {
1216
+ ...idAndRefreshTokens,
1217
+ customToken
1218
+ };
1219
+ }
1220
+ return {
1221
+ customForIdAndRefreshToken,
1222
+ createCustomIdAndRefreshToken,
1223
+ refreshExpiredIdToken
1224
+ };
1225
+ }
1226
+
1227
+ // src/utils/options.ts
1228
+ var defaultOptions = {
1229
+ apiKey: void 0,
1230
+ apiUrl: void 0,
1231
+ apiVersion: void 0
1232
+ };
1233
+ function mergePreDefinedOptions(userOptions = {}) {
1234
+ return {
1235
+ ...defaultOptions,
1236
+ ...userOptions
1237
+ };
1238
+ }
1239
+
1240
+ // src/tokens/c-authenticateRequestProcessor.ts
1241
+ var RequestProcessorContext = class {
1242
+ constructor(ternSecureRequest, options) {
1243
+ this.ternSecureRequest = ternSecureRequest;
1244
+ this.options = options;
1245
+ this.initHeaderValues();
1246
+ this.initCookieValues();
1247
+ this.initUrlValues();
1248
+ Object.assign(this, options);
1249
+ this.ternUrl = this.ternSecureRequest.ternUrl;
1250
+ }
1251
+ get request() {
1252
+ return this.ternSecureRequest;
1253
+ }
1254
+ initHeaderValues() {
1255
+ this.sessionTokenInHeader = this.parseAuthorizationHeader(
1256
+ this.getHeader(constants.Headers.Authorization)
1257
+ );
1258
+ this.origin = this.getHeader(constants.Headers.Origin);
1259
+ this.host = this.getHeader(constants.Headers.Host);
1260
+ this.forwardedHost = this.getHeader(constants.Headers.ForwardedHost);
1261
+ this.forwardedProto = this.getHeader(constants.Headers.CloudFrontForwardedProto) || this.getHeader(constants.Headers.ForwardedProto);
1262
+ this.referrer = this.getHeader(constants.Headers.Referrer);
1263
+ this.userAgent = this.getHeader(constants.Headers.UserAgent);
1264
+ this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);
1265
+ this.accept = this.getHeader(constants.Headers.Accept);
1266
+ }
1267
+ initCookieValues() {
1268
+ const isProduction = process.env.NODE_ENV === "production";
1269
+ const defaultPrefix = isProduction ? "__HOST-" : "__dev_";
1270
+ this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);
1271
+ this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);
1272
+ this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);
1273
+ this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);
1274
+ this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);
1275
+ }
1276
+ initUrlValues() {
1277
+ this.method = this.ternSecureRequest.method;
1278
+ this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split("/").filter(Boolean);
1279
+ this.endpoint = this.pathSegments[2];
1280
+ this.subEndpoint = this.pathSegments[3];
1281
+ }
1282
+ getHeader(name) {
1283
+ return this.ternSecureRequest.headers.get(name) || void 0;
1284
+ }
1285
+ getCookie(name) {
1286
+ return this.ternSecureRequest.cookies.get(name) || void 0;
1287
+ }
1288
+ parseAuthorizationHeader(authorizationHeader) {
1289
+ if (!authorizationHeader) {
1290
+ return void 0;
1291
+ }
1292
+ const [scheme, token] = authorizationHeader.split(" ", 2);
1293
+ if (!token) {
1294
+ return scheme;
1295
+ }
1296
+ if (scheme === "Bearer") {
1297
+ return token;
1298
+ }
1299
+ return void 0;
1300
+ }
1301
+ };
1302
+ var createRequestProcessor = (ternSecureRequest, options) => {
1303
+ return new RequestProcessorContext(ternSecureRequest, options);
1304
+ };
1305
+
1306
+ // src/tokens/cookie.ts
1307
+ var import_cookie2 = require("@tern-secure/shared/cookie");
1308
+
1065
1309
  // src/tokens/request.ts
1066
1310
  function hasAuthorizationHeader(request) {
1067
1311
  return request.headers.has("Authorization");
1068
1312
  }
1313
+ function isRequestForRefresh(error, context, request) {
1314
+ return error.reason === TokenVerificationErrorReason.TokenExpired && !!context.refreshTokenInCookie && request.method === "GET";
1315
+ }
1069
1316
  async function authenticateRequest(request, options) {
1070
1317
  const context = createRequestProcessor(createTernSecureRequest(request), options);
1318
+ const { refreshTokenInCookie } = context;
1319
+ const { refreshExpiredIdToken } = getAuth(options);
1320
+ async function refreshToken() {
1321
+ if (!refreshTokenInCookie) {
1322
+ return {
1323
+ data: null,
1324
+ error: {
1325
+ message: "No refresh token available",
1326
+ reason: AuthErrorReason.SessionTokenMissing
1327
+ }
1328
+ };
1329
+ }
1330
+ return await refreshExpiredIdToken(refreshTokenInCookie, {
1331
+ referer: context.ternUrl.origin
1332
+ });
1333
+ }
1334
+ async function handleRefresh() {
1335
+ const { data: refreshedData, error } = await refreshToken();
1336
+ if (!refreshedData) {
1337
+ return { data: null, error };
1338
+ }
1339
+ const headers = new Headers();
1340
+ const { idToken } = refreshedData;
1341
+ const maxAge = 3600;
1342
+ const cookiePrefix = (0, import_cookie2.getCookiePrefix)();
1343
+ const idTokenCookieName = (0, import_cookie2.getCookieName)(constants.Cookies.IdToken, cookiePrefix);
1344
+ const baseCookieAttributes = "HttpOnly; Secure; SameSite=Strict; Path=/";
1345
+ const idTokenCookie = `${idTokenCookieName}=${idToken}; ${baseCookieAttributes};`;
1346
+ headers.append("Set-Cookie", idTokenCookie);
1347
+ const { data: decoded, errors } = await verifyToken(idToken, options);
1348
+ if (errors) {
1349
+ return {
1350
+ data: null,
1351
+ error: errors ? errors[0] : new Error("Failed to verify refreshed token")
1352
+ };
1353
+ }
1354
+ return { data: { decoded, token: idToken, headers }, error: null };
1355
+ }
1071
1356
  async function authenticateRequestWithTokenInCookie() {
1072
1357
  try {
1073
1358
  const { data, errors } = await verifyToken(context.idTokenInCookie, options);
@@ -1098,6 +1383,23 @@ async function authenticateRequest(request, options) {
1098
1383
  return signedOut(AuthErrorReason.UnexpectedError);
1099
1384
  }
1100
1385
  let refreshError;
1386
+ if (isRequestForRefresh(err, context, request)) {
1387
+ const { data, error } = await handleRefresh();
1388
+ if (data) {
1389
+ return signedIn(data.decoded, data.headers, data.token);
1390
+ }
1391
+ if (error?.cause?.reason) {
1392
+ refreshError = error.cause.reason;
1393
+ }
1394
+ } else {
1395
+ if (request.method !== "GET") {
1396
+ refreshError = RefreshTokenErrorReason.NonEligibleNonGet;
1397
+ } else if (!context.refreshTokenInCookie) {
1398
+ refreshError = RefreshTokenErrorReason.NonEligibleNoCookie;
1399
+ } else {
1400
+ refreshError = null;
1401
+ }
1402
+ }
1101
1403
  err.tokenCarrier = tokenCarrier;
1102
1404
  return signedOut(err.reason, err.getFullMessage());
1103
1405
  }