@axa-fr/oidc-client 7.22.18 → 7.22.19

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 (73) hide show
  1. package/README.md +31 -39
  2. package/bin/copy-service-worker-files.mjs +24 -17
  3. package/dist/OidcTrustedDomains.js +14 -12
  4. package/dist/cache.d.ts.map +1 -1
  5. package/dist/checkSession.d.ts +1 -1
  6. package/dist/checkSession.d.ts.map +1 -1
  7. package/dist/checkSessionIFrame.d.ts.map +1 -1
  8. package/dist/crypto.d.ts.map +1 -1
  9. package/dist/fetch.d.ts +2 -1
  10. package/dist/fetch.d.ts.map +1 -1
  11. package/dist/index.d.ts +5 -5
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +935 -601
  14. package/dist/index.umd.cjs +2 -2
  15. package/dist/initSession.d.ts +1 -1
  16. package/dist/initSession.d.ts.map +1 -1
  17. package/dist/initWorker.d.ts +2 -2
  18. package/dist/initWorker.d.ts.map +1 -1
  19. package/dist/initWorkerOption.d.ts.map +1 -1
  20. package/dist/jwt.d.ts +2 -2
  21. package/dist/jwt.d.ts.map +1 -1
  22. package/dist/keepSession.d.ts.map +1 -1
  23. package/dist/location.d.ts.map +1 -1
  24. package/dist/login.d.ts +1 -1
  25. package/dist/login.d.ts.map +1 -1
  26. package/dist/logout.d.ts +1 -1
  27. package/dist/logout.d.ts.map +1 -1
  28. package/dist/oidc.d.ts +1 -1
  29. package/dist/oidc.d.ts.map +1 -1
  30. package/dist/oidcClient.d.ts +2 -2
  31. package/dist/oidcClient.d.ts.map +1 -1
  32. package/dist/parseTokens.d.ts.map +1 -1
  33. package/dist/renewTokens.d.ts.map +1 -1
  34. package/dist/requests.d.ts +1 -1
  35. package/dist/requests.d.ts.map +1 -1
  36. package/dist/silentLogin.d.ts.map +1 -1
  37. package/dist/timer.d.ts.map +1 -1
  38. package/dist/types.d.ts +1 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/user.d.ts.map +1 -1
  41. package/dist/version.d.ts +1 -1
  42. package/package.json +2 -2
  43. package/src/cache.ts +21 -18
  44. package/src/checkSession.ts +89 -54
  45. package/src/checkSessionIFrame.ts +70 -69
  46. package/src/crypto.ts +27 -25
  47. package/src/events.ts +28 -28
  48. package/src/fetch.ts +40 -21
  49. package/src/index.ts +6 -17
  50. package/src/iniWorker.spec.ts +26 -16
  51. package/src/initSession.ts +115 -113
  52. package/src/initWorker.ts +299 -212
  53. package/src/initWorkerOption.ts +121 -114
  54. package/src/jwt.ts +150 -136
  55. package/src/keepSession.ts +100 -81
  56. package/src/location.ts +24 -26
  57. package/src/login.ts +246 -189
  58. package/src/logout.spec.ts +131 -76
  59. package/src/logout.ts +130 -115
  60. package/src/oidc.ts +426 -337
  61. package/src/oidcClient.ts +129 -105
  62. package/src/parseTokens.spec.ts +198 -179
  63. package/src/parseTokens.ts +221 -186
  64. package/src/renewTokens.ts +397 -284
  65. package/src/requests.spec.ts +5 -7
  66. package/src/requests.ts +142 -114
  67. package/src/route-utils.spec.ts +17 -19
  68. package/src/route-utils.ts +29 -26
  69. package/src/silentLogin.ts +145 -127
  70. package/src/timer.ts +10 -11
  71. package/src/types.ts +56 -46
  72. package/src/user.ts +17 -12
  73. package/src/version.ts +1 -1
@@ -1,233 +1,268 @@
1
- import {sleepAsync} from './initWorker.js';
2
- import {OidcConfiguration, StringMap, TokenAutomaticRenewMode} from "./types";
3
-
4
- const b64DecodeUnicode = (str) =>
5
- decodeURIComponent(Array.prototype.map.call(atob(str), (c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''));
6
- export const parseJwt = (payload:string) => JSON.parse(b64DecodeUnicode(payload.replaceAll(/-/g, '+').replaceAll(/_/g, '/')));
7
-
8
- const extractTokenPayload = (token:string) => {
9
- try {
10
- if (!token) {
11
- return null;
12
- }
13
- if (countLetter(token, '.') === 2) {
14
- return parseJwt(token.split('.')[1]);
15
- } else {
16
- return null;
17
- }
18
- } catch (e) {
19
- console.warn(e);
1
+ import { sleepAsync } from './initWorker.js';
2
+ import { StringMap, TokenAutomaticRenewMode } from './types';
3
+
4
+ const b64DecodeUnicode = str =>
5
+ decodeURIComponent(
6
+ Array.prototype.map
7
+ .call(atob(str), c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
8
+ .join(''),
9
+ );
10
+ export const parseJwt = (payload: string) =>
11
+ JSON.parse(b64DecodeUnicode(payload.replaceAll(/-/g, '+').replaceAll(/_/g, '/')));
12
+
13
+ const extractTokenPayload = (token: string) => {
14
+ try {
15
+ if (!token) {
16
+ return null;
20
17
  }
21
- return null;
18
+ if (countLetter(token, '.') === 2) {
19
+ return parseJwt(token.split('.')[1]);
20
+ } else {
21
+ return null;
22
+ }
23
+ } catch (e) {
24
+ console.warn(e);
25
+ }
26
+ return null;
22
27
  };
23
28
 
24
- const countLetter = (str : string, find) => {
25
- return (str.split(find)).length - 1;
29
+ const countLetter = (str: string, find) => {
30
+ return str.split(find).length - 1;
26
31
  };
27
32
 
28
33
  export type Tokens = {
29
- refreshToken: string;
30
- idTokenPayload:any;
31
- idToken:string;
32
- accessTokenPayload:any;
33
- accessToken:string;
34
- expiresAt: number;
35
- issuedAt: number;
34
+ refreshToken: string;
35
+ idTokenPayload: any;
36
+ idToken: string;
37
+ accessTokenPayload: any;
38
+ accessToken: string;
39
+ expiresAt: number;
40
+ issuedAt: number;
36
41
  };
37
42
 
38
43
  export type TokenRenewModeType = {
39
- access_token_or_id_token_invalid: string;
40
- access_token_invalid:string;
41
- id_token_invalid: string;
42
- }
44
+ access_token_or_id_token_invalid: string;
45
+ access_token_invalid: string;
46
+ id_token_invalid: string;
47
+ };
43
48
 
44
49
  export const TokenRenewMode = {
45
- access_token_or_id_token_invalid: 'access_token_or_id_token_invalid',
46
- access_token_invalid: 'access_token_invalid',
47
- id_token_invalid: 'id_token_invalid',
50
+ access_token_or_id_token_invalid: 'access_token_or_id_token_invalid',
51
+ access_token_invalid: 'access_token_invalid',
52
+ id_token_invalid: 'id_token_invalid',
48
53
  };
49
54
 
50
55
  function extractedIssueAt(tokens, accessTokenPayload, _idTokenPayload) {
51
- if (!tokens.issuedAt) {
52
- if (accessTokenPayload && accessTokenPayload.iat) {
53
- return accessTokenPayload.iat;
54
- } else if (_idTokenPayload && _idTokenPayload.iat) {
55
- return _idTokenPayload.iat;
56
- } else {
57
- const currentTimeUnixSecond = new Date().getTime() / 1000;
58
- return currentTimeUnixSecond;
59
- }
60
- } else if (typeof tokens.issuedAt == "string") {
61
- return parseInt(tokens.issuedAt, 10);
56
+ if (!tokens.issuedAt) {
57
+ if (accessTokenPayload && accessTokenPayload.iat) {
58
+ return accessTokenPayload.iat;
59
+ } else if (_idTokenPayload && _idTokenPayload.iat) {
60
+ return _idTokenPayload.iat;
61
+ } else {
62
+ const currentTimeUnixSecond = new Date().getTime() / 1000;
63
+ return currentTimeUnixSecond;
62
64
  }
63
- return tokens.issuedAt;
65
+ } else if (typeof tokens.issuedAt == 'string') {
66
+ return parseInt(tokens.issuedAt, 10);
67
+ }
68
+ return tokens.issuedAt;
64
69
  }
65
70
 
66
- export const setTokens = (tokens, oldTokens = null, tokenRenewMode: string):Tokens => {
67
- if (!tokens) {
68
- return null;
69
- }
70
- let accessTokenPayload;
71
- const expireIn = typeof tokens.expiresIn == "string" ? parseInt(tokens.expiresIn, 10) : tokens.expiresIn;
72
-
73
- if (tokens.accessTokenPayload !== undefined) {
74
- accessTokenPayload = tokens.accessTokenPayload;
75
- } else {
76
- accessTokenPayload = extractTokenPayload(tokens.accessToken);
77
- }
71
+ export const setTokens = (tokens, oldTokens = null, tokenRenewMode: string): Tokens => {
72
+ if (!tokens) {
73
+ return null;
74
+ }
75
+ let accessTokenPayload;
76
+ const expireIn =
77
+ typeof tokens.expiresIn == 'string' ? parseInt(tokens.expiresIn, 10) : tokens.expiresIn;
78
+
79
+ if (tokens.accessTokenPayload !== undefined) {
80
+ accessTokenPayload = tokens.accessTokenPayload;
81
+ } else {
82
+ accessTokenPayload = extractTokenPayload(tokens.accessToken);
83
+ }
84
+
85
+ // When id_token is not rotated we reuse old id_token
86
+ let idToken: string;
87
+ if (oldTokens != null && 'idToken' in oldTokens && !('idToken' in tokens)) {
88
+ idToken = oldTokens.idToken;
89
+ } else {
90
+ idToken = tokens.idToken;
91
+ }
92
+
93
+ const _idTokenPayload = tokens.idTokenPayload
94
+ ? tokens.idTokenPayload
95
+ : extractTokenPayload(idToken);
96
+
97
+ const idTokenExpireAt =
98
+ _idTokenPayload && _idTokenPayload.exp ? _idTokenPayload.exp : Number.MAX_VALUE;
99
+ const accessTokenExpiresAt =
100
+ accessTokenPayload && accessTokenPayload.exp
101
+ ? accessTokenPayload.exp
102
+ : tokens.issuedAt + expireIn;
103
+
104
+ tokens.issuedAt = extractedIssueAt(tokens, accessTokenPayload, _idTokenPayload);
78
105
 
79
- // When id_token is not rotated we reuse old id_token
80
- let idToken: string;
81
- if (oldTokens != null && 'idToken' in oldTokens && !('idToken' in tokens)) {
82
- idToken = oldTokens.idToken;
106
+ let expiresAt;
107
+ if (tokens.expiresAt) {
108
+ expiresAt = tokens.expiresAt;
109
+ } else {
110
+ if (tokenRenewMode === TokenRenewMode.access_token_invalid) {
111
+ expiresAt = accessTokenExpiresAt;
112
+ } else if (tokenRenewMode === TokenRenewMode.id_token_invalid) {
113
+ expiresAt = idTokenExpireAt;
83
114
  } else {
84
- idToken = tokens.idToken;
85
- }
86
-
87
- const _idTokenPayload = tokens.idTokenPayload ? tokens.idTokenPayload : extractTokenPayload(idToken);
88
-
89
- const idTokenExpireAt = (_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp : Number.MAX_VALUE;
90
- const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp) ? accessTokenPayload.exp : tokens.issuedAt + expireIn;
91
-
92
- tokens.issuedAt = extractedIssueAt(tokens, accessTokenPayload, _idTokenPayload);
93
-
94
- let expiresAt;
95
- if(tokens.expiresAt)
96
- {
97
- expiresAt = tokens.expiresAt;
98
- }
99
- else {
100
- if (tokenRenewMode === TokenRenewMode.access_token_invalid) {
101
- expiresAt = accessTokenExpiresAt;
102
- } else if (tokenRenewMode === TokenRenewMode.id_token_invalid) {
103
- expiresAt = idTokenExpireAt;
104
- } else {
105
- expiresAt = idTokenExpireAt < accessTokenExpiresAt ? idTokenExpireAt : accessTokenExpiresAt;
106
- }
107
- }
108
-
109
- const newTokens = { ...tokens, idTokenPayload: _idTokenPayload, accessTokenPayload, expiresAt, idToken };
110
- // When refresh_token is not rotated we reuse old refresh_token
111
- if (oldTokens != null && 'refreshToken' in oldTokens && !('refreshToken' in tokens)) {
112
- const refreshToken = oldTokens.refreshToken;
113
- return { ...newTokens, refreshToken };
115
+ expiresAt = idTokenExpireAt < accessTokenExpiresAt ? idTokenExpireAt : accessTokenExpiresAt;
114
116
  }
117
+ }
118
+
119
+ const newTokens = {
120
+ ...tokens,
121
+ idTokenPayload: _idTokenPayload,
122
+ accessTokenPayload,
123
+ expiresAt,
124
+ idToken,
125
+ };
126
+ // When refresh_token is not rotated we reuse old refresh_token
127
+ if (oldTokens != null && 'refreshToken' in oldTokens && !('refreshToken' in tokens)) {
128
+ const refreshToken = oldTokens.refreshToken;
129
+ return { ...newTokens, refreshToken };
130
+ }
115
131
 
116
- return newTokens;
132
+ return newTokens;
117
133
  };
118
134
 
119
135
  export const parseOriginalTokens = (tokens, oldTokens, tokenRenewMode: string) => {
120
- if (!tokens) {
121
- return null;
122
- }
123
- if (!tokens.issued_at) {
124
- const currentTimeUnixSecond = new Date().getTime() / 1000;
125
- tokens.issued_at = currentTimeUnixSecond;
126
- }
136
+ if (!tokens) {
137
+ return null;
138
+ }
139
+ if (!tokens.issued_at) {
140
+ const currentTimeUnixSecond = new Date().getTime() / 1000;
141
+ tokens.issued_at = currentTimeUnixSecond;
142
+ }
127
143
 
128
- const data = {
129
- accessToken: tokens.access_token,
130
- expiresIn: tokens.expires_in,
131
- idToken: tokens.id_token,
132
- scope: tokens.scope,
133
- tokenType: tokens.token_type,
134
- issuedAt: tokens.issued_at,
135
- };
136
-
137
- if ('refresh_token' in tokens) {
138
- // @ts-ignore
139
- data.refreshToken = tokens.refresh_token;
140
- }
144
+ const data = {
145
+ accessToken: tokens.access_token,
146
+ expiresIn: tokens.expires_in,
147
+ idToken: tokens.id_token,
148
+ scope: tokens.scope,
149
+ tokenType: tokens.token_type,
150
+ issuedAt: tokens.issued_at,
151
+ };
141
152
 
142
- if (tokens.accessTokenPayload !== undefined) {
143
- // @ts-ignore
144
- data.accessTokenPayload = tokens.accessTokenPayload;
145
- }
153
+ if ('refresh_token' in tokens) {
154
+ // @ts-ignore
155
+ data.refreshToken = tokens.refresh_token;
156
+ }
146
157
 
147
- if (tokens.idTokenPayload !== undefined) {
148
- // @ts-ignore
149
- data.idTokenPayload = tokens.idTokenPayload;
150
- }
158
+ if (tokens.accessTokenPayload !== undefined) {
159
+ // @ts-ignore
160
+ data.accessTokenPayload = tokens.accessTokenPayload;
161
+ }
162
+
163
+ if (tokens.idTokenPayload !== undefined) {
164
+ // @ts-ignore
165
+ data.idTokenPayload = tokens.idTokenPayload;
166
+ }
151
167
 
152
- return setTokens(data, oldTokens, tokenRenewMode);
168
+ return setTokens(data, oldTokens, tokenRenewMode);
153
169
  };
154
170
 
155
171
  export const computeTimeLeft = (refreshTimeBeforeTokensExpirationInSecond, expiresAt) => {
156
- const currentTimeUnixSecond = new Date().getTime() / 1000;
157
-
158
- const timeLeftSecond = expiresAt - currentTimeUnixSecond;
159
-
160
- return Math.round(timeLeftSecond - refreshTimeBeforeTokensExpirationInSecond);
172
+ const currentTimeUnixSecond = new Date().getTime() / 1000;
173
+
174
+ const timeLeftSecond = expiresAt - currentTimeUnixSecond;
175
+
176
+ return Math.round(timeLeftSecond - refreshTimeBeforeTokensExpirationInSecond);
161
177
  };
162
178
 
163
- export const isTokensValid = (tokens) => {
164
- if (!tokens) {
165
- return false;
166
- }
167
- return computeTimeLeft(0, tokens.expiresAt) > 0;
179
+ export const isTokensValid = tokens => {
180
+ if (!tokens) {
181
+ return false;
182
+ }
183
+ return computeTimeLeft(0, tokens.expiresAt) > 0;
168
184
  };
169
185
 
170
186
  export type ValidToken = {
171
- isTokensValid: boolean;
172
- tokens: Tokens;
173
- numberWaited: number;
174
- }
187
+ isTokensValid: boolean;
188
+ tokens: Tokens;
189
+ numberWaited: number;
190
+ };
175
191
 
176
- export interface OidcToken{
177
- tokens?: Tokens;
178
- configuration: { token_automatic_renew_mode?: TokenAutomaticRenewMode; },
179
- renewTokensAsync: (extras: StringMap) => Promise<void>;
192
+ export interface OidcToken {
193
+ tokens?: Tokens;
194
+ configuration: { token_automatic_renew_mode?: TokenAutomaticRenewMode };
195
+ renewTokensAsync: (extras: StringMap) => Promise<void>;
180
196
  }
181
197
 
182
- export const getValidTokenAsync = async (oidc: OidcToken, waitMs = 200, numberWait = 50): Promise<ValidToken> => {
183
- let numberWaitTemp = numberWait;
184
- if (!oidc.tokens) {
185
- return null;
186
- }
187
- while (!isTokensValid(oidc.tokens) && numberWaitTemp > 0) {
188
- if(oidc.configuration.token_automatic_renew_mode == TokenAutomaticRenewMode.AutomaticOnlyWhenFetchExecuted){
189
- await oidc.renewTokensAsync({});
190
- break;
191
- } else {
192
- await sleepAsync({milliseconds: waitMs});
193
- }
194
- numberWaitTemp = numberWaitTemp - 1;
198
+ export const getValidTokenAsync = async (
199
+ oidc: OidcToken,
200
+ waitMs = 200,
201
+ numberWait = 50,
202
+ ): Promise<ValidToken> => {
203
+ let numberWaitTemp = numberWait;
204
+ if (!oidc.tokens) {
205
+ return null;
206
+ }
207
+ while (!isTokensValid(oidc.tokens) && numberWaitTemp > 0) {
208
+ if (
209
+ oidc.configuration.token_automatic_renew_mode ==
210
+ TokenAutomaticRenewMode.AutomaticOnlyWhenFetchExecuted
211
+ ) {
212
+ await oidc.renewTokensAsync({});
213
+ break;
214
+ } else {
215
+ await sleepAsync({ milliseconds: waitMs });
195
216
  }
196
- const isValid = isTokensValid(oidc.tokens);
197
- return {
198
- isTokensValid: isValid,
199
- tokens: oidc.tokens,
200
- numberWaited: numberWaitTemp - numberWait,
201
- };
217
+ numberWaitTemp = numberWaitTemp - 1;
218
+ }
219
+ const isValid = isTokensValid(oidc.tokens);
220
+ return {
221
+ isTokensValid: isValid,
222
+ tokens: oidc.tokens,
223
+ numberWaited: numberWaitTemp - numberWait,
224
+ };
202
225
  };
203
226
 
204
227
  // https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation (excluding rules #1, #4, #5, #7, #8, #12, and #13 which did not apply).
205
228
  // https://github.com/openid/AppAuth-JS/issues/65
206
229
  export const isTokensOidcValid = (tokens, nonce, oidcServerConfiguration) => {
207
- if (tokens.idTokenPayload) {
208
- const idTokenPayload = tokens.idTokenPayload;
209
- // 2: The Issuer Identifier for the OpenID Provider (which is typically obtained during Discovery) MUST exactly match the value of the iss (issuer) Claim.
210
- if (oidcServerConfiguration.issuer !== idTokenPayload.iss) {
211
- return { isValid: false, reason: `Issuer does not match (oidcServerConfiguration issuer) ${oidcServerConfiguration.issuer} !== (idTokenPayload issuer) ${idTokenPayload.iss}` };
212
- }
213
- // 3: The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
214
-
215
- // 6: If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
216
-
217
- // 9: The current time MUST be before the time represented by the exp Claim.
218
- const currentTimeUnixSecond = new Date().getTime() / 1000;
219
- if (idTokenPayload.exp && idTokenPayload.exp < currentTimeUnixSecond) {
220
- return { isValid: false, reason: `Token expired (idTokenPayload exp) ${idTokenPayload.exp} < (currentTimeUnixSecond) ${currentTimeUnixSecond}` };
221
- }
222
- // 10: The iat Claim can be used to reject tokens that were issued too far away from the current time, limiting the amount of time that nonces need to be stored to prevent attacks. The acceptable range is Client specific.
223
- const timeInSevenDays = 60 * 60 * 24 * 7;
224
- if (idTokenPayload.iat && (idTokenPayload.iat + timeInSevenDays) < currentTimeUnixSecond) {
225
- return { isValid: false, reason: `Token is used from too long time (idTokenPayload iat + timeInSevenDays) ${idTokenPayload.iat + timeInSevenDays} < (currentTimeUnixSecond) ${currentTimeUnixSecond}` };
226
- }
227
- // 11: If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked to verify that it is the same value as the one that was sent in the Authentication Request. The Client SHOULD check the nonce value for replay attacks. The precise method for detecting replay attacks is Client specific.
228
- if (idTokenPayload.nonce && idTokenPayload.nonce !== nonce) {
229
- return { isValid: false, reason: `Nonce does not match (idTokenPayload nonce) ${idTokenPayload.nonce} !== (nonce) ${nonce}` };
230
- }
230
+ if (tokens.idTokenPayload) {
231
+ const idTokenPayload = tokens.idTokenPayload;
232
+ // 2: The Issuer Identifier for the OpenID Provider (which is typically obtained during Discovery) MUST exactly match the value of the iss (issuer) Claim.
233
+ if (oidcServerConfiguration.issuer !== idTokenPayload.iss) {
234
+ return {
235
+ isValid: false,
236
+ reason: `Issuer does not match (oidcServerConfiguration issuer) ${oidcServerConfiguration.issuer} !== (idTokenPayload issuer) ${idTokenPayload.iss}`,
237
+ };
238
+ }
239
+ // 3: The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
240
+
241
+ // 6: If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
242
+
243
+ // 9: The current time MUST be before the time represented by the exp Claim.
244
+ const currentTimeUnixSecond = new Date().getTime() / 1000;
245
+ if (idTokenPayload.exp && idTokenPayload.exp < currentTimeUnixSecond) {
246
+ return {
247
+ isValid: false,
248
+ reason: `Token expired (idTokenPayload exp) ${idTokenPayload.exp} < (currentTimeUnixSecond) ${currentTimeUnixSecond}`,
249
+ };
250
+ }
251
+ // 10: The iat Claim can be used to reject tokens that were issued too far away from the current time, limiting the amount of time that nonces need to be stored to prevent attacks. The acceptable range is Client specific.
252
+ const timeInSevenDays = 60 * 60 * 24 * 7;
253
+ if (idTokenPayload.iat && idTokenPayload.iat + timeInSevenDays < currentTimeUnixSecond) {
254
+ return {
255
+ isValid: false,
256
+ reason: `Token is used from too long time (idTokenPayload iat + timeInSevenDays) ${idTokenPayload.iat + timeInSevenDays} < (currentTimeUnixSecond) ${currentTimeUnixSecond}`,
257
+ };
258
+ }
259
+ // 11: If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked to verify that it is the same value as the one that was sent in the Authentication Request. The Client SHOULD check the nonce value for replay attacks. The precise method for detecting replay attacks is Client specific.
260
+ if (idTokenPayload.nonce && idTokenPayload.nonce !== nonce) {
261
+ return {
262
+ isValid: false,
263
+ reason: `Nonce does not match (idTokenPayload nonce) ${idTokenPayload.nonce} !== (nonce) ${nonce}`,
264
+ };
231
265
  }
232
- return { isValid: true, reason: '' };
266
+ }
267
+ return { isValid: true, reason: '' };
233
268
  };