auth0 2.37.0 → 2.38.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 (46) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +33 -11
  3. package/package.json +22 -14
  4. package/src/Auth0RestClient.js +72 -71
  5. package/src/RetryRestClient.js +78 -81
  6. package/src/auth/DatabaseAuthenticator.js +242 -259
  7. package/src/auth/OAUthWithIDTokenValidation.js +99 -103
  8. package/src/auth/OAuthAuthenticator.js +325 -344
  9. package/src/auth/PasswordlessAuthenticator.js +237 -252
  10. package/src/auth/TokensManager.js +231 -246
  11. package/src/auth/UsersManager.js +149 -160
  12. package/src/auth/idToken.js +22 -19
  13. package/src/auth/index.js +510 -583
  14. package/src/errors.js +23 -23
  15. package/src/index.js +3 -2
  16. package/src/management/ActionsManager.js +503 -585
  17. package/src/management/BlacklistedTokensManager.js +77 -84
  18. package/src/management/BrandingManager.js +141 -163
  19. package/src/management/ClientGrantsManager.js +132 -145
  20. package/src/management/ClientsManager.js +145 -161
  21. package/src/management/ConnectionsManager.js +215 -239
  22. package/src/management/CustomDomainsManager.js +140 -157
  23. package/src/management/DeviceCredentialsManager.js +95 -111
  24. package/src/management/EmailProviderManager.js +110 -128
  25. package/src/management/EmailTemplatesManager.js +96 -112
  26. package/src/management/GrantsManager.js +94 -101
  27. package/src/management/GuardianManager.js +381 -455
  28. package/src/management/HooksManager.js +283 -325
  29. package/src/management/JobsManager.js +310 -343
  30. package/src/management/LogStreamsManager.js +142 -158
  31. package/src/management/LogsManager.js +92 -99
  32. package/src/management/ManagementTokenProvider.js +112 -120
  33. package/src/management/MigrationsManager.js +81 -90
  34. package/src/management/OrganizationsManager.js +686 -784
  35. package/src/management/PromptsManager.js +160 -182
  36. package/src/management/ResourceServersManager.js +143 -160
  37. package/src/management/RolesManager.js +323 -369
  38. package/src/management/RulesConfigsManager.js +94 -110
  39. package/src/management/RulesManager.js +154 -176
  40. package/src/management/StatsManager.js +87 -103
  41. package/src/management/TenantManager.js +81 -97
  42. package/src/management/TicketsManager.js +107 -115
  43. package/src/management/UserBlocksManager.js +135 -162
  44. package/src/management/UsersManager.js +729 -852
  45. package/src/management/index.js +3094 -3625
  46. package/src/utils.js +31 -60
@@ -1,8 +1,6 @@
1
- var extend = require('util')._extend;
2
-
3
- var ArgumentError = require('rest-facade').ArgumentError;
4
- var RestClient = require('rest-facade').Client;
5
- var sanitizeArguments = require('../utils').sanitizeArguments;
1
+ const { ArgumentError } = require('rest-facade');
2
+ const RestClient = require('rest-facade').Client;
3
+ const { sanitizeArguments } = require('../utils');
6
4
 
7
5
  function getParamsFromOptions(options) {
8
6
  const params = {};
@@ -10,7 +8,7 @@ function getParamsFromOptions(options) {
10
8
  return params;
11
9
  }
12
10
  if (options.forwardedFor) {
13
- params._requestCustomizer = function(req) {
11
+ params._requestCustomizer = function (req) {
14
12
  req.set('auth0-forwarded-for', options.forwardedFor);
15
13
  };
16
14
  }
@@ -18,283 +16,270 @@ function getParamsFromOptions(options) {
18
16
  }
19
17
 
20
18
  /**
21
- * @class
22
19
  * Handles authenticator with passwordless flows, e.g. SMS, Touch ID, etc.
23
- * @constructor
24
- * @memberOf module:auth
25
- *
26
- * @param {Object} options Authenticator options.
27
- * @param {String} options.baseUrl The auth0 account URL.
28
- * @param {String} [options.clientId] Default client ID.
29
- * @param {String} [options.clientSecret] Default client secret.
30
- * @param {OAuthAuthenticator} oauth OAuthAuthenticator instance.
31
20
  */
32
- var PasswordlessAuthenticator = function(options, oauth) {
33
- if (!options) {
34
- throw new ArgumentError('Missing authenticator options');
35
- }
36
21
 
37
- if (typeof options !== 'object') {
38
- throw new ArgumentError('The authenticator options must be an object');
22
+ class PasswordlessAuthenticator {
23
+ /**
24
+ * @param {object} options Authenticator options.
25
+ * @param {string} options.baseUrl The auth0 account URL.
26
+ * @param {string} [options.clientId] Default client ID.
27
+ * @param {string} [options.clientSecret] Default client secret.
28
+ * @param {OAuthAuthenticator} oauth OAuthAuthenticator instance.
29
+ */
30
+ constructor(options, oauth) {
31
+ if (!options) {
32
+ throw new ArgumentError('Missing authenticator options');
33
+ }
34
+
35
+ if (typeof options !== 'object') {
36
+ throw new ArgumentError('The authenticator options must be an object');
37
+ }
38
+
39
+ /**
40
+ * Options object for the Rest Client instance.
41
+ *
42
+ * @type {object}
43
+ */
44
+ const clientOptions = {
45
+ errorFormatter: { message: 'message', name: 'error' },
46
+ headers: options.headers,
47
+ };
48
+
49
+ this.oauth = oauth;
50
+ this.passwordless = new RestClient(`${options.baseUrl}/passwordless/start`, clientOptions);
51
+ this.clientId = options.clientId;
52
+ this.clientSecret = options.clientSecret;
39
53
  }
40
54
 
41
55
  /**
42
- * Options object for the Rest Client instance.
56
+ * Sign in with the given user credentials.
57
+ *
58
+ * @example <caption>
59
+ * Once you have a verification code, use this endpoint to login
60
+ * the user with their phone number/email and verification code.
61
+ *
62
+ * https://auth0.com/docs/api/authentication#authenticate-user
63
+ * </caption>
64
+ *
65
+ * var data = {
66
+ * username: '{PHONE_NUMBER OR EMAIL}',
67
+ * otp: '{VERIFICATION_CODE}',
68
+ * realm: '{sms or email}' // OPTIONAL DEFAULTS TO SMS
69
+ * };
70
+ *
71
+ * auth0.passwordless.signIn(data, function (err) {
72
+ * if (err) {
73
+ * // Handle error.
74
+ * }
75
+ * });
76
+ * @example <caption>
77
+ * The user data object has the following structure.
78
+ * </caption>
79
+ *
80
+ * {
81
+ * id_token: String,
82
+ * access_token: String,
83
+ * token_type: String
84
+ * }
85
+ * @example <caption>
86
+ * LEGACY signIn using the `/oauth/ro` endpoint. When otp is not specified
87
+ * password is required. Given the user credentials (`phone_number` and `code`),
88
+ * it will do the authentication on the provider and return a JSON with
89
+ * the `access_token` and `id_token`.
90
+ *
91
+ * https://auth0.com/docs/api/authentication#resource-owner
92
+ * </caption>
43
93
  *
44
- * @type {Object}
94
+ * var data = {
95
+ * username: '{PHONE_NUMBER}',
96
+ * password: '{VERIFICATION_CODE}'
97
+ * };
98
+ *
99
+ * auth0.passwordless.signIn(data, function (err) {
100
+ * if (err) {
101
+ * // Handle error.
102
+ * }
103
+ * });
104
+ * @param {object} userData User credentials object.
105
+ * @param {string} userData.username The user's phone number if realm=sms, or the user's email if realm=email
106
+ * @param {string} userData.otp The user's verification code. Required
107
+ * @param {string} [userData.realm=sms] Realm string: "sms" or "email".
108
+ * @param {string} [userData.password] [DEPRECATED] Password required if using legacy /oauth/ro endpoint
109
+ * @param {string} [userData.connection=sms] [DEPRECATED] Connection string: "sms" or "email".
110
+ * @param {object} [options] Additional options.
111
+ * @param {string} [options.forwardedFor] Value to be used for auth0-forwarded-for header
112
+ * @param {Function} [cb] Method callback.
113
+ * @returns {Promise|undefined}
45
114
  */
46
- var clientOptions = {
47
- errorFormatter: { message: 'message', name: 'error' },
48
- headers: options.headers
49
- };
115
+ signIn(userData, options, cb) {
116
+ const { options: sanitizedOptions, cb: sanitizedCb } = sanitizeArguments(options, cb);
50
117
 
51
- this.oauth = oauth;
52
- this.passwordless = new RestClient(options.baseUrl + '/passwordless/start', clientOptions);
53
- this.clientId = options.clientId;
54
- this.clientSecret = options.clientSecret;
55
- };
118
+ if (!userData || typeof userData !== 'object') {
119
+ throw new ArgumentError('Missing user data object');
120
+ }
56
121
 
57
- /**
58
- * Sign in with the given user credentials.
59
- *
60
- * @method signIn
61
- * @memberOf module:auth.PasswordlessAuthenticator.prototype
62
- * @example <caption>
63
- * Once you have a verification code, use this endpoint to login
64
- * the user with their phone number/email and verification code.
65
- *
66
- * https://auth0.com/docs/api/authentication#authenticate-user
67
- * </caption>
68
- *
69
- * var data = {
70
- * username: '{PHONE_NUMBER OR EMAIL}',
71
- * otp: '{VERIFICATION_CODE}',
72
- * realm: '{sms or email}' // OPTIONAL DEFAULTS TO SMS
73
- * };
74
- *
75
- * auth0.passwordless.signIn(data, function (err) {
76
- * if (err) {
77
- * // Handle error.
78
- * }
79
- * });
80
- *
81
- * @example <caption>
82
- * The user data object has the following structure.
83
- * </caption>
84
- *
85
- * {
86
- * id_token: String,
87
- * access_token: String,
88
- * token_type: String
89
- * }
90
- *
91
- * @example <caption>
92
- * LEGACY signIn using the `/oauth/ro` endpoint. When otp is not specified
93
- * password is required. Given the user credentials (`phone_number` and `code`),
94
- * it will do the authentication on the provider and return a JSON with
95
- * the `access_token` and `id_token`.
96
- *
97
- * https://auth0.com/docs/api/authentication#resource-owner
98
- * </caption>
99
- *
100
- * var data = {
101
- * username: '{PHONE_NUMBER}',
102
- * password: '{VERIFICATION_CODE}'
103
- * };
104
- *
105
- * auth0.passwordless.signIn(data, function (err) {
106
- * if (err) {
107
- * // Handle error.
108
- * }
109
- * });
110
- *
111
- * @param {Object} userData User credentials object.
112
- * @param {String} userData.username The user's phone number if realm=sms, or the user's email if realm=email
113
- * @param {String} userData.otp The user's verification code. Required
114
- * @param {String} [userData.realm=sms] Realm string: "sms" or "email".
115
- * @param {String} [userData.password] [DEPRECATED] Password required if using legacy /oauth/ro endpoint
116
- * @param {String} [userData.connection=sms] [DEPRECATED] Connection string: "sms" or "email".
117
- * @param {Object} [options] Additional options.
118
- * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header
119
- * @param {Function} [cb] Method callback.
120
- *
121
- * @return {Promise|undefined}
122
- */
123
- PasswordlessAuthenticator.prototype.signIn = function(userData, options, cb) {
124
- var { options, cb } = sanitizeArguments(options, cb);
125
- var defaultFields = {
126
- client_id: this.clientId,
127
- client_secret: this.clientSecret
128
- };
129
- var data = extend(defaultFields, userData);
122
+ const data = {
123
+ client_id: this.clientId,
124
+ client_secret: this.clientSecret,
125
+ ...userData,
126
+ };
130
127
 
131
- if (!userData || typeof userData !== 'object') {
132
- throw new ArgumentError('Missing user data object');
133
- }
128
+ if (typeof data.username !== 'string' || data.username.trim().length === 0) {
129
+ throw new ArgumentError('username field (phone number) is required');
130
+ }
134
131
 
135
- if (typeof data.username !== 'string' || data.username.trim().length === 0) {
136
- throw new ArgumentError('username field (phone number) is required');
137
- }
132
+ // If otp is provided, attempt to sign in using otp grant
133
+ if (typeof data.otp === 'string' && data.otp.trim().length > 0) {
134
+ if (!data.realm || (data.realm !== 'email' && data.realm !== 'sms')) {
135
+ data.realm = 'sms';
136
+ }
137
+ data.grant_type = 'http://auth0.com/oauth/grant-type/passwordless/otp';
138
+ return this.oauth.signIn(data, { type: 'token', ...sanitizedOptions }, sanitizedCb);
139
+ }
138
140
 
139
- // If otp is provided, attempt to sign in using otp grant
140
- if (typeof data.otp === 'string' && data.otp.trim().length > 0) {
141
- if (!data.realm || (data.realm !== 'email' && data.realm !== 'sms')) {
142
- data.realm = 'sms';
141
+ // Don't let the user override the connection nor the grant type.
142
+ if (!data.connection || (data.connection !== 'email' && data.connection !== 'sms')) {
143
+ data.connection = 'sms';
143
144
  }
144
- data.grant_type = 'http://auth0.com/oauth/grant-type/passwordless/otp';
145
- return this.oauth.signIn(data, extend({ type: 'token' }, options), cb);
146
- }
145
+ data.grant_type = 'password';
147
146
 
148
- // Don't let the user override the connection nor the grant type.
149
- if (!data.connection || (data.connection !== 'email' && data.connection !== 'sms')) {
150
- data.connection = 'sms';
151
- }
152
- data.grant_type = 'password';
147
+ if (typeof data.password !== 'string' || data.password.trim().length === 0) {
148
+ throw new ArgumentError('password field (verification code) is required');
149
+ }
153
150
 
154
- if (typeof data.password !== 'string' || data.password.trim().length === 0) {
155
- throw new ArgumentError('password field (verification code) is required');
151
+ console.warn(
152
+ 'The oauth/ro endpoint has been deprecated. Please use the realm and otp parameters in this function.'
153
+ );
154
+ return this.oauth.signIn(data, sanitizedOptions, sanitizedCb);
156
155
  }
157
156
 
158
- console.warn(
159
- 'The oauth/ro endpoint has been deprecated. Please use the realm and otp parameters in this function.'
160
- );
161
- return this.oauth.signIn(data, options, cb);
162
- };
157
+ /**
158
+ * Start passwordless flow sending an email.
159
+ *
160
+ * @example <caption>
161
+ * Given the user `email` address, it will send an email with:
162
+ *
163
+ * <ul>
164
+ * <li>A link (default, `send:"link"`). You can then authenticate with this
165
+ * user opening the link and he will be automatically logged in to the
166
+ * application. Optionally, you can append/override parameters to the link
167
+ * (like `scope`, `redirect_uri`, `protocol`, `response_type`, etc.) using
168
+ * `authParams` object.
169
+ * </li>
170
+ * <li>
171
+ * A verification code (`send:"code"`). You can then authenticate with
172
+ * this user using the `/oauth/ro` endpoint specifying `email` as
173
+ * `username` and `code` as `password`.
174
+ * </li>
175
+ * </ul>
176
+ *
177
+ * Find more information in the
178
+ * <a href="https://auth0.com/docs/auth-api#!#post--with_email">API Docs</a>
179
+ * </caption>
180
+ *
181
+ * var data = {
182
+ * email: '{EMAIL}',
183
+ * send: 'link',
184
+ * authParams: {} // Optional auth params.
185
+ * };
186
+ *
187
+ * auth0.passwordless.sendEmail(data, function (err) {
188
+ * if (err) {
189
+ * // Handle error.
190
+ * }
191
+ * });
192
+ * @param {object} userData User account data.
193
+ * @param {string} userData.email User email address.
194
+ * @param {string} userData.send The type of email to be sent.
195
+ * @param {object} [options] Additional options.
196
+ * @param {string} [options.forwardedFor] Value to be used for auth0-forwarded-for header
197
+ * @param {Function} [cb] Method callback.
198
+ * @returns {Promise|undefined}
199
+ */
200
+ sendEmail(userData, options, cb) {
201
+ const { options: sanitizedOptions, cb: sanitizedCb } = sanitizeArguments(options, cb);
202
+ const data = {
203
+ client_id: this.clientId,
204
+ client_secret: this.clientSecret,
205
+ ...userData,
206
+ };
207
+ const params = getParamsFromOptions(sanitizedOptions);
163
208
 
164
- /**
165
- * Start passwordless flow sending an email.
166
- *
167
- * @method sendEmail
168
- * @memberOf module:auth.PasswordlessAuthenticator.prototype
169
- * @example <caption>
170
- * Given the user `email` address, it will send an email with:
171
- *
172
- * <ul>
173
- * <li>A link (default, `send:"link"`). You can then authenticate with this
174
- * user opening the link and he will be automatically logged in to the
175
- * application. Optionally, you can append/override parameters to the link
176
- * (like `scope`, `redirect_uri`, `protocol`, `response_type`, etc.) using
177
- * `authParams` object.
178
- * </li>
179
- * <li>
180
- * A verification code (`send:"code"`). You can then authenticate with
181
- * this user using the `/oauth/ro` endpoint specifying `email` as
182
- * `username` and `code` as `password`.
183
- * </li>
184
- * </ul>
185
- *
186
- * Find more information in the
187
- * <a href="https://auth0.com/docs/auth-api#!#post--with_email">API Docs</a>
188
- * </caption>
189
- *
190
- * var data = {
191
- * email: '{EMAIL}',
192
- * send: 'link',
193
- * authParams: {} // Optional auth params.
194
- * };
195
- *
196
- * auth0.passwordless.sendEmail(data, function (err) {
197
- * if (err) {
198
- * // Handle error.
199
- * }
200
- * });
201
- *
202
- * @param {Object} userData User account data.
203
- * @param {String} userData.email User email address.
204
- * @param {String} userData.send The type of email to be sent.
205
- * @param {Object} [options] Additional options.
206
- * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header
207
- * @param {Function} [cb] Method callback.
208
- *
209
- * @return {Promise|undefined}
210
- */
211
- PasswordlessAuthenticator.prototype.sendEmail = function(userData, options, cb) {
212
- var { options, cb } = sanitizeArguments(options, cb);
213
- var defaultFields = {
214
- client_id: this.clientId,
215
- client_secret: this.clientSecret
216
- };
217
- var params = getParamsFromOptions(options);
218
- var data = extend(defaultFields, userData);
209
+ // Don't let the user override the connection nor the grant type.
210
+ data.connection = 'email';
219
211
 
220
- // Don't let the user override the connection nor the grant type.
221
- data.connection = 'email';
212
+ if (!userData || typeof userData !== 'object') {
213
+ throw new ArgumentError('Missing user data object');
214
+ }
222
215
 
223
- if (!userData || typeof userData !== 'object') {
224
- throw new ArgumentError('Missing user data object');
225
- }
216
+ if (typeof data.email !== 'string' || data.email.trim().length === 0) {
217
+ throw new ArgumentError('email field is required');
218
+ }
226
219
 
227
- if (typeof data.email !== 'string' || data.email.trim().length === 0) {
228
- throw new ArgumentError('email field is required');
229
- }
220
+ if (typeof data.send !== 'string' || data.send.trim().length === 0) {
221
+ throw new ArgumentError('send field is required');
222
+ }
230
223
 
231
- if (typeof data.send !== 'string' || data.send.trim().length === 0) {
232
- throw new ArgumentError('send field is required');
233
- }
224
+ if (sanitizedCb && sanitizedCb instanceof Function) {
225
+ return this.passwordless.create(params, data, sanitizedCb);
226
+ }
234
227
 
235
- if (cb && cb instanceof Function) {
236
- return this.passwordless.create(params, data, cb);
228
+ return this.passwordless.create(params, data);
237
229
  }
238
230
 
239
- return this.passwordless.create(params, data);
240
- };
231
+ /**
232
+ * Start passwordless flow sending an SMS.
233
+ *
234
+ * @example <caption>
235
+ * Given the user `phone_number`, it will send a SMS message with a
236
+ * verification code. You can then authenticate with this user using the
237
+ * `/oauth/ro` endpoint specifying `phone_number` as `username` and `code` as
238
+ * `password`:
239
+ * </caption>
240
+ *
241
+ * var data = {
242
+ * phone_number: '{PHONE}'
243
+ * };
244
+ *
245
+ * auth0.passwordless.sendSMS(data, function (err) {
246
+ * if (err) {
247
+ * // Handle error.
248
+ * }
249
+ * });
250
+ * @param {object} userData User account data.
251
+ * @param {string} userData.phone_number User phone number.
252
+ * @param {object} [options] Additional options.
253
+ * @param {string} [options.forwardedFor] Value to be used for auth0-forwarded-for header
254
+ * @param {Function} [cb] Method callback.
255
+ * @returns {Promise|undefined}
256
+ */
257
+ sendSMS(userData, options, cb) {
258
+ const { options: sanitizedOptions, cb: sanitizedCb } = sanitizeArguments(options, cb);
259
+ const data = {
260
+ client_id: this.clientId,
261
+ client_secret: this.clientSecret,
262
+ ...userData,
263
+ };
264
+ const params = getParamsFromOptions(sanitizedOptions);
241
265
 
242
- /**
243
- * Start passwordless flow sending an SMS.
244
- *
245
- * @method sendSMS
246
- * @memberOf module:auth.PasswordlessAuthenticator.prototype
247
- *
248
- * @example <caption>
249
- * Given the user `phone_number`, it will send a SMS message with a
250
- * verification code. You can then authenticate with this user using the
251
- * `/oauth/ro` endpoint specifying `phone_number` as `username` and `code` as
252
- * `password`:
253
- * </caption>
254
- *
255
- * var data = {
256
- * phone_number: '{PHONE}'
257
- * };
258
- *
259
- * auth0.passwordless.sendSMS(data, function (err) {
260
- * if (err) {
261
- * // Handle error.
262
- * }
263
- * });
264
- *
265
- * @param {Object} userData User account data.
266
- * @param {String} userData.phone_number User phone number.
267
- * @param {Object} [options] Additional options.
268
- * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header
269
- * @param {Function} [cb] Method callback.
270
- *
271
- * @return {Promise|undefined}
272
- */
273
- PasswordlessAuthenticator.prototype.sendSMS = function(userData, options, cb) {
274
- var { options, cb } = sanitizeArguments(options, cb);
275
- var defaultFields = {
276
- client_id: this.clientId,
277
- client_secret: this.clientSecret
278
- };
279
- var params = getParamsFromOptions(options);
280
- var data = extend(defaultFields, userData);
266
+ // Don't let the user override the connection nor the grant type.
267
+ data.connection = 'sms';
281
268
 
282
- // Don't let the user override the connection nor the grant type.
283
- data.connection = 'sms';
269
+ if (!userData || typeof userData !== 'object') {
270
+ throw new ArgumentError('Missing user data object');
271
+ }
284
272
 
285
- if (!userData || typeof userData !== 'object') {
286
- throw new ArgumentError('Missing user data object');
287
- }
273
+ if (typeof data.phone_number !== 'string' || data.phone_number.trim().length === 0) {
274
+ throw new ArgumentError('phone_number field is required');
275
+ }
288
276
 
289
- if (typeof data.phone_number !== 'string' || data.phone_number.trim().length === 0) {
290
- throw new ArgumentError('phone_number field is required');
291
- }
277
+ if (sanitizedCb && sanitizedCb instanceof Function) {
278
+ return this.passwordless.create(params, data, sanitizedCb);
279
+ }
292
280
 
293
- if (cb && cb instanceof Function) {
294
- return this.passwordless.create(params, data, cb);
281
+ return this.passwordless.create(params, data);
295
282
  }
296
-
297
- return this.passwordless.create(params, data);
298
- };
283
+ }
299
284
 
300
285
  module.exports = PasswordlessAuthenticator;