@mimik/oauth-helper 1.9.6 → 1.10.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.
- package/README.md +2 -2
- package/index.js +75 -25
- package/package.json +12 -12
- package/test/oauthHelper.spec.js +102 -0
- package/test/testConfig.js +9 -0
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ Validate the request by inspecting the token. To be used for `system` and `user`
|
|
|
108
108
|
| request | <code>object</code> | The request with a token in the header. |
|
|
109
109
|
| definitions | <code>object</code> | Swagger security definitions to compare with. |
|
|
110
110
|
| scopes | <code>Array.<string></code> | List of swagger scopes associated whith the requested endpoint. |
|
|
111
|
-
| next | [<code>requestCallback</code>](#requestCallback) | The callback that handles the response. The validation adds the following properties to the request: - in case of 'system' token: 'clientId', 'tokenType', 'customer', 'onBehlaf'. If the token is a cluster token the property 'cluster' is set to true. - in case of 'user' token: userId, appId, onBehalfId, 'onBehalf'. |
|
|
111
|
+
| next | [<code>requestCallback</code>](#requestCallback) | The callback that handles the response. The validation adds the following properties to the request: - in case of 'system' token: 'claims', clientId', 'tokenType', 'customer', 'onBehlaf'. If the token is a cluster token the property 'cluster' is set to true. - in case of 'user' token: claims, userId, appId, onBehalfId, 'onBehalf'. The claims array contains the claims that are included on the scope of the recieved token. It there is no claims in the scope the claims property in request is an emtpy array. The scope must have the followimg format: `<action>:<resourceName>::<claims>`` where claims is a set of claims separatedby `,`. The is an exception for onBelf scope where the format is `onbBehalf:<action><resourceName>::<claims>`. The claims will be validated looking at the definitions property of the swagger file, by looking at at the top level properties of a definition named: `<resourceName>Claims`. If there is multiple scopes to use, the claims array will contain a concatenation of all the claims if present. |
|
|
112
112
|
|
|
113
113
|
<a name="module_oauth-helper..apiTokenAdminSecurityHelper"></a>
|
|
114
114
|
|
|
@@ -123,7 +123,7 @@ Validate the request by inspecting the token. To be used for `admin` token.
|
|
|
123
123
|
| request | <code>object</code> | The request with a token in the header. |
|
|
124
124
|
| definitions | <code>object</code> | Swagger security definitions to compare with. |
|
|
125
125
|
| scopes | <code>Array.<string></code> | List of swagger scopes associated whith the requested endpoint. |
|
|
126
|
-
| next | [<code>requestCallback</code>](#requestCallback) | The callback that handles the response. The validation adds the following properties to the request: 'clientId', tokenType', 'customer'. |
|
|
126
|
+
| next | [<code>requestCallback</code>](#requestCallback) | The callback that handles the response. The validation adds the following properties to the request: 'claims', clientId', tokenType', 'customer'. The claims array contains the claims that are included on the scope of the recieved token. It there is no claims in the scope the claims property in request is an emtpy array. The scope must have the followimg format: `<action>:<resourceName>::<claims>`` where claims is a set of claims separatedby `,`. The is an exception for onBelf scope where the format is `onbBehalf:<action><resourceName>::<claims>`. The claims will be validated looking at the definitions property of the swagger file, by looking at at the top level properties of a definition named: `<resourceName>Claims`. If there is multiple scopes to use, the claims array will contain a concatenation of all the claims if present. |
|
|
127
127
|
|
|
128
128
|
<a name="requestCallback"></a>
|
|
129
129
|
|
package/index.js
CHANGED
|
@@ -26,6 +26,11 @@ const CLIENT = '@clients';
|
|
|
26
26
|
const AUTHORIZATION = 'authorization';
|
|
27
27
|
const HEADER = 'header';
|
|
28
28
|
const CLUSTER = 'cluster';
|
|
29
|
+
const SCOPES_SEPARATOR = ' ';
|
|
30
|
+
const CLAIMS_SEPARATOR = ',';
|
|
31
|
+
const RESOURCE_SEPARATOR = ':';
|
|
32
|
+
const SCOPE_CLAIMS_SEPARATOR = '::';
|
|
33
|
+
const CLAIMS_DEFINITION = 'Claims';
|
|
29
34
|
|
|
30
35
|
const tokens = {};
|
|
31
36
|
|
|
@@ -87,24 +92,55 @@ module.exports = (config) => {
|
|
|
87
92
|
}
|
|
88
93
|
return auth[1];
|
|
89
94
|
};
|
|
90
|
-
const checkScopes = (tokenScopes, defScopes) => {
|
|
95
|
+
const checkScopes = (tokenScopes, defScopes, swagger) => {
|
|
91
96
|
if (!tokenScopes) {
|
|
92
97
|
throw new Error('no scope in authorization token');
|
|
93
98
|
}
|
|
94
|
-
|
|
99
|
+
let claims = [];
|
|
100
|
+
let onBehalf = false;
|
|
95
101
|
|
|
96
102
|
if (defScopes && defScopes.length !== 0) {
|
|
97
|
-
const
|
|
103
|
+
const currentScopes = tokenScopes.split(SCOPES_SEPARATOR);
|
|
104
|
+
const intersects = [];
|
|
105
|
+
let resourceIndex = 1;
|
|
106
|
+
|
|
107
|
+
currentScopes.forEach((currentScope) => {
|
|
108
|
+
const analyzedScope = currentScope.split(SCOPE_CLAIMS_SEPARATOR);
|
|
109
|
+
const analyzedResource = analyzedScope[0].split(RESOURCE_SEPARATOR);
|
|
110
|
+
if (analyzedResource[0] === ON_BEHALF) {
|
|
111
|
+
onBehalf = true;
|
|
112
|
+
resourceIndex = 2; // legacy handling
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (defScopes.includes(analyzedScope[0])) {
|
|
116
|
+
if (analyzedScope[1]) {
|
|
117
|
+
const includedDefinitionName = `${analyzedResource[resourceIndex]}${CLAIMS_DEFINITION}`;
|
|
98
118
|
|
|
119
|
+
if (!swagger || !swagger.swaggerObject || !swagger.swaggerObject.definitions) {
|
|
120
|
+
throw new Error(`missing ${includedDefinitionName} definition: no definitions`);
|
|
121
|
+
}
|
|
122
|
+
const includedDefinition = swagger.swaggerObject.definitions[includedDefinitionName];
|
|
123
|
+
|
|
124
|
+
if (!includedDefinition) {
|
|
125
|
+
throw new Error(`missing ${includedDefinitionName} definition`);
|
|
126
|
+
}
|
|
127
|
+
const includedClaims = analyzedScope[1].split(CLAIMS_SEPARATOR);
|
|
128
|
+
const definitionClaims = Object.keys(includedDefinition);
|
|
129
|
+
const claimsIntersects = _.intersection(includedClaims, definitionClaims);
|
|
130
|
+
|
|
131
|
+
if (claimsIntersects.length !== includedClaims.length) {
|
|
132
|
+
throw new Error(`incorrect claims included: ${_.difference(includedClaims, claimsIntersects)}`);
|
|
133
|
+
}
|
|
134
|
+
claims = claims.concat(claimsIntersects);
|
|
135
|
+
}
|
|
136
|
+
intersects.push(analyzedScope[0]);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
99
139
|
if (intersects.length === 0) {
|
|
100
140
|
throw new Error(`incorrect scopes: ${tokenScopes}`);
|
|
101
141
|
}
|
|
102
|
-
|
|
103
|
-
if (_.find(intersects, (scope) => scope.split(':')[0] === ON_BEHALF)) {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
142
|
}
|
|
107
|
-
return
|
|
143
|
+
return { onBehalf, claims };
|
|
108
144
|
};
|
|
109
145
|
|
|
110
146
|
const getToken = (type, origin, options, correlationId) => {
|
|
@@ -246,8 +282,13 @@ module.exports = (config) => {
|
|
|
246
282
|
* @param {requestCallback} next - The callback that handles the response.
|
|
247
283
|
*
|
|
248
284
|
* The validation adds the following properties to the request:
|
|
249
|
-
* - in case of 'system' token: 'clientId', 'tokenType', 'customer', 'onBehlaf'. If the token is a cluster token the property 'cluster' is set to true.
|
|
250
|
-
* - in case of 'user' token: userId, appId, onBehalfId, 'onBehalf'.
|
|
285
|
+
* - in case of 'system' token: 'claims', clientId', 'tokenType', 'customer', 'onBehlaf'. If the token is a cluster token the property 'cluster' is set to true.
|
|
286
|
+
* - in case of 'user' token: claims, userId, appId, onBehalfId, 'onBehalf'.
|
|
287
|
+
*
|
|
288
|
+
* The claims array contains the claims that are included on the scope of the recieved token. It there is no claims in the scope the claims property in request is an emtpy array.
|
|
289
|
+
* The scope must have the followimg format: `<action>:<resourceName>::<claims>`` where claims is a set of claims separatedby `,`. The is an exception for onBelf scope where the format is `onbBehalf:<action><resourceName>::<claims>`.
|
|
290
|
+
* The claims will be validated looking at the definitions property of the swagger file, by looking at at the top level properties of a definition named: `<resourceName>Claims`.
|
|
291
|
+
* If there is multiple scopes to use, the claims array will contain a concatenation of all the claims if present.
|
|
251
292
|
*/
|
|
252
293
|
const apiTokenSecurityHelper = (request, definitions, scopes, next) => {
|
|
253
294
|
let authToken;
|
|
@@ -282,14 +323,15 @@ module.exports = (config) => {
|
|
|
282
323
|
return;
|
|
283
324
|
}
|
|
284
325
|
}
|
|
285
|
-
let
|
|
326
|
+
let scopeResult;
|
|
286
327
|
|
|
287
|
-
try {
|
|
328
|
+
try { scopeResult = checkScopes(token.scope, scopes, request.swagger); }
|
|
288
329
|
catch (errScopes) {
|
|
289
330
|
next(errScopes);
|
|
290
331
|
return;
|
|
291
332
|
}
|
|
292
|
-
if (
|
|
333
|
+
if (scopeResult.onBehalf) request[TOKEN_PARAMS.onBehalf] = true;
|
|
334
|
+
request[TOKEN_PARAMS.claims] = scopeResult.claims;
|
|
293
335
|
if (definitions.flow === IMPLICIT) {
|
|
294
336
|
if (token.sub) request[TOKEN_PARAMS.userId] = token.sub;
|
|
295
337
|
if (token.azp) request[TOKEN_PARAMS.appId] = token.azp;
|
|
@@ -319,7 +361,12 @@ module.exports = (config) => {
|
|
|
319
361
|
* @param {string[]} scopes - List of swagger scopes associated whith the requested endpoint.
|
|
320
362
|
* @param {requestCallback} next - The callback that handles the response.
|
|
321
363
|
*
|
|
322
|
-
* The validation adds the following properties to the request: 'clientId', tokenType', 'customer'.
|
|
364
|
+
* The validation adds the following properties to the request: 'claims', clientId', tokenType', 'customer'.
|
|
365
|
+
*
|
|
366
|
+
* The claims array contains the claims that are included on the scope of the recieved token. It there is no claims in the scope the claims property in request is an emtpy array.
|
|
367
|
+
* The scope must have the followimg format: `<action>:<resourceName>::<claims>`` where claims is a set of claims separatedby `,`. The is an exception for onBelf scope where the format is `onbBehalf:<action><resourceName>::<claims>`.
|
|
368
|
+
* The claims will be validated looking at the definitions property of the swagger file, by looking at at the top level properties of a definition named: `<resourceName>Claims`.
|
|
369
|
+
* If there is multiple scopes to use, the claims array will contain a concatenation of all the claims if present.
|
|
323
370
|
*/
|
|
324
371
|
const apiTokenAdminSecurityHelper = (request, definitions, scopes, next) => {
|
|
325
372
|
let authToken;
|
|
@@ -341,6 +388,16 @@ module.exports = (config) => {
|
|
|
341
388
|
next(new Error('invalid token: wrong type'));
|
|
342
389
|
return;
|
|
343
390
|
}
|
|
391
|
+
if (token.subType === SUB_ADMIN) {
|
|
392
|
+
if (!token.cust) {
|
|
393
|
+
next(new Error('invalid token: no customer'));
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else if (token.sub !== `${config.security.admin.externalId}${CLIENT}`) {
|
|
398
|
+
next(new Error(`jwt subject invalid: ${token.sub}`));
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
344
401
|
try {
|
|
345
402
|
jwt.verify(authToken, keys(flow), jwtOptions(flow));
|
|
346
403
|
}
|
|
@@ -357,21 +414,14 @@ module.exports = (config) => {
|
|
|
357
414
|
return;
|
|
358
415
|
}
|
|
359
416
|
}
|
|
360
|
-
|
|
417
|
+
let scopeResult;
|
|
418
|
+
|
|
419
|
+
try { scopeResult = checkScopes(token.scope, scopes, request.swagger); }
|
|
361
420
|
catch (errScopes) {
|
|
362
421
|
next(errScopes);
|
|
363
422
|
return;
|
|
364
423
|
}
|
|
365
|
-
|
|
366
|
-
if (!token.cust) {
|
|
367
|
-
next(new Error('invalid token: no customer'));
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
else if (token.sub !== `${config.security.admin.externalId}${CLIENT}`) {
|
|
372
|
-
next(new Error(`jwt subject invalid: ${token.sub}`));
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
424
|
+
request[TOKEN_PARAMS.claims] = scopeResult.claims;
|
|
375
425
|
if (token.subType) request[TOKEN_PARAMS.tokenType] = token.subType;
|
|
376
426
|
if (token.sub) request[TOKEN_PARAMS.clientId] = token.sub;
|
|
377
427
|
if (token.cust) request[TOKEN_PARAMS.customer] = token.cust;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/oauth-helper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Oauth helper for mimik microservices",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -31,33 +31,33 @@
|
|
|
31
31
|
"@mimik/request-retry": "^2.0.6",
|
|
32
32
|
"@mimik/response-helper": "^2.6.0",
|
|
33
33
|
"@mimik/sumologic-winston-logger": "^1.6.6",
|
|
34
|
-
"@mimik/swagger-helper": "^2.5.
|
|
34
|
+
"@mimik/swagger-helper": "^2.5.1",
|
|
35
35
|
"bluebird": "3.7.2",
|
|
36
36
|
"jsonwebtoken": "8.5.1",
|
|
37
37
|
"lodash": "4.17.21"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@mimik/eslint-plugin-dependencies": "^2.4.1",
|
|
41
|
-
"@mimik/eslint-plugin-document-env": "^1.0.
|
|
41
|
+
"@mimik/eslint-plugin-document-env": "^1.0.1",
|
|
42
42
|
"@mimik/request-helper": "^1.7.3",
|
|
43
|
-
"body-parser": "1.19.
|
|
44
|
-
"chai": "4.3.
|
|
45
|
-
"eslint": "8.
|
|
43
|
+
"body-parser": "1.19.2",
|
|
44
|
+
"chai": "4.3.6",
|
|
45
|
+
"eslint": "8.10.0",
|
|
46
46
|
"eslint-config-airbnb": "18.2.1",
|
|
47
|
-
"eslint-plugin-import": "2.25.
|
|
47
|
+
"eslint-plugin-import": "2.25.4",
|
|
48
48
|
"eslint-plugin-jsx-a11y": "6.5.1",
|
|
49
49
|
"eslint-plugin-react": "7.27.1",
|
|
50
50
|
"eslint-plugin-react-hooks": "4.3.0",
|
|
51
|
-
"express": "4.17.
|
|
52
|
-
"fancy-log": "
|
|
51
|
+
"express": "4.17.3",
|
|
52
|
+
"fancy-log": "2.0.0",
|
|
53
53
|
"gulp": "4.0.2",
|
|
54
54
|
"gulp-eslint": "6.0.0",
|
|
55
55
|
"gulp-git": "2.10.1",
|
|
56
56
|
"gulp-spawn-mocha": "6.0.0",
|
|
57
57
|
"husky": "7.0.4",
|
|
58
|
-
"jsdoc-to-markdown": "7.1.
|
|
59
|
-
"mocha": "9.1
|
|
60
|
-
"mochawesome": "7.0
|
|
58
|
+
"jsdoc-to-markdown": "7.1.1",
|
|
59
|
+
"mocha": "9.2.1",
|
|
60
|
+
"mochawesome": "7.1.0",
|
|
61
61
|
"nyc": "15.1.0"
|
|
62
62
|
}
|
|
63
63
|
}
|
package/test/oauthHelper.spec.js
CHANGED
|
@@ -40,6 +40,7 @@ const adminTokenAppWrongId = jwt.sign(payload.admin, config.appGeneric.security.
|
|
|
40
40
|
const adminTokenAppNoScope = jwt.sign(payload.adminNoScope, config.appGeneric.security.generic.key, options.adminApp);
|
|
41
41
|
const subAdminTokenApp = jwt.sign(payload.subAdmin, config.appGeneric.security.generic.key, options.adminApp);
|
|
42
42
|
const subAdminTokenAppNoCustomer = jwt.sign(payload.subAdminNoCustomer, config.appGeneric.security.generic.key, options.adminApp);
|
|
43
|
+
const tokenWithClaims = jwt.sign(payload.withClaims, config.implImplicit.security.implicit.key, options.implImplicit);
|
|
43
44
|
|
|
44
45
|
describe('OauthHelper Unit Tests', () => {
|
|
45
46
|
before(() => {
|
|
@@ -137,6 +138,107 @@ describe('OauthHelper Unit Tests', () => {
|
|
|
137
138
|
expect(err.message).to.equal(`incorrect scopes: ${scope.regular}`);
|
|
138
139
|
});
|
|
139
140
|
});
|
|
141
|
+
it('should generate an error missing definition: no definition', () => {
|
|
142
|
+
oauthImplImplicit.apiTokenSecurityHelper({ headers: { authorization: `Bearer ${tokenWithClaims}` } }, definition.implicit, scope.forClaims, (err) => {
|
|
143
|
+
if (!err) throw new Error('cannot be successful');
|
|
144
|
+
expect(err.message).to.equal('missing userClaims definition: no definitions');
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
it('should generate an error missing definition', () => {
|
|
148
|
+
oauthImplImplicit.apiTokenSecurityHelper({
|
|
149
|
+
headers: { authorization: `Bearer ${tokenWithClaims}` },
|
|
150
|
+
swagger: {
|
|
151
|
+
swaggerObject: {
|
|
152
|
+
definitions: {
|
|
153
|
+
testClaims: {
|
|
154
|
+
test: 'test',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
}, definition.implicit, scope.forClaims, (err) => {
|
|
160
|
+
if (!err) throw new Error('cannot be successful');
|
|
161
|
+
expect(err.message).to.equal('missing userClaims definition');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
it('should generate an error incorrect claims included', () => {
|
|
165
|
+
oauthImplImplicit.apiTokenSecurityHelper({
|
|
166
|
+
headers: { authorization: `Bearer ${tokenWithClaims}` },
|
|
167
|
+
swagger: {
|
|
168
|
+
swaggerObject: {
|
|
169
|
+
definitions: {
|
|
170
|
+
userClaims: {
|
|
171
|
+
test: 'test',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
}, definition.implicit, scope.forClaims, (err) => {
|
|
177
|
+
if (!err) throw new Error('cannot be successful');
|
|
178
|
+
expect(err.message).to.equal('incorrect claims included: lastName,firstName');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
it('should generate an error incorrect claims included', () => {
|
|
182
|
+
oauthImplImplicit.apiTokenSecurityHelper({
|
|
183
|
+
headers: { authorization: `Bearer ${tokenWithClaims}` },
|
|
184
|
+
swagger: {
|
|
185
|
+
swaggerObject: {
|
|
186
|
+
definitions: {
|
|
187
|
+
userClaims: {
|
|
188
|
+
lastName: 'test',
|
|
189
|
+
test: 'test',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
}, definition.implicit, scope.forClaims, (err) => {
|
|
195
|
+
if (!err) throw new Error('cannot be successful');
|
|
196
|
+
expect(err.message).to.equal('incorrect claims included: firstName');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
it('should return a token and request contains claims', () => {
|
|
200
|
+
const request = {
|
|
201
|
+
headers: { authorization: `Bearer ${tokenWithClaims}` },
|
|
202
|
+
swagger: {
|
|
203
|
+
swaggerObject: {
|
|
204
|
+
definitions: {
|
|
205
|
+
userClaims: {
|
|
206
|
+
lastName: 'test',
|
|
207
|
+
firstName: 'test',
|
|
208
|
+
test: 'test',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
oauthImplImplicit.apiTokenSecurityHelper(request, definition.implicit, scope.forClaims, (err) => {
|
|
215
|
+
if (err) throw err;
|
|
216
|
+
expect(request.claims).to.deep.equal(['lastName', 'firstName']);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
it('should return a token and request contains multiple claims', () => {
|
|
220
|
+
const request = {
|
|
221
|
+
headers: { authorization: `Bearer ${tokenWithClaims}` },
|
|
222
|
+
swagger: {
|
|
223
|
+
swaggerObject: {
|
|
224
|
+
definitions: {
|
|
225
|
+
userClaims: {
|
|
226
|
+
lastName: 'test',
|
|
227
|
+
firstName: 'test',
|
|
228
|
+
test: 'test',
|
|
229
|
+
},
|
|
230
|
+
usersClaims: {
|
|
231
|
+
email: 'test',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
oauthImplImplicit.apiTokenSecurityHelper(request, definition.implicit, scope.forClaimsMultiple, (err) => {
|
|
238
|
+
if (err) throw err;
|
|
239
|
+
expect(request.claims).to.deep.equal(['lastName', 'firstName', 'email']);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
140
242
|
it('should have update request implicit with authorization', () => {
|
|
141
243
|
const request = {
|
|
142
244
|
headers: {
|
package/test/testConfig.js
CHANGED
|
@@ -216,9 +216,12 @@ const config = {
|
|
|
216
216
|
const scope = {
|
|
217
217
|
regular: 'test:1 test:2 test:3',
|
|
218
218
|
onBehalf: 'test:1 onBehalf:1',
|
|
219
|
+
withClaims: 'get:user::lastName,firstName get:users::email',
|
|
219
220
|
scopes: ['test:1', 'test:2', 'test:3'],
|
|
220
221
|
otherScopes: ['test:4', 'test:5'],
|
|
221
222
|
onBehalfScopes: ['onBehalf:1', 'test:6'],
|
|
223
|
+
forClaims: ['get:user'],
|
|
224
|
+
forClaimsMultiple: ['get:user', 'get:users'],
|
|
222
225
|
};
|
|
223
226
|
const cust = 'testCustomer';
|
|
224
227
|
const subType = 'testType';
|
|
@@ -251,6 +254,12 @@ const payload = {
|
|
|
251
254
|
subType,
|
|
252
255
|
cust,
|
|
253
256
|
},
|
|
257
|
+
withClaims: {
|
|
258
|
+
scope: scope.withClaims,
|
|
259
|
+
subType,
|
|
260
|
+
azp,
|
|
261
|
+
cust,
|
|
262
|
+
},
|
|
254
263
|
exchange: {
|
|
255
264
|
scope: scope.regular,
|
|
256
265
|
subType,
|