@rodit/rodit-auth-be 9.11.14 → 9.11.20
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/lib/auth/tokenservice.js +238 -63
- package/package.json +1 -1
package/lib/auth/tokenservice.js
CHANGED
|
@@ -25,9 +25,8 @@ logger.infoWithContext("TokenService using SessionManager instance", {
|
|
|
25
25
|
timestamp: new Date().toISOString()
|
|
26
26
|
});
|
|
27
27
|
const stateManager = require('../blockchain/statemanager');
|
|
28
|
-
const {
|
|
29
|
-
nearorg_rpc_tokenfromroditid,
|
|
30
|
-
nearorg_rpc_tokensfromaccountid,
|
|
28
|
+
const {
|
|
29
|
+
nearorg_rpc_tokenfromroditid,
|
|
31
30
|
nearorg_rpc_fetchpublickeybytes,
|
|
32
31
|
} = require("../blockchain/blockchainservice");
|
|
33
32
|
|
|
@@ -62,6 +61,15 @@ function isCanonicalBase64Url(value) {
|
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
|
|
64
|
+
/** Login peer RODiT token id embedded in JWT sub (`{sp};sub={peerTokenId}`). */
|
|
65
|
+
function extractLoginPeerRoditIdFromSub(sub) {
|
|
66
|
+
if (!sub || typeof sub !== "string") {
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
const subParts = sub.split(";sub=");
|
|
70
|
+
return subParts.length > 1 ? subParts[1] : "";
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
function parseRoditJwtDurationSeconds(metadata) {
|
|
66
74
|
const parsed = parseInt(metadata?.jwt_duration, 10);
|
|
67
75
|
if (Number.isFinite(parsed) && parsed > 0) {
|
|
@@ -965,6 +973,31 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
965
973
|
keyCreationDuration,
|
|
966
974
|
});
|
|
967
975
|
|
|
976
|
+
const signatureStart = Date.now();
|
|
977
|
+
const timeString = await unixTimeToDateString(now);
|
|
978
|
+
const roditidandtimestamp = new TextEncoder().encode(
|
|
979
|
+
token.rodit_id + timeString
|
|
980
|
+
);
|
|
981
|
+
let privateKeyToUse = config_own_rodit.own_rodit_bytes_private_key;
|
|
982
|
+
if (Buffer.isBuffer(privateKeyToUse)) {
|
|
983
|
+
privateKeyToUse = new Uint8Array(privateKeyToUse);
|
|
984
|
+
} else if (!(privateKeyToUse instanceof Uint8Array)) {
|
|
985
|
+
privateKeyToUse = new Uint8Array(Array.from(privateKeyToUse));
|
|
986
|
+
}
|
|
987
|
+
const own_rodit_bytes_signature = nacl.sign.detached(
|
|
988
|
+
roditidandtimestamp,
|
|
989
|
+
privateKeyToUse
|
|
990
|
+
);
|
|
991
|
+
const renewed_rodit_idsignature = Buffer.from(
|
|
992
|
+
own_rodit_bytes_signature
|
|
993
|
+
).toString("base64url");
|
|
994
|
+
logger.debug("Regenerated rodit_idsignature for renewed credential", {
|
|
995
|
+
requestId,
|
|
996
|
+
signatureDuration: Date.now() - signatureStart,
|
|
997
|
+
roditId: token.rodit_id,
|
|
998
|
+
iat: now,
|
|
999
|
+
});
|
|
1000
|
+
|
|
968
1001
|
// Keep existing session ID and creation time
|
|
969
1002
|
const session_id = existingSessionId;
|
|
970
1003
|
const session_iat = token.session_iat;
|
|
@@ -1020,7 +1053,7 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
1020
1053
|
rodit_id: token.rodit_id,
|
|
1021
1054
|
rodit_owner: token.rodit_owner,
|
|
1022
1055
|
rodit_allowediso3166list: token.rodit_allowediso3166list,
|
|
1023
|
-
rodit_idsignature:
|
|
1056
|
+
rodit_idsignature: renewed_rodit_idsignature,
|
|
1024
1057
|
rodit_maxrequests: token.rodit_maxrequests,
|
|
1025
1058
|
rodit_maxrqwindow: token.rodit_maxrqwindow,
|
|
1026
1059
|
rodit_permissionedroutes: token.rodit_permissionedroutes,
|
|
@@ -1657,14 +1690,35 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
1657
1690
|
newToken = renewalResult.newToken;
|
|
1658
1691
|
|
|
1659
1692
|
if (isExpired && !newToken) {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1693
|
+
const renewalNow = Math.floor(Date.now() / 1000);
|
|
1694
|
+
const sessionExpUnix =
|
|
1695
|
+
payload.session_exp != null ? Number(payload.session_exp) : null;
|
|
1696
|
+
const sessionStillActive =
|
|
1697
|
+
Number.isFinite(sessionExpUnix) && sessionExpUnix > renewalNow;
|
|
1698
|
+
|
|
1699
|
+
if (sessionStillActive) {
|
|
1700
|
+
logger.warn(
|
|
1701
|
+
"Credential expired and renewal failed but session still active; allowing request",
|
|
1702
|
+
{
|
|
1703
|
+
component: "JwtAuth",
|
|
1704
|
+
method: "validate_jwt_token_be",
|
|
1705
|
+
requestId,
|
|
1706
|
+
jti: payload.jti,
|
|
1707
|
+
sessionExp: sessionExpUnix,
|
|
1708
|
+
now: renewalNow,
|
|
1709
|
+
}
|
|
1710
|
+
);
|
|
1711
|
+
} else {
|
|
1712
|
+
logger.error("Token expired and renewal failed", {
|
|
1713
|
+
component: "JwtAuth",
|
|
1714
|
+
method: "validate_jwt_token_be",
|
|
1715
|
+
requestId,
|
|
1716
|
+
jti: payload.jti,
|
|
1717
|
+
sessionExp: sessionExpUnix,
|
|
1718
|
+
});
|
|
1719
|
+
|
|
1720
|
+
throw new Error("Error 007: Token has expired and renewal failed");
|
|
1721
|
+
}
|
|
1668
1722
|
}
|
|
1669
1723
|
} else if (isExpired) {
|
|
1670
1724
|
logger.info("Allowing signature-valid expired token for special flow", {
|
|
@@ -1727,20 +1781,30 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
1727
1781
|
const startTime = Date.now();
|
|
1728
1782
|
|
|
1729
1783
|
try {
|
|
1784
|
+
const extractedSub = extractLoginPeerRoditIdFromSub(token.sub);
|
|
1785
|
+
if (!extractedSub) {
|
|
1786
|
+
const duration = Date.now() - startTime;
|
|
1787
|
+
logger.warn("Brief token validation failed - missing login peer in sub", {
|
|
1788
|
+
component: "JwtAuth",
|
|
1789
|
+
method: "brief_validate_jwt_token_be",
|
|
1790
|
+
requestId,
|
|
1791
|
+
duration,
|
|
1792
|
+
tokenJti: token.jti,
|
|
1793
|
+
tokenSub: token.sub,
|
|
1794
|
+
});
|
|
1795
|
+
logger.metric("jwt_brief_validation", duration, {
|
|
1796
|
+
result: "failure",
|
|
1797
|
+
token_jti: token.jti || "unknown",
|
|
1798
|
+
id_match: "false",
|
|
1799
|
+
});
|
|
1800
|
+
return { isValid: false, notAfter: null };
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1730
1803
|
const tokenFetchStart = Date.now();
|
|
1731
|
-
const peer_rodit =
|
|
1732
|
-
await nearorg_rpc_tokensfromaccountid(
|
|
1733
|
-
|
|
1734
|
-
token.aud
|
|
1735
|
-
);
|
|
1804
|
+
const peer_rodit = await nearorg_rpc_tokenfromroditid(extractedSub);
|
|
1736
1805
|
const tokenFetchDuration = Date.now() - tokenFetchStart;
|
|
1737
1806
|
|
|
1738
|
-
const
|
|
1739
|
-
const extractedSub = subParts.length > 1 ? subParts[1] : "";
|
|
1740
|
-
|
|
1741
|
-
const isValid =
|
|
1742
|
-
peer_rodit.token_id === extractedSub &&
|
|
1743
|
-
peer_rodit.owner_id === token.aud;
|
|
1807
|
+
const isValid = !!peer_rodit?.token_id && peer_rodit.token_id === extractedSub;
|
|
1744
1808
|
|
|
1745
1809
|
const totalDuration = Date.now() - startTime;
|
|
1746
1810
|
|
|
@@ -1753,6 +1817,7 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
1753
1817
|
tokenFetchDuration,
|
|
1754
1818
|
tokenJti: token.jti,
|
|
1755
1819
|
peerRoditId: peer_rodit.token_id,
|
|
1820
|
+
extractedSub,
|
|
1756
1821
|
notAfter: peer_rodit.metadata.not_after,
|
|
1757
1822
|
});
|
|
1758
1823
|
|
|
@@ -1769,26 +1834,23 @@ function resolveCredentialExpirationUnix(now, sessionExpiration, own_rodit) {
|
|
|
1769
1834
|
duration: totalDuration,
|
|
1770
1835
|
tokenFetchDuration,
|
|
1771
1836
|
tokenJti: token.jti,
|
|
1772
|
-
peerRoditId: peer_rodit
|
|
1837
|
+
peerRoditId: peer_rodit?.token_id || null,
|
|
1773
1838
|
extractedSub,
|
|
1774
1839
|
tokenAud: token.aud,
|
|
1775
|
-
|
|
1776
|
-
idMatch: peer_rodit.token_id === extractedSub,
|
|
1777
|
-
ownerMatch: peer_rodit.owner_id === token.aud,
|
|
1840
|
+
idMatch: peer_rodit?.token_id === extractedSub,
|
|
1778
1841
|
});
|
|
1779
1842
|
|
|
1780
1843
|
// Add metrics for failed brief validations
|
|
1781
1844
|
logger.metric("jwt_brief_validation", totalDuration, {
|
|
1782
1845
|
result: "failure",
|
|
1783
1846
|
token_jti: token.jti || "unknown",
|
|
1784
|
-
id_match: peer_rodit
|
|
1785
|
-
owner_match: peer_rodit.owner_id === token.aud ? "true" : "false",
|
|
1847
|
+
id_match: peer_rodit?.token_id === extractedSub ? "true" : "false",
|
|
1786
1848
|
});
|
|
1787
1849
|
}
|
|
1788
1850
|
|
|
1789
1851
|
return {
|
|
1790
1852
|
isValid,
|
|
1791
|
-
notAfter: peer_rodit
|
|
1853
|
+
notAfter: peer_rodit?.metadata?.not_after ?? null,
|
|
1792
1854
|
};
|
|
1793
1855
|
} catch (error) {
|
|
1794
1856
|
const duration = Date.now() - startTime;
|
|
@@ -1831,14 +1893,32 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
1831
1893
|
const startTime = performance.now(); // More precise timing measurement
|
|
1832
1894
|
|
|
1833
1895
|
try {
|
|
1896
|
+
const extractedSub = extractLoginPeerRoditIdFromSub(token.sub);
|
|
1897
|
+
if (!extractedSub) {
|
|
1898
|
+
logger.warn("Thorough token validation failed - missing login peer in sub", {
|
|
1899
|
+
component: "JwtAuth",
|
|
1900
|
+
method: "thorough_validate_jwt_token_be",
|
|
1901
|
+
requestId,
|
|
1902
|
+
duration: performance.now() - startTime,
|
|
1903
|
+
tokenJti: token?.jti,
|
|
1904
|
+
tokenSub: token?.sub,
|
|
1905
|
+
});
|
|
1906
|
+
logger.metric &&
|
|
1907
|
+
logger.metric("jwt_thorough_validation", performance.now() - startTime, {
|
|
1908
|
+
result: "missing_login_peer_sub",
|
|
1909
|
+
token_jti: token.jti || "unknown",
|
|
1910
|
+
});
|
|
1911
|
+
return { isValid: false, notAfter: null };
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1834
1914
|
// Fetch configuration with better timing measurements
|
|
1835
1915
|
const configStart = performance.now();
|
|
1836
1916
|
const config_own_rodit = await stateManager.getConfigOwnRodit();
|
|
1837
1917
|
const configDuration = performance.now() - configStart;
|
|
1838
1918
|
|
|
1839
|
-
// Fetch peer RODiT
|
|
1919
|
+
// Fetch login peer RODiT (client identity from sub), not server passport (rodit_id claim)
|
|
1840
1920
|
const tokenFetchStart = performance.now();
|
|
1841
|
-
const peer_rodit = await nearorg_rpc_tokenfromroditid(
|
|
1921
|
+
const peer_rodit = await nearorg_rpc_tokenfromroditid(extractedSub);
|
|
1842
1922
|
const tokenFetchDuration = performance.now() - tokenFetchStart;
|
|
1843
1923
|
|
|
1844
1924
|
if (!peer_rodit) {
|
|
@@ -1846,7 +1926,7 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
1846
1926
|
component: "JwtAuth",
|
|
1847
1927
|
requestId,
|
|
1848
1928
|
duration: performance.now() - startTime,
|
|
1849
|
-
|
|
1929
|
+
loginPeerRoditId: extractedSub,
|
|
1850
1930
|
});
|
|
1851
1931
|
|
|
1852
1932
|
// Add metrics for failed token fetch
|
|
@@ -2075,11 +2155,7 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2075
2155
|
};
|
|
2076
2156
|
}
|
|
2077
2157
|
|
|
2078
|
-
|
|
2079
|
-
const subParts = token.sub.split(";sub=");
|
|
2080
|
-
const extractedSub = subParts.length > 1 ? subParts[1] : "";
|
|
2081
|
-
|
|
2082
|
-
logger.debug("Extracted subject from token", {
|
|
2158
|
+
logger.debug("Login peer identity check", {
|
|
2083
2159
|
requestId,
|
|
2084
2160
|
extractedSub,
|
|
2085
2161
|
tokenSub: token.sub,
|
|
@@ -2088,10 +2164,8 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2088
2164
|
tokenAud: token.aud,
|
|
2089
2165
|
});
|
|
2090
2166
|
|
|
2091
|
-
// Additional identity checks
|
|
2092
2167
|
const idMatch = peer_rodit.token_id === extractedSub;
|
|
2093
|
-
const
|
|
2094
|
-
const isValid = idMatch && ownerMatch;
|
|
2168
|
+
const isValid = idMatch;
|
|
2095
2169
|
|
|
2096
2170
|
const totalDuration = performance.now() - startTime;
|
|
2097
2171
|
|
|
@@ -2114,10 +2188,6 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2114
2188
|
peer_rodit_id: peer_rodit.token_id,
|
|
2115
2189
|
});
|
|
2116
2190
|
} else {
|
|
2117
|
-
const failedIdentityChecks = [];
|
|
2118
|
-
if (!idMatch) failedIdentityChecks.push("token_id_mismatch");
|
|
2119
|
-
if (!ownerMatch) failedIdentityChecks.push("owner_id_mismatch");
|
|
2120
|
-
|
|
2121
2191
|
logger.warn("Token identity verification failed", {
|
|
2122
2192
|
component: "JwtAuth",
|
|
2123
2193
|
method: "thorough_validate_jwt_token_be",
|
|
@@ -2129,8 +2199,7 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2129
2199
|
tokenAud: token.aud,
|
|
2130
2200
|
peerRoditOwnerId: peer_rodit.owner_id,
|
|
2131
2201
|
idMatch,
|
|
2132
|
-
|
|
2133
|
-
failedIdentityChecks,
|
|
2202
|
+
failedIdentityChecks: ["token_id_mismatch"],
|
|
2134
2203
|
});
|
|
2135
2204
|
|
|
2136
2205
|
// Add metrics for identity mismatch with more details
|
|
@@ -2138,19 +2207,22 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2138
2207
|
logger.metric("jwt_thorough_validation", totalDuration, {
|
|
2139
2208
|
result: "identity_mismatch",
|
|
2140
2209
|
token_jti: token.jti || "unknown",
|
|
2141
|
-
id_match:
|
|
2142
|
-
|
|
2143
|
-
failed_checks: failedIdentityChecks.join(","),
|
|
2210
|
+
id_match: "false",
|
|
2211
|
+
failed_checks: "token_id_mismatch",
|
|
2144
2212
|
peer_rodit_id: peer_rodit.token_id,
|
|
2145
2213
|
});
|
|
2146
2214
|
}
|
|
2147
2215
|
|
|
2216
|
+
const failedIdentityChecks = !isValid ? ["token_id_mismatch"] : [];
|
|
2217
|
+
|
|
2148
2218
|
return {
|
|
2149
2219
|
isValid,
|
|
2150
2220
|
notAfter: peer_rodit.metadata.not_after,
|
|
2151
2221
|
error: !isValid ? "Token identity verification failed" : undefined,
|
|
2152
2222
|
errorCode: !isValid ? "SERVER_TOKEN_IDENTITY_MISMATCH" : undefined,
|
|
2153
|
-
errorMessage: !isValid
|
|
2223
|
+
errorMessage: !isValid
|
|
2224
|
+
? `Server token identity mismatch: ${failedIdentityChecks.join(", ")}`
|
|
2225
|
+
: undefined
|
|
2154
2226
|
};
|
|
2155
2227
|
} catch (error) {
|
|
2156
2228
|
const duration = performance.now() - startTime;
|
|
@@ -2187,6 +2259,70 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2187
2259
|
}
|
|
2188
2260
|
}
|
|
2189
2261
|
|
|
2262
|
+
/**
|
|
2263
|
+
* Decide brief vs thorough renewal verification using existing SECURITY_OPTIONS constants.
|
|
2264
|
+
*
|
|
2265
|
+
* @param {Object} params
|
|
2266
|
+
* @returns {Object} Plan with shouldDoFullVerification, urgency, pThorough, newduration, floors
|
|
2267
|
+
*/
|
|
2268
|
+
function resolveRenewalVerificationPlan({
|
|
2269
|
+
forceRenewal = false,
|
|
2270
|
+
durationLeftpct = 0,
|
|
2271
|
+
currentDuration = 0,
|
|
2272
|
+
lapsedProportion = 0.8,
|
|
2273
|
+
thresholdValidationType = 0.1,
|
|
2274
|
+
durationRamp = 0.85,
|
|
2275
|
+
fallbackJwtDuration = 3600,
|
|
2276
|
+
roditMaxRqWindow,
|
|
2277
|
+
randomNumber = Math.random(),
|
|
2278
|
+
}) {
|
|
2279
|
+
const eligibilityTail = 1.0 - lapsedProportion;
|
|
2280
|
+
const safeCurrentDuration = Math.max(0, Number(currentDuration) || 0);
|
|
2281
|
+
const newduration = safeCurrentDuration * durationRamp;
|
|
2282
|
+
|
|
2283
|
+
let urgency;
|
|
2284
|
+
if (forceRenewal) {
|
|
2285
|
+
urgency = 1;
|
|
2286
|
+
} else if (eligibilityTail <= 0) {
|
|
2287
|
+
urgency = 1;
|
|
2288
|
+
} else {
|
|
2289
|
+
const tailFraction = durationLeftpct / 100 / eligibilityTail;
|
|
2290
|
+
urgency = Math.min(1, Math.max(0, 1 - tailFraction));
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
const pThorough =
|
|
2294
|
+
thresholdValidationType + urgency * (1 - thresholdValidationType);
|
|
2295
|
+
|
|
2296
|
+
const baselineDuration = Math.max(1, Number(fallbackJwtDuration) || 3600);
|
|
2297
|
+
const rampedFloor = baselineDuration * eligibilityTail * durationRamp;
|
|
2298
|
+
const maxRqWindow = Number(roditMaxRqWindow) || baselineDuration;
|
|
2299
|
+
const rqWindowFloor = maxRqWindow * eligibilityTail;
|
|
2300
|
+
|
|
2301
|
+
const stochasticThorough = urgency >= 1 || randomNumber < pThorough;
|
|
2302
|
+
const rampedFloorThorough = newduration <= rampedFloor;
|
|
2303
|
+
const rqWindowFloorThorough = newduration <= rqWindowFloor;
|
|
2304
|
+
const deterministicThorough = rampedFloorThorough || rqWindowFloorThorough;
|
|
2305
|
+
|
|
2306
|
+
let verificationReason = "brief";
|
|
2307
|
+
if (deterministicThorough) {
|
|
2308
|
+
verificationReason = rampedFloorThorough ? "ramped_floor" : "rq_window_floor";
|
|
2309
|
+
} else if (stochasticThorough) {
|
|
2310
|
+
verificationReason = "stochastic";
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
return {
|
|
2314
|
+
shouldDoFullVerification: stochasticThorough || deterministicThorough,
|
|
2315
|
+
urgency,
|
|
2316
|
+
pThorough,
|
|
2317
|
+
newduration,
|
|
2318
|
+
rampedFloor,
|
|
2319
|
+
rqWindowFloor,
|
|
2320
|
+
stochasticThorough,
|
|
2321
|
+
deterministicThorough,
|
|
2322
|
+
verificationReason,
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2190
2326
|
/**
|
|
2191
2327
|
* Check if a token needs renewal and renew if necessary
|
|
2192
2328
|
*
|
|
@@ -2210,12 +2346,16 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2210
2346
|
const DURATIONRAMP = parseFloat(
|
|
2211
2347
|
config.get('SECURITY_OPTIONS.DURATIONRAMP', '0.85')
|
|
2212
2348
|
);
|
|
2349
|
+
const FALLBACK_JWT_DURATION = parseInt(
|
|
2350
|
+
config.get('SECURITY_OPTIONS.FALLBACK_JWT_DURATION', '3600'),
|
|
2351
|
+
10
|
|
2352
|
+
);
|
|
2213
2353
|
|
|
2214
2354
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
2215
2355
|
const timeLeft = payload.exp - currentTime;
|
|
2216
2356
|
const currentDuration = payload.exp - payload.iat;
|
|
2217
|
-
const durationLeftpct =
|
|
2218
|
-
|
|
2357
|
+
const durationLeftpct =
|
|
2358
|
+
currentDuration > 0 ? (timeLeft / currentDuration) * 100 : 0;
|
|
2219
2359
|
|
|
2220
2360
|
// Log session information
|
|
2221
2361
|
const sessionInfo = {
|
|
@@ -2275,13 +2415,40 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2275
2415
|
...sessionInfo,
|
|
2276
2416
|
});
|
|
2277
2417
|
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2418
|
+
const renewalPlan = resolveRenewalVerificationPlan({
|
|
2419
|
+
forceRenewal,
|
|
2420
|
+
durationLeftpct,
|
|
2421
|
+
currentDuration,
|
|
2422
|
+
lapsedProportion: LAPSED_LIFETIME_PROPORTION_4RENEWAL_ELIGIBILITY,
|
|
2423
|
+
thresholdValidationType: THRESHOLD_VALIDATION_TYPE,
|
|
2424
|
+
durationRamp: DURATIONRAMP,
|
|
2425
|
+
fallbackJwtDuration: FALLBACK_JWT_DURATION,
|
|
2426
|
+
roditMaxRqWindow: payload.rodit_maxrqwindow,
|
|
2427
|
+
});
|
|
2428
|
+
const {
|
|
2429
|
+
shouldDoFullVerification,
|
|
2430
|
+
urgency,
|
|
2431
|
+
pThorough,
|
|
2432
|
+
newduration,
|
|
2433
|
+
rampedFloor,
|
|
2434
|
+
rqWindowFloor,
|
|
2435
|
+
verificationReason,
|
|
2436
|
+
} = renewalPlan;
|
|
2437
|
+
|
|
2438
|
+
logger.debug("Renewal verification plan", {
|
|
2439
|
+
component: "TokenRenewalService",
|
|
2440
|
+
method: "checkandrenew_jwt_token",
|
|
2441
|
+
requestId,
|
|
2442
|
+
forceRenewal,
|
|
2443
|
+
durationLeftpct: durationLeftpct.toFixed(1),
|
|
2444
|
+
urgency: urgency.toFixed(3),
|
|
2445
|
+
pThorough: pThorough.toFixed(3),
|
|
2446
|
+
newduration: Math.floor(newduration),
|
|
2447
|
+
rampedFloor: Math.floor(rampedFloor),
|
|
2448
|
+
rqWindowFloor: Math.floor(rqWindowFloor),
|
|
2449
|
+
verificationReason,
|
|
2450
|
+
shouldDoFullVerification,
|
|
2451
|
+
});
|
|
2285
2452
|
|
|
2286
2453
|
const verificationStartTime = Date.now();
|
|
2287
2454
|
|
|
@@ -2366,7 +2533,7 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2366
2533
|
logInfo: {
|
|
2367
2534
|
newDuration: newduration,
|
|
2368
2535
|
reason: shouldDoFullVerification
|
|
2369
|
-
?
|
|
2536
|
+
? `Thorough verification (${verificationReason})`
|
|
2370
2537
|
: "Brief verification",
|
|
2371
2538
|
notAfter: notAfter,
|
|
2372
2539
|
renewalDuration,
|
|
@@ -2409,10 +2576,18 @@ async function thorough_validate_jwt_token_be(token, requestId = ulid()) {
|
|
|
2409
2576
|
|
|
2410
2577
|
|
|
2411
2578
|
// Export the class directly (will be instantiated in rodit.js)
|
|
2412
|
-
module.exports = {
|
|
2579
|
+
module.exports = {
|
|
2580
|
+
generate_jwt_token,
|
|
2581
|
+
base64url2jwk_public_key,
|
|
2413
2582
|
checkandrenew_jwt_token,
|
|
2583
|
+
resolveRenewalVerificationPlan,
|
|
2414
2584
|
thorough_validate_jwt_token_be,
|
|
2415
2585
|
brief_validate_jwt_token_be,
|
|
2416
2586
|
generate_jwt_token_fromtoken,
|
|
2417
|
-
verify_jwt_token,
|
|
2587
|
+
verify_jwt_token,
|
|
2588
|
+
validate_jwt_token_be,
|
|
2589
|
+
generate_session_termination_token,
|
|
2590
|
+
parseRoditJwtDurationSeconds,
|
|
2591
|
+
resolveSessionExpirationUnix,
|
|
2592
|
+
resolveCredentialExpirationUnix,
|
|
2418
2593
|
};
|