auth0 3.4.0 → 4.0.0-beta.0

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 (51) hide show
  1. package/README.md +19 -15
  2. package/package.json +47 -33
  3. package/CHANGELOG.md +0 -685
  4. package/src/Auth0RestClient.js +0 -123
  5. package/src/RetryRestClient.js +0 -105
  6. package/src/auth/DatabaseAuthenticator.js +0 -282
  7. package/src/auth/OAUthWithIDTokenValidation.js +0 -124
  8. package/src/auth/OAuthAuthenticator.js +0 -405
  9. package/src/auth/PasswordlessAuthenticator.js +0 -303
  10. package/src/auth/TokensManager.js +0 -254
  11. package/src/auth/UsersManager.js +0 -161
  12. package/src/auth/clientAuthentication.js +0 -86
  13. package/src/auth/idToken.js +0 -167
  14. package/src/auth/index.js +0 -573
  15. package/src/errors.js +0 -60
  16. package/src/index.js +0 -11
  17. package/src/index.mjs +0 -4
  18. package/src/management/ActionsManager.js +0 -526
  19. package/src/management/AttackProtectionManager.js +0 -158
  20. package/src/management/BaseManager.js +0 -41
  21. package/src/management/BlacklistedTokensManager.js +0 -67
  22. package/src/management/BrandingManager.js +0 -250
  23. package/src/management/ClientCredentialsManager.js +0 -112
  24. package/src/management/ClientGrantsManager.js +0 -124
  25. package/src/management/ClientsManager.js +0 -184
  26. package/src/management/ConnectionsManager.js +0 -213
  27. package/src/management/CustomDomainsManager.js +0 -141
  28. package/src/management/DeviceCredentialsManager.js +0 -91
  29. package/src/management/EmailProviderManager.js +0 -101
  30. package/src/management/EmailTemplatesManager.js +0 -90
  31. package/src/management/GrantsManager.js +0 -84
  32. package/src/management/GuardianManager.js +0 -361
  33. package/src/management/HooksManager.js +0 -295
  34. package/src/management/JobsManager.js +0 -324
  35. package/src/management/LogStreamsManager.js +0 -136
  36. package/src/management/LogsManager.js +0 -82
  37. package/src/management/ManagementTokenProvider.js +0 -144
  38. package/src/management/MigrationsManager.js +0 -76
  39. package/src/management/OrganizationsManager.js +0 -721
  40. package/src/management/PromptsManager.js +0 -162
  41. package/src/management/ResourceServersManager.js +0 -143
  42. package/src/management/RolesManager.js +0 -329
  43. package/src/management/RulesConfigsManager.js +0 -86
  44. package/src/management/RulesManager.js +0 -148
  45. package/src/management/StatsManager.js +0 -84
  46. package/src/management/TenantManager.js +0 -76
  47. package/src/management/TicketsManager.js +0 -104
  48. package/src/management/UserBlocksManager.js +0 -121
  49. package/src/management/UsersManager.js +0 -882
  50. package/src/management/index.js +0 -3409
  51. package/src/utils.js +0 -60
@@ -1,254 +0,0 @@
1
- const axios = require('axios');
2
- const { ArgumentError } = require('rest-facade');
3
- const { addClientAuthentication } = require('./clientAuthentication');
4
-
5
- /**
6
- * Provides methods for getting token data and exchanging tokens.
7
- */
8
- class TokensManager {
9
- /**
10
- * @param {object} options Manager options.
11
- * @param {string} options.baseUrl The auth0 account URL.
12
- * @param {string} [options.headers] Default request headers.
13
- * @param {string} [options.domain] Required if using clientAssertionSigningKey.
14
- * @param {string} [options.clientId] Default client ID.
15
- * @param {string} [options.clientSecret] Default client Secret.
16
- * @param {string} [options.clientAssertionSigningKey] Private key used to sign the client assertion JWT.
17
- * @param {string} [options.clientAssertionSigningAlg] Default 'RS256'.
18
- */
19
- constructor(options) {
20
- if (typeof options !== 'object') {
21
- throw new ArgumentError('Missing tokens manager options');
22
- }
23
-
24
- if (typeof options.baseUrl !== 'string') {
25
- throw new ArgumentError('baseUrl field is required');
26
- }
27
-
28
- this.baseUrl = options.baseUrl;
29
- this.headers = options.headers || {};
30
- this.domain = options.domain;
31
- this.clientId = options.clientId || '';
32
- this.clientSecret = options.clientSecret || '';
33
- this.clientAssertionSigningKey = options.clientAssertionSigningKey;
34
- this.clientAssertionSigningAlg = options.clientAssertionSigningAlg;
35
- }
36
-
37
- /**
38
- * Given an ID token get the user profile linked to it.
39
- *
40
- * @example <caption>
41
- * Validates a JSON Web Token (signature and expiration) and returns the user
42
- * information associated with the user id (sub property) of the token. Find
43
- * more information in the
44
- * <a href="https://auth0.com/docs/auth-api#!#post--tokeninfo">API Docs</a>.
45
- * </caption>
46
- *
47
- * auth0.tokens.getInfo(token, function (err, tokenInfo) {
48
- * if (err) {
49
- * // Handle error.
50
- * }
51
- *
52
- * console.log(tokenInfo);
53
- * });
54
- * @param {string} idToken User ID token.
55
- * @param {Function} [cb] Method callback.
56
- * @returns {Promise|undefined}
57
- */
58
- getInfo(idToken, cb) {
59
- const headers = { ...this.headers };
60
-
61
- if (idToken === null || idToken === undefined) {
62
- throw new ArgumentError('An ID token is required');
63
- }
64
-
65
- if (typeof idToken !== 'string' || idToken.trim().length === 0) {
66
- throw new ArgumentError('The ID token is not valid');
67
- }
68
-
69
- // Perform the request.
70
- const promise = axios({
71
- method: 'POST',
72
- url: `${this.baseUrl}/tokeninfo`,
73
- data: { id_token: idToken },
74
- headers,
75
- }).then(({ data }) => data);
76
-
77
- // Use callback if given.
78
- if (cb instanceof Function) {
79
- promise.then(cb.bind(null, null)).catch(cb);
80
- return;
81
- }
82
-
83
- return promise;
84
- }
85
-
86
- /**
87
- * Exchange the token of the logged in user with a token that is valid to call
88
- * the API (signed with the API secret).
89
- *
90
- * @example <caption>
91
- * Given an existing token, this endpoint will generate a new token signed
92
- * with the target client secret. This is used to flow the identity of the
93
- * user from the application to an API or across different APIs that are
94
- * protected with different secrets. Find more information in the
95
- * <a href="https://auth0.com/docs/auth-api#!#post--delegation">API Docs</a>.
96
- * </caption>
97
- *
98
- * var data = {
99
- * id_token: '{ID_TOKEN}',
100
- * api_type: 'app',
101
- * target: '{TARGET}',
102
- * grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
103
- * };
104
- *
105
- * auth0.tokens.getDelegationToken(data, function (err, token) {
106
- * if (err) {
107
- * // Handle error.
108
- * }
109
- *
110
- * console.log(token);
111
- * });
112
- * @param {object} data Token data object.
113
- * @param {string} data.id_token User ID token.
114
- * @param {string} data.refresh_token User refresh token.
115
- * @param {string} data.target Target client ID.
116
- * @param {string} data.api_type The API to be used (aws, auth0, etc).
117
- * @param {string} data.grant_type Grant type (password, jwt, etc).
118
- * @param {Function} [cb] Callback function.
119
- * @returns {Promise|undefined}
120
- */
121
- getDelegationToken(data, cb) {
122
- const body = { client_id: this.clientId, ...data };
123
- const { headers } = this;
124
-
125
- if (!data) {
126
- throw new ArgumentError('Missing token data object');
127
- }
128
-
129
- const hasIdToken = typeof data.id_token === 'string' && data.id_token.trim().length !== 0;
130
-
131
- const hasRefreshToken =
132
- typeof data.refresh_token === 'string' && data.refresh_token.trim().length !== 0;
133
-
134
- if (!hasIdToken && !hasRefreshToken) {
135
- throw new ArgumentError('one of id_token or refresh_token is required');
136
- }
137
-
138
- if (hasIdToken && hasRefreshToken) {
139
- throw new ArgumentError(
140
- 'id_token and refresh_token fields cannot be specified simulatenously'
141
- );
142
- }
143
-
144
- if (typeof data.target !== 'string' || data.target.trim().length === 0) {
145
- throw new ArgumentError('target field is required');
146
- }
147
-
148
- if (typeof data.api_type !== 'string' || data.api_type.trim().length === 0) {
149
- throw new ArgumentError('api_type field is required');
150
- }
151
-
152
- if (typeof data.grant_type !== 'string' || data.grant_type.trim().length === 0) {
153
- throw new ArgumentError('grant_type field is required');
154
- }
155
-
156
- // Perform the request.
157
- const promise = axios({
158
- method: 'POST',
159
- url: `${this.baseUrl}/delegation`,
160
- data: body,
161
- headers,
162
- }).then(({ data }) => data);
163
-
164
- // Use callback if given.
165
- if (cb instanceof Function) {
166
- promise.then(cb.bind(null, null)).catch(cb);
167
- return;
168
- }
169
-
170
- return promise;
171
- }
172
-
173
- /**
174
- * Proactively revoke an issued refresh token.
175
- *
176
- * @example <caption>
177
- * Given an existing refresh token, this endpoint will revoke it in order
178
- * to prevent unauthorized silently user authentication tokens refresh.
179
- * Find more information in the <a href="https://auth0.com/docs/api/authentication#revoke-refresh-token">API Docs</a>.
180
- * </caption>
181
- *
182
- * var data = {
183
- * token: '{REFRESH_TOKEN}'
184
- * };
185
- *
186
- * auth0.tokens.revokeRefreshToken(data, function (err, _) {
187
- * if (err) {
188
- * // Handle error.
189
- * }
190
- *
191
- * // Do stuff.
192
- * });
193
- * @param {object} data Token data object.
194
- * @param {string} data.token User refresh token.
195
- * @param {string} [data.client_id] Target client ID.
196
- * @param {string} [data.client_secret] Target client secret.
197
- * @param {Function} [cb] Callback function.
198
- * @returns {Promise|undefined}
199
- */
200
- revokeRefreshToken(data, cb) {
201
- if (!data) {
202
- throw new ArgumentError('Missing token data object');
203
- }
204
-
205
- const hasToken = typeof data.token === 'string' && data.token.trim().length !== 0;
206
-
207
- if (!hasToken) {
208
- throw new ArgumentError('token property is required');
209
- }
210
-
211
- const hasClientId =
212
- (data.client_id &&
213
- typeof data.client_id === 'string' &&
214
- data.client_id.trim().length !== 0) ||
215
- this.clientId !== '';
216
-
217
- if (!hasClientId) {
218
- throw new ArgumentError(
219
- 'Neither token data client_id property or constructor clientId property has been set'
220
- );
221
- }
222
-
223
- const body = addClientAuthentication({
224
- payload: {
225
- client_id: this.clientId,
226
- ...data,
227
- },
228
- domain: this.domain,
229
- clientSecret: this.clientSecret,
230
- clientAssertionSigningKey: this.clientAssertionSigningKey,
231
- clientAssertionSigningAlg: this.clientAssertionSigningAlg,
232
- });
233
-
234
- const { headers } = this;
235
-
236
- // Perform the request.
237
- const promise = axios({
238
- method: 'POST',
239
- url: `${this.baseUrl}/oauth/revoke`,
240
- data: body,
241
- headers,
242
- }).then(({ data }) => data);
243
-
244
- // Use callback if given.
245
- if (cb instanceof Function) {
246
- promise.then(cb.bind(null, null)).catch(cb);
247
- return;
248
- }
249
-
250
- return promise;
251
- }
252
- }
253
-
254
- module.exports = TokensManager;
@@ -1,161 +0,0 @@
1
- const axios = require('axios');
2
-
3
- const { ArgumentError } = require('rest-facade');
4
-
5
- /**
6
- * Provides methods for getting user information and impersonating users.
7
- */
8
- class UsersManager {
9
- /**
10
- * @param {object} options Manager options.
11
- * @param {string} options.baseUrl The auth0 account URL.
12
- * @param {string} [options.headers] Default request headers.
13
- * @param {string} [options.clientId] Default client ID.
14
- */
15
- constructor(options) {
16
- if (typeof options !== 'object') {
17
- throw new ArgumentError('Missing users manager options');
18
- }
19
-
20
- if (typeof options.baseUrl !== 'string') {
21
- throw new ArgumentError('baseUrl field is required');
22
- }
23
-
24
- this.baseUrl = options.baseUrl;
25
- this.headers = options.headers;
26
- this.clientId = options.clientId;
27
- }
28
-
29
- /**
30
- * Given an access token get the user profile linked to it.
31
- *
32
- * @example <caption>
33
- * Get the user information based on the Auth0 access token (obtained during
34
- * login). Find more information in the
35
- * <a href="https://auth0.com/docs/auth-api#!#get--userinfo">API Docs</a>.
36
- * </caption>
37
- *
38
- * auth0.users.getInfo(accessToken, function (err, userInfo) {
39
- * if (err) {
40
- * // Handle error.
41
- * }
42
- *
43
- * console.log(userInfo);
44
- * });
45
- * @param {string} accessToken User access token.
46
- * @param {Function} [cb] Callback function.
47
- * @returns {Promise|undefined}
48
- */
49
- getInfo(accessToken, cb) {
50
- const url = `${this.baseUrl}/userinfo`;
51
- const headers = { ...this.headers };
52
-
53
- if (accessToken === null || accessToken === undefined) {
54
- throw new ArgumentError('An access token is required');
55
- }
56
-
57
- if (typeof accessToken !== 'string' || accessToken.trim().length === 0) {
58
- throw new ArgumentError('Invalid access token');
59
- }
60
-
61
- // Send the user access token in the Authorization header.
62
- headers['Authorization'] = `Bearer ${accessToken}`;
63
-
64
- // Perform the request.
65
- const promise = axios({
66
- method: 'GET',
67
- url,
68
- headers,
69
- }).then(({ data }) => data);
70
-
71
- // Use callback if given.
72
- if (cb instanceof Function) {
73
- promise.then(cb.bind(null, null)).catch(cb);
74
- return;
75
- }
76
-
77
- return promise;
78
- }
79
-
80
- /**
81
- * Impersonate the user with the given user ID.
82
- *
83
- * @example <caption>
84
- * Gets a link that can be used once to log in as a specific user. Useful for
85
- * troubleshooting. Find more information in the
86
- * [API Docs](https://auth0.com/docs/auth-api#!#post--users--user_id--impersonate).
87
- * </caption>
88
- *
89
- * var settings = {
90
- * impersonator_id: '{IMPERSONATOR_ID}',
91
- * protocol: 'oauth2',
92
- * additionalParameters: {} // Optional additional params.
93
- * };
94
- *
95
- * auth0.users.impersonate(userId, settings, function (err, link) {
96
- * if (err) {
97
- * // Handle error.
98
- * }
99
- *
100
- * console.log(link);
101
- * });
102
- * @param {string} userId User ID token.
103
- * @param {object} settings Impersonation settings.
104
- * @param {string} settings.impersonator_id Impersonator user ID.
105
- * @param {string} settings.protocol The authentication protocol.
106
- * @param {string} settings.token API v1 token obtained for impersonation
107
- * @param {string} [settings.clientId] Client id used for impersonation. Uses the one supplied in the constructor by default.
108
- * @param {Function} [cb] Callback function.
109
- * @returns {Promise|undefined}
110
- */
111
- impersonate(userId, settings, cb) {
112
- const url = `${this.baseUrl}/users/${userId}/impersonate`;
113
-
114
- if (userId === null || userId === undefined) {
115
- throw new ArgumentError('You must specify a user ID');
116
- }
117
-
118
- if (typeof userId !== 'string' || userId.trim().length === 0) {
119
- throw new ArgumentError('The user ID is not valid');
120
- }
121
-
122
- if (typeof settings !== 'object') {
123
- throw new ArgumentError('Missing impersonation settings object');
124
- }
125
-
126
- if (
127
- typeof settings.impersonator_id !== 'string' ||
128
- settings.impersonator_id.trim().length === 0
129
- ) {
130
- throw new ArgumentError('impersonator_id field is required');
131
- }
132
-
133
- if (typeof settings.protocol !== 'string' || settings.protocol.trim().length === 0) {
134
- throw new ArgumentError('protocol field is required');
135
- }
136
-
137
- if (typeof settings.token !== 'string' || settings.token.trim().length === 0) {
138
- throw new ArgumentError('token field is required');
139
- }
140
-
141
- const data = { client_id: settings.clientId || this.clientId, ...settings };
142
- const headers = { Authorization: `Bearer ${settings.token}`, ...this.headers };
143
- // Perform the request.
144
- const promise = axios({
145
- method: 'POST',
146
- headers,
147
- data,
148
- url,
149
- }).then(({ data }) => data);
150
-
151
- // Use callback if given.
152
- if (cb instanceof Function) {
153
- promise.then(cb.bind(null, null)).catch(cb);
154
- return;
155
- }
156
-
157
- return promise;
158
- }
159
- }
160
-
161
- module.exports = UsersManager;
@@ -1,86 +0,0 @@
1
- const { ArgumentError } = require('rest-facade');
2
- const jwt = require('jsonwebtoken');
3
- const uuid = require('uuid');
4
-
5
- /**
6
- * Create a JWT signed with the clientAssertionSigningKey
7
- * for use on clients with token endpoint auth method of private_key_jwt.
8
- *
9
- * @param {string} domain The domain of the Authorization Server (can be a custom domain).
10
- * @param {string} clientId The Client ID.
11
- * @param {string} clientAssertionSigningKey A private key in PEM format to sign the client assertion JWT.
12
- * @param {string} clientAssertionSigningAlg The alg to use to sign the JWT (default RS256)
13
- * @returns {string} A JWT.
14
- */
15
- const createClientAssertionJWT = ({
16
- clientId,
17
- clientAssertionSigningKey,
18
- clientAssertionSigningAlg,
19
- domain,
20
- }) => {
21
- const now = Math.floor(Date.now() / 1000);
22
- const payload = {
23
- iss: clientId,
24
- sub: clientId,
25
- aud: `https://${domain}/`,
26
- iat: now,
27
- exp: now + 180,
28
- jti: uuid.v4(),
29
- };
30
- return jwt.sign(payload, clientAssertionSigningKey, {
31
- algorithm: clientAssertionSigningAlg || 'RS256',
32
- });
33
- };
34
-
35
- /**
36
- * Adds client authentication, if available, to the payload of the following requests:
37
- * - /oauth/token
38
- * - /oauth/revoke
39
- * - /mfa/associate
40
- * - /mfa/challenge
41
- * - /passwordless/start
42
- *
43
- * Adds `client_secret` for Client Secret Post token endpoint auth method (the SDK doesn't use Client Secret Basic)
44
- * Adds `client_assertion` and `client_assertion_type` for Private Key JWT token endpoint auth method.
45
- *
46
- * If `clientAssertionSigningKey` is provided it takes precedent over `clientSecret` .
47
- *
48
- * @param {object} payload The body of the request to be authenticated.
49
- * @param {string} domain The domain of the Authorization Server (can be a custom domain).
50
- * @param {boolean} [required] True if client authentication is required.
51
- * @param {string} [clientAssertionSigningKey] A private key in PEM format to sign the client assertion JWT.
52
- * @param {string} clientAssertionSigningAlg The alg to use to sign the JWT (default RS256)
53
- * @param {string} [clientSecret] The client secret.
54
- * @returns {object} The payload with additional fields for client authentication.
55
- */
56
- const addClientAuthentication = ({
57
- payload,
58
- domain,
59
- required,
60
- clientAssertionSigningKey,
61
- clientAssertionSigningAlg,
62
- clientSecret,
63
- }) => {
64
- const clientId = payload.client_id;
65
- if (clientAssertionSigningKey && !payload.client_assertion) {
66
- payload.client_assertion = createClientAssertionJWT({
67
- clientId,
68
- clientAssertionSigningKey,
69
- clientAssertionSigningAlg,
70
- domain,
71
- });
72
- payload.client_assertion_type = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';
73
- } else if (clientSecret && !payload.client_secret) {
74
- payload.client_secret = clientSecret;
75
- }
76
- if (
77
- required &&
78
- (!payload.client_secret || payload.client_secret.trim().length === 0) &&
79
- (!payload.client_assertion || payload.client_assertion.trim().length === 0)
80
- ) {
81
- throw new ArgumentError('The client_secret or client_assertion field is required.');
82
- }
83
- return payload;
84
- };
85
-
86
- module.exports.addClientAuthentication = addClientAuthentication;
@@ -1,167 +0,0 @@
1
- const urlDecodeB64 = function (data) {
2
- return Buffer.from(data, 'base64').toString('utf8');
3
- };
4
-
5
- /**
6
- * Decodes a string token into the 3 parts, throws if the format is invalid
7
- *
8
- * @param {string} token token
9
- * @returns {object}
10
- */
11
- const decode = function (token) {
12
- const parts = token.split('.');
13
-
14
- if (parts.length !== 3) {
15
- throw new Error('ID token could not be decoded');
16
- }
17
-
18
- return {
19
- _raw: token,
20
- header: JSON.parse(urlDecodeB64(parts[0])),
21
- payload: JSON.parse(urlDecodeB64(parts[1])),
22
- signature: parts[2],
23
- };
24
- };
25
-
26
- const DEFAULT_LEEWAY = 60; //default clock-skew, in seconds
27
-
28
- /**
29
- * Validator for ID Tokens following OIDC spec.
30
- *
31
- * @param {string} token the string token to verify
32
- * @param {object} options the options required to run this verification
33
- * @returns {object} The decoded token payload, or throws an exception if validation failed
34
- */
35
- const validate = function (token, options) {
36
- if (!token) {
37
- throw new Error('ID token is required but missing');
38
- }
39
-
40
- const decodedToken = decode(token);
41
-
42
- // Check algorithm
43
- const { header } = decodedToken;
44
- if (header.alg !== 'RS256' && header.alg !== 'HS256') {
45
- throw new Error(
46
- `Signature algorithm of "${header.alg}" is not supported. Expected the ID token to be signed with "RS256" or "HS256".`
47
- );
48
- }
49
-
50
- const { payload } = decodedToken;
51
-
52
- // Issuer
53
- if (!payload.iss || typeof payload.iss !== 'string') {
54
- throw new Error('Issuer (iss) claim must be a string present in the ID token');
55
- }
56
- if (payload.iss !== options.issuer) {
57
- throw new Error(
58
- `Issuer (iss) claim mismatch in the ID token; expected "${options.issuer}", found "${payload.iss}"`
59
- );
60
- }
61
-
62
- // Subject
63
- if (!payload.sub || typeof payload.sub !== 'string') {
64
- throw new Error('Subject (sub) claim must be a string present in the ID token');
65
- }
66
-
67
- // Audience
68
- if (!payload.aud || !(typeof payload.aud === 'string' || Array.isArray(payload.aud))) {
69
- throw new Error(
70
- 'Audience (aud) claim must be a string or array of strings present in the ID token'
71
- );
72
- }
73
- if (Array.isArray(payload.aud) && !payload.aud.includes(options.audience)) {
74
- throw new Error(
75
- `Audience (aud) claim mismatch in the ID token; expected "${
76
- options.audience
77
- }" but was not one of "${payload.aud.join(', ')}"`
78
- );
79
- } else if (typeof payload.aud === 'string' && payload.aud !== options.audience) {
80
- throw new Error(
81
- `Audience (aud) claim mismatch in the ID token; expected "${options.audience}" but found "${payload.aud}"`
82
- );
83
- }
84
-
85
- // Organization
86
- if (options.organization) {
87
- if (!payload.org_id || typeof payload.org_id !== 'string') {
88
- throw new Error('Organization Id (org_id) claim must be a string present in the ID token');
89
- }
90
-
91
- if (payload.org_id !== options.organization) {
92
- throw new Error(
93
- `Organization Id (org_id) claim value mismatch in the ID token; expected "${options.organization}", found "${payload.org_id}"'`
94
- );
95
- }
96
- }
97
-
98
- // --Time validation (epoch)--
99
- const now = Math.floor(Date.now() / 1000);
100
- const leeway = options.leeway || DEFAULT_LEEWAY;
101
-
102
- // Expires at
103
- if (!payload.exp || typeof payload.exp !== 'number') {
104
- throw new Error('Expiration Time (exp) claim must be a number present in the ID token');
105
- }
106
- const expTime = payload.exp + leeway;
107
-
108
- if (now > expTime) {
109
- throw new Error(
110
- `Expiration Time (exp) claim error in the ID token; current time (${now}) is after expiration time (${expTime})`
111
- );
112
- }
113
-
114
- // Issued at
115
- if (!payload.iat || typeof payload.iat !== 'number') {
116
- throw new Error('Issued At (iat) claim must be a number present in the ID token');
117
- }
118
-
119
- // Nonce
120
- if (options.nonce) {
121
- if (!payload.nonce || typeof payload.nonce !== 'string') {
122
- throw new Error('Nonce (nonce) claim must be a string present in the ID token');
123
- }
124
- if (payload.nonce !== options.nonce) {
125
- throw new Error(
126
- `Nonce (nonce) claim mismatch in the ID token; expected "${options.nonce}", found "${payload.nonce}"`
127
- );
128
- }
129
- }
130
-
131
- // Authorized party
132
- if (Array.isArray(payload.aud) && payload.aud.length > 1) {
133
- if (!payload.azp || typeof payload.azp !== 'string') {
134
- throw new Error(
135
- 'Authorized Party (azp) claim must be a string present in the ID token when Audience (aud) claim has multiple values'
136
- );
137
- }
138
- if (payload.azp !== options.audience) {
139
- throw new Error(
140
- `Authorized Party (azp) claim mismatch in the ID token; expected "${options.audience}", found "${payload.azp}"`
141
- );
142
- }
143
- }
144
-
145
- // Authentication time
146
- if (options.maxAge) {
147
- if (!payload.auth_time || typeof payload.auth_time !== 'number') {
148
- throw new Error(
149
- 'Authentication Time (auth_time) claim must be a number present in the ID token when Max Age (max_age) is specified'
150
- );
151
- }
152
-
153
- const authValidUntil = payload.auth_time + options.maxAge + leeway;
154
- if (now > authValidUntil) {
155
- throw new Error(
156
- `Authentication Time (auth_time) claim in the ID token indicates that too much time has passed since the last end-user authentication. Currrent time (${now}) is after last auth at ${authValidUntil}`
157
- );
158
- }
159
- }
160
-
161
- return decodedToken;
162
- };
163
-
164
- module.exports = {
165
- decode,
166
- validate,
167
- };