auth0 3.0.1 → 3.1.1
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/CHANGELOG.md +17 -0
- package/package.json +4 -3
- package/src/auth/OAuthAuthenticator.js +31 -19
- package/src/auth/PasswordlessAuthenticator.js +24 -9
- package/src/auth/TokensManager.js +17 -5
- package/src/auth/clientAuthentication.js +86 -0
- package/src/auth/index.js +4 -0
- package/src/management/ClientCredentialsManager.js +112 -0
- package/src/management/ManagementTokenProvider.js +9 -2
- package/src/management/index.js +26 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [v3.1.1](https://github.com/auth0/node-auth0/tree/v3.1.1) (2023-01-12)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/auth0/node-auth0/compare/v3.1.0...v3.1.1)
|
|
6
|
+
|
|
7
|
+
**Fixed**
|
|
8
|
+
|
|
9
|
+
- bump-jwks-rsa [\#776](https://github.com/auth0/node-auth0/pull/776) ([adamjmcgrath](https://github.com/adamjmcgrath))
|
|
10
|
+
|
|
11
|
+
## [v3.1.0](https://github.com/auth0/node-auth0/tree/v3.1.0) (2023-01-12)
|
|
12
|
+
|
|
13
|
+
[Full Changelog](https://github.com/auth0/node-auth0/compare/v3.0.1...v3.1.0)
|
|
14
|
+
|
|
15
|
+
**Added**
|
|
16
|
+
|
|
17
|
+
- [SDK-3868] Add support for managing client credentials [\#774](https://github.com/auth0/node-auth0/pull/774) ([adamjmcgrath](https://github.com/adamjmcgrath))
|
|
18
|
+
- [SDK-3856] Add `client_assertion` to authenticate clients [\#761](https://github.com/auth0/node-auth0/pull/761) ([adamjmcgrath](https://github.com/adamjmcgrath))
|
|
19
|
+
|
|
3
20
|
## [v3.0.1](https://github.com/auth0/node-auth0/tree/v3.0.1) (2022-12-22)
|
|
4
21
|
|
|
5
22
|
[Full Changelog](https://github.com/auth0/node-auth0/compare/v3.0.0...v3.0.1)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auth0",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "SDK for Auth0 API v2",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -36,10 +36,11 @@
|
|
|
36
36
|
"axios": "^0.27.2",
|
|
37
37
|
"form-data": "^3.0.1",
|
|
38
38
|
"jsonwebtoken": "^9.0.0",
|
|
39
|
-
"jwks-rsa": "^3.0.
|
|
39
|
+
"jwks-rsa": "^3.0.1",
|
|
40
40
|
"lru-memoizer": "^2.1.4",
|
|
41
41
|
"rest-facade": "^1.16.3",
|
|
42
|
-
"retry": "^0.13.1"
|
|
42
|
+
"retry": "^0.13.1",
|
|
43
|
+
"uuid": "^9.0.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"chai": "^4.2.0",
|
|
@@ -3,6 +3,7 @@ const { ArgumentError } = require('rest-facade');
|
|
|
3
3
|
const RestClient = require('rest-facade').Client;
|
|
4
4
|
const { SanitizedError } = require('../errors');
|
|
5
5
|
const OAUthWithIDTokenValidation = require('./OAUthWithIDTokenValidation');
|
|
6
|
+
const { addClientAuthentication } = require('./clientAuthentication');
|
|
6
7
|
|
|
7
8
|
function getParamsFromOptions(options) {
|
|
8
9
|
const params = {};
|
|
@@ -31,6 +32,8 @@ class OAuthAuthenticator {
|
|
|
31
32
|
* @param {string} options.domain AuthenticationClient server domain
|
|
32
33
|
* @param {string} [options.clientId] Default client ID.
|
|
33
34
|
* @param {string} [options.clientSecret] Default client Secret.
|
|
35
|
+
* @param {string} [options.clientAssertionSigningKey] Private key used to sign the client assertion JWT.
|
|
36
|
+
* @param {string} [options.clientAssertionSigningAlg] Default 'RS256'.
|
|
34
37
|
* @param {boolean} [options.__bypassIdTokenValidation] Whether the id_token should be validated or not
|
|
35
38
|
*/
|
|
36
39
|
constructor(options) {
|
|
@@ -55,8 +58,22 @@ class OAuthAuthenticator {
|
|
|
55
58
|
|
|
56
59
|
this.oauth = new RestClient(`${options.baseUrl}/oauth/:type`, clientOptions);
|
|
57
60
|
this.oauthWithIDTokenValidation = new OAUthWithIDTokenValidation(this.oauth, options);
|
|
61
|
+
this.domain = options.domain;
|
|
58
62
|
this.clientId = options.clientId;
|
|
59
63
|
this.clientSecret = options.clientSecret;
|
|
64
|
+
this.clientAssertionSigningKey = options.clientAssertionSigningKey;
|
|
65
|
+
this.clientAssertionSigningAlg = options.clientAssertionSigningAlg;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
_addClientAuthentication(payload, required) {
|
|
69
|
+
return addClientAuthentication({
|
|
70
|
+
payload,
|
|
71
|
+
required,
|
|
72
|
+
domain: this.domain,
|
|
73
|
+
clientSecret: this.clientSecret,
|
|
74
|
+
clientAssertionSigningKey: this.clientAssertionSigningKey,
|
|
75
|
+
clientAssertionSigningAlg: this.clientAssertionSigningAlg,
|
|
76
|
+
});
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
/**
|
|
@@ -173,12 +190,11 @@ class OAuthAuthenticator {
|
|
|
173
190
|
throw new ArgumentError('Missing user data object');
|
|
174
191
|
}
|
|
175
192
|
|
|
176
|
-
const data = {
|
|
193
|
+
const data = this._addClientAuthentication({
|
|
177
194
|
client_id: this.clientId,
|
|
178
|
-
client_secret: this.clientSecret,
|
|
179
195
|
grant_type: 'password',
|
|
180
196
|
...userData,
|
|
181
|
-
};
|
|
197
|
+
});
|
|
182
198
|
|
|
183
199
|
if (typeof data.username !== 'string' || data.username.split().length === 0) {
|
|
184
200
|
throw new ArgumentError('username field is required');
|
|
@@ -238,12 +254,11 @@ class OAuthAuthenticator {
|
|
|
238
254
|
throw new ArgumentError('Missing data object');
|
|
239
255
|
}
|
|
240
256
|
|
|
241
|
-
data = {
|
|
257
|
+
data = this._addClientAuthentication({
|
|
242
258
|
client_id: this.clientId,
|
|
243
|
-
client_secret: this.clientSecret,
|
|
244
259
|
grant_type: 'refresh_token',
|
|
245
260
|
...data,
|
|
246
|
-
};
|
|
261
|
+
});
|
|
247
262
|
|
|
248
263
|
if (typeof data.refresh_token !== 'string' || data.refresh_token.split().length === 0) {
|
|
249
264
|
throw new ArgumentError('refresh_token is required');
|
|
@@ -297,21 +312,19 @@ class OAuthAuthenticator {
|
|
|
297
312
|
throw new ArgumentError('Missing options object');
|
|
298
313
|
}
|
|
299
314
|
|
|
300
|
-
const data =
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
315
|
+
const data = this._addClientAuthentication(
|
|
316
|
+
{
|
|
317
|
+
grant_type: 'client_credentials',
|
|
318
|
+
client_id: this.clientId,
|
|
319
|
+
...options,
|
|
320
|
+
},
|
|
321
|
+
true
|
|
322
|
+
);
|
|
306
323
|
|
|
307
324
|
if (!data.client_id || data.client_id.trim().length === 0) {
|
|
308
325
|
throw new ArgumentError('client_id field is required');
|
|
309
326
|
}
|
|
310
327
|
|
|
311
|
-
if (!data.client_secret || data.client_secret.trim().length === 0) {
|
|
312
|
-
throw new ArgumentError('client_secret field is required');
|
|
313
|
-
}
|
|
314
|
-
|
|
315
328
|
const params = {
|
|
316
329
|
type: 'token',
|
|
317
330
|
};
|
|
@@ -361,12 +374,11 @@ class OAuthAuthenticator {
|
|
|
361
374
|
throw new ArgumentError('Missing options object');
|
|
362
375
|
}
|
|
363
376
|
|
|
364
|
-
const data = {
|
|
377
|
+
const data = this._addClientAuthentication({
|
|
365
378
|
grant_type: 'authorization_code',
|
|
366
379
|
client_id: this.clientId,
|
|
367
|
-
client_secret: this.clientSecret,
|
|
368
380
|
...options,
|
|
369
|
-
};
|
|
381
|
+
});
|
|
370
382
|
|
|
371
383
|
if (!data.code || data.code.trim().length === 0) {
|
|
372
384
|
throw new ArgumentError('code field is required');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { ArgumentError } = require('rest-facade');
|
|
2
2
|
const RestClient = require('rest-facade').Client;
|
|
3
3
|
const { sanitizeArguments } = require('../utils');
|
|
4
|
+
const { addClientAuthentication } = require('./clientAuthentication');
|
|
4
5
|
|
|
5
6
|
function getParamsFromOptions(options) {
|
|
6
7
|
const params = {};
|
|
@@ -23,8 +24,11 @@ class PasswordlessAuthenticator {
|
|
|
23
24
|
/**
|
|
24
25
|
* @param {object} options Authenticator options.
|
|
25
26
|
* @param {string} options.baseUrl The auth0 account URL.
|
|
27
|
+
* @param {string} [options.domain] Required if using clientAssertionSigningKey.
|
|
26
28
|
* @param {string} [options.clientId] Default client ID.
|
|
27
29
|
* @param {string} [options.clientSecret] Default client secret.
|
|
30
|
+
* @param {string} [options.clientAssertionSigningKey] Private key used to sign the client assertion JWT.
|
|
31
|
+
* @param {string} [options.clientAssertionSigningAlg] Default 'RS256'.
|
|
28
32
|
* @param {OAuthAuthenticator} oauth OAuthAuthenticator instance.
|
|
29
33
|
*/
|
|
30
34
|
constructor(options, oauth) {
|
|
@@ -48,8 +52,22 @@ class PasswordlessAuthenticator {
|
|
|
48
52
|
|
|
49
53
|
this.oauth = oauth;
|
|
50
54
|
this.passwordless = new RestClient(`${options.baseUrl}/passwordless/start`, clientOptions);
|
|
55
|
+
this.domain = options.domain;
|
|
51
56
|
this.clientId = options.clientId;
|
|
52
57
|
this.clientSecret = options.clientSecret;
|
|
58
|
+
this.clientAssertionSigningKey = options.clientAssertionSigningKey;
|
|
59
|
+
this.clientAssertionSigningAlg = options.clientAssertionSigningAlg;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_addClientAuthentication(payload, required) {
|
|
63
|
+
return addClientAuthentication({
|
|
64
|
+
payload,
|
|
65
|
+
required,
|
|
66
|
+
domain: this.domain,
|
|
67
|
+
clientSecret: this.clientSecret,
|
|
68
|
+
clientAssertionSigningKey: this.clientAssertionSigningKey,
|
|
69
|
+
clientAssertionSigningAlg: this.clientAssertionSigningAlg,
|
|
70
|
+
});
|
|
53
71
|
}
|
|
54
72
|
|
|
55
73
|
/**
|
|
@@ -120,11 +138,10 @@ class PasswordlessAuthenticator {
|
|
|
120
138
|
throw new ArgumentError('Missing user data object');
|
|
121
139
|
}
|
|
122
140
|
|
|
123
|
-
const data = {
|
|
141
|
+
const data = this._addClientAuthentication({
|
|
124
142
|
client_id: this.clientId,
|
|
125
|
-
client_secret: this.clientSecret,
|
|
126
143
|
...userData,
|
|
127
|
-
};
|
|
144
|
+
});
|
|
128
145
|
|
|
129
146
|
if (typeof data.username !== 'string' || data.username.trim().length === 0) {
|
|
130
147
|
throw new ArgumentError('username field (phone number) is required');
|
|
@@ -200,11 +217,10 @@ class PasswordlessAuthenticator {
|
|
|
200
217
|
*/
|
|
201
218
|
sendEmail(userData, options, cb) {
|
|
202
219
|
const { options: sanitizedOptions, cb: sanitizedCb } = sanitizeArguments(options, cb);
|
|
203
|
-
const data = {
|
|
220
|
+
const data = this._addClientAuthentication({
|
|
204
221
|
client_id: this.clientId,
|
|
205
|
-
client_secret: this.clientSecret,
|
|
206
222
|
...userData,
|
|
207
|
-
};
|
|
223
|
+
});
|
|
208
224
|
const params = getParamsFromOptions(sanitizedOptions);
|
|
209
225
|
|
|
210
226
|
// Don't let the user override the connection nor the grant type.
|
|
@@ -257,11 +273,10 @@ class PasswordlessAuthenticator {
|
|
|
257
273
|
*/
|
|
258
274
|
sendSMS(userData, options, cb) {
|
|
259
275
|
const { options: sanitizedOptions, cb: sanitizedCb } = sanitizeArguments(options, cb);
|
|
260
|
-
const data = {
|
|
276
|
+
const data = this._addClientAuthentication({
|
|
261
277
|
client_id: this.clientId,
|
|
262
|
-
client_secret: this.clientSecret,
|
|
263
278
|
...userData,
|
|
264
|
-
};
|
|
279
|
+
});
|
|
265
280
|
const params = getParamsFromOptions(sanitizedOptions);
|
|
266
281
|
|
|
267
282
|
// Don't let the user override the connection nor the grant type.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const { ArgumentError } = require('rest-facade');
|
|
3
|
+
const { addClientAuthentication } = require('./clientAuthentication');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Provides methods for getting token data and exchanging tokens.
|
|
@@ -9,8 +10,11 @@ class TokensManager {
|
|
|
9
10
|
* @param {object} options Manager options.
|
|
10
11
|
* @param {string} options.baseUrl The auth0 account URL.
|
|
11
12
|
* @param {string} [options.headers] Default request headers.
|
|
13
|
+
* @param {string} [options.domain] Required if using clientAssertionSigningKey.
|
|
12
14
|
* @param {string} [options.clientId] Default client ID.
|
|
13
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'.
|
|
14
18
|
*/
|
|
15
19
|
constructor(options) {
|
|
16
20
|
if (typeof options !== 'object') {
|
|
@@ -23,8 +27,11 @@ class TokensManager {
|
|
|
23
27
|
|
|
24
28
|
this.baseUrl = options.baseUrl;
|
|
25
29
|
this.headers = options.headers || {};
|
|
30
|
+
this.domain = options.domain;
|
|
26
31
|
this.clientId = options.clientId || '';
|
|
27
32
|
this.clientSecret = options.clientSecret || '';
|
|
33
|
+
this.clientAssertionSigningKey = options.clientAssertionSigningKey;
|
|
34
|
+
this.clientAssertionSigningAlg = options.clientAssertionSigningAlg;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
/**
|
|
@@ -213,11 +220,16 @@ class TokensManager {
|
|
|
213
220
|
);
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
const body = {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
+
});
|
|
221
233
|
|
|
222
234
|
const { headers } = this;
|
|
223
235
|
|
|
@@ -0,0 +1,86 @@
|
|
|
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;
|
package/src/auth/index.js
CHANGED
|
@@ -37,6 +37,8 @@ class AuthenticationClient {
|
|
|
37
37
|
* @param {string} options.domain AuthenticationClient server domain.
|
|
38
38
|
* @param {string} [options.clientId] Default client ID.
|
|
39
39
|
* @param {string} [options.clientSecret] Default client Secret.
|
|
40
|
+
* @param {string} [options.clientAssertionSigningKey] Private key used to sign the client assertion JWT.
|
|
41
|
+
* @param {string} [options.clientAssertionSigningAlg] Default RS256
|
|
40
42
|
* @param {string} [options.supportedAlgorithms] Algorithms that your application expects to receive
|
|
41
43
|
* @param {boolean} [options.__bypassIdTokenValidation] Whether the id_token should be validated or not
|
|
42
44
|
* @param {object} [options.headers] Additional headers that will be added to the outgoing requests.
|
|
@@ -59,6 +61,8 @@ class AuthenticationClient {
|
|
|
59
61
|
clientId: options.clientId,
|
|
60
62
|
domain: options.domain,
|
|
61
63
|
clientSecret: options.clientSecret,
|
|
64
|
+
clientAssertionSigningKey: options.clientAssertionSigningKey,
|
|
65
|
+
clientAssertionSigningAlg: options.clientAssertionSigningAlg,
|
|
62
66
|
headers: Object.assign(defaultHeaders, options.headers || {}),
|
|
63
67
|
baseUrl: util.format(BASE_URL_FORMAT, options.domain),
|
|
64
68
|
supportedAlgorithms: options.supportedAlgorithms,
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const BaseManager = require('./BaseManager');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The client credentials class provides a simple abstraction for performing CRUD operations
|
|
5
|
+
* on Auth0 ClientCredentials.
|
|
6
|
+
*/
|
|
7
|
+
class ClientCredentialsManager extends BaseManager {
|
|
8
|
+
/**
|
|
9
|
+
* @param {object} options The client options.
|
|
10
|
+
* @param {string} options.baseUrl The URL of the API.
|
|
11
|
+
* @param {object} [options.headers] Headers to be included in all requests.
|
|
12
|
+
* @param {object} [options.retry] Retry Policy Config
|
|
13
|
+
*/
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super(options);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @type {external:RestClient}
|
|
19
|
+
*/
|
|
20
|
+
this.resource = this._getRestClient('/clients/:client_id/credentials/:credential_id');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a new client credential.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* var params = { client_id: CLIENT_ID };
|
|
28
|
+
*
|
|
29
|
+
* management.clientCredentials.create(params, data, function (err, credential) {
|
|
30
|
+
* if (err) {
|
|
31
|
+
* // Handle error.
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* // The credential created.
|
|
35
|
+
* console.log({credential});
|
|
36
|
+
* });
|
|
37
|
+
* @param {string} params.client_id The client id.
|
|
38
|
+
* @param {object} data Client Credential data object.
|
|
39
|
+
* @param {Function} [cb] Callback function.
|
|
40
|
+
* @returns {Promise|undefined}
|
|
41
|
+
*/
|
|
42
|
+
create(...args) {
|
|
43
|
+
return this.resource.create(...args);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Return a list of credentials for a given client.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* var params = { client_id: CLIENT_ID };
|
|
51
|
+
*
|
|
52
|
+
* management.clientCredentials.getAll(params, function (err, credentials) {
|
|
53
|
+
* if (err) {
|
|
54
|
+
* // Handle error.
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* // A list of credentials associated with that client.
|
|
58
|
+
* console.log({credentials});
|
|
59
|
+
* });
|
|
60
|
+
* @param {string} params.client_id The client id.
|
|
61
|
+
* @param {Function} [cb] Callback function.
|
|
62
|
+
* @returns {Promise|undefined}
|
|
63
|
+
*/
|
|
64
|
+
getAll(...args) {
|
|
65
|
+
return this.resource.getAll(...args);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Return a credential for a given client.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* var params = { client_id: CLIENT_ID, credential_id: CREDENTIAL_ID };
|
|
73
|
+
*
|
|
74
|
+
* management.clientCredentials.getById(data, function (err, credential) {
|
|
75
|
+
* if (err) {
|
|
76
|
+
* // Handle error.
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* // A specific credential associated with that credential.
|
|
80
|
+
* console.log({credential});
|
|
81
|
+
* });
|
|
82
|
+
* @param {string} params.client_id The client id.
|
|
83
|
+
* @param {string} params.credential_id The credential id.
|
|
84
|
+
* @param {Function} [cb] Callback function.
|
|
85
|
+
* @returns {Promise|undefined}
|
|
86
|
+
*/
|
|
87
|
+
get(...args) {
|
|
88
|
+
return this.resource.get(...args);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Delete a credential for a given client.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* var params = { client_id: CLIENT_ID, credential_id: CREDENTIAL_ID };
|
|
96
|
+
*
|
|
97
|
+
* management.clientCredentials.delete(params, data, function (err) {
|
|
98
|
+
* if (err) {
|
|
99
|
+
* // Handle error.
|
|
100
|
+
* }
|
|
101
|
+
* });
|
|
102
|
+
* @param {string} params.client_id The client id.
|
|
103
|
+
* @param {string} params.credential_id The credential id.
|
|
104
|
+
* @param {Function} [cb] Callback function.
|
|
105
|
+
* @returns {Promise|undefined}
|
|
106
|
+
*/
|
|
107
|
+
delete(...args) {
|
|
108
|
+
return this.resource.delete(...args);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = ClientCredentialsManager;
|
|
@@ -12,6 +12,8 @@ class ManagementTokenProvider {
|
|
|
12
12
|
* @param {string} options.domain ManagementClient server domain.
|
|
13
13
|
* @param {string} options.clientId Non Interactive Client Id.
|
|
14
14
|
* @param {string} options.clientSecret Non Interactive Client Secret.
|
|
15
|
+
* @param {string} options.clientAssertionSigningKey Private key used to sign the client assertion JWT.
|
|
16
|
+
* @param {string} options.clientAssertionSigningAlg Default 'RS256'.
|
|
15
17
|
* @param {string} options.scope Non Interactive Client Scope.
|
|
16
18
|
* @param {string} options.audience Audience of the Management API.
|
|
17
19
|
* @param {boolean} [options.enableCache=true] Enabled or Disable Cache
|
|
@@ -33,8 +35,11 @@ class ManagementTokenProvider {
|
|
|
33
35
|
throw new ArgumentError('Must provide a clientId');
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
+
if (
|
|
39
|
+
(!params.clientSecret || params.clientSecret.length === 0) &&
|
|
40
|
+
(!params.clientAssertionSigningKey || params.clientAssertionSigningKey.length === 0)
|
|
41
|
+
) {
|
|
42
|
+
throw new ArgumentError('Must provide a clientSecret or a clientAssertionSigningKey');
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
if (!params.audience || params.audience.length === 0) {
|
|
@@ -64,6 +69,8 @@ class ManagementTokenProvider {
|
|
|
64
69
|
domain: this.options.domain,
|
|
65
70
|
clientId: this.options.clientId,
|
|
66
71
|
clientSecret: this.options.clientSecret,
|
|
72
|
+
clientAssertionSigningKey: this.options.clientAssertionSigningKey,
|
|
73
|
+
clientAssertionSigningAlg: this.options.clientAssertionSigningAlg,
|
|
67
74
|
telemetry: this.options.telemetry,
|
|
68
75
|
clientInfo: this.options.clientInfo,
|
|
69
76
|
headers: this.options.headers,
|
package/src/management/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const { jsonToBase64, generateClientInfo } = utils;
|
|
|
4
4
|
const { ArgumentError } = require('rest-facade');
|
|
5
5
|
|
|
6
6
|
// Managers.
|
|
7
|
+
const ClientCredentialsManager = require('./ClientCredentialsManager');
|
|
7
8
|
const ClientsManager = require('./ClientsManager');
|
|
8
9
|
const ClientGrantsManager = require('./ClientGrantsManager');
|
|
9
10
|
const GrantsManager = require('./GrantsManager');
|
|
@@ -73,16 +74,32 @@ const MANAGEMENT_API_AUD_FORMAT = 'https://%s/api/v2/';
|
|
|
73
74
|
* cacheTTLInSeconds: 10
|
|
74
75
|
* }
|
|
75
76
|
* });
|
|
77
|
+
* @example <caption>
|
|
78
|
+
* Initialize your client class, by using a Non Interactive Client to fetch an access_token
|
|
79
|
+
* via the Client Credentials Grant, providing a Private Key using the private_key_jwt token
|
|
80
|
+
* endpoint auth method.
|
|
81
|
+
* </caption>
|
|
82
|
+
*
|
|
83
|
+
* var ManagementClient = require('auth0').ManagementClient;
|
|
84
|
+
* var auth0 = new ManagementClient({
|
|
85
|
+
* domain: '{YOUR_ACCOUNT}.auth0.com',
|
|
86
|
+
* clientId: '{YOUR_NON_INTERACTIVE_CLIENT_ID}',
|
|
87
|
+
* clientAssertionSigningKey: fs.readFileSync('private-key.pem'),
|
|
88
|
+
* scope: "read:users write:users"
|
|
89
|
+
* });
|
|
76
90
|
*/
|
|
77
91
|
class ManagementClient {
|
|
78
92
|
/**
|
|
79
93
|
* @param {object} options Options for the ManagementClient SDK.
|
|
80
94
|
* If a token is provided only the domain is required, other parameters are ignored.
|
|
81
|
-
* If no token is provided domain, clientId, clientSecret
|
|
95
|
+
* If no token is provided domain, clientId, clientSecret (or clientAssertionSigningKey)
|
|
96
|
+
* and scopes are required
|
|
82
97
|
* @param {string} options.domain ManagementClient server domain.
|
|
83
98
|
* @param {string} [options.token] API access token.
|
|
84
99
|
* @param {string} [options.clientId] Management API Non Interactive Client Id.
|
|
85
100
|
* @param {string} [options.clientSecret] Management API Non Interactive Client Secret.
|
|
101
|
+
* @param {string} [options.clientAssertionSigningKey] Private key used to sign the client assertion JWT.
|
|
102
|
+
* @param {string} [options.clientAssertionSigningAlg] Default 'RS256'.
|
|
86
103
|
* @param {string} [options.audience] Management API Audience. By default is your domain's, e.g. the domain is `tenant.auth0.com` and the audience is `http://tenant.auth0.com/api/v2/`
|
|
87
104
|
* @param {string} [options.scope] Management API Scopes.
|
|
88
105
|
* @param {boolean} [options.tokenProvider.enableCache=true] Enabled or Disable Cache.
|
|
@@ -160,6 +177,14 @@ class ManagementClient {
|
|
|
160
177
|
*/
|
|
161
178
|
this.clients = new ClientsManager(managerOptions);
|
|
162
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Simple abstraction for performing CRUD operations on the
|
|
182
|
+
* client credentials endpoint.
|
|
183
|
+
*
|
|
184
|
+
* @type {module:management.ClientCredentialsManager}
|
|
185
|
+
*/
|
|
186
|
+
this.clientCredentials = new ClientCredentialsManager(managerOptions);
|
|
187
|
+
|
|
163
188
|
/**
|
|
164
189
|
* Simple abstraction for performing CRUD operations on the client grants
|
|
165
190
|
* endpoint.
|