@auth0/auth0-spa-js 2.5.0 → 2.6.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.
@@ -550,7 +550,7 @@ var browserTabsLock = createCommonjsModule((function(module, exports) {
550
550
 
551
551
  var Lock = unwrapExports(browserTabsLock);
552
552
 
553
- var version = "2.5.0";
553
+ var version = "2.6.0";
554
554
 
555
555
  const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
556
556
 
@@ -602,6 +602,16 @@ class AuthenticationError extends GenericError {
602
602
  }
603
603
  }
604
604
 
605
+ class ConnectError extends GenericError {
606
+ constructor(error, error_description, connection, state, appState = null) {
607
+ super(error, error_description);
608
+ this.connection = connection;
609
+ this.state = state;
610
+ this.appState = appState;
611
+ Object.setPrototypeOf(this, ConnectError.prototype);
612
+ }
613
+ }
614
+
605
615
  class TimeoutError extends GenericError {
606
616
  constructor() {
607
617
  super("timeout", "Timeout");
@@ -662,6 +672,7 @@ const parseAuthenticationResult = queryString => {
662
672
  return {
663
673
  state: searchParams.get("state"),
664
674
  code: searchParams.get("code") || undefined,
675
+ connect_code: searchParams.get("connect_code") || undefined,
665
676
  error: searchParams.get("error") || undefined,
666
677
  error_description: searchParams.get("error_description") || undefined
667
678
  };
@@ -1873,6 +1884,15 @@ const SessionStorage = {
1873
1884
  }
1874
1885
  };
1875
1886
 
1887
+ exports.ResponseType = void 0;
1888
+
1889
+ (function(ResponseType) {
1890
+ ResponseType["Code"] = "code";
1891
+ ResponseType["ConnectCode"] = "connect_code";
1892
+ })(exports.ResponseType || (exports.ResponseType = {}));
1893
+
1894
+ class User {}
1895
+
1876
1896
  function decodeBase64(base64, enableUnicode) {
1877
1897
  var binaryString = atob(base64);
1878
1898
  if (enableUnicode) {
@@ -2175,7 +2195,7 @@ class Fetcher {
2175
2195
  }
2176
2196
  return new Request(this.buildUrl(this.config.baseUrl, request.url), request);
2177
2197
  }
2178
- async setAuthorizationHeader(request, accessToken) {
2198
+ setAuthorizationHeader(request, accessToken) {
2179
2199
  request.headers.set("authorization", `${this.config.dpopNonceId ? "DPoP" : "Bearer"} ${accessToken}`);
2180
2200
  }
2181
2201
  async setDpopProofHeader(request, accessToken) {
@@ -2241,6 +2261,65 @@ class Fetcher {
2241
2261
  }
2242
2262
  }
2243
2263
 
2264
+ class MyAccountApiClient {
2265
+ constructor(myAccountFetcher, apiBase) {
2266
+ this.myAccountFetcher = myAccountFetcher;
2267
+ this.apiBase = apiBase;
2268
+ }
2269
+ async connectAccount(params) {
2270
+ const res = await this.myAccountFetcher.fetchWithAuth(`${this.apiBase}v1/connected-accounts/connect`, {
2271
+ method: "POST",
2272
+ headers: {
2273
+ "Content-Type": "application/json"
2274
+ },
2275
+ body: JSON.stringify(params)
2276
+ });
2277
+ return this._handleResponse(res);
2278
+ }
2279
+ async completeAccount(params) {
2280
+ const res = await this.myAccountFetcher.fetchWithAuth(`${this.apiBase}v1/connected-accounts/complete`, {
2281
+ method: "POST",
2282
+ headers: {
2283
+ "Content-Type": "application/json"
2284
+ },
2285
+ body: JSON.stringify(params)
2286
+ });
2287
+ return this._handleResponse(res);
2288
+ }
2289
+ async _handleResponse(res) {
2290
+ let body;
2291
+ try {
2292
+ body = await res.text();
2293
+ body = JSON.parse(body);
2294
+ } catch (err) {
2295
+ throw new MyAccountApiError({
2296
+ type: "invalid_json",
2297
+ status: res.status,
2298
+ title: "Invalid JSON response",
2299
+ detail: body || String(err)
2300
+ });
2301
+ }
2302
+ if (res.ok) {
2303
+ return body;
2304
+ } else {
2305
+ throw new MyAccountApiError(body);
2306
+ }
2307
+ }
2308
+ }
2309
+
2310
+ class MyAccountApiError extends Error {
2311
+ constructor({type: type, status: status, title: title, detail: detail, validation_errors: validation_errors}) {
2312
+ super(detail);
2313
+ this.name = "MyAccountApiError";
2314
+ this.type = type;
2315
+ this.status = status;
2316
+ this.title = title;
2317
+ this.detail = detail;
2318
+ this.validation_errors = validation_errors;
2319
+ Object.setPrototypeOf(this, MyAccountApiError.prototype);
2320
+ }
2321
+ }
2322
+
2244
2323
  const lock = new Lock;
2245
2324
 
2246
2325
  class Auth0Client {
@@ -2288,6 +2367,18 @@ class Auth0Client {
2288
2367
  this.dpop = this.options.useDpop ? new Dpop(this.options.clientId) : undefined;
2289
2368
  this.domainUrl = getDomain(this.options.domain);
2290
2369
  this.tokenIssuer = getTokenIssuer(this.options.issuer, this.domainUrl);
2370
+ const myAccountApiIdentifier = `${this.domainUrl}/me/`;
2371
+ const myAccountFetcher = this.createFetcher(Object.assign(Object.assign({}, this.options.useDpop && {
2372
+ dpopNonceId: "__auth0_my_account_api__"
2373
+ }), {
2374
+ getAccessToken: () => this.getTokenSilently({
2375
+ authorizationParams: {
2376
+ scope: "create:me:connected_accounts",
2377
+ audience: myAccountApiIdentifier
2378
+ }
2379
+ })
2380
+ }));
2381
+ this.myAccountApi = new MyAccountApiClient(myAccountFetcher, myAccountApiIdentifier);
2291
2382
  if (typeof window !== "undefined" && window.Worker && this.options.useRefreshTokens && cacheLocation === CACHE_LOCATION_MEMORY) {
2292
2383
  if (this.options.workerUrl) {
2293
2384
  this.worker = new Worker(this.options.workerUrl);
@@ -2397,7 +2488,8 @@ class Auth0Client {
2397
2488
  const organization = ((_a = urlOptions.authorizationParams) === null || _a === void 0 ? void 0 : _a.organization) || this.options.authorizationParams.organization;
2398
2489
  const _c = await this._prepareAuthorizeUrl(urlOptions.authorizationParams || {}), {url: url} = _c, transaction = __rest(_c, [ "url" ]);
2399
2490
  this.transactionManager.create(Object.assign(Object.assign(Object.assign({}, transaction), {
2400
- appState: appState
2491
+ appState: appState,
2492
+ response_type: exports.ResponseType.Code
2401
2493
  }), organization && {
2402
2494
  organization: organization
2403
2495
  }));
@@ -2413,12 +2505,19 @@ class Auth0Client {
2413
2505
  if (queryStringFragments.length === 0) {
2414
2506
  throw new Error("There are no query params available for parsing.");
2415
2507
  }
2416
- const {state: state, code: code, error: error, error_description: error_description} = parseAuthenticationResult(queryStringFragments.join(""));
2417
2508
  const transaction = this.transactionManager.get();
2418
2509
  if (!transaction) {
2419
2510
  throw new GenericError("missing_transaction", "Invalid state");
2420
2511
  }
2421
2512
  this.transactionManager.remove();
2513
+ const authenticationResult = parseAuthenticationResult(queryStringFragments.join(""));
2514
+ if (transaction.response_type === exports.ResponseType.ConnectCode) {
2515
+ return this._handleConnectAccountRedirectCallback(authenticationResult, transaction);
2516
+ }
2517
+ return this._handleLoginRedirectCallback(authenticationResult, transaction);
2518
+ }
2519
+ async _handleLoginRedirectCallback(authenticationResult, transaction) {
2520
+ const {code: code, state: state, error: error, error_description: error_description} = authenticationResult;
2422
2521
  if (error) {
2423
2522
  throw new AuthenticationError(error, error_description || error, state, transaction.appState);
2424
2523
  }
@@ -2441,9 +2540,32 @@ class Auth0Client {
2441
2540
  organization: organization
2442
2541
  });
2443
2542
  return {
2444
- appState: transaction.appState
2543
+ appState: transaction.appState,
2544
+ response_type: exports.ResponseType.Code
2445
2545
  };
2446
2546
  }
2547
+ async _handleConnectAccountRedirectCallback(connectResult, transaction) {
2548
+ const {connect_code: connect_code, state: state, error: error, error_description: error_description} = connectResult;
2549
+ if (error) {
2550
+ throw new ConnectError(error, error_description || error, transaction.connection, state, transaction.appState);
2551
+ }
2552
+ if (!connect_code) {
2553
+ throw new GenericError("missing_connect_code", "Missing connect code");
2554
+ }
2555
+ if (!transaction.code_verifier || !transaction.state || !transaction.auth_session || !transaction.redirect_uri || transaction.state !== state) {
2556
+ throw new GenericError("state_mismatch", "Invalid state");
2557
+ }
2558
+ const data = await this.myAccountApi.completeAccount({
2559
+ auth_session: transaction.auth_session,
2560
+ connect_code: connect_code,
2561
+ redirect_uri: transaction.redirect_uri,
2562
+ code_verifier: transaction.code_verifier
2563
+ });
2564
+ return Object.assign(Object.assign({}, data), {
2565
+ appState: transaction.appState,
2566
+ response_type: exports.ResponseType.ConnectCode
2567
+ });
2568
+ }
2447
2569
  async checkSession(options) {
2448
2570
  if (!this.cookieStorage.get(this.isAuthenticatedCookieName)) {
2449
2571
  if (!this.cookieStorage.get(OLD_IS_AUTHENTICATED_COOKIE_NAME)) {
@@ -2795,14 +2917,52 @@ class Auth0Client {
2795
2917
  });
2796
2918
  },
2797
2919
  getDpopNonce: () => this.getDpopNonce(config.dpopNonceId),
2798
- setDpopNonce: nonce => this.setDpopNonce(nonce),
2920
+ setDpopNonce: nonce => this.setDpopNonce(nonce, config.dpopNonceId),
2799
2921
  generateDpopProof: params => this.generateDpopProof(params)
2800
2922
  });
2801
2923
  }
2924
+ async connectAccountWithRedirect(options) {
2925
+ if (!this.options.useDpop) {
2926
+ throw new Error("`useDpop` option must be enabled before using connectAccountWithRedirect.");
2927
+ }
2928
+ if (!this.options.useMrrt) {
2929
+ throw new Error("`useMrrt` option must be enabled before using connectAccountWithRedirect.");
2930
+ }
2931
+ const {openUrl: openUrl, appState: appState, connection: connection, authorization_params: authorization_params, redirectUri: redirectUri = this.options.authorizationParams.redirect_uri || window.location.origin} = options;
2932
+ if (!connection) {
2933
+ throw new Error("connection is required");
2934
+ }
2935
+ const state = encode(createRandomString());
2936
+ const code_verifier = createRandomString();
2937
+ const code_challengeBuffer = await sha256(code_verifier);
2938
+ const code_challenge = bufferToBase64UrlEncoded(code_challengeBuffer);
2939
+ const {connect_uri: connect_uri, connect_params: connect_params, auth_session: auth_session} = await this.myAccountApi.connectAccount({
2940
+ connection: connection,
2941
+ redirect_uri: redirectUri,
2942
+ state: state,
2943
+ code_challenge: code_challenge,
2944
+ code_challenge_method: "S256",
2945
+ authorization_params: authorization_params
2946
+ });
2947
+ this.transactionManager.create({
2948
+ state: state,
2949
+ code_verifier: code_verifier,
2950
+ auth_session: auth_session,
2951
+ redirect_uri: redirectUri,
2952
+ appState: appState,
2953
+ connection: connection,
2954
+ response_type: exports.ResponseType.ConnectCode
2955
+ });
2956
+ const url = new URL(connect_uri);
2957
+ url.searchParams.set("ticket", connect_params.ticket);
2958
+ if (openUrl) {
2959
+ await openUrl(url.toString());
2960
+ } else {
2961
+ window.location.assign(url);
2962
+ }
2963
+ }
2802
2964
  }
2803
2965
 
2804
- class User {}
2805
-
2806
2966
  async function createAuth0Client(options) {
2807
2967
  const auth0 = new Auth0Client(options);
2808
2968
  await auth0.checkSession();
@@ -2815,6 +2975,8 @@ exports.AuthenticationError = AuthenticationError;
2815
2975
 
2816
2976
  exports.CacheKey = CacheKey;
2817
2977
 
2978
+ exports.ConnectError = ConnectError;
2979
+
2818
2980
  exports.GenericError = GenericError;
2819
2981
 
2820
2982
  exports.InMemoryCache = InMemoryCache;
@@ -2825,6 +2987,8 @@ exports.MfaRequiredError = MfaRequiredError;
2825
2987
 
2826
2988
  exports.MissingRefreshTokenError = MissingRefreshTokenError;
2827
2989
 
2990
+ exports.MyAccountApiError = MyAccountApiError;
2991
+
2828
2992
  exports.PopupCancelledError = PopupCancelledError;
2829
2993
 
2830
2994
  exports.PopupTimeoutError = PopupTimeoutError;