@auth0/auth0-spa-js 2.1.2 → 2.2.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 +6 -6
- package/dist/auth0-spa-js.development.js +117 -36
- 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/auth0-spa-js.worker.development.js +124 -0
- package/dist/auth0-spa-js.worker.development.js.map +1 -0
- package/dist/auth0-spa-js.worker.production.js +2 -0
- package/dist/auth0-spa-js.worker.production.js.map +1 -0
- package/dist/lib/auth0-spa-js.cjs.js +118 -36
- package/dist/lib/auth0-spa-js.cjs.js.map +1 -1
- package/dist/typings/Auth0Client.d.ts +41 -1
- package/dist/typings/TokenExchange.d.ts +70 -0
- package/dist/typings/cache/shared.d.ts +6 -6
- package/dist/typings/global.d.ts +13 -4
- package/dist/typings/scope.d.ts +6 -0
- package/dist/typings/storage.d.ts +1 -1
- package/dist/typings/version.d.ts +1 -1
- package/dist/typings/worker/worker.types.d.ts +1 -1
- package/package.json +6 -11
- package/src/Auth0Client.ts +80 -2
- package/src/TokenExchange.ts +74 -0
- package/src/global.ts +10 -0
- package/src/scope.ts +6 -0
- package/src/utils.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Auth0ClientOptions, RedirectLoginOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, User, IdToken, GetTokenSilentlyVerboseResponse } from './global';
|
|
1
|
+
import { Auth0ClientOptions, RedirectLoginOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, User, IdToken, GetTokenSilentlyVerboseResponse, TokenEndpointResponse } from './global';
|
|
2
|
+
import { CustomTokenExchangeOptions } from './TokenExchange';
|
|
2
3
|
/**
|
|
3
4
|
* Auth0 SDK for Single Page Applications using [Authorization Code Grant Flow with PKCE](https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce).
|
|
4
5
|
*/
|
|
@@ -186,4 +187,43 @@ export declare class Auth0Client {
|
|
|
186
187
|
*/
|
|
187
188
|
private _releaseLockOnPageHide;
|
|
188
189
|
private _requestToken;
|
|
190
|
+
/**
|
|
191
|
+
* Exchanges an external subject token for an Auth0 token via a token exchange request.
|
|
192
|
+
*
|
|
193
|
+
* @param {CustomTokenExchangeOptions} options - The options required to perform the token exchange.
|
|
194
|
+
*
|
|
195
|
+
* @returns {Promise<TokenEndpointResponse>} A promise that resolves to the token endpoint response,
|
|
196
|
+
* which contains the issued Auth0 tokens.
|
|
197
|
+
*
|
|
198
|
+
* This method implements the token exchange grant as specified in RFC 8693 by first validating
|
|
199
|
+
* the provided subject token type and then constructing a token request to the /oauth/token endpoint.
|
|
200
|
+
* The request includes the following parameters:
|
|
201
|
+
*
|
|
202
|
+
* - `grant_type`: Hard-coded to "urn:ietf:params:oauth:grant-type:token-exchange".
|
|
203
|
+
* - `subject_token`: The external token provided via the options.
|
|
204
|
+
* - `subject_token_type`: The type of the external token (validated by this function).
|
|
205
|
+
* - `scope`: A unique set of scopes, generated by merging the scopes supplied in the options
|
|
206
|
+
* with the SDK’s default scopes.
|
|
207
|
+
* - `audience`: The target audience, as determined by the SDK's authorization configuration.
|
|
208
|
+
*
|
|
209
|
+
* **Example Usage:**
|
|
210
|
+
*
|
|
211
|
+
* ```
|
|
212
|
+
* // Define the token exchange options
|
|
213
|
+
* const options: CustomTokenExchangeOptions = {
|
|
214
|
+
* subject_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp...',
|
|
215
|
+
* subject_token_type: 'urn:acme:legacy-system-token',
|
|
216
|
+
* scope: ['openid', 'profile']
|
|
217
|
+
* };
|
|
218
|
+
*
|
|
219
|
+
* // Exchange the external token for Auth0 tokens
|
|
220
|
+
* try {
|
|
221
|
+
* const tokenResponse = await instance.exchangeToken(options);
|
|
222
|
+
* console.log('Token response:', tokenResponse);
|
|
223
|
+
* } catch (error) {
|
|
224
|
+
* console.error('Token exchange failed:', error);
|
|
225
|
+
* }
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
exchangeToken(options: CustomTokenExchangeOptions): Promise<TokenEndpointResponse>;
|
|
189
229
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the configuration options required for initiating a Custom Token Exchange request
|
|
3
|
+
* following RFC 8693 specifications.
|
|
4
|
+
*
|
|
5
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8693 | RFC 8693: OAuth 2.0 Token Exchange}
|
|
6
|
+
*/
|
|
7
|
+
export type CustomTokenExchangeOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* The type identifier for the subject token being exchanged
|
|
10
|
+
*
|
|
11
|
+
* @pattern
|
|
12
|
+
* - Must be a namespaced URI under your organization's control
|
|
13
|
+
* - Forbidden patterns:
|
|
14
|
+
* - `^urn:ietf:params:oauth:*` (IETF reserved)
|
|
15
|
+
* - `^https:\/\/auth0\.com/*` (Auth0 reserved)
|
|
16
|
+
* - `^urn:auth0:*` (Auth0 reserved)
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* "urn:acme:legacy-system-token"
|
|
20
|
+
* "https://api.yourcompany.com/token-type/v1"
|
|
21
|
+
*/
|
|
22
|
+
subject_token_type: string;
|
|
23
|
+
/**
|
|
24
|
+
* The opaque token value being exchanged for Auth0 tokens
|
|
25
|
+
*
|
|
26
|
+
* @security
|
|
27
|
+
* - Must be validated in Auth0 Actions using strong cryptographic verification
|
|
28
|
+
* - Implement replay attack protection
|
|
29
|
+
* - Recommended validation libraries: `jose`, `jsonwebtoken`
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
|
|
33
|
+
*/
|
|
34
|
+
subject_token: string;
|
|
35
|
+
/**
|
|
36
|
+
* The target audience for the requested Auth0 token
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* Must match exactly with an API identifier configured in your Auth0 tenant
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* "https://api.your-service.com/v1"
|
|
43
|
+
*/
|
|
44
|
+
audience: string;
|
|
45
|
+
/**
|
|
46
|
+
* Space-separated list of OAuth 2.0 scopes being requested
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* Subject to API authorization policies configured in Auth0
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* "openid profile email read:data write:data"
|
|
53
|
+
*/
|
|
54
|
+
scope?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Additional custom parameters for Auth0 Action processing
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* Accessible in Action code via `event.request.body`
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* {
|
|
64
|
+
* custom_parameter: "session_context",
|
|
65
|
+
* device_fingerprint: "a3d8f7...",
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IdToken, User } from '../global';
|
|
2
2
|
export declare const CACHE_KEY_PREFIX = "@@auth0spajs@@";
|
|
3
3
|
export declare const CACHE_KEY_ID_TOKEN_SUFFIX = "@@user@@";
|
|
4
|
-
export
|
|
4
|
+
export type CacheKeyData = {
|
|
5
5
|
audience?: string;
|
|
6
6
|
scope?: string;
|
|
7
7
|
clientId: string;
|
|
@@ -39,7 +39,7 @@ export interface IdTokenEntry {
|
|
|
39
39
|
id_token: string;
|
|
40
40
|
decodedToken: DecodedToken;
|
|
41
41
|
}
|
|
42
|
-
export
|
|
42
|
+
export type CacheEntry = {
|
|
43
43
|
id_token?: string;
|
|
44
44
|
access_token: string;
|
|
45
45
|
expires_in: number;
|
|
@@ -50,15 +50,15 @@ export declare type CacheEntry = {
|
|
|
50
50
|
refresh_token?: string;
|
|
51
51
|
oauthTokenScope?: string;
|
|
52
52
|
};
|
|
53
|
-
export
|
|
53
|
+
export type WrappedCacheEntry = {
|
|
54
54
|
body: Partial<CacheEntry>;
|
|
55
55
|
expiresAt: number;
|
|
56
56
|
};
|
|
57
|
-
export
|
|
57
|
+
export type KeyManifestEntry = {
|
|
58
58
|
keys: string[];
|
|
59
59
|
};
|
|
60
|
-
export
|
|
61
|
-
export
|
|
60
|
+
export type Cacheable = WrappedCacheEntry | KeyManifestEntry;
|
|
61
|
+
export type MaybePromise<T> = Promise<T> | T;
|
|
62
62
|
export interface ICache {
|
|
63
63
|
set<T = Cacheable>(key: string, entry: T): MaybePromise<void>;
|
|
64
64
|
get<T = Cacheable>(key: string): MaybePromise<T | undefined>;
|
package/dist/typings/global.d.ts
CHANGED
|
@@ -231,11 +231,20 @@ export interface Auth0ClientOptions extends BaseLoginOptions {
|
|
|
231
231
|
* **Note**: Using this improperly can potentially compromise the token validation.
|
|
232
232
|
*/
|
|
233
233
|
nowProvider?: () => Promise<number> | number;
|
|
234
|
+
/**
|
|
235
|
+
* If provided, the SDK will load the token worker from this URL instead of the integrated `blob`. An example of when this is useful is if you have strict
|
|
236
|
+
* Content-Security-Policy (CSP) and wish to avoid needing to set `worker-src: blob:`. We recommend either serving the worker, which you can find in the module
|
|
237
|
+
* at `<module_path>/dist/auth0-spa-js.worker.production.js`, from the same host as your application or using the Auth0 CDN
|
|
238
|
+
* `https://cdn.auth0.com/js/auth0-spa-js/<version>/auth0-spa-js.worker.production.js`.
|
|
239
|
+
*
|
|
240
|
+
* **Note**: The worker is only used when `useRefreshTokens: true`, `cacheLocation: 'memory'`, and the `cache` is not custom.
|
|
241
|
+
*/
|
|
242
|
+
workerUrl?: string;
|
|
234
243
|
}
|
|
235
244
|
/**
|
|
236
245
|
* The possible locations where tokens can be stored
|
|
237
246
|
*/
|
|
238
|
-
export
|
|
247
|
+
export type CacheLocation = 'memory' | 'localstorage';
|
|
239
248
|
/**
|
|
240
249
|
* @ignore
|
|
241
250
|
*/
|
|
@@ -466,7 +475,7 @@ export interface TokenEndpointOptions {
|
|
|
466
475
|
useFormData?: boolean;
|
|
467
476
|
[key: string]: any;
|
|
468
477
|
}
|
|
469
|
-
export
|
|
478
|
+
export type TokenEndpointResponse = {
|
|
470
479
|
id_token: string;
|
|
471
480
|
access_token: string;
|
|
472
481
|
refresh_token?: string;
|
|
@@ -569,12 +578,12 @@ export declare class User {
|
|
|
569
578
|
/**
|
|
570
579
|
* @ignore
|
|
571
580
|
*/
|
|
572
|
-
export
|
|
581
|
+
export type FetchOptions = {
|
|
573
582
|
method?: string;
|
|
574
583
|
headers?: Record<string, string>;
|
|
575
584
|
credentials?: 'include' | 'omit';
|
|
576
585
|
body?: string;
|
|
577
586
|
signal?: AbortSignal;
|
|
578
587
|
};
|
|
579
|
-
export
|
|
588
|
+
export type GetTokenSilentlyVerboseResponse = Omit<TokenEndpointResponse, 'refresh_token'>;
|
|
580
589
|
export {};
|
package/dist/typings/scope.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @ignore
|
|
3
3
|
*/
|
|
4
|
+
/**
|
|
5
|
+
* Returns a string of unique scopes by removing duplicates and unnecessary whitespace.
|
|
6
|
+
*
|
|
7
|
+
* @param {...(string | undefined)[]} scopes - A list of scope strings or undefined values.
|
|
8
|
+
* @returns {string} A string containing unique scopes separated by a single space.
|
|
9
|
+
*/
|
|
4
10
|
export declare const getUniqueScopes: (...scopes: (string | undefined)[]) => string;
|
|
@@ -5,7 +5,7 @@ interface ClientStorageOptions {
|
|
|
5
5
|
/**
|
|
6
6
|
* Defines a type that handles storage to/from a storage location
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export type ClientStorage = {
|
|
9
9
|
get<T extends Object>(key: string): T | undefined;
|
|
10
10
|
save(key: string, value: any, options?: ClientStorageOptions): void;
|
|
11
11
|
remove(key: string, options?: ClientStorageOptions): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "2.
|
|
1
|
+
declare const _default: "2.2.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.
|
|
6
|
+
"version": "2.2.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",
|
|
@@ -33,19 +33,16 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@auth0/component-cdn-uploader": "github:auth0/component-cdn-uploader#v2.2.2",
|
|
36
|
-
"@babel/core": "^7.18.13",
|
|
37
|
-
"@babel/preset-env": "^7.18.10",
|
|
38
36
|
"@rollup/plugin-replace": "^4.0.0",
|
|
39
37
|
"@types/cypress": "^1.1.3",
|
|
40
38
|
"@types/jest": "^28.1.7",
|
|
41
39
|
"@typescript-eslint/eslint-plugin-tslint": "^5.33.1",
|
|
42
40
|
"@typescript-eslint/parser": "^5.33.1",
|
|
43
|
-
"babel-jest": "^28.1.3",
|
|
44
41
|
"browser-tabs-lock": "^1.2.15",
|
|
45
|
-
"browserstack-cypress-cli": "1.
|
|
42
|
+
"browserstack-cypress-cli": "1.28.0",
|
|
46
43
|
"cli-table": "^0.3.6",
|
|
47
44
|
"concurrently": "^7.3.0",
|
|
48
|
-
"cypress": "
|
|
45
|
+
"cypress": "13.6.1",
|
|
49
46
|
"es-check": "^7.0.1",
|
|
50
47
|
"es-cookie": "~1.3.2",
|
|
51
48
|
"eslint": "^8.22.0",
|
|
@@ -59,11 +56,9 @@
|
|
|
59
56
|
"jest-junit": "^14.0.0",
|
|
60
57
|
"jest-localstorage-mock": "^2.4.22",
|
|
61
58
|
"jsonwebtoken": "^9.0.0",
|
|
62
|
-
"node-fetch": "^3.2.10",
|
|
63
59
|
"oidc-provider": "^7.14.0",
|
|
64
60
|
"prettier": "^2.7.1",
|
|
65
61
|
"pretty-quick": "^3.1.2",
|
|
66
|
-
"qss": "^2.0.3",
|
|
67
62
|
"rimraf": "^3.0.2",
|
|
68
63
|
"rollup": "^2.78.0",
|
|
69
64
|
"rollup-plugin-analyzer": "^4.0.0",
|
|
@@ -73,15 +68,15 @@
|
|
|
73
68
|
"rollup-plugin-node-resolve": "^5.2.0",
|
|
74
69
|
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
75
70
|
"rollup-plugin-terser": "^7.0.2",
|
|
76
|
-
"rollup-plugin-typescript2": "^0.
|
|
71
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
77
72
|
"rollup-plugin-visualizer": "^5.7.1",
|
|
78
73
|
"rollup-plugin-web-worker-loader": "^1.6.1",
|
|
79
74
|
"serve": "^14.0.1",
|
|
80
75
|
"ts-jest": "^28.0.8",
|
|
81
76
|
"tslib": "^2.4.0",
|
|
82
|
-
"typedoc": "^0.
|
|
77
|
+
"typedoc": "^0.25.1",
|
|
83
78
|
"typescript": "^4.7.4",
|
|
84
|
-
"wait-on": "^
|
|
79
|
+
"wait-on": "^7.2.0"
|
|
85
80
|
},
|
|
86
81
|
"files": [
|
|
87
82
|
"src",
|
package/src/Auth0Client.ts
CHANGED
|
@@ -92,6 +92,7 @@ import {
|
|
|
92
92
|
OLD_IS_AUTHENTICATED_COOKIE_NAME,
|
|
93
93
|
patchOpenUrlWithOnRedirect
|
|
94
94
|
} from './Auth0Client.utils';
|
|
95
|
+
import { CustomTokenExchangeOptions } from './TokenExchange';
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
98
|
* @ignore
|
|
@@ -231,7 +232,11 @@ export class Auth0Client {
|
|
|
231
232
|
this.options.useRefreshTokens &&
|
|
232
233
|
cacheLocation === CACHE_LOCATION_MEMORY
|
|
233
234
|
) {
|
|
234
|
-
this.
|
|
235
|
+
if (this.options.workerUrl) {
|
|
236
|
+
this.worker = new Worker(this.options.workerUrl);
|
|
237
|
+
} else {
|
|
238
|
+
this.worker = new TokenWorker();
|
|
239
|
+
}
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
242
|
|
|
@@ -1093,7 +1098,10 @@ export class Auth0Client {
|
|
|
1093
1098
|
};
|
|
1094
1099
|
|
|
1095
1100
|
private async _requestToken(
|
|
1096
|
-
options:
|
|
1101
|
+
options:
|
|
1102
|
+
| PKCERequestTokenOptions
|
|
1103
|
+
| RefreshTokenRequestTokenOptions
|
|
1104
|
+
| TokenExchangeRequestOptions,
|
|
1097
1105
|
additionalParameters?: RequestTokenAdditionalParameters
|
|
1098
1106
|
) {
|
|
1099
1107
|
const { nonceIn, organization } = additionalParameters || {};
|
|
@@ -1133,6 +1141,68 @@ export class Auth0Client {
|
|
|
1133
1141
|
|
|
1134
1142
|
return { ...authResult, decodedToken };
|
|
1135
1143
|
}
|
|
1144
|
+
|
|
1145
|
+
/*
|
|
1146
|
+
Custom Token Exchange
|
|
1147
|
+
* **Implementation Notes:**
|
|
1148
|
+
* - Ensure that the `subject_token` provided has been securely obtained and is valid according
|
|
1149
|
+
* to your external identity provider's policies before invoking this function.
|
|
1150
|
+
* - The function leverages internal helper methods:
|
|
1151
|
+
* - `validateTokenType` confirms that the `subject_token_type` is supported.
|
|
1152
|
+
* - `getUniqueScopes` merges and de-duplicates scopes between the provided options and
|
|
1153
|
+
* the instance's default scopes.
|
|
1154
|
+
* - `_requestToken` performs the actual HTTP request to the token endpoint.
|
|
1155
|
+
*/
|
|
1156
|
+
|
|
1157
|
+
/**
|
|
1158
|
+
* Exchanges an external subject token for an Auth0 token via a token exchange request.
|
|
1159
|
+
*
|
|
1160
|
+
* @param {CustomTokenExchangeOptions} options - The options required to perform the token exchange.
|
|
1161
|
+
*
|
|
1162
|
+
* @returns {Promise<TokenEndpointResponse>} A promise that resolves to the token endpoint response,
|
|
1163
|
+
* which contains the issued Auth0 tokens.
|
|
1164
|
+
*
|
|
1165
|
+
* This method implements the token exchange grant as specified in RFC 8693 by first validating
|
|
1166
|
+
* the provided subject token type and then constructing a token request to the /oauth/token endpoint.
|
|
1167
|
+
* The request includes the following parameters:
|
|
1168
|
+
*
|
|
1169
|
+
* - `grant_type`: Hard-coded to "urn:ietf:params:oauth:grant-type:token-exchange".
|
|
1170
|
+
* - `subject_token`: The external token provided via the options.
|
|
1171
|
+
* - `subject_token_type`: The type of the external token (validated by this function).
|
|
1172
|
+
* - `scope`: A unique set of scopes, generated by merging the scopes supplied in the options
|
|
1173
|
+
* with the SDK’s default scopes.
|
|
1174
|
+
* - `audience`: The target audience, as determined by the SDK's authorization configuration.
|
|
1175
|
+
*
|
|
1176
|
+
* **Example Usage:**
|
|
1177
|
+
*
|
|
1178
|
+
* ```
|
|
1179
|
+
* // Define the token exchange options
|
|
1180
|
+
* const options: CustomTokenExchangeOptions = {
|
|
1181
|
+
* subject_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp...',
|
|
1182
|
+
* subject_token_type: 'urn:acme:legacy-system-token',
|
|
1183
|
+
* scope: ['openid', 'profile']
|
|
1184
|
+
* };
|
|
1185
|
+
*
|
|
1186
|
+
* // Exchange the external token for Auth0 tokens
|
|
1187
|
+
* try {
|
|
1188
|
+
* const tokenResponse = await instance.exchangeToken(options);
|
|
1189
|
+
* console.log('Token response:', tokenResponse);
|
|
1190
|
+
* } catch (error) {
|
|
1191
|
+
* console.error('Token exchange failed:', error);
|
|
1192
|
+
* }
|
|
1193
|
+
* ```
|
|
1194
|
+
*/
|
|
1195
|
+
async exchangeToken(
|
|
1196
|
+
options: CustomTokenExchangeOptions
|
|
1197
|
+
): Promise<TokenEndpointResponse> {
|
|
1198
|
+
return this._requestToken({
|
|
1199
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
|
|
1200
|
+
subject_token: options.subject_token,
|
|
1201
|
+
subject_token_type: options.subject_token_type,
|
|
1202
|
+
scope: getUniqueScopes(options.scope, this.scope),
|
|
1203
|
+
audience: this.options.authorizationParams.audience
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1136
1206
|
}
|
|
1137
1207
|
|
|
1138
1208
|
interface BaseRequestTokenOptions {
|
|
@@ -1153,6 +1223,14 @@ interface RefreshTokenRequestTokenOptions extends BaseRequestTokenOptions {
|
|
|
1153
1223
|
refresh_token?: string;
|
|
1154
1224
|
}
|
|
1155
1225
|
|
|
1226
|
+
interface TokenExchangeRequestOptions extends BaseRequestTokenOptions {
|
|
1227
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange';
|
|
1228
|
+
subject_token: string;
|
|
1229
|
+
subject_token_type: string;
|
|
1230
|
+
actor_token?: string;
|
|
1231
|
+
actor_token_type?: string;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1156
1234
|
interface RequestTokenAdditionalParameters {
|
|
1157
1235
|
nonceIn?: string;
|
|
1158
1236
|
organization?: string;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the configuration options required for initiating a Custom Token Exchange request
|
|
3
|
+
* following RFC 8693 specifications.
|
|
4
|
+
*
|
|
5
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8693 | RFC 8693: OAuth 2.0 Token Exchange}
|
|
6
|
+
*/
|
|
7
|
+
export type CustomTokenExchangeOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* The type identifier for the subject token being exchanged
|
|
10
|
+
*
|
|
11
|
+
* @pattern
|
|
12
|
+
* - Must be a namespaced URI under your organization's control
|
|
13
|
+
* - Forbidden patterns:
|
|
14
|
+
* - `^urn:ietf:params:oauth:*` (IETF reserved)
|
|
15
|
+
* - `^https:\/\/auth0\.com/*` (Auth0 reserved)
|
|
16
|
+
* - `^urn:auth0:*` (Auth0 reserved)
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* "urn:acme:legacy-system-token"
|
|
20
|
+
* "https://api.yourcompany.com/token-type/v1"
|
|
21
|
+
*/
|
|
22
|
+
subject_token_type: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The opaque token value being exchanged for Auth0 tokens
|
|
26
|
+
*
|
|
27
|
+
* @security
|
|
28
|
+
* - Must be validated in Auth0 Actions using strong cryptographic verification
|
|
29
|
+
* - Implement replay attack protection
|
|
30
|
+
* - Recommended validation libraries: `jose`, `jsonwebtoken`
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
|
|
34
|
+
*/
|
|
35
|
+
subject_token: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The target audience for the requested Auth0 token
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* Must match exactly with an API identifier configured in your Auth0 tenant
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* "https://api.your-service.com/v1"
|
|
45
|
+
*/
|
|
46
|
+
audience: string;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Space-separated list of OAuth 2.0 scopes being requested
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* Subject to API authorization policies configured in Auth0
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* "openid profile email read:data write:data"
|
|
56
|
+
*/
|
|
57
|
+
scope?: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Additional custom parameters for Auth0 Action processing
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* Accessible in Action code via `event.request.body`
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* {
|
|
68
|
+
* custom_parameter: "session_context",
|
|
69
|
+
* device_fingerprint: "a3d8f7...",
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
};
|
package/src/global.ts
CHANGED
|
@@ -259,6 +259,16 @@ export interface Auth0ClientOptions extends BaseLoginOptions {
|
|
|
259
259
|
* **Note**: Using this improperly can potentially compromise the token validation.
|
|
260
260
|
*/
|
|
261
261
|
nowProvider?: () => Promise<number> | number;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* If provided, the SDK will load the token worker from this URL instead of the integrated `blob`. An example of when this is useful is if you have strict
|
|
265
|
+
* Content-Security-Policy (CSP) and wish to avoid needing to set `worker-src: blob:`. We recommend either serving the worker, which you can find in the module
|
|
266
|
+
* at `<module_path>/dist/auth0-spa-js.worker.production.js`, from the same host as your application or using the Auth0 CDN
|
|
267
|
+
* `https://cdn.auth0.com/js/auth0-spa-js/<version>/auth0-spa-js.worker.production.js`.
|
|
268
|
+
*
|
|
269
|
+
* **Note**: The worker is only used when `useRefreshTokens: true`, `cacheLocation: 'memory'`, and the `cache` is not custom.
|
|
270
|
+
*/
|
|
271
|
+
workerUrl?: string;
|
|
262
272
|
}
|
|
263
273
|
|
|
264
274
|
/**
|
package/src/scope.ts
CHANGED
|
@@ -6,6 +6,12 @@ const dedupe = (arr: string[]) => Array.from(new Set(arr));
|
|
|
6
6
|
/**
|
|
7
7
|
* @ignore
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Returns a string of unique scopes by removing duplicates and unnecessary whitespace.
|
|
11
|
+
*
|
|
12
|
+
* @param {...(string | undefined)[]} scopes - A list of scope strings or undefined values.
|
|
13
|
+
* @returns {string} A string containing unique scopes separated by a single space.
|
|
14
|
+
*/
|
|
9
15
|
export const getUniqueScopes = (...scopes: (string | undefined)[]) => {
|
|
10
16
|
return dedupe(scopes.filter(Boolean).join(' ').trim().split(/\s+/)).join(' ');
|
|
11
17
|
};
|
package/src/utils.ts
CHANGED
|
@@ -210,7 +210,7 @@ export const validateCrypto = () => {
|
|
|
210
210
|
}
|
|
211
211
|
if (typeof getCrypto().subtle === 'undefined') {
|
|
212
212
|
throw new Error(`
|
|
213
|
-
auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/
|
|
213
|
+
auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#why-do-i-get-auth0-spa-js-must-run-on-a-secure-origin for more information.
|
|
214
214
|
`);
|
|
215
215
|
}
|
|
216
216
|
};
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '2.
|
|
1
|
+
export default '2.2.0';
|