@auth0/auth0-spa-js 2.0.7 → 2.1.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 +1 -1
- package/dist/auth0-spa-js.development.js +38 -29
- package/dist/auth0-spa-js.development.js.map +1 -1
- package/dist/auth0-spa-js.production.esm.js +1 -1
- package/dist/auth0-spa-js.production.esm.js.map +1 -1
- package/dist/auth0-spa-js.production.js +1 -1
- package/dist/auth0-spa-js.production.js.map +1 -1
- package/dist/lib/auth0-spa-js.cjs.js +38 -29
- package/dist/lib/auth0-spa-js.cjs.js.map +1 -1
- package/dist/typings/Auth0Client.d.ts +1 -1
- package/dist/typings/global.d.ts +9 -5
- package/dist/typings/transaction-manager.d.ts +1 -2
- package/dist/typings/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Auth0Client.ts +21 -20
- package/src/global.ts +9 -5
- package/src/jwt.ts +25 -9
- package/src/transaction-manager.ts +8 -9
- package/src/version.ts +1 -1
package/dist/typings/global.d.ts
CHANGED
|
@@ -66,10 +66,13 @@ export interface AuthorizationParams {
|
|
|
66
66
|
*/
|
|
67
67
|
connection?: string;
|
|
68
68
|
/**
|
|
69
|
-
* The
|
|
69
|
+
* The organization to log in to.
|
|
70
|
+
*
|
|
71
|
+
* This will specify an `organization` parameter in your user's login request.
|
|
72
|
+
*
|
|
73
|
+
* - If you provide an Organization ID (a string with the prefix `org_`), it will be validated against the `org_id` claim of your user's ID Token. The validation is case-sensitive.
|
|
74
|
+
* - If you provide an Organization Name (a string *without* the prefix `org_`), it will be validated against the `org_name` claim of your user's ID Token. The validation is case-insensitive.
|
|
70
75
|
*
|
|
71
|
-
* This will specify an `organization` parameter in your user's login request and will add a step to validate
|
|
72
|
-
* the `org_id` claim in your user's ID Token.
|
|
73
76
|
*/
|
|
74
77
|
organization?: string;
|
|
75
78
|
/**
|
|
@@ -496,7 +499,7 @@ export interface JWTVerifyOptions {
|
|
|
496
499
|
nonce?: string;
|
|
497
500
|
leeway?: number;
|
|
498
501
|
max_age?: number;
|
|
499
|
-
|
|
502
|
+
organization?: string;
|
|
500
503
|
now?: number;
|
|
501
504
|
}
|
|
502
505
|
export interface IdToken {
|
|
@@ -532,11 +535,12 @@ export interface IdToken {
|
|
|
532
535
|
at_hash?: string;
|
|
533
536
|
c_hash?: string;
|
|
534
537
|
acr?: string;
|
|
535
|
-
amr?: string;
|
|
538
|
+
amr?: string[];
|
|
536
539
|
sub_jwk?: string;
|
|
537
540
|
cnf?: string;
|
|
538
541
|
sid?: string;
|
|
539
542
|
org_id?: string;
|
|
543
|
+
org_name?: string;
|
|
540
544
|
[key: string]: any;
|
|
541
545
|
}
|
|
542
546
|
export declare class User {
|
|
@@ -6,14 +6,13 @@ interface Transaction {
|
|
|
6
6
|
appState?: any;
|
|
7
7
|
code_verifier: string;
|
|
8
8
|
redirect_uri?: string;
|
|
9
|
-
|
|
9
|
+
organization?: string;
|
|
10
10
|
state?: string;
|
|
11
11
|
}
|
|
12
12
|
export declare class TransactionManager {
|
|
13
13
|
private storage;
|
|
14
14
|
private clientId;
|
|
15
15
|
private cookieDomain?;
|
|
16
|
-
private transaction;
|
|
17
16
|
private storageKey;
|
|
18
17
|
constructor(storage: ClientStorage, clientId: string, cookieDomain?: string | undefined);
|
|
19
18
|
create(transaction: Transaction): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "2.0
|
|
1
|
+
declare const _default: "2.1.0";
|
|
2
2
|
export default _default;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "@auth0/auth0-spa-js",
|
|
4
4
|
"description": "Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "2.0
|
|
6
|
+
"version": "2.1.0",
|
|
7
7
|
"main": "dist/lib/auth0-spa-js.cjs.js",
|
|
8
8
|
"types": "dist/typings/index.d.ts",
|
|
9
9
|
"module": "dist/auth0-spa-js.production.esm.js",
|
package/src/Auth0Client.ts
CHANGED
|
@@ -208,7 +208,7 @@ export class Auth0Client {
|
|
|
208
208
|
this.transactionManager = new TransactionManager(
|
|
209
209
|
transactionStorage,
|
|
210
210
|
this.options.clientId,
|
|
211
|
-
this.options.cookieDomain
|
|
211
|
+
this.options.cookieDomain
|
|
212
212
|
);
|
|
213
213
|
|
|
214
214
|
this.nowProvider = this.options.nowProvider || DEFAULT_NOW_PROVIDER;
|
|
@@ -249,7 +249,7 @@ export class Auth0Client {
|
|
|
249
249
|
private async _verifyIdToken(
|
|
250
250
|
id_token: string,
|
|
251
251
|
nonce?: string,
|
|
252
|
-
|
|
252
|
+
organization?: string
|
|
253
253
|
) {
|
|
254
254
|
const now = await this.nowProvider();
|
|
255
255
|
|
|
@@ -258,16 +258,16 @@ export class Auth0Client {
|
|
|
258
258
|
aud: this.options.clientId,
|
|
259
259
|
id_token,
|
|
260
260
|
nonce,
|
|
261
|
-
|
|
261
|
+
organization,
|
|
262
262
|
leeway: this.options.leeway,
|
|
263
263
|
max_age: parseNumber(this.options.authorizationParams.max_age),
|
|
264
264
|
now
|
|
265
265
|
});
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
private
|
|
269
|
-
if (
|
|
270
|
-
this.cookieStorage.save(this.orgHintCookieName,
|
|
268
|
+
private _processOrgHint(organization?: string) {
|
|
269
|
+
if (organization) {
|
|
270
|
+
this.cookieStorage.save(this.orgHintCookieName, organization, {
|
|
271
271
|
daysUntilExpire: this.sessionCheckExpiryDays,
|
|
272
272
|
cookieDomain: this.options.cookieDomain
|
|
273
273
|
});
|
|
@@ -383,7 +383,7 @@ export class Auth0Client {
|
|
|
383
383
|
throw new GenericError('state_mismatch', 'Invalid state');
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
const
|
|
386
|
+
const organization =
|
|
387
387
|
options.authorizationParams?.organization ||
|
|
388
388
|
this.options.authorizationParams.organization;
|
|
389
389
|
|
|
@@ -398,7 +398,7 @@ export class Auth0Client {
|
|
|
398
398
|
},
|
|
399
399
|
{
|
|
400
400
|
nonceIn: params.nonce,
|
|
401
|
-
|
|
401
|
+
organization
|
|
402
402
|
}
|
|
403
403
|
);
|
|
404
404
|
}
|
|
@@ -449,7 +449,7 @@ export class Auth0Client {
|
|
|
449
449
|
const { openUrl, fragment, appState, ...urlOptions } =
|
|
450
450
|
patchOpenUrlWithOnRedirect(options);
|
|
451
451
|
|
|
452
|
-
const
|
|
452
|
+
const organization =
|
|
453
453
|
urlOptions.authorizationParams?.organization ||
|
|
454
454
|
this.options.authorizationParams.organization;
|
|
455
455
|
|
|
@@ -460,7 +460,7 @@ export class Auth0Client {
|
|
|
460
460
|
this.transactionManager.create({
|
|
461
461
|
...transaction,
|
|
462
462
|
appState,
|
|
463
|
-
...(
|
|
463
|
+
...(organization && { organization })
|
|
464
464
|
});
|
|
465
465
|
|
|
466
466
|
const urlWithFragment = fragment ? `${url}#${fragment}` : url;
|
|
@@ -516,7 +516,7 @@ export class Auth0Client {
|
|
|
516
516
|
throw new GenericError('state_mismatch', 'Invalid state');
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
-
const
|
|
519
|
+
const organization = transaction.organization;
|
|
520
520
|
const nonceIn = transaction.nonce;
|
|
521
521
|
const redirect_uri = transaction.redirect_uri;
|
|
522
522
|
|
|
@@ -529,7 +529,7 @@ export class Auth0Client {
|
|
|
529
529
|
code: code as string,
|
|
530
530
|
...(redirect_uri ? { redirect_uri } : {})
|
|
531
531
|
},
|
|
532
|
-
{ nonceIn,
|
|
532
|
+
{ nonceIn, organization }
|
|
533
533
|
);
|
|
534
534
|
|
|
535
535
|
return {
|
|
@@ -862,10 +862,10 @@ export class Auth0Client {
|
|
|
862
862
|
prompt: 'none'
|
|
863
863
|
};
|
|
864
864
|
|
|
865
|
-
const
|
|
865
|
+
const orgHint = this.cookieStorage.get<string>(this.orgHintCookieName);
|
|
866
866
|
|
|
867
|
-
if (
|
|
868
|
-
params.organization =
|
|
867
|
+
if (orgHint && !params.organization) {
|
|
868
|
+
params.organization = orgHint;
|
|
869
869
|
}
|
|
870
870
|
|
|
871
871
|
const {
|
|
@@ -912,7 +912,8 @@ export class Auth0Client {
|
|
|
912
912
|
timeout: options.authorizationParams.timeout || this.httpTimeoutMs
|
|
913
913
|
},
|
|
914
914
|
{
|
|
915
|
-
nonceIn
|
|
915
|
+
nonceIn,
|
|
916
|
+
organization: params.organization
|
|
916
917
|
}
|
|
917
918
|
);
|
|
918
919
|
|
|
@@ -1095,7 +1096,7 @@ export class Auth0Client {
|
|
|
1095
1096
|
options: PKCERequestTokenOptions | RefreshTokenRequestTokenOptions,
|
|
1096
1097
|
additionalParameters?: RequestTokenAdditionalParameters
|
|
1097
1098
|
) {
|
|
1098
|
-
const { nonceIn,
|
|
1099
|
+
const { nonceIn, organization } = additionalParameters || {};
|
|
1099
1100
|
const authResult = await oauthToken(
|
|
1100
1101
|
{
|
|
1101
1102
|
baseUrl: this.domainUrl,
|
|
@@ -1111,7 +1112,7 @@ export class Auth0Client {
|
|
|
1111
1112
|
const decodedToken = await this._verifyIdToken(
|
|
1112
1113
|
authResult.id_token,
|
|
1113
1114
|
nonceIn,
|
|
1114
|
-
|
|
1115
|
+
organization
|
|
1115
1116
|
);
|
|
1116
1117
|
|
|
1117
1118
|
await this._saveEntryInCache({
|
|
@@ -1128,7 +1129,7 @@ export class Auth0Client {
|
|
|
1128
1129
|
cookieDomain: this.options.cookieDomain
|
|
1129
1130
|
});
|
|
1130
1131
|
|
|
1131
|
-
this.
|
|
1132
|
+
this._processOrgHint(organization);
|
|
1132
1133
|
|
|
1133
1134
|
return { ...authResult, decodedToken };
|
|
1134
1135
|
}
|
|
@@ -1154,5 +1155,5 @@ interface RefreshTokenRequestTokenOptions extends BaseRequestTokenOptions {
|
|
|
1154
1155
|
|
|
1155
1156
|
interface RequestTokenAdditionalParameters {
|
|
1156
1157
|
nonceIn?: string;
|
|
1157
|
-
|
|
1158
|
+
organization?: string;
|
|
1158
1159
|
}
|
package/src/global.ts
CHANGED
|
@@ -78,10 +78,13 @@ export interface AuthorizationParams {
|
|
|
78
78
|
connection?: string;
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* The
|
|
81
|
+
* The organization to log in to.
|
|
82
|
+
*
|
|
83
|
+
* This will specify an `organization` parameter in your user's login request.
|
|
84
|
+
*
|
|
85
|
+
* - If you provide an Organization ID (a string with the prefix `org_`), it will be validated against the `org_id` claim of your user's ID Token. The validation is case-sensitive.
|
|
86
|
+
* - If you provide an Organization Name (a string *without* the prefix `org_`), it will be validated against the `org_name` claim of your user's ID Token. The validation is case-insensitive.
|
|
82
87
|
*
|
|
83
|
-
* This will specify an `organization` parameter in your user's login request and will add a step to validate
|
|
84
|
-
* the `org_id` claim in your user's ID Token.
|
|
85
88
|
*/
|
|
86
89
|
organization?: string;
|
|
87
90
|
|
|
@@ -551,7 +554,7 @@ export interface JWTVerifyOptions {
|
|
|
551
554
|
nonce?: string;
|
|
552
555
|
leeway?: number;
|
|
553
556
|
max_age?: number;
|
|
554
|
-
|
|
557
|
+
organization?: string;
|
|
555
558
|
now?: number;
|
|
556
559
|
}
|
|
557
560
|
|
|
@@ -588,11 +591,12 @@ export interface IdToken {
|
|
|
588
591
|
at_hash?: string;
|
|
589
592
|
c_hash?: string;
|
|
590
593
|
acr?: string;
|
|
591
|
-
amr?: string;
|
|
594
|
+
amr?: string[];
|
|
592
595
|
sub_jwk?: string;
|
|
593
596
|
cnf?: string;
|
|
594
597
|
sid?: string;
|
|
595
598
|
org_id?: string;
|
|
599
|
+
org_name?: string;
|
|
596
600
|
[key: string]: any;
|
|
597
601
|
}
|
|
598
602
|
|
package/src/jwt.ts
CHANGED
|
@@ -193,15 +193,31 @@ export const verify = (options: JWTVerifyOptions) => {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
if (options.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
)
|
|
196
|
+
if (options.organization) {
|
|
197
|
+
const org = options.organization.trim();
|
|
198
|
+
if (org.startsWith('org_')) {
|
|
199
|
+
const orgId = org;
|
|
200
|
+
if (!decoded.claims.org_id) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
'Organization ID (org_id) claim must be a string present in the ID token'
|
|
203
|
+
);
|
|
204
|
+
} else if (orgId !== decoded.claims.org_id) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Organization ID (org_id) claim mismatch in the ID token; expected "${orgId}", found "${decoded.claims.org_id}"`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
const orgName = org.toLowerCase();
|
|
211
|
+
// TODO should we verify if there is an `org_id` claim?
|
|
212
|
+
if (!decoded.claims.org_name) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
'Organization Name (org_name) claim must be a string present in the ID token'
|
|
215
|
+
);
|
|
216
|
+
} else if (orgName !== decoded.claims.org_name.toLowerCase()) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Organization Name (org_name) claim mismatch in the ID token; expected "${orgName}", found "${decoded.claims.org_name.toLowerCase()}"`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
205
221
|
}
|
|
206
222
|
}
|
|
207
223
|
|
|
@@ -9,34 +9,33 @@ interface Transaction {
|
|
|
9
9
|
appState?: any;
|
|
10
10
|
code_verifier: string;
|
|
11
11
|
redirect_uri?: string;
|
|
12
|
-
|
|
12
|
+
organization?: string;
|
|
13
13
|
state?: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export class TransactionManager {
|
|
17
|
-
private transaction: Transaction | undefined;
|
|
18
17
|
private storageKey: string;
|
|
19
18
|
|
|
20
|
-
constructor(
|
|
19
|
+
constructor(
|
|
20
|
+
private storage: ClientStorage,
|
|
21
|
+
private clientId: string,
|
|
22
|
+
private cookieDomain?: string
|
|
23
|
+
) {
|
|
21
24
|
this.storageKey = `${TRANSACTION_STORAGE_KEY_PREFIX}.${this.clientId}`;
|
|
22
|
-
this.transaction = this.storage.get(this.storageKey);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
public create(transaction: Transaction) {
|
|
26
|
-
this.transaction = transaction;
|
|
27
|
-
|
|
28
28
|
this.storage.save(this.storageKey, transaction, {
|
|
29
29
|
daysUntilExpire: 1,
|
|
30
|
-
cookieDomain: this.cookieDomain
|
|
30
|
+
cookieDomain: this.cookieDomain
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
public get(): Transaction | undefined {
|
|
35
|
-
return this.
|
|
35
|
+
return this.storage.get(this.storageKey);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
public remove() {
|
|
39
|
-
delete this.transaction;
|
|
40
39
|
this.storage.remove(this.storageKey, {
|
|
41
40
|
cookieDomain: this.cookieDomain
|
|
42
41
|
});
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '2.0
|
|
1
|
+
export default '2.1.0';
|