@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.
package/README.md CHANGED
@@ -29,7 +29,7 @@ npm install @auth0/auth0-spa-js
29
29
  From the CDN:
30
30
 
31
31
  ```html
32
- <script src="https://cdn.auth0.com/js/auth0-spa-js/2.5/auth0-spa-js.production.js"></script>
32
+ <script src="https://cdn.auth0.com/js/auth0-spa-js/2.6/auth0-spa-js.production.js"></script>
33
33
  ```
34
34
 
35
35
  ### Configure Auth0
@@ -540,7 +540,7 @@
540
540
  exports.default = SuperTokensLock;
541
541
  }));
542
542
  var Lock = unwrapExports(browserTabsLock);
543
- var version = "2.5.0";
543
+ var version = "2.6.0";
544
544
  const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
545
545
  const DEFAULT_POPUP_CONFIG_OPTIONS = {
546
546
  timeoutInSeconds: DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS
@@ -577,6 +577,15 @@
577
577
  Object.setPrototypeOf(this, AuthenticationError.prototype);
578
578
  }
579
579
  }
580
+ class ConnectError extends GenericError {
581
+ constructor(error, error_description, connection, state, appState = null) {
582
+ super(error, error_description);
583
+ this.connection = connection;
584
+ this.state = state;
585
+ this.appState = appState;
586
+ Object.setPrototypeOf(this, ConnectError.prototype);
587
+ }
588
+ }
580
589
  class TimeoutError extends GenericError {
581
590
  constructor() {
582
591
  super("timeout", "Timeout");
@@ -630,6 +639,7 @@
630
639
  return {
631
640
  state: searchParams.get("state"),
632
641
  code: searchParams.get("code") || undefined,
642
+ connect_code: searchParams.get("connect_code") || undefined,
633
643
  error: searchParams.get("error") || undefined,
634
644
  error_description: searchParams.get("error_description") || undefined
635
645
  };
@@ -1756,6 +1766,12 @@
1756
1766
  sessionStorage.removeItem(key);
1757
1767
  }
1758
1768
  };
1769
+ exports.ResponseType = void 0;
1770
+ (function(ResponseType) {
1771
+ ResponseType["Code"] = "code";
1772
+ ResponseType["ConnectCode"] = "connect_code";
1773
+ })(exports.ResponseType || (exports.ResponseType = {}));
1774
+ class User {}
1759
1775
  function decodeBase64(base64, enableUnicode) {
1760
1776
  var binaryString = atob(base64);
1761
1777
  if (enableUnicode) {
@@ -2033,7 +2049,7 @@
2033
2049
  }
2034
2050
  return new Request(this.buildUrl(this.config.baseUrl, request.url), request);
2035
2051
  }
2036
- async setAuthorizationHeader(request, accessToken) {
2052
+ setAuthorizationHeader(request, accessToken) {
2037
2053
  request.headers.set("authorization", `${this.config.dpopNonceId ? "DPoP" : "Bearer"} ${accessToken}`);
2038
2054
  }
2039
2055
  async setDpopProofHeader(request, accessToken) {
@@ -2098,6 +2114,63 @@
2098
2114
  return this.internalFetchWithAuth(info, init, callbacks, authParams);
2099
2115
  }
2100
2116
  }
2117
+ class MyAccountApiClient {
2118
+ constructor(myAccountFetcher, apiBase) {
2119
+ this.myAccountFetcher = myAccountFetcher;
2120
+ this.apiBase = apiBase;
2121
+ }
2122
+ async connectAccount(params) {
2123
+ const res = await this.myAccountFetcher.fetchWithAuth(`${this.apiBase}v1/connected-accounts/connect`, {
2124
+ method: "POST",
2125
+ headers: {
2126
+ "Content-Type": "application/json"
2127
+ },
2128
+ body: JSON.stringify(params)
2129
+ });
2130
+ return this._handleResponse(res);
2131
+ }
2132
+ async completeAccount(params) {
2133
+ const res = await this.myAccountFetcher.fetchWithAuth(`${this.apiBase}v1/connected-accounts/complete`, {
2134
+ method: "POST",
2135
+ headers: {
2136
+ "Content-Type": "application/json"
2137
+ },
2138
+ body: JSON.stringify(params)
2139
+ });
2140
+ return this._handleResponse(res);
2141
+ }
2142
+ async _handleResponse(res) {
2143
+ let body;
2144
+ try {
2145
+ body = await res.text();
2146
+ body = JSON.parse(body);
2147
+ } catch (err) {
2148
+ throw new MyAccountApiError({
2149
+ type: "invalid_json",
2150
+ status: res.status,
2151
+ title: "Invalid JSON response",
2152
+ detail: body || String(err)
2153
+ });
2154
+ }
2155
+ if (res.ok) {
2156
+ return body;
2157
+ } else {
2158
+ throw new MyAccountApiError(body);
2159
+ }
2160
+ }
2161
+ }
2162
+ class MyAccountApiError extends Error {
2163
+ constructor({type: type, status: status, title: title, detail: detail, validation_errors: validation_errors}) {
2164
+ super(detail);
2165
+ this.name = "MyAccountApiError";
2166
+ this.type = type;
2167
+ this.status = status;
2168
+ this.title = title;
2169
+ this.detail = detail;
2170
+ this.validation_errors = validation_errors;
2171
+ Object.setPrototypeOf(this, MyAccountApiError.prototype);
2172
+ }
2173
+ }
2101
2174
  const lock = new Lock;
2102
2175
  class Auth0Client {
2103
2176
  constructor(options) {
@@ -2144,6 +2217,18 @@
2144
2217
  this.dpop = this.options.useDpop ? new Dpop(this.options.clientId) : undefined;
2145
2218
  this.domainUrl = getDomain(this.options.domain);
2146
2219
  this.tokenIssuer = getTokenIssuer(this.options.issuer, this.domainUrl);
2220
+ const myAccountApiIdentifier = `${this.domainUrl}/me/`;
2221
+ const myAccountFetcher = this.createFetcher(Object.assign(Object.assign({}, this.options.useDpop && {
2222
+ dpopNonceId: "__auth0_my_account_api__"
2223
+ }), {
2224
+ getAccessToken: () => this.getTokenSilently({
2225
+ authorizationParams: {
2226
+ scope: "create:me:connected_accounts",
2227
+ audience: myAccountApiIdentifier
2228
+ }
2229
+ })
2230
+ }));
2231
+ this.myAccountApi = new MyAccountApiClient(myAccountFetcher, myAccountApiIdentifier);
2147
2232
  if (typeof window !== "undefined" && window.Worker && this.options.useRefreshTokens && cacheLocation === CACHE_LOCATION_MEMORY) {
2148
2233
  if (this.options.workerUrl) {
2149
2234
  this.worker = new Worker(this.options.workerUrl);
@@ -2253,7 +2338,8 @@
2253
2338
  const organization = ((_a = urlOptions.authorizationParams) === null || _a === void 0 ? void 0 : _a.organization) || this.options.authorizationParams.organization;
2254
2339
  const _c = await this._prepareAuthorizeUrl(urlOptions.authorizationParams || {}), {url: url} = _c, transaction = __rest(_c, [ "url" ]);
2255
2340
  this.transactionManager.create(Object.assign(Object.assign(Object.assign({}, transaction), {
2256
- appState: appState
2341
+ appState: appState,
2342
+ response_type: exports.ResponseType.Code
2257
2343
  }), organization && {
2258
2344
  organization: organization
2259
2345
  }));
@@ -2269,12 +2355,19 @@
2269
2355
  if (queryStringFragments.length === 0) {
2270
2356
  throw new Error("There are no query params available for parsing.");
2271
2357
  }
2272
- const {state: state, code: code, error: error, error_description: error_description} = parseAuthenticationResult(queryStringFragments.join(""));
2273
2358
  const transaction = this.transactionManager.get();
2274
2359
  if (!transaction) {
2275
2360
  throw new GenericError("missing_transaction", "Invalid state");
2276
2361
  }
2277
2362
  this.transactionManager.remove();
2363
+ const authenticationResult = parseAuthenticationResult(queryStringFragments.join(""));
2364
+ if (transaction.response_type === exports.ResponseType.ConnectCode) {
2365
+ return this._handleConnectAccountRedirectCallback(authenticationResult, transaction);
2366
+ }
2367
+ return this._handleLoginRedirectCallback(authenticationResult, transaction);
2368
+ }
2369
+ async _handleLoginRedirectCallback(authenticationResult, transaction) {
2370
+ const {code: code, state: state, error: error, error_description: error_description} = authenticationResult;
2278
2371
  if (error) {
2279
2372
  throw new AuthenticationError(error, error_description || error, state, transaction.appState);
2280
2373
  }
@@ -2297,9 +2390,32 @@
2297
2390
  organization: organization
2298
2391
  });
2299
2392
  return {
2300
- appState: transaction.appState
2393
+ appState: transaction.appState,
2394
+ response_type: exports.ResponseType.Code
2301
2395
  };
2302
2396
  }
2397
+ async _handleConnectAccountRedirectCallback(connectResult, transaction) {
2398
+ const {connect_code: connect_code, state: state, error: error, error_description: error_description} = connectResult;
2399
+ if (error) {
2400
+ throw new ConnectError(error, error_description || error, transaction.connection, state, transaction.appState);
2401
+ }
2402
+ if (!connect_code) {
2403
+ throw new GenericError("missing_connect_code", "Missing connect code");
2404
+ }
2405
+ if (!transaction.code_verifier || !transaction.state || !transaction.auth_session || !transaction.redirect_uri || transaction.state !== state) {
2406
+ throw new GenericError("state_mismatch", "Invalid state");
2407
+ }
2408
+ const data = await this.myAccountApi.completeAccount({
2409
+ auth_session: transaction.auth_session,
2410
+ connect_code: connect_code,
2411
+ redirect_uri: transaction.redirect_uri,
2412
+ code_verifier: transaction.code_verifier
2413
+ });
2414
+ return Object.assign(Object.assign({}, data), {
2415
+ appState: transaction.appState,
2416
+ response_type: exports.ResponseType.ConnectCode
2417
+ });
2418
+ }
2303
2419
  async checkSession(options) {
2304
2420
  if (!this.cookieStorage.get(this.isAuthenticatedCookieName)) {
2305
2421
  if (!this.cookieStorage.get(OLD_IS_AUTHENTICATED_COOKIE_NAME)) {
@@ -2651,12 +2767,51 @@
2651
2767
  });
2652
2768
  },
2653
2769
  getDpopNonce: () => this.getDpopNonce(config.dpopNonceId),
2654
- setDpopNonce: nonce => this.setDpopNonce(nonce),
2770
+ setDpopNonce: nonce => this.setDpopNonce(nonce, config.dpopNonceId),
2655
2771
  generateDpopProof: params => this.generateDpopProof(params)
2656
2772
  });
2657
2773
  }
2774
+ async connectAccountWithRedirect(options) {
2775
+ if (!this.options.useDpop) {
2776
+ throw new Error("`useDpop` option must be enabled before using connectAccountWithRedirect.");
2777
+ }
2778
+ if (!this.options.useMrrt) {
2779
+ throw new Error("`useMrrt` option must be enabled before using connectAccountWithRedirect.");
2780
+ }
2781
+ const {openUrl: openUrl, appState: appState, connection: connection, authorization_params: authorization_params, redirectUri: redirectUri = this.options.authorizationParams.redirect_uri || window.location.origin} = options;
2782
+ if (!connection) {
2783
+ throw new Error("connection is required");
2784
+ }
2785
+ const state = encode(createRandomString());
2786
+ const code_verifier = createRandomString();
2787
+ const code_challengeBuffer = await sha256(code_verifier);
2788
+ const code_challenge = bufferToBase64UrlEncoded(code_challengeBuffer);
2789
+ const {connect_uri: connect_uri, connect_params: connect_params, auth_session: auth_session} = await this.myAccountApi.connectAccount({
2790
+ connection: connection,
2791
+ redirect_uri: redirectUri,
2792
+ state: state,
2793
+ code_challenge: code_challenge,
2794
+ code_challenge_method: "S256",
2795
+ authorization_params: authorization_params
2796
+ });
2797
+ this.transactionManager.create({
2798
+ state: state,
2799
+ code_verifier: code_verifier,
2800
+ auth_session: auth_session,
2801
+ redirect_uri: redirectUri,
2802
+ appState: appState,
2803
+ connection: connection,
2804
+ response_type: exports.ResponseType.ConnectCode
2805
+ });
2806
+ const url = new URL(connect_uri);
2807
+ url.searchParams.set("ticket", connect_params.ticket);
2808
+ if (openUrl) {
2809
+ await openUrl(url.toString());
2810
+ } else {
2811
+ window.location.assign(url);
2812
+ }
2813
+ }
2658
2814
  }
2659
- class User {}
2660
2815
  async function createAuth0Client(options) {
2661
2816
  const auth0 = new Auth0Client(options);
2662
2817
  await auth0.checkSession();
@@ -2665,11 +2820,13 @@
2665
2820
  exports.Auth0Client = Auth0Client;
2666
2821
  exports.AuthenticationError = AuthenticationError;
2667
2822
  exports.CacheKey = CacheKey;
2823
+ exports.ConnectError = ConnectError;
2668
2824
  exports.GenericError = GenericError;
2669
2825
  exports.InMemoryCache = InMemoryCache;
2670
2826
  exports.LocalStorageCache = LocalStorageCache;
2671
2827
  exports.MfaRequiredError = MfaRequiredError;
2672
2828
  exports.MissingRefreshTokenError = MissingRefreshTokenError;
2829
+ exports.MyAccountApiError = MyAccountApiError;
2673
2830
  exports.PopupCancelledError = PopupCancelledError;
2674
2831
  exports.PopupTimeoutError = PopupTimeoutError;
2675
2832
  exports.TimeoutError = TimeoutError;