@tern-secure/backend 1.2.0-canary.v20251030165007 → 1.2.0-canary.v20251125170702
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/request.test.d.ts +2 -0
- package/dist/__tests__/request.test.d.ts.map +1 -0
- package/dist/admin/index.d.ts +1 -0
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +68 -8
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +53 -8
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/nextSessionTernSecure.d.ts.map +1 -1
- package/dist/admin/sessionTernSecure.d.ts.map +1 -1
- package/dist/admin/user.d.ts +16 -0
- package/dist/admin/user.d.ts.map +1 -0
- package/dist/auth/getauth.d.ts +1 -0
- package/dist/auth/getauth.d.ts.map +1 -1
- package/dist/auth/index.js +49 -31
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +3 -3
- package/dist/{chunk-IBABNFOK.mjs → chunk-ASGV4MFO.mjs} +2 -2
- package/dist/{chunk-5AP2WM3W.mjs → chunk-DDUNOEIM.mjs} +20 -31
- package/dist/chunk-DDUNOEIM.mjs.map +1 -0
- package/dist/{chunk-VY5FVZL2.mjs → chunk-DFAJCSBJ.mjs} +17 -3
- package/dist/chunk-DFAJCSBJ.mjs.map +1 -0
- package/dist/{chunk-A5G3CWO5.mjs → chunk-MS6L7M3C.mjs} +9 -4
- package/dist/chunk-MS6L7M3C.mjs.map +1 -0
- package/dist/constants.d.ts +13 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/fireRestApi/createFireApi.d.ts +3 -2
- package/dist/fireRestApi/createFireApi.d.ts.map +1 -1
- package/dist/fireRestApi/endpointUrl.d.ts +2 -1
- package/dist/fireRestApi/endpointUrl.d.ts.map +1 -1
- package/dist/fireRestApi/endpoints/SignInApi.d.ts +11 -0
- package/dist/fireRestApi/endpoints/SignInApi.d.ts.map +1 -0
- package/dist/fireRestApi/endpoints/index.d.ts +1 -0
- package/dist/fireRestApi/endpoints/index.d.ts.map +1 -1
- package/dist/fireRestApi/resources/EmailAddress.d.ts +7 -0
- package/dist/fireRestApi/resources/EmailAddress.d.ts.map +1 -0
- package/dist/fireRestApi/resources/JSON.d.ts +4 -0
- package/dist/fireRestApi/resources/JSON.d.ts.map +1 -1
- package/dist/index.js +186 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +151 -17
- package/dist/index.mjs.map +1 -1
- package/dist/jwt/index.js +19 -30
- package/dist/jwt/index.js.map +1 -1
- package/dist/jwt/index.mjs +1 -1
- package/dist/jwt/verifyJwt.d.ts.map +1 -1
- package/dist/tokens/authstate.d.ts +16 -4
- package/dist/tokens/authstate.d.ts.map +1 -1
- package/dist/tokens/c-authenticateRequestProcessor.d.ts +5 -0
- package/dist/tokens/c-authenticateRequestProcessor.d.ts.map +1 -1
- package/dist/tokens/request.d.ts.map +1 -1
- package/dist/tokens/types.d.ts +4 -0
- package/dist/tokens/types.d.ts.map +1 -1
- package/package.json +9 -7
- package/dist/chunk-5AP2WM3W.mjs.map +0 -1
- package/dist/chunk-A5G3CWO5.mjs.map +0 -1
- package/dist/chunk-VY5FVZL2.mjs.map +0 -1
- /package/dist/{chunk-IBABNFOK.mjs.map → chunk-ASGV4MFO.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -54,15 +54,28 @@ var Attributes = {
|
|
|
54
54
|
};
|
|
55
55
|
var Cookies = {
|
|
56
56
|
Session: "__session",
|
|
57
|
-
CsrfToken: "
|
|
57
|
+
CsrfToken: "__terncf",
|
|
58
58
|
IdToken: "TernSecure_[DEFAULT]",
|
|
59
59
|
Refresh: "TernSecureID_[DEFAULT]",
|
|
60
60
|
Custom: "__custom",
|
|
61
|
+
TernAut: "tern_aut",
|
|
61
62
|
Handshake: "__ternsecure_handshake",
|
|
62
63
|
DevBrowser: "__ternsecure_db_jwt",
|
|
63
64
|
RedirectCount: "__ternsecure_redirect_count",
|
|
64
65
|
HandshakeNonce: "__ternsecure_handshake_nonce"
|
|
65
66
|
};
|
|
67
|
+
var QueryParameters = {
|
|
68
|
+
TernSynced: "__tern_synced",
|
|
69
|
+
SuffixedCookies: "suffixed_cookies",
|
|
70
|
+
TernRedirectUrl: "__tern_redirect_url",
|
|
71
|
+
// use the reference to Cookies to indicate that it's the same value
|
|
72
|
+
DevBrowser: Cookies.DevBrowser,
|
|
73
|
+
Handshake: Cookies.Handshake,
|
|
74
|
+
HandshakeHelp: "__tern_help",
|
|
75
|
+
LegacyDevBrowser: "__dev_session",
|
|
76
|
+
HandshakeReason: "__tern_hs_reason",
|
|
77
|
+
HandshakeNonce: Cookies.HandshakeNonce
|
|
78
|
+
};
|
|
66
79
|
var Headers2 = {
|
|
67
80
|
Accept: "accept",
|
|
68
81
|
AuthMessage: "x-ternsecure-auth-message",
|
|
@@ -99,7 +112,8 @@ var constants = {
|
|
|
99
112
|
Attributes,
|
|
100
113
|
Cookies,
|
|
101
114
|
Headers: Headers2,
|
|
102
|
-
ContentTypes
|
|
115
|
+
ContentTypes,
|
|
116
|
+
QueryParameters
|
|
103
117
|
};
|
|
104
118
|
|
|
105
119
|
// src/createRedirect.ts
|
|
@@ -233,16 +247,20 @@ function mapJwtPayloadToDecodedIdToken(payload) {
|
|
|
233
247
|
// src/tokens/authstate.ts
|
|
234
248
|
var AuthStatus = {
|
|
235
249
|
SignedIn: "signed-in",
|
|
236
|
-
SignedOut: "signed-out"
|
|
250
|
+
SignedOut: "signed-out",
|
|
251
|
+
Handshake: "handshake"
|
|
237
252
|
};
|
|
238
253
|
var AuthErrorReason = {
|
|
239
|
-
|
|
254
|
+
AuthTimeout: "auth-timeout",
|
|
255
|
+
SessionTokenAndAuthMissing: "session-token-and-aut-missing",
|
|
240
256
|
SessionTokenMissing: "session-token-missing",
|
|
241
257
|
SessionTokenExpired: "session-token-expired",
|
|
242
|
-
|
|
258
|
+
SessionTokenIATBeforeTernAUT: "session-token-iat-before-tern-aut",
|
|
243
259
|
SessionTokenNBF: "session-token-nbf",
|
|
244
260
|
SessionTokenIatInTheFuture: "session-token-iat-in-the-future",
|
|
245
|
-
|
|
261
|
+
SessionTokenWithoutTernAUT: "session-token-but-no-tern-uat",
|
|
262
|
+
TernAutWithoutSessionToken: "tern-aut-but-no-session-token",
|
|
263
|
+
SyncRequired: "sync-required",
|
|
246
264
|
UnexpectedError: "unexpected-error"
|
|
247
265
|
};
|
|
248
266
|
function createHasAuthorization(decodedIdToken) {
|
|
@@ -294,6 +312,7 @@ function signedIn(authCtx, sessionClaims, headers = new Headers(), token) {
|
|
|
294
312
|
const authObject = signedInAuthObject(token, sessionClaims);
|
|
295
313
|
return {
|
|
296
314
|
status: AuthStatus.SignedIn,
|
|
315
|
+
message: null,
|
|
297
316
|
reason: null,
|
|
298
317
|
signInUrl: authCtx.signInUrl || "",
|
|
299
318
|
signUpUrl: authCtx.signUpUrl || "",
|
|
@@ -318,6 +337,12 @@ function signedOut(authCtx, reason, message = "", headers = new Headers()) {
|
|
|
318
337
|
}
|
|
319
338
|
var decorateHeaders = (requestState) => {
|
|
320
339
|
const headers = new Headers(requestState.headers || {});
|
|
340
|
+
if (requestState.message) {
|
|
341
|
+
try {
|
|
342
|
+
headers.set(constants.Headers.AuthMessage, requestState.message);
|
|
343
|
+
} catch {
|
|
344
|
+
}
|
|
345
|
+
}
|
|
321
346
|
if (requestState.reason) {
|
|
322
347
|
try {
|
|
323
348
|
headers.set(constants.Headers.AuthReason, requestState.reason);
|
|
@@ -399,6 +424,30 @@ var PasswordApi = class extends AbstractAPI {
|
|
|
399
424
|
}
|
|
400
425
|
};
|
|
401
426
|
|
|
427
|
+
// src/fireRestApi/endpoints/SignInApi.ts
|
|
428
|
+
var SignInApi = class extends AbstractAPI {
|
|
429
|
+
async resetPasswordEmail(apiKey, params) {
|
|
430
|
+
try {
|
|
431
|
+
this.requireApiKey(apiKey);
|
|
432
|
+
const { ...restParams } = params;
|
|
433
|
+
const response = await this.request({
|
|
434
|
+
endpoint: "sendOobCode",
|
|
435
|
+
method: "POST",
|
|
436
|
+
apiKey,
|
|
437
|
+
bodyParams: restParams
|
|
438
|
+
});
|
|
439
|
+
if (response.errors) {
|
|
440
|
+
const errorMessage = response.errors[0]?.message || "Failed to send reset password email";
|
|
441
|
+
throw new Error(errorMessage);
|
|
442
|
+
}
|
|
443
|
+
return response.data;
|
|
444
|
+
} catch (error) {
|
|
445
|
+
const contextualMessage = `Failed to send reset password email: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
446
|
+
throw new Error(contextualMessage);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
402
451
|
// src/fireRestApi/endpoints/SignInTokenApi.ts
|
|
403
452
|
var SignInTokenApi = class extends AbstractAPI {
|
|
404
453
|
async createCustomToken(apiKey, params) {
|
|
@@ -531,6 +580,9 @@ var signInWithPassword = (apiKey) => {
|
|
|
531
580
|
var signUpEndpoint = (apiKey) => {
|
|
532
581
|
return `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${apiKey}`;
|
|
533
582
|
};
|
|
583
|
+
var sendOobCode = (apiKey) => {
|
|
584
|
+
return `https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${apiKey}`;
|
|
585
|
+
};
|
|
534
586
|
var getCustomTokenEndpoint = (apiKey) => {
|
|
535
587
|
if (useEmulator() && FIREBASE_AUTH_EMULATOR_HOST) {
|
|
536
588
|
let protocol = "http://";
|
|
@@ -541,9 +593,6 @@ var getCustomTokenEndpoint = (apiKey) => {
|
|
|
541
593
|
}
|
|
542
594
|
return `https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apiKey}`;
|
|
543
595
|
};
|
|
544
|
-
var passwordResetEndpoint = (apiKey) => {
|
|
545
|
-
return `https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=${apiKey}`;
|
|
546
|
-
};
|
|
547
596
|
|
|
548
597
|
// src/fireRestApi/request.ts
|
|
549
598
|
var FIREBASE_ENDPOINT_MAP = {
|
|
@@ -551,8 +600,8 @@ var FIREBASE_ENDPOINT_MAP = {
|
|
|
551
600
|
signInWithPassword,
|
|
552
601
|
signUp: signUpEndpoint,
|
|
553
602
|
signInWithCustomToken: getCustomTokenEndpoint,
|
|
554
|
-
passwordReset:
|
|
555
|
-
sendOobCode
|
|
603
|
+
passwordReset: sendOobCode,
|
|
604
|
+
sendOobCode,
|
|
556
605
|
lookup: lookupEndpoint
|
|
557
606
|
};
|
|
558
607
|
function createRequest(options) {
|
|
@@ -685,7 +734,8 @@ function createFireApi(options) {
|
|
|
685
734
|
return {
|
|
686
735
|
email: new EmailApi(request),
|
|
687
736
|
password: new PasswordApi(request),
|
|
688
|
-
signIn: new
|
|
737
|
+
signIn: new SignInApi(request),
|
|
738
|
+
signInToken: new SignInTokenApi(request),
|
|
689
739
|
signUp: new SignUpApi(request),
|
|
690
740
|
tokens: new TokenApi(request),
|
|
691
741
|
userData: new UserData(request)
|
|
@@ -705,6 +755,9 @@ function mergePreDefinedOptions(userOptions = {}) {
|
|
|
705
755
|
};
|
|
706
756
|
}
|
|
707
757
|
|
|
758
|
+
// src/tokens/request.ts
|
|
759
|
+
var import_ms = require("@tern-secure/shared/ms");
|
|
760
|
+
|
|
708
761
|
// src/jwt/customJwt.ts
|
|
709
762
|
var import_jose = require("jose");
|
|
710
763
|
var CustomTokenError = class extends Error {
|
|
@@ -1041,44 +1094,33 @@ async function verifySignature(jwt, key) {
|
|
|
1041
1094
|
}
|
|
1042
1095
|
}
|
|
1043
1096
|
function ternDecodeJwt(token) {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
if (tokenParts.length !== 3) {
|
|
1049
|
-
return {
|
|
1050
|
-
errors: [
|
|
1051
|
-
new TokenVerificationError({
|
|
1052
|
-
reason: TokenVerificationErrorReason.TokenInvalid,
|
|
1053
|
-
message: "Invalid JWT format"
|
|
1054
|
-
})
|
|
1055
|
-
]
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
|
-
const [rawHeader, rawPayload, rawSignature] = tokenParts;
|
|
1059
|
-
const signature = base64url.parse(rawSignature, { loose: true });
|
|
1060
|
-
const data = {
|
|
1061
|
-
header,
|
|
1062
|
-
payload,
|
|
1063
|
-
signature,
|
|
1064
|
-
raw: {
|
|
1065
|
-
header: rawHeader,
|
|
1066
|
-
payload: rawPayload,
|
|
1067
|
-
signature: rawSignature,
|
|
1068
|
-
text: token
|
|
1069
|
-
}
|
|
1070
|
-
};
|
|
1071
|
-
return { data };
|
|
1072
|
-
} catch (error) {
|
|
1097
|
+
const header = (0, import_jose3.decodeProtectedHeader)(token);
|
|
1098
|
+
const payload = (0, import_jose3.decodeJwt)(token);
|
|
1099
|
+
const tokenParts = (token || "").toString().split(".");
|
|
1100
|
+
if (tokenParts.length !== 3) {
|
|
1073
1101
|
return {
|
|
1074
1102
|
errors: [
|
|
1075
1103
|
new TokenVerificationError({
|
|
1076
1104
|
reason: TokenVerificationErrorReason.TokenInvalid,
|
|
1077
|
-
message:
|
|
1105
|
+
message: "Invalid JWT format"
|
|
1078
1106
|
})
|
|
1079
1107
|
]
|
|
1080
1108
|
};
|
|
1081
1109
|
}
|
|
1110
|
+
const [rawHeader, rawPayload, rawSignature] = tokenParts;
|
|
1111
|
+
const signature = base64url.parse(rawSignature, { loose: true });
|
|
1112
|
+
const data = {
|
|
1113
|
+
header,
|
|
1114
|
+
payload,
|
|
1115
|
+
signature,
|
|
1116
|
+
raw: {
|
|
1117
|
+
header: rawHeader,
|
|
1118
|
+
payload: rawPayload,
|
|
1119
|
+
signature: rawSignature,
|
|
1120
|
+
text: token
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
1123
|
+
return { data };
|
|
1082
1124
|
}
|
|
1083
1125
|
async function verifyJwt(token, options) {
|
|
1084
1126
|
const { key } = options;
|
|
@@ -1326,9 +1368,14 @@ function getAuth(options) {
|
|
|
1326
1368
|
const idAndRefreshTokens = await customForIdAndRefreshToken(customToken, {
|
|
1327
1369
|
referer: opts.referer
|
|
1328
1370
|
});
|
|
1371
|
+
const decodedCustomIdToken = await verifyToken(idAndRefreshTokens.idToken, options);
|
|
1372
|
+
if (decodedCustomIdToken.errors) {
|
|
1373
|
+
throw decodedCustomIdToken.errors[0];
|
|
1374
|
+
}
|
|
1329
1375
|
return {
|
|
1330
1376
|
...idAndRefreshTokens,
|
|
1331
|
-
customToken
|
|
1377
|
+
customToken,
|
|
1378
|
+
auth_time: decodedCustomIdToken.data.auth_time
|
|
1332
1379
|
};
|
|
1333
1380
|
}
|
|
1334
1381
|
return {
|
|
@@ -1346,6 +1393,7 @@ var RequestProcessorContext = class {
|
|
|
1346
1393
|
this.options = options;
|
|
1347
1394
|
this.initHeaderValues();
|
|
1348
1395
|
this.initCookieValues();
|
|
1396
|
+
this.initHandshakeValues();
|
|
1349
1397
|
this.initUrlValues();
|
|
1350
1398
|
Object.assign(this, options);
|
|
1351
1399
|
this.ternUrl = this.ternSecureRequest.ternUrl;
|
|
@@ -1374,6 +1422,11 @@ var RequestProcessorContext = class {
|
|
|
1374
1422
|
this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);
|
|
1375
1423
|
this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);
|
|
1376
1424
|
this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);
|
|
1425
|
+
this.ternAuth = Number.parseInt(this.getCookie(constants.Cookies.TernAut) || "0", 10);
|
|
1426
|
+
}
|
|
1427
|
+
initHandshakeValues() {
|
|
1428
|
+
this.handshakeToken = this.getQueryParam(constants.QueryParameters.Handshake) || this.getCookie(constants.Cookies.Handshake);
|
|
1429
|
+
this.handshakeNonce = this.getQueryParam(constants.QueryParameters.HandshakeNonce) || this.getCookie(constants.Cookies.HandshakeNonce);
|
|
1377
1430
|
}
|
|
1378
1431
|
initUrlValues() {
|
|
1379
1432
|
this.method = this.ternSecureRequest.method;
|
|
@@ -1381,6 +1434,9 @@ var RequestProcessorContext = class {
|
|
|
1381
1434
|
this.endpoint = this.pathSegments[2];
|
|
1382
1435
|
this.subEndpoint = this.pathSegments[3];
|
|
1383
1436
|
}
|
|
1437
|
+
getQueryParam(name) {
|
|
1438
|
+
return this.ternSecureRequest.ternUrl.searchParams.get(name);
|
|
1439
|
+
}
|
|
1384
1440
|
getHeader(name) {
|
|
1385
1441
|
return this.ternSecureRequest.headers.get(name) || void 0;
|
|
1386
1442
|
}
|
|
@@ -1412,6 +1468,9 @@ var import_cookie2 = require("@tern-secure/shared/cookie");
|
|
|
1412
1468
|
function hasAuthorizationHeader(request) {
|
|
1413
1469
|
return request.headers.has("Authorization");
|
|
1414
1470
|
}
|
|
1471
|
+
function convertToSeconds(value) {
|
|
1472
|
+
return (0, import_ms.ms)(value) / 1e3;
|
|
1473
|
+
}
|
|
1415
1474
|
function isRequestForRefresh(error, context, request) {
|
|
1416
1475
|
return error.reason === TokenVerificationErrorReason.TokenExpired && !!context.refreshTokenInCookie && request.method === "GET";
|
|
1417
1476
|
}
|
|
@@ -1419,6 +1478,16 @@ async function authenticateRequest(request, options) {
|
|
|
1419
1478
|
const context = createRequestProcessor(createTernSecureRequest(request), options);
|
|
1420
1479
|
const { refreshTokenInCookie } = context;
|
|
1421
1480
|
const { refreshExpiredIdToken } = getAuth(options);
|
|
1481
|
+
function checkSessionTimeout(authTimeValue) {
|
|
1482
|
+
const defaultMaxAgeSeconds = convertToSeconds("5 days");
|
|
1483
|
+
const REAUTH_PERIOD_SECONDS = context.session?.maxAge ? convertToSeconds(context.session.maxAge) : defaultMaxAgeSeconds;
|
|
1484
|
+
const currentTime = Math.floor(Date.now() / 1e3);
|
|
1485
|
+
const authAge = currentTime - authTimeValue;
|
|
1486
|
+
if (authTimeValue > 0 && authAge > REAUTH_PERIOD_SECONDS) {
|
|
1487
|
+
return signedOut(context, AuthErrorReason.AuthTimeout, "Authentication expired");
|
|
1488
|
+
}
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1422
1491
|
async function refreshToken() {
|
|
1423
1492
|
if (!refreshTokenInCookie) {
|
|
1424
1493
|
return {
|
|
@@ -1440,10 +1509,10 @@ async function authenticateRequest(request, options) {
|
|
|
1440
1509
|
}
|
|
1441
1510
|
const headers = new Headers();
|
|
1442
1511
|
const { idToken } = refreshedData;
|
|
1443
|
-
const maxAge =
|
|
1512
|
+
const maxAge = 365 * 24 * 60 * 60;
|
|
1444
1513
|
const cookiePrefix = (0, import_cookie2.getCookiePrefix)();
|
|
1445
1514
|
const idTokenCookieName = (0, import_cookie2.getCookieName)(constants.Cookies.IdToken, cookiePrefix);
|
|
1446
|
-
const baseCookieAttributes =
|
|
1515
|
+
const baseCookieAttributes = `HttpOnly; Secure; SameSite=Strict; Max-Age=${maxAge}; Path=/`;
|
|
1447
1516
|
const idTokenCookie = `${idTokenCookieName}=${idToken}; ${baseCookieAttributes};`;
|
|
1448
1517
|
headers.append("Set-Cookie", idTokenCookie);
|
|
1449
1518
|
const { data: decoded, errors } = await verifyToken(idToken, options);
|
|
@@ -1455,7 +1524,78 @@ async function authenticateRequest(request, options) {
|
|
|
1455
1524
|
}
|
|
1456
1525
|
return { data: { decoded, token: idToken, headers }, error: null };
|
|
1457
1526
|
}
|
|
1527
|
+
async function handleLocalHandshakeWithErrorCheck(context2, reason, message, skipSessionCheck = false) {
|
|
1528
|
+
const hasRefreshTokenInCookie = !!context2.refreshTokenInCookie;
|
|
1529
|
+
if (!hasRefreshTokenInCookie) {
|
|
1530
|
+
return signedOut(context2, reason, "Refresh token missing in cookie");
|
|
1531
|
+
}
|
|
1532
|
+
if (reason === AuthErrorReason.TernAutWithoutSessionToken) {
|
|
1533
|
+
if (!skipSessionCheck) {
|
|
1534
|
+
const sessionTimeoutResult = checkSessionTimeout(context2.ternAuth);
|
|
1535
|
+
if (sessionTimeoutResult) {
|
|
1536
|
+
return sessionTimeoutResult;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
const { data, error } = await handleRefresh();
|
|
1540
|
+
if (data) {
|
|
1541
|
+
return signedIn(context2, data.decoded, data.headers, data.token);
|
|
1542
|
+
}
|
|
1543
|
+
return signedOut(context2, reason, "Failed to refresh idToken");
|
|
1544
|
+
}
|
|
1545
|
+
if (reason === AuthErrorReason.SessionTokenWithoutTernAUT || reason === AuthErrorReason.SessionTokenIATBeforeTernAUT) {
|
|
1546
|
+
const { data, errors } = ternDecodeJwt(context2.idTokenInCookie);
|
|
1547
|
+
if (errors) {
|
|
1548
|
+
throw errors[0];
|
|
1549
|
+
}
|
|
1550
|
+
const authTime = data.payload.auth_time;
|
|
1551
|
+
if (!authTime || typeof authTime !== "number") {
|
|
1552
|
+
return signedOut(context2, reason, "Token missing auth_time");
|
|
1553
|
+
}
|
|
1554
|
+
if (!skipSessionCheck) {
|
|
1555
|
+
const sessionTimeoutResult = checkSessionTimeout(authTime);
|
|
1556
|
+
if (sessionTimeoutResult) {
|
|
1557
|
+
return sessionTimeoutResult;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
const { data: verifiedToken, errors: verifyErrors } = await verifyToken(context2.idTokenInCookie, options);
|
|
1561
|
+
if (verifyErrors) {
|
|
1562
|
+
throw verifyErrors[0];
|
|
1563
|
+
}
|
|
1564
|
+
const headers = new Headers();
|
|
1565
|
+
const oneYearInSeconds = 365 * 24 * 60 * 60;
|
|
1566
|
+
const ternAutCookie = `${constants.Cookies.TernAut}=${authTime}; Max-Age=${oneYearInSeconds}; Secure; SameSite=Strict; Path=/`;
|
|
1567
|
+
headers.append("Set-Cookie", ternAutCookie);
|
|
1568
|
+
return signedIn(context2, verifiedToken, headers, context2.idTokenInCookie);
|
|
1569
|
+
}
|
|
1570
|
+
return signedOut(context2, reason, message);
|
|
1571
|
+
}
|
|
1458
1572
|
async function authenticateRequestWithTokenInCookie() {
|
|
1573
|
+
const hasTernAuth = context.ternAuth;
|
|
1574
|
+
const hasIdTokenInCookie = !!context.idTokenInCookie;
|
|
1575
|
+
if (!hasTernAuth && !hasIdTokenInCookie) {
|
|
1576
|
+
return signedOut(context, AuthErrorReason.SessionTokenAndAuthMissing);
|
|
1577
|
+
}
|
|
1578
|
+
if (!hasTernAuth && hasIdTokenInCookie) {
|
|
1579
|
+
return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenWithoutTernAUT, "");
|
|
1580
|
+
}
|
|
1581
|
+
if (hasTernAuth && !hasIdTokenInCookie) {
|
|
1582
|
+
return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.TernAutWithoutSessionToken, "");
|
|
1583
|
+
}
|
|
1584
|
+
const sessionTimeoutResult = checkSessionTimeout(context.ternAuth);
|
|
1585
|
+
if (sessionTimeoutResult) {
|
|
1586
|
+
return sessionTimeoutResult;
|
|
1587
|
+
}
|
|
1588
|
+
const { data: decodedResult, errors: decodeErrors } = ternDecodeJwt(context.idTokenInCookie);
|
|
1589
|
+
if (decodeErrors) {
|
|
1590
|
+
return handleError(decodeErrors[0], "cookie");
|
|
1591
|
+
}
|
|
1592
|
+
const tokenIat = decodedResult.payload.iat;
|
|
1593
|
+
if (!tokenIat) {
|
|
1594
|
+
return signedOut(context, AuthErrorReason.SessionTokenMissing, "");
|
|
1595
|
+
}
|
|
1596
|
+
if (tokenIat < context.ternAuth) {
|
|
1597
|
+
return await handleLocalHandshakeWithErrorCheck(context, AuthErrorReason.SessionTokenIATBeforeTernAUT, "", true);
|
|
1598
|
+
}
|
|
1459
1599
|
try {
|
|
1460
1600
|
const { data, errors } = await verifyToken(context.idTokenInCookie, options);
|
|
1461
1601
|
if (errors) {
|
|
@@ -1466,6 +1606,7 @@ async function authenticateRequest(request, options) {
|
|
|
1466
1606
|
} catch (err) {
|
|
1467
1607
|
return handleError(err, "cookie");
|
|
1468
1608
|
}
|
|
1609
|
+
return signedOut(context, AuthErrorReason.UnexpectedError);
|
|
1469
1610
|
}
|
|
1470
1611
|
async function authenticateRequestWithTokenInHeader() {
|
|
1471
1612
|
const { sessionTokenInHeader } = context;
|