This commit is contained in:
nucther committed 2025-12-01 23:23:05 +07:00
commit d282e2bcae
3481 files changed
+568488

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Auth0
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+185
View File
@@ -0,0 +1,185 @@
![Auth0 SDK for React Single Page Applications](https://cdn.auth0.com/website/sdks/banners/auth0-react-banner.png)
[![npm](https://img.shields.io/npm/v/@auth0/auth0-react.svg?style=flat)](https://www.npmjs.com/package/@auth0/auth0-react)
[![codecov](https://img.shields.io/codecov/c/github/auth0/auth0-react/main.svg?style=flat)](https://codecov.io/gh/auth0/auth0-react)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/auth0/auth0-react)
![Downloads](https://img.shields.io/npm/dw/@auth0/auth0-react)
[![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://opensource.org/licenses/MIT)
[![CircleCI](https://img.shields.io/circleci/build/github/auth0/auth0-react.svg?branch=main&style=flat)](https://circleci.com/gh/auth0/auth0-react)
📚 [Documentation](#documentation) - 🚀 [Getting Started](#getting-started) - 💻 [API Reference](#api-reference) - 💬 [Feedback](#feedback)
## Documentation
- [Quickstart](https://auth0.com/docs/quickstart/spa/react) - our interactive guide for quickly adding login, logout and user information to a React app using Auth0.
- [Sample App](https://github.com/auth0-samples/auth0-react-samples/tree/master/Sample-01) - a full-fledged React application integrated with Auth0.
- [FAQs](https://github.com/auth0/auth0-react/blob/main/FAQ.md) - frequently asked questions about the auth0-react SDK.
- [Examples](https://github.com/auth0/auth0-react/blob/main/EXAMPLES.md) - code samples for common React authentication scenario's.
- [Docs site](https://www.auth0.com/docs) - explore our docs site and learn more about Auth0.
## Getting started
### Installation
Using [npm](https://npmjs.org/)
```bash
npm install @auth0/auth0-react
```
Using [yarn](https://yarnpkg.com/)
```bash
yarn add @auth0/auth0-react
```
### Configure Auth0
Create a **Single Page Application** in the [Auth0 Dashboard](https://manage.auth0.com/#/applications).
> **If you're using an existing application**, verify that you have configured the following settings in your Single Page Application:
>
> - Click on the "Settings" tab of your application's page.
> - Scroll down and click on the "Show Advanced Settings" link.
> - Under "Advanced Settings", click on the "OAuth" tab.
> - Ensure that "JsonWebToken Signature Algorithm" is set to `RS256` and that "OIDC Conformant" is enabled.
Next, configure the following URLs for your application under the "Application URIs" section of the "Settings" page:
- **Allowed Callback URLs**: `http://localhost:3000`
- **Allowed Logout URLs**: `http://localhost:3000`
- **Allowed Web Origins**: `http://localhost:3000`
> These URLs should reflect the origins that your application is running on. **Allowed Callback URLs** may also include a path, depending on where you're handling the callback.
Take note of the **Client ID** and **Domain** values under the "Basic Information" section. You'll need these values in the next step.
### Configure the SDK
Configure the SDK by wrapping your application in `Auth0Provider`:
```jsx
// src/index.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App';
const root = createRoot(document.getElementById('app'));
root.render(
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
<App />
</Auth0Provider>
);
```
<details>
<summary>Instructions for React <18</summary>
<br>
```jsx
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App';
ReactDOM.render(
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
<App />
</Auth0Provider>,
document.getElementById('app')
);
```
</details>
Use the `useAuth0` hook in your components to access authentication state (`isLoading`, `isAuthenticated` and `user`) and authentication methods (`loginWithRedirect` and `logout`):
```jsx
// src/App.js
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
function App() {
const { isLoading, isAuthenticated, error, user, loginWithRedirect, logout } =
useAuth0();
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Oops... {error.message}</div>;
}
if (isAuthenticated) {
return (
<div>
Hello {user.name}{' '}
<button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>
Log out
</button>
</div>
);
} else {
return <button onClick={() => loginWithRedirect()}>Log in</button>;
}
}
export default App;
```
For more code samples on how to integrate **auth0-react** SDK in your **React** application, have a look at our [examples](https://github.com/auth0/auth0-react/blob/main/EXAMPLES.md).
## API reference
Explore public API's available in auth0-react.
- [Auth0Provider](https://auth0.github.io/auth0-react/functions/Auth0Provider.html)
- [Auth0ProviderOptions](https://auth0.github.io/auth0-react/interfaces/Auth0ProviderOptions.html)
- [useAuth0](https://auth0.github.io/auth0-react/functions/useAuth0.html)
- [withAuth0](https://auth0.github.io/auth0-react/functions/withAuth0.html)
- [withAuthenticationRequired](https://auth0.github.io/auth0-react/functions/withAuthenticationRequired.html)
## Feedback
### Contributing
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
- [This repo's contribution guide](https://github.com/auth0/auth0-react/blob/main/CONTRIBUTING.md)
### Raise an issue
To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-react/issues).
### Vulnerability Reporting
Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.
---
<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150">
<img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
</picture>
</p>
<p align="center">Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a></p>
<p align="center">
This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-react/blob/main/LICENSE"> LICENSE</a> file for more info.</p>
+15
View File
@@ -0,0 +1,15 @@
import { User } from '@auth0/auth0-spa-js';
/**
* The auth state which, when combined with the auth methods, make up the return object of the `useAuth0` hook.
*/
export interface AuthState<TUser extends User = User> {
error: Error | undefined;
isAuthenticated: boolean;
isLoading: boolean;
user: TUser | undefined;
}
/**
* The initial auth state.
*/
export declare const initialAuthState: AuthState;
//# sourceMappingURL=auth-state.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth-state.d.ts","sourceRoot":"","sources":["../src/auth-state.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI;IAClD,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAK9B,CAAC"}
+200
View File
@@ -0,0 +1,200 @@
import { GetTokenSilentlyOptions, GetTokenWithPopupOptions, IdToken, LogoutOptions as SPALogoutOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, User, GetTokenSilentlyVerboseResponse, RedirectLoginOptions as SPARedirectLoginOptions, type Auth0Client, RedirectConnectAccountOptions, ConnectAccountRedirectResult } from '@auth0/auth0-spa-js';
import { AuthState } from './auth-state';
import { AppState } from './auth0-provider';
export interface LogoutOptions extends Omit<SPALogoutOptions, 'onRedirect'> {
}
export interface RedirectLoginOptions<TAppState = AppState> extends Omit<SPARedirectLoginOptions<TAppState>, 'onRedirect'> {
}
/**
* Contains the authenticated state and authentication methods provided by the `useAuth0` hook.
*/
export interface Auth0ContextInterface<TUser extends User = User> extends AuthState<TUser> {
/**
* ```js
* const token = await getAccessTokenSilently(options);
* ```
*
* If there's a valid token stored, return it. Otherwise, opens an
* iframe with the `/authorize` URL using the parameters provided
* as arguments. Random and secure `state` and `nonce` parameters
* will be auto-generated. If the response is successful, results
* will be valid according to their expiration times.
*
* If refresh tokens are used, the token endpoint is called directly with the
* 'refresh_token' grant. If no refresh token is available to make this call,
* the SDK will only fall back to using an iframe to the '/authorize' URL if
* the `useRefreshTokensFallback` setting has been set to `true`. By default this
* setting is `false`.
*
* This method may use a web worker to perform the token call if the in-memory
* cache is used.
*
* If an `audience` value is given to this function, the SDK always falls
* back to using an iframe to make the token exchange.
*
* Note that in all cases, falling back to an iframe requires access to
* the `auth0` cookie.
*/
getAccessTokenSilently: {
(options: GetTokenSilentlyOptions & {
detailedResponse: true;
}): Promise<GetTokenSilentlyVerboseResponse>;
(options?: GetTokenSilentlyOptions): Promise<string>;
(options: GetTokenSilentlyOptions): Promise<GetTokenSilentlyVerboseResponse | string>;
};
/**
* ```js
* const token = await getTokenWithPopup(options, config);
* ```
*
* Get an access token interactively.
*
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*/
getAccessTokenWithPopup: (options?: GetTokenWithPopupOptions, config?: PopupConfigOptions) => Promise<string | undefined>;
/**
* ```js
* const claims = await getIdTokenClaims();
* ```
*
* Returns all claims from the id_token if available.
*/
getIdTokenClaims: () => Promise<IdToken | undefined>;
/**
* ```js
* await loginWithRedirect(options);
* ```
*
* Performs a redirect to `/authorize` using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated.
*/
loginWithRedirect: (options?: RedirectLoginOptions<AppState>) => Promise<void>;
/**
* ```js
* await loginWithPopup(options, config);
* ```
*
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*
* IMPORTANT: This method has to be called from an event handler
* that was started by the user like a button click, for example,
* otherwise the popup will be blocked in most browsers.
*/
loginWithPopup: (options?: PopupLoginOptions, config?: PopupConfigOptions) => Promise<void>;
/**
* ```js
* await connectAccountWithRedirect({
* connection: 'google-oauth2',
* scopes: ['openid', 'profile', 'email', 'https://www.googleapis.com/auth/drive.readonly'],
* authorization_params: {
* // additional authorization params to forward to the authorization server
* }
* });
* ```
*
* Redirects to the `/connect` URL using the parameters
* provided as arguments. This then redirects to the connection's login page
* where the user can authenticate and authorize the account to be connected.
*
* If connecting the account is successful `onRedirectCallback` will be called
* with the details of the connected account.
*/
connectAccountWithRedirect: (options: RedirectConnectAccountOptions) => Promise<void>;
/**
* ```js
* auth0.logout({ logoutParams: { returnTo: window.location.origin } });
* ```
*
* Clears the application session and performs a redirect to `/v2/logout`, using
* the parameters provided as arguments, to clear the Auth0 session.
* If the `logoutParams.federated` option is specified, it also clears the Identity Provider session.
* [Read more about how Logout works at Auth0](https://auth0.com/docs/logout).
*/
logout: (options?: LogoutOptions) => Promise<void>;
/**
* After the browser redirects back to the callback page,
* call `handleRedirectCallback` to handle success and error
* responses from Auth0. If the response is successful, results
* will be valid according to their expiration times.
*
* @param url The URL to that should be used to retrieve the `state` and `code` values. Defaults to `window.location.href` if not given.
*/
handleRedirectCallback: (url?: string) => Promise<RedirectLoginResult | ConnectAccountRedirectResult>;
/**
* Returns the current DPoP nonce used for making requests to Auth0.
*
* It can return `undefined` because when starting fresh it will not
* be populated until after the first response from the server.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will get the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
getDpopNonce: Auth0Client['getDpopNonce'];
/**
* Sets the current DPoP nonce used for making requests to Auth0.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will set the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
setDpopNonce: Auth0Client['setDpopNonce'];
/**
* Returns a string to be used to demonstrate possession of the private
* key used to cryptographically bind access tokens with DPoP.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*/
generateDpopProof: Auth0Client['generateDpopProof'];
/**
* Returns a new `Fetcher` class that will contain a `fetchWithAuth()` method.
* This is a drop-in replacement for the Fetch API's `fetch()` method, but will
* handle certain authentication logic for you, like building the proper auth
* headers or managing DPoP nonces and retries automatically.
*
* Check the `EXAMPLES.md` file for a deeper look into this method.
*/
createFetcher: Auth0Client['createFetcher'];
}
/**
* @ignore
*/
export declare const initialContext: {
buildAuthorizeUrl: () => never;
buildLogoutUrl: () => never;
getAccessTokenSilently: () => never;
getAccessTokenWithPopup: () => never;
getIdTokenClaims: () => never;
loginWithRedirect: () => never;
loginWithPopup: () => never;
connectAccountWithRedirect: () => never;
logout: () => never;
handleRedirectCallback: () => never;
getDpopNonce: () => never;
setDpopNonce: () => never;
generateDpopProof: () => never;
createFetcher: () => never;
error: Error | undefined;
isAuthenticated: boolean;
isLoading: boolean;
user: User | undefined;
};
/**
* The Auth0 Context
*/
declare const Auth0Context: import("react").Context<Auth0ContextInterface<User>>;
export default Auth0Context;
//# sourceMappingURL=auth0-context.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-context.d.ts","sourceRoot":"","sources":["../src/auth0-context.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,OAAO,EACP,aAAa,IAAI,gBAAgB,EACjC,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,IAAI,EACJ,+BAA+B,EAC/B,oBAAoB,IAAI,uBAAuB,EAC/C,KAAK,WAAW,EAChB,6BAA6B,EAC7B,4BAA4B,EAC7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC;CAAG;AAE9E,MAAM,WAAW,oBAAoB,CAAC,SAAS,GAAG,QAAQ,CACxD,SAAQ,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;CAAG;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,CAC9D,SAAQ,SAAS,CAAC,KAAK,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,sBAAsB,EAAE;QACtB,CACE,OAAO,EAAE,uBAAuB,GAAG;YAAE,gBAAgB,EAAE,IAAI,CAAA;SAAE,GAC5D,OAAO,CAAC,+BAA+B,CAAC,CAAC;QAC5C,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CACzC,+BAA+B,GAAG,MAAM,CACzC,CAAC;KACH,CAAC;IAEF;;;;;;;;;;;OAWG;IACH,uBAAuB,EAAE,CACvB,OAAO,CAAC,EAAE,wBAAwB,EAClC,MAAM,CAAC,EAAE,kBAAkB,KACxB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAErD;;;;;;;;OAQG;IACH,iBAAiB,EAAE,CACjB,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;;;;;;;;;;;OAaG;IACH,cAAc,EAAE,CACd,OAAO,CAAC,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,kBAAkB,KACxB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;;;;;;;;;;;;;;;OAiBG;IACH,0BAA0B,EAAE,CAC1B,OAAO,EAAE,6BAA6B,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;;;;;;;OASG;IACH,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;;;OAOG;IACH,sBAAsB,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,GAAG,4BAA4B,CAAC,CAAC;IAEtG;;;;;;;;;;;;OAYG;IACH,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAE1C;;;;;;;;;OASG;IACH,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAE1C;;;;;OAKG;IACH,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAEpD;;;;;;;OAOG;IACH,aAAa,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;CAC7C;AASD;;GAEG;AACH,eAAO,MAAM,cAAc;6BAPV,KAAK;0BAAL,KAAK;kCAAL,KAAK;mCAAL,KAAK;4BAAL,KAAK;6BAAL,KAAK;0BAAL,KAAK;sCAAL,KAAK;kBAAL,KAAK;kCAAL,KAAK;wBAAL,KAAK;wBAAL,KAAK;6BAAL,KAAK;yBAAL,KAAK;;;;;CAuBrB,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,YAAY,sDAAuD,CAAC;AAE1E,eAAe,YAAY,CAAC"}
+79
View File
@@ -0,0 +1,79 @@
import React from 'react';
import { Auth0ClientOptions, User, ConnectAccountRedirectResult, ResponseType } from '@auth0/auth0-spa-js';
import { Auth0ContextInterface } from './auth0-context';
/**
* The account that has been connected during the connect flow.
*/
export type ConnectedAccount = Omit<ConnectAccountRedirectResult, 'appState' | 'response_type'>;
/**
* The state of the application before the user was redirected to the login page
* and any account that the user may have connected to.
*/
export type AppState = {
returnTo?: string;
connectedAccount?: ConnectedAccount;
response_type?: ResponseType;
[key: string]: any;
};
/**
* The main configuration to instantiate the `Auth0Provider`.
*/
export interface Auth0ProviderOptions<TUser extends User = User> extends Auth0ClientOptions {
/**
* The child nodes your Provider has wrapped
*/
children?: React.ReactNode;
/**
* By default this removes the code and state parameters from the url when you are redirected from the authorize page.
* It uses `window.history` but you might want to overwrite this if you are using a custom router, like `react-router-dom`
* See the EXAMPLES.md for more info.
*/
onRedirectCallback?: (appState?: AppState, user?: TUser) => void;
/**
* By default, if the page url has code/state params, the SDK will treat them as Auth0's and attempt to exchange the
* code for a token. In some cases the code might be for something else (another OAuth SDK perhaps). In these
* instances you can instruct the client to ignore them eg
*
* ```jsx
* <Auth0Provider
* clientId={clientId}
* domain={domain}
* skipRedirectCallback={window.location.pathname === '/stripe-oauth-callback'}
* >
* ```
*/
skipRedirectCallback?: boolean;
/**
* Context to be used when creating the Auth0Provider, defaults to the internally created context.
*
* This allows multiple Auth0Providers to be nested within the same application, the context value can then be
* passed to useAuth0, withAuth0, or withAuthenticationRequired to use that specific Auth0Provider to access
* auth state and methods specifically tied to the provider that the context belongs to.
*
* When using multiple Auth0Providers in a single application you should do the following to ensure sessions are not
* overwritten:
*
* * Configure a different redirect_uri for each Auth0Provider, and set skipRedirectCallback for each provider to ignore
* the others redirect_uri
* * If using localstorage for both Auth0Providers, ensure that the audience and scope are different for so that the key
* used to store data is different
*
* For a sample on using multiple Auth0Providers review the [React Account Linking Sample](https://github.com/auth0-samples/auth0-link-accounts-sample/tree/react-variant)
*/
context?: React.Context<Auth0ContextInterface<TUser>>;
}
/**
* ```jsx
* <Auth0Provider
* domain={domain}
* clientId={clientId}
* authorizationParams={{ redirect_uri: window.location.origin }}>
* <MyApp />
* </Auth0Provider>
* ```
*
* Provides the Auth0Context to its child components.
*/
declare const Auth0Provider: <TUser extends User = User>(opts: Auth0ProviderOptions<TUser>) => React.JSX.Element;
export default Auth0Provider;
//# sourceMappingURL=auth0-provider.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-provider.d.ts","sourceRoot":"","sources":["../src/auth0-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,kBAAkB,EAMlB,IAAI,EAEJ,4BAA4B,EAC5B,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAqB,EACnB,qBAAqB,EAGtB,MAAM,iBAAiB,CAAC;AAUzB;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,4BAA4B,EAAE,UAAU,GAAG,eAAe,CAAC,CAAC;AAEhG;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,CAAE,SAAQ,kBAAkB;IACzF;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACjE;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;CACvD;AAoCD;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,aAAa,GAAI,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,MAAM,oBAAoB,CAAC,KAAK,CAAC,sBA6MlF,CAAC;AAEF,eAAe,aAAa,CAAC"}
+608
View File
@@ -0,0 +1,608 @@
'use strict';
var React = require('react');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]]);}return n}"function"==typeof SuppressedError&&SuppressedError;var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o));},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n());}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0);}else e.locked.delete(t);};}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()};}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e));}catch(e){r(e);}}function a(e){try{c(o.throw(e));}catch(e){r(e);}}function c(e){e.done?i(e.value):new n((function(t){t(e.value);})).then(s,a);}c((o=o.apply(e,t||[])).next());}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s);}catch(e){r=[6,e],o=0;}finally{n=i=0;}if(5&r[0])throw r[1];return {value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,"__esModule",{value:!0});var a="browser-tabs-lock-key",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return [2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",n="",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)];}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[]);}return e.prototype.acquireLock=function(t,n){return void 0===n&&(n=5e3),o(this,void 0,void 0,(function(){var o,i,s,h,l,p,m;return r(this,(function(r){switch(r.label){case 0:o=Date.now()+d(4),i=Date.now()+n,s=a+"-"+t,h=void 0===this.storageHandler?c:this.storageHandler,r.label=1;case 1:return Date.now()<i?[4,u(30)]:[3,8];case 2:return r.sent(),null!==h.getItemSync(s)?[3,5]:(l=this.id+"-"+t+"-"+o,[4,u(MathLine truncated
/**
* The initial auth state.
*/
var initialAuthState = {
isAuthenticated: false,
isLoading: true,
error: undefined,
user: undefined,
};
/**
* @ignore
*/
var stub = function () {
throw new Error('You forgot to wrap your component in <Auth0Provider>.');
};
/**
* @ignore
*/
var initialContext = __assign(__assign({}, initialAuthState), { buildAuthorizeUrl: stub, buildLogoutUrl: stub, getAccessTokenSilently: stub, getAccessTokenWithPopup: stub, getIdTokenClaims: stub, loginWithRedirect: stub, loginWithPopup: stub, connectAccountWithRedirect: stub, logout: stub, handleRedirectCallback: stub, getDpopNonce: stub, setDpopNonce: stub, generateDpopProof: stub, createFetcher: stub });
/**
* The Auth0 Context
*/
var Auth0Context = React.createContext(initialContext);
/**
* An OAuth2 error will come from the authorization server and will have at least an `error` property which will
* be the error code. And possibly an `error_description` property
*
* See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.6
*/
var OAuthError = /** @class */ (function (_super) {
__extends(OAuthError, _super);
function OAuthError(error, error_description) {
var _this = _super.call(this, error_description !== null && error_description !== void 0 ? error_description : error) || this;
_this.error = error;
_this.error_description = error_description;
// https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, OAuthError.prototype);
return _this;
}
return OAuthError;
}(Error));
var CODE_RE = /[?&](?:connect_)?code=[^&]+/;
var STATE_RE = /[?&]state=[^&]+/;
var ERROR_RE = /[?&]error=[^&]+/;
var hasAuthParams = function (searchParams) {
if (searchParams === void 0) { searchParams = window.location.search; }
return (CODE_RE.test(searchParams) || ERROR_RE.test(searchParams)) &&
STATE_RE.test(searchParams);
};
var normalizeErrorFn = function (fallbackMessage) {
return function (error) {
if (error instanceof Error) {
return error;
}
// try to check errors of the following form: {error: string; error_description?: string}
if (error !== null &&
typeof error === 'object' &&
'error' in error &&
typeof error.error === 'string') {
if ('error_description' in error &&
typeof error.error_description === 'string') {
var e_1 = error;
return new OAuthError(e_1.error, e_1.error_description);
}
var e = error;
return new OAuthError(e.error);
}
return new Error(fallbackMessage);
};
};
var loginError = normalizeErrorFn('Login failed');
var tokenError = normalizeErrorFn('Get access token failed');
/**
* @ignore
* Helper function to map the v1 `redirectUri` option to the v2 `authorizationParams.redirect_uri`
* and log a warning.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var deprecateRedirectUri = function (options) {
var _a, _b;
if (options === null || options === void 0 ? void 0 : options.redirectUri) {
console.warn('Using `redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `redirectUri` will be no longer supported in a future version');
options.authorizationParams = (_a = options.authorizationParams) !== null && _a !== void 0 ? _a : {};
options.authorizationParams.redirect_uri = options.redirectUri;
delete options.redirectUri;
}
if ((_b = options === null || options === void 0 ? void 0 : options.authorizationParams) === null || _b === void 0 ? void 0 : _b.redirectUri) {
console.warn('Using `authorizationParams.redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `authorizationParams.redirectUri` will be removed in a future version');
options.authorizationParams.redirect_uri =
options.authorizationParams.redirectUri;
delete options.authorizationParams.redirectUri;
}
};
/**
* Handles how that state changes in the `useAuth0` hook.
*/
var reducer = function (state, action) {
switch (action.type) {
case 'LOGIN_POPUP_STARTED':
return __assign(__assign({}, state), { isLoading: true });
case 'LOGIN_POPUP_COMPLETE':
case 'INITIALISED':
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user, isLoading: false, error: undefined });
case 'HANDLE_REDIRECT_COMPLETE':
case 'GET_ACCESS_TOKEN_COMPLETE':
if (state.user === action.user) {
return state;
}
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user });
case 'LOGOUT':
return __assign(__assign({}, state), { isAuthenticated: false, user: undefined });
case 'ERROR':
return __assign(__assign({}, state), { isLoading: false, error: action.error });
}
};
/**
* @ignore
*/
var toAuth0ClientOptions = function (opts) {
deprecateRedirectUri(opts);
return __assign(__assign({}, opts), { auth0Client: {
name: 'auth0-react',
version: '2.9.0',
} });
};
/**
* @ignore
*/
var defaultOnRedirectCallback = function (appState) {
var _a;
window.history.replaceState({}, document.title, (_a = appState.returnTo) !== null && _a !== void 0 ? _a : window.location.pathname);
};
/**
* ```jsx
* <Auth0Provider
* domain={domain}
* clientId={clientId}
* authorizationParams={{ redirect_uri: window.location.origin }}>
* <MyApp />
* </Auth0Provider>
* ```
*
* Provides the Auth0Context to its child components.
*/
var Auth0Provider = function (opts) {
var children = opts.children, skipRedirectCallback = opts.skipRedirectCallback, _a = opts.onRedirectCallback, onRedirectCallback = _a === void 0 ? defaultOnRedirectCallback : _a, _b = opts.context, context = _b === void 0 ? Auth0Context : _b, clientOpts = __rest(opts, ["children", "skipRedirectCallback", "onRedirectCallback", "context"]);
var client = React.useState(function () { return new Ue(toAuth0ClientOptions(clientOpts)); })[0];
var _c = React.useReducer((reducer), initialAuthState), state = _c[0], dispatch = _c[1];
var didInitialise = React.useRef(false);
var handleError = React.useCallback(function (error) {
dispatch({ type: 'ERROR', error: error });
return error;
}, []);
React.useEffect(function () {
if (didInitialise.current) {
return;
}
didInitialise.current = true;
(function () { return __awaiter(void 0, void 0, void 0, function () {
var user, _a, _b, appState, response_type, result, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 7, , 8]);
user = void 0;
if (!(hasAuthParams() && !skipRedirectCallback)) return [3 /*break*/, 3];
return [4 /*yield*/, client.handleRedirectCallback()];
case 1:
_a = _c.sent(), _b = _a.appState, appState = _b === void 0 ? {} : _b, response_type = _a.response_type, result = __rest(_a, ["appState", "response_type"]);
return [4 /*yield*/, client.getUser()];
case 2:
user = _c.sent();
appState.response_type = response_type;
if (response_type === exports.ResponseType.ConnectCode) {
appState.connectedAccount = result;
}
onRedirectCallback(appState, user);
return [3 /*break*/, 6];
case 3: return [4 /*yield*/, client.checkSession()];
case 4:
_c.sent();
return [4 /*yield*/, client.getUser()];
case 5:
user = _c.sent();
_c.label = 6;
case 6:
dispatch({ type: 'INITIALISED', user: user });
return [3 /*break*/, 8];
case 7:
error_1 = _c.sent();
handleError(loginError(error_1));
return [3 /*break*/, 8];
case 8: return [2 /*return*/];
}
});
}); })();
}, [client, onRedirectCallback, skipRedirectCallback, handleError]);
var loginWithRedirect = React.useCallback(function (opts) {
deprecateRedirectUri(opts);
return client.loginWithRedirect(opts);
}, [client]);
var loginWithPopup = React.useCallback(function (options, config) { return __awaiter(void 0, void 0, void 0, function () {
var error_2, user;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch({ type: 'LOGIN_POPUP_STARTED' });
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, client.loginWithPopup(options, config)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
handleError(loginError(error_2));
return [2 /*return*/];
case 4: return [4 /*yield*/, client.getUser()];
case 5:
user = _a.sent();
dispatch({ type: 'LOGIN_POPUP_COMPLETE', user: user });
return [2 /*return*/];
}
});
}); }, [client, handleError]);
var logout = React.useCallback(function () {
var args_1 = [];
for (var _i = 0; _i < arguments.length; _i++) {
args_1[_i] = arguments[_i];
}
return __awaiter(void 0, __spreadArray([], args_1, true), void 0, function (opts) {
if (opts === void 0) { opts = {}; }
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, client.logout(opts)];
case 1:
_a.sent();
if (opts.openUrl || opts.openUrl === false) {
dispatch({ type: 'LOGOUT' });
}
return [2 /*return*/];
}
});
});
}, [client]);
var getAccessTokenSilently = React.useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (opts) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_3, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenSilently(opts)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_3 = _c.sent();
throw tokenError(error_3);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var getAccessTokenWithPopup = React.useCallback(function (opts, config) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_4, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenWithPopup(opts, config)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_4 = _c.sent();
throw tokenError(error_4);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var connectAccountWithRedirect = React.useCallback(function (options) {
return client.connectAccountWithRedirect(options);
}, [client]);
var getIdTokenClaims = React.useCallback(function () { return client.getIdTokenClaims(); }, [client]);
var handleRedirectCallback = React.useCallback(function (url) { return __awaiter(void 0, void 0, void 0, function () {
var error_5, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.handleRedirectCallback(url)];
case 1: return [2 /*return*/, _c.sent()];
case 2:
error_5 = _c.sent();
throw tokenError(error_5);
case 3:
_a = dispatch;
_b = {
type: 'HANDLE_REDIRECT_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
}
});
}); }, [client]);
var getDpopNonce = React.useCallback(function (id) { return client.getDpopNonce(id); }, [client]);
var setDpopNonce = React.useCallback(function (nonce, id) { return client.setDpopNonce(nonce, id); }, [client]);
var generateDpopProof = React.useCallback(function (params) { return client.generateDpopProof(params); }, [client]);
var createFetcher = React.useCallback(function (config) { return client.createFetcher(config); }, [client]);
var contextValue = React.useMemo(function () {
return __assign(__assign({}, state), { getAccessTokenSilently: getAccessTokenSilently, getAccessTokenWithPopup: getAccessTokenWithPopup, getIdTokenClaims: getIdTokenClaims, loginWithRedirect: loginWithRedirect, loginWithPopup: loginWithPopup, connectAccountWithRedirect: connectAccountWithRedirect, logout: logout, handleRedirectCallback: handleRedirectCallback, getDpopNonce: getDpopNonce, setDpopNonce: setDpopNonce, generateDpopProof: generateDpopProof, createFetcher: createFetcher });
}, [
state,
getAccessTokenSilently,
getAccessTokenWithPopup,
getIdTokenClaims,
loginWithRedirect,
loginWithPopup,
connectAccountWithRedirect,
logout,
handleRedirectCallback,
getDpopNonce,
setDpopNonce,
generateDpopProof,
createFetcher,
]);
return React.createElement(context.Provider, { value: contextValue }, children);
};
/**
* ```js
* const {
* // Auth state:
* error,
* isAuthenticated,
* isLoading,
* user,
* // Auth methods:
* getAccessTokenSilently,
* getAccessTokenWithPopup,
* getIdTokenClaims,
* loginWithRedirect,
* loginWithPopup,
* logout,
* } = useAuth0<TUser>();
* ```
*
* Use the `useAuth0` hook in your components to access the auth state and methods.
*
* TUser is an optional type param to provide a type to the `user` field.
*/
var useAuth0 = function (context) {
if (context === void 0) { context = Auth0Context; }
return React.useContext(context);
};
/**
* ```jsx
* class MyComponent extends Component {
* render() {
* // Access the auth context from the `auth0` prop
* const { user } = this.props.auth0;
* return <div>Hello {user.name}!</div>
* }
* }
* // Wrap your class component in withAuth0
* export default withAuth0(MyComponent);
* ```
*
* Wrap your class components in this Higher Order Component to give them access to the Auth0Context.
*
* Providing a context as the second argument allows you to configure the Auth0Provider the Auth0Context
* should come from f you have multiple within your application.
*/
var withAuth0 = function (Component, context) {
if (context === void 0) { context = Auth0Context; }
return function WithAuth(props) {
return (React.createElement(context.Consumer, null, function (auth) { return (React.createElement(Component, __assign({}, props, { auth0: auth }))); }));
};
};
/**
* @ignore
*/
var defaultOnRedirecting = function () { return React.createElement(React.Fragment, null); };
/**
* @ignore
*/
var defaultOnBeforeAuthentication = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
return [2 /*return*/];
}); }); };
/**
* @ignore
*/
var defaultReturnTo = function () {
return "".concat(window.location.pathname).concat(window.location.search);
};
/**
* ```js
* const MyProtectedComponent = withAuthenticationRequired(MyComponent);
* ```
*
* When you wrap your components in this Higher Order Component and an anonymous user visits your component
* they will be redirected to the login page; after login they will be returned to the page they were redirected from.
*/
var withAuthenticationRequired = function (Component, options) {
if (options === void 0) { options = {}; }
return function WithAuthenticationRequired(props) {
var _this = this;
var _a = options.returnTo, returnTo = _a === void 0 ? defaultReturnTo : _a, _b = options.onRedirecting, onRedirecting = _b === void 0 ? defaultOnRedirecting : _b, _c = options.onBeforeAuthentication, onBeforeAuthentication = _c === void 0 ? defaultOnBeforeAuthentication : _c, loginOptions = options.loginOptions, _d = options.context, context = _d === void 0 ? Auth0Context : _d;
var _e = useAuth0(context), isAuthenticated = _e.isAuthenticated, isLoading = _e.isLoading, loginWithRedirect = _e.loginWithRedirect;
React.useEffect(function () {
if (isLoading || isAuthenticated) {
return;
}
var opts = __assign(__assign({}, loginOptions), { appState: __assign(__assign({}, loginOptions === null || loginOptions === void 0 ? void 0 : loginOptions.appState), { returnTo: typeof returnTo === 'function' ? returnTo() : returnTo }) });
void (function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, onBeforeAuthentication()];
case 1:
_a.sent();
return [4 /*yield*/, loginWithRedirect(opts)];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}); })();
}, [
isLoading,
isAuthenticated,
loginWithRedirect,
onBeforeAuthentication,
loginOptions,
returnTo,
]);
return isAuthenticated ? React.createElement(Component, __assign({}, props)) : onRedirecting();
};
};
exports.Auth0Context = Auth0Context;
exports.Auth0Provider = Auth0Provider;
exports.AuthenticationError = d;
exports.ConnectError = h;
exports.GenericError = u;
exports.InMemoryCache = oe;
exports.LocalStorageCache = ne;
exports.MfaRequiredError = f;
exports.MissingRefreshTokenError = g;
exports.OAuthError = OAuthError;
exports.PopupCancelledError = m;
exports.PopupTimeoutError = p;
exports.TimeoutError = l;
exports.UseDpopNonceError = w;
exports.User = ye;
exports.initialContext = initialContext;
exports.useAuth0 = useAuth0;
exports.withAuth0 = withAuth0;
exports.withAuthenticationRequired = withAuthenticationRequired;
//# sourceMappingURL=auth0-react.cjs.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-react.cjs.js","sources":["../node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js","../src/auth-state.tsx","../src/auth0-context.tsx","../src/errors.tsx","../src/utils.tsx","../src/reducer.tsx","../src/auth0-provider.tsx","../src/use-auth0.tsx","../src/with-auth0.tsx","../src/with-authentication-required.tsx"],"sourcesContent":["function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&\"function\"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}\"function\"==typeof SuppressedError&&SuppressedError;var t=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},\"function\"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError(\"Generator is already executing.\");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,\"__esModule\",{value:!0});var a=\"browser-tabs-lock-key\",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\",n=\"\",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)]}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototypeLine truncated
+588
View File
@@ -0,0 +1,588 @@
import React, { createContext, useState, useReducer, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]]);}return n}"function"==typeof SuppressedError&&SuppressedError;var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o));},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n());}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0);}else e.locked.delete(t);};}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()};}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e));}catch(e){r(e);}}function a(e){try{c(o.throw(e));}catch(e){r(e);}}function c(e){e.done?i(e.value):new n((function(t){t(e.value);})).then(s,a);}c((o=o.apply(e,t||[])).next());}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s);}catch(e){r=[6,e],o=0;}finally{n=i=0;}if(5&r[0])throw r[1];return {value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,"__esModule",{value:!0});var a="browser-tabs-lock-key",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return [2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",n="",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)];}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[]);}return e.prototype.acquireLock=function(t,n){return void 0===n&&(n=5e3),o(this,void 0,void 0,(function(){var o,i,s,h,l,p,m;return r(this,(function(r){switch(r.label){case 0:o=Date.now()+d(4),i=Date.now()+n,s=a+"-"+t,h=void 0===this.storageHandler?c:this.storageHandler,r.label=1;case 1:return Date.now()<i?[4,u(30)]:[3,8];case 2:return r.sent(),null!==h.getItemSync(s)?[3,5]:(l=this.id+"-"+t+"-"+o,[4,u(MathLine truncated
/**
* The initial auth state.
*/
var initialAuthState = {
isAuthenticated: false,
isLoading: true,
error: undefined,
user: undefined,
};
/**
* @ignore
*/
var stub = function () {
throw new Error('You forgot to wrap your component in <Auth0Provider>.');
};
/**
* @ignore
*/
var initialContext = __assign(__assign({}, initialAuthState), { buildAuthorizeUrl: stub, buildLogoutUrl: stub, getAccessTokenSilently: stub, getAccessTokenWithPopup: stub, getIdTokenClaims: stub, loginWithRedirect: stub, loginWithPopup: stub, connectAccountWithRedirect: stub, logout: stub, handleRedirectCallback: stub, getDpopNonce: stub, setDpopNonce: stub, generateDpopProof: stub, createFetcher: stub });
/**
* The Auth0 Context
*/
var Auth0Context = createContext(initialContext);
/**
* An OAuth2 error will come from the authorization server and will have at least an `error` property which will
* be the error code. And possibly an `error_description` property
*
* See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.6
*/
var OAuthError = /** @class */ (function (_super) {
__extends(OAuthError, _super);
function OAuthError(error, error_description) {
var _this = _super.call(this, error_description !== null && error_description !== void 0 ? error_description : error) || this;
_this.error = error;
_this.error_description = error_description;
// https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, OAuthError.prototype);
return _this;
}
return OAuthError;
}(Error));
var CODE_RE = /[?&](?:connect_)?code=[^&]+/;
var STATE_RE = /[?&]state=[^&]+/;
var ERROR_RE = /[?&]error=[^&]+/;
var hasAuthParams = function (searchParams) {
if (searchParams === void 0) { searchParams = window.location.search; }
return (CODE_RE.test(searchParams) || ERROR_RE.test(searchParams)) &&
STATE_RE.test(searchParams);
};
var normalizeErrorFn = function (fallbackMessage) {
return function (error) {
if (error instanceof Error) {
return error;
}
// try to check errors of the following form: {error: string; error_description?: string}
if (error !== null &&
typeof error === 'object' &&
'error' in error &&
typeof error.error === 'string') {
if ('error_description' in error &&
typeof error.error_description === 'string') {
var e_1 = error;
return new OAuthError(e_1.error, e_1.error_description);
}
var e = error;
return new OAuthError(e.error);
}
return new Error(fallbackMessage);
};
};
var loginError = normalizeErrorFn('Login failed');
var tokenError = normalizeErrorFn('Get access token failed');
/**
* @ignore
* Helper function to map the v1 `redirectUri` option to the v2 `authorizationParams.redirect_uri`
* and log a warning.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var deprecateRedirectUri = function (options) {
var _a, _b;
if (options === null || options === void 0 ? void 0 : options.redirectUri) {
console.warn('Using `redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `redirectUri` will be no longer supported in a future version');
options.authorizationParams = (_a = options.authorizationParams) !== null && _a !== void 0 ? _a : {};
options.authorizationParams.redirect_uri = options.redirectUri;
delete options.redirectUri;
}
if ((_b = options === null || options === void 0 ? void 0 : options.authorizationParams) === null || _b === void 0 ? void 0 : _b.redirectUri) {
console.warn('Using `authorizationParams.redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `authorizationParams.redirectUri` will be removed in a future version');
options.authorizationParams.redirect_uri =
options.authorizationParams.redirectUri;
delete options.authorizationParams.redirectUri;
}
};
/**
* Handles how that state changes in the `useAuth0` hook.
*/
var reducer = function (state, action) {
switch (action.type) {
case 'LOGIN_POPUP_STARTED':
return __assign(__assign({}, state), { isLoading: true });
case 'LOGIN_POPUP_COMPLETE':
case 'INITIALISED':
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user, isLoading: false, error: undefined });
case 'HANDLE_REDIRECT_COMPLETE':
case 'GET_ACCESS_TOKEN_COMPLETE':
if (state.user === action.user) {
return state;
}
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user });
case 'LOGOUT':
return __assign(__assign({}, state), { isAuthenticated: false, user: undefined });
case 'ERROR':
return __assign(__assign({}, state), { isLoading: false, error: action.error });
}
};
/**
* @ignore
*/
var toAuth0ClientOptions = function (opts) {
deprecateRedirectUri(opts);
return __assign(__assign({}, opts), { auth0Client: {
name: 'auth0-react',
version: '2.9.0',
} });
};
/**
* @ignore
*/
var defaultOnRedirectCallback = function (appState) {
var _a;
window.history.replaceState({}, document.title, (_a = appState.returnTo) !== null && _a !== void 0 ? _a : window.location.pathname);
};
/**
* ```jsx
* <Auth0Provider
* domain={domain}
* clientId={clientId}
* authorizationParams={{ redirect_uri: window.location.origin }}>
* <MyApp />
* </Auth0Provider>
* ```
*
* Provides the Auth0Context to its child components.
*/
var Auth0Provider = function (opts) {
var children = opts.children, skipRedirectCallback = opts.skipRedirectCallback, _a = opts.onRedirectCallback, onRedirectCallback = _a === void 0 ? defaultOnRedirectCallback : _a, _b = opts.context, context = _b === void 0 ? Auth0Context : _b, clientOpts = __rest(opts, ["children", "skipRedirectCallback", "onRedirectCallback", "context"]);
var client = useState(function () { return new Ue(toAuth0ClientOptions(clientOpts)); })[0];
var _c = useReducer((reducer), initialAuthState), state = _c[0], dispatch = _c[1];
var didInitialise = useRef(false);
var handleError = useCallback(function (error) {
dispatch({ type: 'ERROR', error: error });
return error;
}, []);
useEffect(function () {
if (didInitialise.current) {
return;
}
didInitialise.current = true;
(function () { return __awaiter(void 0, void 0, void 0, function () {
var user, _a, _b, appState, response_type, result, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 7, , 8]);
user = void 0;
if (!(hasAuthParams() && !skipRedirectCallback)) return [3 /*break*/, 3];
return [4 /*yield*/, client.handleRedirectCallback()];
case 1:
_a = _c.sent(), _b = _a.appState, appState = _b === void 0 ? {} : _b, response_type = _a.response_type, result = __rest(_a, ["appState", "response_type"]);
return [4 /*yield*/, client.getUser()];
case 2:
user = _c.sent();
appState.response_type = response_type;
if (response_type === ge.ConnectCode) {
appState.connectedAccount = result;
}
onRedirectCallback(appState, user);
return [3 /*break*/, 6];
case 3: return [4 /*yield*/, client.checkSession()];
case 4:
_c.sent();
return [4 /*yield*/, client.getUser()];
case 5:
user = _c.sent();
_c.label = 6;
case 6:
dispatch({ type: 'INITIALISED', user: user });
return [3 /*break*/, 8];
case 7:
error_1 = _c.sent();
handleError(loginError(error_1));
return [3 /*break*/, 8];
case 8: return [2 /*return*/];
}
});
}); })();
}, [client, onRedirectCallback, skipRedirectCallback, handleError]);
var loginWithRedirect = useCallback(function (opts) {
deprecateRedirectUri(opts);
return client.loginWithRedirect(opts);
}, [client]);
var loginWithPopup = useCallback(function (options, config) { return __awaiter(void 0, void 0, void 0, function () {
var error_2, user;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch({ type: 'LOGIN_POPUP_STARTED' });
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, client.loginWithPopup(options, config)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
handleError(loginError(error_2));
return [2 /*return*/];
case 4: return [4 /*yield*/, client.getUser()];
case 5:
user = _a.sent();
dispatch({ type: 'LOGIN_POPUP_COMPLETE', user: user });
return [2 /*return*/];
}
});
}); }, [client, handleError]);
var logout = useCallback(function () {
var args_1 = [];
for (var _i = 0; _i < arguments.length; _i++) {
args_1[_i] = arguments[_i];
}
return __awaiter(void 0, __spreadArray([], args_1, true), void 0, function (opts) {
if (opts === void 0) { opts = {}; }
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, client.logout(opts)];
case 1:
_a.sent();
if (opts.openUrl || opts.openUrl === false) {
dispatch({ type: 'LOGOUT' });
}
return [2 /*return*/];
}
});
});
}, [client]);
var getAccessTokenSilently = useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (opts) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_3, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenSilently(opts)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_3 = _c.sent();
throw tokenError(error_3);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var getAccessTokenWithPopup = useCallback(function (opts, config) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_4, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenWithPopup(opts, config)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_4 = _c.sent();
throw tokenError(error_4);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var connectAccountWithRedirect = useCallback(function (options) {
return client.connectAccountWithRedirect(options);
}, [client]);
var getIdTokenClaims = useCallback(function () { return client.getIdTokenClaims(); }, [client]);
var handleRedirectCallback = useCallback(function (url) { return __awaiter(void 0, void 0, void 0, function () {
var error_5, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.handleRedirectCallback(url)];
case 1: return [2 /*return*/, _c.sent()];
case 2:
error_5 = _c.sent();
throw tokenError(error_5);
case 3:
_a = dispatch;
_b = {
type: 'HANDLE_REDIRECT_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
}
});
}); }, [client]);
var getDpopNonce = useCallback(function (id) { return client.getDpopNonce(id); }, [client]);
var setDpopNonce = useCallback(function (nonce, id) { return client.setDpopNonce(nonce, id); }, [client]);
var generateDpopProof = useCallback(function (params) { return client.generateDpopProof(params); }, [client]);
var createFetcher = useCallback(function (config) { return client.createFetcher(config); }, [client]);
var contextValue = useMemo(function () {
return __assign(__assign({}, state), { getAccessTokenSilently: getAccessTokenSilently, getAccessTokenWithPopup: getAccessTokenWithPopup, getIdTokenClaims: getIdTokenClaims, loginWithRedirect: loginWithRedirect, loginWithPopup: loginWithPopup, connectAccountWithRedirect: connectAccountWithRedirect, logout: logout, handleRedirectCallback: handleRedirectCallback, getDpopNonce: getDpopNonce, setDpopNonce: setDpopNonce, generateDpopProof: generateDpopProof, createFetcher: createFetcher });
}, [
state,
getAccessTokenSilently,
getAccessTokenWithPopup,
getIdTokenClaims,
loginWithRedirect,
loginWithPopup,
connectAccountWithRedirect,
logout,
handleRedirectCallback,
getDpopNonce,
setDpopNonce,
generateDpopProof,
createFetcher,
]);
return React.createElement(context.Provider, { value: contextValue }, children);
};
/**
* ```js
* const {
* // Auth state:
* error,
* isAuthenticated,
* isLoading,
* user,
* // Auth methods:
* getAccessTokenSilently,
* getAccessTokenWithPopup,
* getIdTokenClaims,
* loginWithRedirect,
* loginWithPopup,
* logout,
* } = useAuth0<TUser>();
* ```
*
* Use the `useAuth0` hook in your components to access the auth state and methods.
*
* TUser is an optional type param to provide a type to the `user` field.
*/
var useAuth0 = function (context) {
if (context === void 0) { context = Auth0Context; }
return useContext(context);
};
/**
* ```jsx
* class MyComponent extends Component {
* render() {
* // Access the auth context from the `auth0` prop
* const { user } = this.props.auth0;
* return <div>Hello {user.name}!</div>
* }
* }
* // Wrap your class component in withAuth0
* export default withAuth0(MyComponent);
* ```
*
* Wrap your class components in this Higher Order Component to give them access to the Auth0Context.
*
* Providing a context as the second argument allows you to configure the Auth0Provider the Auth0Context
* should come from f you have multiple within your application.
*/
var withAuth0 = function (Component, context) {
if (context === void 0) { context = Auth0Context; }
return function WithAuth(props) {
return (React.createElement(context.Consumer, null, function (auth) { return (React.createElement(Component, __assign({}, props, { auth0: auth }))); }));
};
};
/**
* @ignore
*/
var defaultOnRedirecting = function () { return React.createElement(React.Fragment, null); };
/**
* @ignore
*/
var defaultOnBeforeAuthentication = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
return [2 /*return*/];
}); }); };
/**
* @ignore
*/
var defaultReturnTo = function () {
return "".concat(window.location.pathname).concat(window.location.search);
};
/**
* ```js
* const MyProtectedComponent = withAuthenticationRequired(MyComponent);
* ```
*
* When you wrap your components in this Higher Order Component and an anonymous user visits your component
* they will be redirected to the login page; after login they will be returned to the page they were redirected from.
*/
var withAuthenticationRequired = function (Component, options) {
if (options === void 0) { options = {}; }
return function WithAuthenticationRequired(props) {
var _this = this;
var _a = options.returnTo, returnTo = _a === void 0 ? defaultReturnTo : _a, _b = options.onRedirecting, onRedirecting = _b === void 0 ? defaultOnRedirecting : _b, _c = options.onBeforeAuthentication, onBeforeAuthentication = _c === void 0 ? defaultOnBeforeAuthentication : _c, loginOptions = options.loginOptions, _d = options.context, context = _d === void 0 ? Auth0Context : _d;
var _e = useAuth0(context), isAuthenticated = _e.isAuthenticated, isLoading = _e.isLoading, loginWithRedirect = _e.loginWithRedirect;
useEffect(function () {
if (isLoading || isAuthenticated) {
return;
}
var opts = __assign(__assign({}, loginOptions), { appState: __assign(__assign({}, loginOptions === null || loginOptions === void 0 ? void 0 : loginOptions.appState), { returnTo: typeof returnTo === 'function' ? returnTo() : returnTo }) });
void (function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, onBeforeAuthentication()];
case 1:
_a.sent();
return [4 /*yield*/, loginWithRedirect(opts)];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}); })();
}, [
isLoading,
isAuthenticated,
loginWithRedirect,
onBeforeAuthentication,
loginOptions,
returnTo,
]);
return isAuthenticated ? React.createElement(Component, __assign({}, props)) : onRedirecting();
};
};
export { Auth0Context, Auth0Provider, d as AuthenticationError, h as ConnectError, u as GenericError, oe as InMemoryCache, ne as LocalStorageCache, f as MfaRequiredError, g as MissingRefreshTokenError, OAuthError, m as PopupCancelledError, p as PopupTimeoutError, ge as ResponseType, l as TimeoutError, w as UseDpopNonceError, ye as User, initialContext, useAuth0, withAuth0, withAuthenticationRequired };
//# sourceMappingURL=auth0-react.esm.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-react.esm.js","sources":["../node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js","../src/auth-state.tsx","../src/auth0-context.tsx","../src/errors.tsx","../src/utils.tsx","../src/reducer.tsx","../src/auth0-provider.tsx","../src/use-auth0.tsx","../src/with-auth0.tsx","../src/with-authentication-required.tsx"],"sourcesContent":["function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&\"function\"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}\"function\"==typeof SuppressedError&&SuppressedError;var t=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},\"function\"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError(\"Generator is already executing.\");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,\"__esModule\",{value:!0});var a=\"browser-tabs-lock-key\",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\",n=\"\",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)]}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototypeLine truncated
+612
View File
@@ -0,0 +1,612 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.reactAuth0 = {}, global.React));
})(this, (function (exports, React) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]]);}return n}"function"==typeof SuppressedError&&SuppressedError;var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o));},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n());}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0);}else e.locked.delete(t);};}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()};}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e));}catch(e){r(e);}}function a(e){try{c(o.throw(e));}catch(e){r(e);}}function c(e){e.done?i(e.value):new n((function(t){t(e.value);})).then(s,a);}c((o=o.apply(e,t||[])).next());}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s);}catch(e){r=[6,e],o=0;}finally{n=i=0;}if(5&r[0])throw r[1];return {value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,"__esModule",{value:!0});var a="browser-tabs-lock-key",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return [2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",n="",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)];}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[]);}return e.prototype.acquireLock=function(t,n){return void 0===n&&(n=5e3),o(this,void 0,void 0,(function(){var o,i,s,h,l,p,m;return r(this,(function(r){switch(r.label){case 0:o=Date.now()+d(4),i=Date.now()+n,s=a+"-"+t,h=void 0===this.storageHandler?c:this.storageHandler,r.label=1;case 1:return Date.now()<i?[4,u(30)]:[3,8];case 2:return r.sent(),null!==h.getItemSync(s)?[3,5]:(l=this.id+"-"+t+"-"+o,[4,u(Line truncated
/**
* The initial auth state.
*/
var initialAuthState = {
isAuthenticated: false,
isLoading: true,
error: undefined,
user: undefined,
};
/**
* @ignore
*/
var stub = function () {
throw new Error('You forgot to wrap your component in <Auth0Provider>.');
};
/**
* @ignore
*/
var initialContext = __assign(__assign({}, initialAuthState), { buildAuthorizeUrl: stub, buildLogoutUrl: stub, getAccessTokenSilently: stub, getAccessTokenWithPopup: stub, getIdTokenClaims: stub, loginWithRedirect: stub, loginWithPopup: stub, connectAccountWithRedirect: stub, logout: stub, handleRedirectCallback: stub, getDpopNonce: stub, setDpopNonce: stub, generateDpopProof: stub, createFetcher: stub });
/**
* The Auth0 Context
*/
var Auth0Context = React.createContext(initialContext);
/**
* An OAuth2 error will come from the authorization server and will have at least an `error` property which will
* be the error code. And possibly an `error_description` property
*
* See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.6
*/
var OAuthError = /** @class */ (function (_super) {
__extends(OAuthError, _super);
function OAuthError(error, error_description) {
var _this = _super.call(this, error_description !== null && error_description !== void 0 ? error_description : error) || this;
_this.error = error;
_this.error_description = error_description;
// https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, OAuthError.prototype);
return _this;
}
return OAuthError;
}(Error));
var CODE_RE = /[?&](?:connect_)?code=[^&]+/;
var STATE_RE = /[?&]state=[^&]+/;
var ERROR_RE = /[?&]error=[^&]+/;
var hasAuthParams = function (searchParams) {
if (searchParams === void 0) { searchParams = window.location.search; }
return (CODE_RE.test(searchParams) || ERROR_RE.test(searchParams)) &&
STATE_RE.test(searchParams);
};
var normalizeErrorFn = function (fallbackMessage) {
return function (error) {
if (error instanceof Error) {
return error;
}
// try to check errors of the following form: {error: string; error_description?: string}
if (error !== null &&
typeof error === 'object' &&
'error' in error &&
typeof error.error === 'string') {
if ('error_description' in error &&
typeof error.error_description === 'string') {
var e_1 = error;
return new OAuthError(e_1.error, e_1.error_description);
}
var e = error;
return new OAuthError(e.error);
}
return new Error(fallbackMessage);
};
};
var loginError = normalizeErrorFn('Login failed');
var tokenError = normalizeErrorFn('Get access token failed');
/**
* @ignore
* Helper function to map the v1 `redirectUri` option to the v2 `authorizationParams.redirect_uri`
* and log a warning.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var deprecateRedirectUri = function (options) {
var _a, _b;
if (options === null || options === void 0 ? void 0 : options.redirectUri) {
console.warn('Using `redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `redirectUri` will be no longer supported in a future version');
options.authorizationParams = (_a = options.authorizationParams) !== null && _a !== void 0 ? _a : {};
options.authorizationParams.redirect_uri = options.redirectUri;
delete options.redirectUri;
}
if ((_b = options === null || options === void 0 ? void 0 : options.authorizationParams) === null || _b === void 0 ? void 0 : _b.redirectUri) {
console.warn('Using `authorizationParams.redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `authorizationParams.redirectUri` will be removed in a future version');
options.authorizationParams.redirect_uri =
options.authorizationParams.redirectUri;
delete options.authorizationParams.redirectUri;
}
};
/**
* Handles how that state changes in the `useAuth0` hook.
*/
var reducer = function (state, action) {
switch (action.type) {
case 'LOGIN_POPUP_STARTED':
return __assign(__assign({}, state), { isLoading: true });
case 'LOGIN_POPUP_COMPLETE':
case 'INITIALISED':
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user, isLoading: false, error: undefined });
case 'HANDLE_REDIRECT_COMPLETE':
case 'GET_ACCESS_TOKEN_COMPLETE':
if (state.user === action.user) {
return state;
}
return __assign(__assign({}, state), { isAuthenticated: !!action.user, user: action.user });
case 'LOGOUT':
return __assign(__assign({}, state), { isAuthenticated: false, user: undefined });
case 'ERROR':
return __assign(__assign({}, state), { isLoading: false, error: action.error });
}
};
/**
* @ignore
*/
var toAuth0ClientOptions = function (opts) {
deprecateRedirectUri(opts);
return __assign(__assign({}, opts), { auth0Client: {
name: 'auth0-react',
version: '2.9.0',
} });
};
/**
* @ignore
*/
var defaultOnRedirectCallback = function (appState) {
var _a;
window.history.replaceState({}, document.title, (_a = appState.returnTo) !== null && _a !== void 0 ? _a : window.location.pathname);
};
/**
* ```jsx
* <Auth0Provider
* domain={domain}
* clientId={clientId}
* authorizationParams={{ redirect_uri: window.location.origin }}>
* <MyApp />
* </Auth0Provider>
* ```
*
* Provides the Auth0Context to its child components.
*/
var Auth0Provider = function (opts) {
var children = opts.children, skipRedirectCallback = opts.skipRedirectCallback, _a = opts.onRedirectCallback, onRedirectCallback = _a === void 0 ? defaultOnRedirectCallback : _a, _b = opts.context, context = _b === void 0 ? Auth0Context : _b, clientOpts = __rest(opts, ["children", "skipRedirectCallback", "onRedirectCallback", "context"]);
var client = React.useState(function () { return new Ue(toAuth0ClientOptions(clientOpts)); })[0];
var _c = React.useReducer((reducer), initialAuthState), state = _c[0], dispatch = _c[1];
var didInitialise = React.useRef(false);
var handleError = React.useCallback(function (error) {
dispatch({ type: 'ERROR', error: error });
return error;
}, []);
React.useEffect(function () {
if (didInitialise.current) {
return;
}
didInitialise.current = true;
(function () { return __awaiter(void 0, void 0, void 0, function () {
var user, _a, _b, appState, response_type, result, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 7, , 8]);
user = void 0;
if (!(hasAuthParams() && !skipRedirectCallback)) return [3 /*break*/, 3];
return [4 /*yield*/, client.handleRedirectCallback()];
case 1:
_a = _c.sent(), _b = _a.appState, appState = _b === void 0 ? {} : _b, response_type = _a.response_type, result = __rest(_a, ["appState", "response_type"]);
return [4 /*yield*/, client.getUser()];
case 2:
user = _c.sent();
appState.response_type = response_type;
if (response_type === exports.ResponseType.ConnectCode) {
appState.connectedAccount = result;
}
onRedirectCallback(appState, user);
return [3 /*break*/, 6];
case 3: return [4 /*yield*/, client.checkSession()];
case 4:
_c.sent();
return [4 /*yield*/, client.getUser()];
case 5:
user = _c.sent();
_c.label = 6;
case 6:
dispatch({ type: 'INITIALISED', user: user });
return [3 /*break*/, 8];
case 7:
error_1 = _c.sent();
handleError(loginError(error_1));
return [3 /*break*/, 8];
case 8: return [2 /*return*/];
}
});
}); })();
}, [client, onRedirectCallback, skipRedirectCallback, handleError]);
var loginWithRedirect = React.useCallback(function (opts) {
deprecateRedirectUri(opts);
return client.loginWithRedirect(opts);
}, [client]);
var loginWithPopup = React.useCallback(function (options, config) { return __awaiter(void 0, void 0, void 0, function () {
var error_2, user;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch({ type: 'LOGIN_POPUP_STARTED' });
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, client.loginWithPopup(options, config)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
handleError(loginError(error_2));
return [2 /*return*/];
case 4: return [4 /*yield*/, client.getUser()];
case 5:
user = _a.sent();
dispatch({ type: 'LOGIN_POPUP_COMPLETE', user: user });
return [2 /*return*/];
}
});
}); }, [client, handleError]);
var logout = React.useCallback(function () {
var args_1 = [];
for (var _i = 0; _i < arguments.length; _i++) {
args_1[_i] = arguments[_i];
}
return __awaiter(void 0, __spreadArray([], args_1, true), void 0, function (opts) {
if (opts === void 0) { opts = {}; }
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, client.logout(opts)];
case 1:
_a.sent();
if (opts.openUrl || opts.openUrl === false) {
dispatch({ type: 'LOGOUT' });
}
return [2 /*return*/];
}
});
});
}, [client]);
var getAccessTokenSilently = React.useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (opts) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_3, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenSilently(opts)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_3 = _c.sent();
throw tokenError(error_3);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var getAccessTokenWithPopup = React.useCallback(function (opts, config) { return __awaiter(void 0, void 0, void 0, function () {
var token, error_4, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.getTokenWithPopup(opts, config)];
case 1:
token = _c.sent();
return [3 /*break*/, 5];
case 2:
error_4 = _c.sent();
throw tokenError(error_4);
case 3:
_a = dispatch;
_b = {
type: 'GET_ACCESS_TOKEN_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/, token];
}
});
}); }, [client]);
var connectAccountWithRedirect = React.useCallback(function (options) {
return client.connectAccountWithRedirect(options);
}, [client]);
var getIdTokenClaims = React.useCallback(function () { return client.getIdTokenClaims(); }, [client]);
var handleRedirectCallback = React.useCallback(function (url) { return __awaiter(void 0, void 0, void 0, function () {
var error_5, _a;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, 3, 5]);
return [4 /*yield*/, client.handleRedirectCallback(url)];
case 1: return [2 /*return*/, _c.sent()];
case 2:
error_5 = _c.sent();
throw tokenError(error_5);
case 3:
_a = dispatch;
_b = {
type: 'HANDLE_REDIRECT_COMPLETE'
};
return [4 /*yield*/, client.getUser()];
case 4:
_a.apply(void 0, [(_b.user = _c.sent(),
_b)]);
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
}
});
}); }, [client]);
var getDpopNonce = React.useCallback(function (id) { return client.getDpopNonce(id); }, [client]);
var setDpopNonce = React.useCallback(function (nonce, id) { return client.setDpopNonce(nonce, id); }, [client]);
var generateDpopProof = React.useCallback(function (params) { return client.generateDpopProof(params); }, [client]);
var createFetcher = React.useCallback(function (config) { return client.createFetcher(config); }, [client]);
var contextValue = React.useMemo(function () {
return __assign(__assign({}, state), { getAccessTokenSilently: getAccessTokenSilently, getAccessTokenWithPopup: getAccessTokenWithPopup, getIdTokenClaims: getIdTokenClaims, loginWithRedirect: loginWithRedirect, loginWithPopup: loginWithPopup, connectAccountWithRedirect: connectAccountWithRedirect, logout: logout, handleRedirectCallback: handleRedirectCallback, getDpopNonce: getDpopNonce, setDpopNonce: setDpopNonce, generateDpopProof: generateDpopProof, createFetcher: createFetcher });
}, [
state,
getAccessTokenSilently,
getAccessTokenWithPopup,
getIdTokenClaims,
loginWithRedirect,
loginWithPopup,
connectAccountWithRedirect,
logout,
handleRedirectCallback,
getDpopNonce,
setDpopNonce,
generateDpopProof,
createFetcher,
]);
return React.createElement(context.Provider, { value: contextValue }, children);
};
/**
* ```js
* const {
* // Auth state:
* error,
* isAuthenticated,
* isLoading,
* user,
* // Auth methods:
* getAccessTokenSilently,
* getAccessTokenWithPopup,
* getIdTokenClaims,
* loginWithRedirect,
* loginWithPopup,
* logout,
* } = useAuth0<TUser>();
* ```
*
* Use the `useAuth0` hook in your components to access the auth state and methods.
*
* TUser is an optional type param to provide a type to the `user` field.
*/
var useAuth0 = function (context) {
if (context === void 0) { context = Auth0Context; }
return React.useContext(context);
};
/**
* ```jsx
* class MyComponent extends Component {
* render() {
* // Access the auth context from the `auth0` prop
* const { user } = this.props.auth0;
* return <div>Hello {user.name}!</div>
* }
* }
* // Wrap your class component in withAuth0
* export default withAuth0(MyComponent);
* ```
*
* Wrap your class components in this Higher Order Component to give them access to the Auth0Context.
*
* Providing a context as the second argument allows you to configure the Auth0Provider the Auth0Context
* should come from f you have multiple within your application.
*/
var withAuth0 = function (Component, context) {
if (context === void 0) { context = Auth0Context; }
return function WithAuth(props) {
return (React.createElement(context.Consumer, null, function (auth) { return (React.createElement(Component, __assign({}, props, { auth0: auth }))); }));
};
};
/**
* @ignore
*/
var defaultOnRedirecting = function () { return React.createElement(React.Fragment, null); };
/**
* @ignore
*/
var defaultOnBeforeAuthentication = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
return [2 /*return*/];
}); }); };
/**
* @ignore
*/
var defaultReturnTo = function () {
return "".concat(window.location.pathname).concat(window.location.search);
};
/**
* ```js
* const MyProtectedComponent = withAuthenticationRequired(MyComponent);
* ```
*
* When you wrap your components in this Higher Order Component and an anonymous user visits your component
* they will be redirected to the login page; after login they will be returned to the page they were redirected from.
*/
var withAuthenticationRequired = function (Component, options) {
if (options === void 0) { options = {}; }
return function WithAuthenticationRequired(props) {
var _this = this;
var _a = options.returnTo, returnTo = _a === void 0 ? defaultReturnTo : _a, _b = options.onRedirecting, onRedirecting = _b === void 0 ? defaultOnRedirecting : _b, _c = options.onBeforeAuthentication, onBeforeAuthentication = _c === void 0 ? defaultOnBeforeAuthentication : _c, loginOptions = options.loginOptions, _d = options.context, context = _d === void 0 ? Auth0Context : _d;
var _e = useAuth0(context), isAuthenticated = _e.isAuthenticated, isLoading = _e.isLoading, loginWithRedirect = _e.loginWithRedirect;
React.useEffect(function () {
if (isLoading || isAuthenticated) {
return;
}
var opts = __assign(__assign({}, loginOptions), { appState: __assign(__assign({}, loginOptions === null || loginOptions === void 0 ? void 0 : loginOptions.appState), { returnTo: typeof returnTo === 'function' ? returnTo() : returnTo }) });
void (function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, onBeforeAuthentication()];
case 1:
_a.sent();
return [4 /*yield*/, loginWithRedirect(opts)];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}); })();
}, [
isLoading,
isAuthenticated,
loginWithRedirect,
onBeforeAuthentication,
loginOptions,
returnTo,
]);
return isAuthenticated ? React.createElement(Component, __assign({}, props)) : onRedirecting();
};
};
exports.Auth0Context = Auth0Context;
exports.Auth0Provider = Auth0Provider;
exports.AuthenticationError = d;
exports.ConnectError = h;
exports.GenericError = u;
exports.InMemoryCache = oe;
exports.LocalStorageCache = ne;
exports.MfaRequiredError = f;
exports.MissingRefreshTokenError = g;
exports.OAuthError = OAuthError;
exports.PopupCancelledError = m;
exports.PopupTimeoutError = p;
exports.TimeoutError = l;
exports.UseDpopNonceError = w;
exports.User = ye;
exports.initialContext = initialContext;
exports.useAuth0 = useAuth0;
exports.withAuth0 = withAuth0;
exports.withAuthenticationRequired = withAuthenticationRequired;
}));
//# sourceMappingURL=auth0-react.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-react.js","sources":["../node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js","../src/auth-state.tsx","../src/auth0-context.tsx","../src/errors.tsx","../src/utils.tsx","../src/reducer.tsx","../src/auth0-provider.tsx","../src/use-auth0.tsx","../src/with-auth0.tsx","../src/with-authentication-required.tsx"],"sourcesContent":["function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&\"function\"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}\"function\"==typeof SuppressedError&&SuppressedError;var t=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},\"function\"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError(\"Generator is already executing.\");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,\"__esModule\",{value:!0});var a=\"browser-tabs-lock-key\",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\",n=\"\",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)]}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototype.acqLine truncated
+2
View File
@@ -0,0 +1,2 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).reactAuth0={},e.React)}(this,(function(e,t){"use strict";var n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},n(e,t)};var o=function(){return o=Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},o.apply(this,arguments)};function i(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}function r(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((o=o.apply(e,t||[])).next())}))}function s(e,t){var n,o,i,r={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},s=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return s.next=a(0),s.throw=a(1),s.return=a(2),"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(r=0)),r;)try{if(n=1,o&&(i=2&a[0]?o.return:a[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,a[1])).done)return i;switch(o=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return r.label++,{value:a[1],done:!1};case 5:r.label++,o=a[1],a=[0];continue;case 7:a=r.ops.pop(),r.trys.pop();continue;default:if(!(i=r.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){r=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){r.label=a[1];break}if(6===a[0]&&r.label<i[1]){r.label=i[1],i=a;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(a);break}i[2]&&r.ops.pop(),r.trys.pop();continue}a=t.call(e,r)}catch(e){a=[6,e],o=0}finally{n=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}function a(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}"function"==typeof SuppressedError&&SuppressedError,"function"==typeof SuppressedError&&SuppressedError;var c="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function u(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function d(e,t){return e(t={exports:{}},t.exports),t.exports}var l=d((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));u(l);var h=u(d((function(e,t){var n=c&&c.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},o=c&&c.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!((i=(i=s.trys).leLine truncated
//# sourceMappingURL=auth0-react.min.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-react.min.js","sources":["../node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js","../src/auth-state.tsx","../src/auth0-context.tsx","../src/errors.tsx","../src/utils.tsx","../src/reducer.tsx","../src/auth0-provider.tsx","../src/use-auth0.tsx","../src/with-authentication-required.tsx","../src/with-auth0.tsx"],"sourcesContent":["function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&\"function\"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}\"function\"==typeof SuppressedError&&SuppressedError;var t=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},\"function\"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError(\"Generator is already executing.\");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,\"__esModule\",{value:!0});var a=\"browser-tabs-lock-key\",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error(\"Unsupported\")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\",n=\"\",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)]}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototypeLine truncated
+12
View File
@@ -0,0 +1,12 @@
/**
* An OAuth2 error will come from the authorization server and will have at least an `error` property which will
* be the error code. And possibly an `error_description` property
*
* See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.6
*/
export declare class OAuthError extends Error {
error: string;
error_description?: string | undefined;
constructor(error: string, error_description?: string | undefined);
}
//# sourceMappingURL=errors.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAChB,KAAK,EAAE,MAAM;IAAS,iBAAiB,CAAC,EAAE,MAAM;gBAAhD,KAAK,EAAE,MAAM,EAAS,iBAAiB,CAAC,EAAE,MAAM,YAAA;CAMpE"}
+8
View File
@@ -0,0 +1,8 @@
export { default as Auth0Provider, Auth0ProviderOptions, AppState, ConnectedAccount } from './auth0-provider';
export { default as useAuth0 } from './use-auth0';
export { default as withAuth0, WithAuth0Props } from './with-auth0';
export { default as withAuthenticationRequired, WithAuthenticationRequiredOptions, } from './with-authentication-required';
export { default as Auth0Context, Auth0ContextInterface, initialContext, LogoutOptions, RedirectLoginOptions, } from './auth0-context';
export { AuthorizationParams, PopupLoginOptions, PopupConfigOptions, GetTokenWithPopupOptions, LogoutUrlOptions, CacheLocation, GetTokenSilentlyOptions, IdToken, User, ICache, InMemoryCache, LocalStorageCache, Cacheable, TimeoutError, MfaRequiredError, PopupCancelledError, PopupTimeoutError, AuthenticationError, MissingRefreshTokenError, GenericError, UseDpopNonceError, type FetcherConfig, RedirectConnectAccountOptions, ConnectAccountRedirectResult, ResponseType, ConnectError } from '@auth0/auth0-spa-js';
export { OAuthError } from './errors';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,IAAI,aAAa,EACxB,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EACL,OAAO,IAAI,0BAA0B,EACrC,iCAAiC,GAClC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,OAAO,IAAI,YAAY,EACvB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,OAAO,EACP,IAAI,EACJ,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,KAAK,aAAa,EAClB,6BAA6B,EAC7B,4BAA4B,EAC5B,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
+19
View File
@@ -0,0 +1,19 @@
import { User } from '@auth0/auth0-spa-js';
import { AuthState } from './auth-state';
type Action = {
type: 'LOGIN_POPUP_STARTED';
} | {
type: 'INITIALISED' | 'LOGIN_POPUP_COMPLETE' | 'GET_ACCESS_TOKEN_COMPLETE' | 'HANDLE_REDIRECT_COMPLETE';
user: User | undefined;
} | {
type: 'LOGOUT';
} | {
type: 'ERROR';
error: Error;
};
/**
* Handles how that state changes in the `useAuth0` hook.
*/
export declare const reducer: <TUser extends User = User>(state: AuthState<TUser>, action: Action) => AuthState<TUser>;
export {};
//# sourceMappingURL=reducer.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../src/reducer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,KAAK,MAAM,GACP;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IACE,IAAI,EACA,aAAa,GACb,sBAAsB,GACtB,2BAA2B,GAC3B,0BAA0B,CAAC;IAC/B,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACxB,GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpC;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,OAAO,SAAS,CAAC,KAAK,CAAC,EAAE,QAAQ,MAAM,KAAG,SAAS,CAAC,KAAK,CAuC3G,CAAC"}
+27
View File
@@ -0,0 +1,27 @@
import { User } from '@auth0/auth0-spa-js';
import { Auth0ContextInterface } from './auth0-context';
/**
* ```js
* const {
* // Auth state:
* error,
* isAuthenticated,
* isLoading,
* user,
* // Auth methods:
* getAccessTokenSilently,
* getAccessTokenWithPopup,
* getIdTokenClaims,
* loginWithRedirect,
* loginWithPopup,
* logout,
* } = useAuth0<TUser>();
* ```
*
* Use the `useAuth0` hook in your components to access the auth state and methods.
*
* TUser is an optional type param to provide a type to the `user` field.
*/
declare const useAuth0: <TUser extends User = User>(context?: import("react").Context<Auth0ContextInterface<User>>) => Auth0ContextInterface<TUser>;
export default useAuth0;
//# sourceMappingURL=use-auth0.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"use-auth0.d.ts","sourceRoot":"","sources":["../src/use-auth0.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,QAAA,MAAM,QAAQ,GAAI,KAAK,SAAS,IAAI,GAAG,IAAI,EACzC,8DAAsB,KACrB,qBAAqB,CAAC,KAAK,CACuB,CAAC;AAEtD,eAAe,QAAQ,CAAC"}
+10
View File
@@ -0,0 +1,10 @@
export declare const hasAuthParams: (searchParams?: string) => boolean;
export declare const loginError: (error: unknown) => Error;
export declare const tokenError: (error: unknown) => Error;
/**
* @ignore
* Helper function to map the v1 `redirectUri` option to the v2 `authorizationParams.redirect_uri`
* and log a warning.
*/
export declare const deprecateRedirectUri: (options?: any) => void;
//# sourceMappingURL=utils.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,aAAa,GAAI,qBAAqC,KAAG,OAEzC,CAAC;AA4B9B,eAAO,MAAM,UAAU,UAxBb,OAAO,KAAG,KAwBsC,CAAC;AAE3D,eAAO,MAAM,UAAU,UA1Bb,OAAO,KAAG,KA0BiD,CAAC;AAEtE;;;;GAIG;AAEH,eAAO,MAAM,oBAAoB,GAAI,UAAU,GAAG,SAkBjD,CAAC"}
+29
View File
@@ -0,0 +1,29 @@
import React, { ComponentType } from 'react';
import { Auth0ContextInterface } from './auth0-context';
/**
* Components wrapped in `withAuth0` will have an additional `auth0` prop
*/
export interface WithAuth0Props {
auth0: Auth0ContextInterface;
}
/**
* ```jsx
* class MyComponent extends Component {
* render() {
* // Access the auth context from the `auth0` prop
* const { user } = this.props.auth0;
* return <div>Hello {user.name}!</div>
* }
* }
* // Wrap your class component in withAuth0
* export default withAuth0(MyComponent);
* ```
*
* Wrap your class components in this Higher Order Component to give them access to the Auth0Context.
*
* Providing a context as the second argument allows you to configure the Auth0Provider the Auth0Context
* should come from f you have multiple within your application.
*/
declare const withAuth0: <P extends WithAuth0Props>(Component: ComponentType<P>, context?: React.Context<Auth0ContextInterface<import("@auth0/auth0-spa-js").User>>) => ComponentType<Omit<P, keyof WithAuth0Props>>;
export default withAuth0;
//# sourceMappingURL=with-auth0.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"with-auth0.d.ts","sourceRoot":"","sources":["../src/with-auth0.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,SAAS,GAAI,CAAC,SAAS,cAAc,EACzC,WAAW,aAAa,CAAC,CAAC,CAAC,EAC3B,kFAAsB,KACrB,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,cAAc,CAAC,CAU7C,CAAC;AAEF,eAAe,SAAS,CAAC"}
+77
View File
@@ -0,0 +1,77 @@
import React, { ComponentType, FC } from 'react';
import { Auth0ContextInterface, RedirectLoginOptions } from './auth0-context';
/**
* Options for the withAuthenticationRequired Higher Order Component
*/
export interface WithAuthenticationRequiredOptions {
/**
* ```js
* withAuthenticationRequired(Profile, {
* returnTo: '/profile'
* })
* ```
*
* or
*
* ```js
* withAuthenticationRequired(Profile, {
* returnTo: () => window.location.hash.substr(1)
* })
* ```
*
* Add a path for the `onRedirectCallback` handler to return the user to after login.
*/
returnTo?: string | (() => string);
/**
* ```js
* withAuthenticationRequired(Profile, {
* onRedirecting: () => <div>Redirecting you to the login...</div>
* })
* ```
*
* Render a message to show that the user is being redirected to the login.
*/
onRedirecting?: () => React.JSX.Element;
/**
* ```js
* withAuthenticationRequired(Profile, {
* onBeforeAuthentication: () => { analyticsLibrary.track('login_triggered'); }
* })
* ```
*
* Allows executing logic before the user is redirected to the login page.
*/
onBeforeAuthentication?: () => Promise<void>;
/**
* ```js
* withAuthenticationRequired(Profile, {
* loginOptions: {
* appState: {
* customProp: 'foo'
* }
* }
* })
* ```
*
* Pass additional login options, like extra `appState` to the login page.
* This will be merged with the `returnTo` option used by the `onRedirectCallback` handler.
*/
loginOptions?: RedirectLoginOptions;
/**
* The context to be used when calling useAuth0, this should only be provided if you are using multiple Auth0Providers
* within your application and you wish to tie a specific component to a Auth0Provider other than the Auth0Provider
* associated with the default Auth0Context.
*/
context?: React.Context<Auth0ContextInterface>;
}
/**
* ```js
* const MyProtectedComponent = withAuthenticationRequired(MyComponent);
* ```
*
* When you wrap your components in this Higher Order Component and an anonymous user visits your component
* they will be redirected to the login page; after login they will be returned to the page they were redirected from.
*/
declare const withAuthenticationRequired: <P extends object>(Component: ComponentType<P>, options?: WithAuthenticationRequiredOptions) => FC<P>;
export default withAuthenticationRequired;
//# sourceMappingURL=with-authentication-required.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"with-authentication-required.d.ts","sourceRoot":"","sources":["../src/with-authentication-required.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAa,EAAE,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAqB,EACnB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAkBzB;;GAEG;AACH,MAAM,WAAW,iCAAiC;IAChD;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACnC;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;IACxC;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,QAAA,MAAM,0BAA0B,GAAI,CAAC,SAAS,MAAM,EAClD,WAAW,aAAa,CAAC,CAAC,CAAC,EAC3B,UAAS,iCAAsC,KAC9C,EAAE,CAAC,CAAC,CAuCN,CAAC;AAEF,eAAe,0BAA0B,CAAC"}
+100
View File
@@ -0,0 +1,100 @@
{
"author": "Auth0",
"name": "@auth0/auth0-react",
"version": "2.9.0",
"description": "Auth0 SDK for React Single Page Applications (SPA)",
"keywords": [
"auth0",
"login",
"Authorization Code Grant Flow",
"PKCE",
"Single Page Application authentication",
"SPA authentication",
"react"
],
"files": [
"src",
"dist"
],
"main": "dist/auth0-react.cjs.js",
"types": "dist/index.d.ts",
"module": "dist/auth0-react.esm.js",
"scripts": {
"build": "npm run lint && rollup -c --environment NODE_ENV:production",
"lint": "eslint --ext=tsx ./src ./__tests__",
"start": "rollup -cw",
"test": "jest --coverage",
"prepack": "npm run build",
"docs": "typedoc --options typedoc.js src",
"install:examples": "npm i --prefix=examples/cra-react-router --no-package-lock --legacy-peer-deps && npm i --prefix=examples/gatsby-app --no-package-lock --legacy-peer-deps && npm i --prefix=examples/nextjs-app --no-package-lock --legacy-peer-deps && npm ci --prefix=examples/users-api",
"start:cra": "npm start --prefix=examples/cra-react-router",
"start:gatsby": "npm start --prefix=examples/gatsby-app",
"start:nextjs": "npm run dev --prefix=examples/nextjs-app",
"start:api": "npm start --prefix=examples/users-api",
"test:cra": "start-server-and-test start:api 3001 start:cra http-get://127.0.0.1:3000 cypress:run",
"test:cra:watch": "start-server-and-test start:api 3001 start:cra 3000 cypress:open",
"test:gatsby": "start-server-and-test start:api 3001 start:gatsby http-get://localhost:3000 cypress:run",
"test:gatsby:watch": "start-server-and-test start:api 3001 start:gatsby 3000 cypress:open",
"test:nextjs": "start-server-and-test start:api 3001 start:nextjs 3000 cypress:run",
"test:nextjs:watch": "start-server-and-test start:api 3001 start:nextjs 3000 cypress:open",
"test:integration": "npm run test:cra && npm run test:gatsby && npm run test:nextjs",
"cypress:run": "cypress run --spec 'cypress/e2e/smoke.cy.ts'",
"cypress:open": "cypress open"
},
"repository": {
"type": "git",
"url": "git+https://github.com/auth0/auth0-react.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/auth0/auth0-react/issues"
},
"homepage": "https://github.com/auth0/auth0-react#readme",
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.1",
"@rollup/plugin-terser": "^0.4.3",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "6.8.0",
"@testing-library/react": "16.3.0",
"@types/jest": "^29.5.14",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@typescript-eslint/eslint-plugin": "^8.36.0",
"@typescript-eslint/parser": "^8.36.0",
"browserstack-cypress-cli": "^1.19.1",
"cypress": "^13.1.0",
"eslint": "^8.28.0",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.3",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.3.1",
"jest-junit": "^15.0.0",
"oidc-provider": "^8.8.1",
"prettier": "^2.8.1",
"pretty-quick": "^3.1.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"rollup": "^3.7.0",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-dev": "^1.1.3",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-serve": "^2.0.2",
"rollup-plugin-typescript2": "^0.36.0",
"start-server-and-test": "^2.0",
"ts-jest": "^29.4.0",
"tslib": "^2.8.1",
"typedoc": "^0.28.7",
"typescript": "^5.8.3"
},
"peerDependencies": {
"react": "^16.11.0 || ^17 || ^18 || ^19",
"react-dom": "^16.11.0 || ^17 || ^18 || ^19"
},
"dependencies": {
"@auth0/auth0-spa-js": "^2.9.0"
}
}
+21
View File
@@ -0,0 +1,21 @@
import { User } from '@auth0/auth0-spa-js';
/**
* The auth state which, when combined with the auth methods, make up the return object of the `useAuth0` hook.
*/
export interface AuthState<TUser extends User = User> {
error: Error | undefined;
isAuthenticated: boolean;
isLoading: boolean;
user: TUser | undefined;
}
/**
* The initial auth state.
*/
export const initialAuthState: AuthState = {
isAuthenticated: false,
isLoading: true,
error: undefined,
user: undefined,
};
+248
View File
@@ -0,0 +1,248 @@
import {
GetTokenSilentlyOptions,
GetTokenWithPopupOptions,
IdToken,
LogoutOptions as SPALogoutOptions,
PopupLoginOptions,
PopupConfigOptions,
RedirectLoginResult,
User,
GetTokenSilentlyVerboseResponse,
RedirectLoginOptions as SPARedirectLoginOptions,
type Auth0Client,
RedirectConnectAccountOptions,
ConnectAccountRedirectResult
} from '@auth0/auth0-spa-js';
import { createContext } from 'react';
import { AuthState, initialAuthState } from './auth-state';
import { AppState } from './auth0-provider';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface LogoutOptions extends Omit<SPALogoutOptions, 'onRedirect'> {}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface RedirectLoginOptions<TAppState = AppState>
extends Omit<SPARedirectLoginOptions<TAppState>, 'onRedirect'> {}
/**
* Contains the authenticated state and authentication methods provided by the `useAuth0` hook.
*/
export interface Auth0ContextInterface<TUser extends User = User>
extends AuthState<TUser> {
/**
* ```js
* const token = await getAccessTokenSilently(options);
* ```
*
* If there's a valid token stored, return it. Otherwise, opens an
* iframe with the `/authorize` URL using the parameters provided
* as arguments. Random and secure `state` and `nonce` parameters
* will be auto-generated. If the response is successful, results
* will be valid according to their expiration times.
*
* If refresh tokens are used, the token endpoint is called directly with the
* 'refresh_token' grant. If no refresh token is available to make this call,
* the SDK will only fall back to using an iframe to the '/authorize' URL if
* the `useRefreshTokensFallback` setting has been set to `true`. By default this
* setting is `false`.
*
* This method may use a web worker to perform the token call if the in-memory
* cache is used.
*
* If an `audience` value is given to this function, the SDK always falls
* back to using an iframe to make the token exchange.
*
* Note that in all cases, falling back to an iframe requires access to
* the `auth0` cookie.
*/
getAccessTokenSilently: {
(
options: GetTokenSilentlyOptions & { detailedResponse: true }
): Promise<GetTokenSilentlyVerboseResponse>;
(options?: GetTokenSilentlyOptions): Promise<string>;
(options: GetTokenSilentlyOptions): Promise<
GetTokenSilentlyVerboseResponse | string
>;
};
/**
* ```js
* const token = await getTokenWithPopup(options, config);
* ```
*
* Get an access token interactively.
*
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*/
getAccessTokenWithPopup: (
options?: GetTokenWithPopupOptions,
config?: PopupConfigOptions
) => Promise<string | undefined>;
/**
* ```js
* const claims = await getIdTokenClaims();
* ```
*
* Returns all claims from the id_token if available.
*/
getIdTokenClaims: () => Promise<IdToken | undefined>;
/**
* ```js
* await loginWithRedirect(options);
* ```
*
* Performs a redirect to `/authorize` using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated.
*/
loginWithRedirect: (
options?: RedirectLoginOptions<AppState>
) => Promise<void>;
/**
* ```js
* await loginWithPopup(options, config);
* ```
*
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*
* IMPORTANT: This method has to be called from an event handler
* that was started by the user like a button click, for example,
* otherwise the popup will be blocked in most browsers.
*/
loginWithPopup: (
options?: PopupLoginOptions,
config?: PopupConfigOptions
) => Promise<void>;
/**
* ```js
* await connectAccountWithRedirect({
* connection: 'google-oauth2',
* scopes: ['openid', 'profile', 'email', 'https://www.googleapis.com/auth/drive.readonly'],
* authorization_params: {
* // additional authorization params to forward to the authorization server
* }
* });
* ```
*
* Redirects to the `/connect` URL using the parameters
* provided as arguments. This then redirects to the connection's login page
* where the user can authenticate and authorize the account to be connected.
*
* If connecting the account is successful `onRedirectCallback` will be called
* with the details of the connected account.
*/
connectAccountWithRedirect: (
options: RedirectConnectAccountOptions
) => Promise<void>;
/**
* ```js
* auth0.logout({ logoutParams: { returnTo: window.location.origin } });
* ```
*
* Clears the application session and performs a redirect to `/v2/logout`, using
* the parameters provided as arguments, to clear the Auth0 session.
* If the `logoutParams.federated` option is specified, it also clears the Identity Provider session.
* [Read more about how Logout works at Auth0](https://auth0.com/docs/logout).
*/
logout: (options?: LogoutOptions) => Promise<void>;
/**
* After the browser redirects back to the callback page,
* call `handleRedirectCallback` to handle success and error
* responses from Auth0. If the response is successful, results
* will be valid according to their expiration times.
*
* @param url The URL to that should be used to retrieve the `state` and `code` values. Defaults to `window.location.href` if not given.
*/
handleRedirectCallback: (url?: string) => Promise<RedirectLoginResult | ConnectAccountRedirectResult>;
/**
* Returns the current DPoP nonce used for making requests to Auth0.
*
* It can return `undefined` because when starting fresh it will not
* be populated until after the first response from the server.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will get the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
getDpopNonce: Auth0Client['getDpopNonce'];
/**
* Sets the current DPoP nonce used for making requests to Auth0.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will set the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
setDpopNonce: Auth0Client['setDpopNonce'];
/**
* Returns a string to be used to demonstrate possession of the private
* key used to cryptographically bind access tokens with DPoP.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*/
generateDpopProof: Auth0Client['generateDpopProof'];
/**
* Returns a new `Fetcher` class that will contain a `fetchWithAuth()` method.
* This is a drop-in replacement for the Fetch API's `fetch()` method, but will
* handle certain authentication logic for you, like building the proper auth
* headers or managing DPoP nonces and retries automatically.
*
* Check the `EXAMPLES.md` file for a deeper look into this method.
*/
createFetcher: Auth0Client['createFetcher'];
}
/**
* @ignore
*/
const stub = (): never => {
throw new Error('You forgot to wrap your component in <Auth0Provider>.');
};
/**
* @ignore
*/
export const initialContext = {
...initialAuthState,
buildAuthorizeUrl: stub,
buildLogoutUrl: stub,
getAccessTokenSilently: stub,
getAccessTokenWithPopup: stub,
getIdTokenClaims: stub,
loginWithRedirect: stub,
loginWithPopup: stub,
connectAccountWithRedirect: stub,
logout: stub,
handleRedirectCallback: stub,
getDpopNonce: stub,
setDpopNonce: stub,
generateDpopProof: stub,
createFetcher: stub,
};
/**
* The Auth0 Context
*/
const Auth0Context = createContext<Auth0ContextInterface>(initialContext);
export default Auth0Context;
+353
View File
@@ -0,0 +1,353 @@
import React, {
useCallback,
useEffect,
useMemo,
useReducer,
useRef,
useState,
} from 'react';
import {
Auth0Client,
Auth0ClientOptions,
PopupLoginOptions,
PopupConfigOptions,
GetTokenWithPopupOptions,
RedirectLoginResult,
GetTokenSilentlyOptions,
User,
RedirectConnectAccountOptions,
ConnectAccountRedirectResult,
ResponseType
} from '@auth0/auth0-spa-js';
import Auth0Context, {
Auth0ContextInterface,
LogoutOptions,
RedirectLoginOptions,
} from './auth0-context';
import {
hasAuthParams,
loginError,
tokenError,
deprecateRedirectUri,
} from './utils';
import { reducer } from './reducer';
import { initialAuthState, type AuthState } from './auth-state';
/**
* The account that has been connected during the connect flow.
*/
export type ConnectedAccount = Omit<ConnectAccountRedirectResult, 'appState' | 'response_type'>;
/**
* The state of the application before the user was redirected to the login page
* and any account that the user may have connected to.
*/
export type AppState = {
returnTo?: string;
connectedAccount?: ConnectedAccount;
response_type?: ResponseType;
[key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
};
/**
* The main configuration to instantiate the `Auth0Provider`.
*/
export interface Auth0ProviderOptions<TUser extends User = User> extends Auth0ClientOptions {
/**
* The child nodes your Provider has wrapped
*/
children?: React.ReactNode;
/**
* By default this removes the code and state parameters from the url when you are redirected from the authorize page.
* It uses `window.history` but you might want to overwrite this if you are using a custom router, like `react-router-dom`
* See the EXAMPLES.md for more info.
*/
onRedirectCallback?: (appState?: AppState, user?: TUser) => void;
/**
* By default, if the page url has code/state params, the SDK will treat them as Auth0's and attempt to exchange the
* code for a token. In some cases the code might be for something else (another OAuth SDK perhaps). In these
* instances you can instruct the client to ignore them eg
*
* ```jsx
* <Auth0Provider
* clientId={clientId}
* domain={domain}
* skipRedirectCallback={window.location.pathname === '/stripe-oauth-callback'}
* >
* ```
*/
skipRedirectCallback?: boolean;
/**
* Context to be used when creating the Auth0Provider, defaults to the internally created context.
*
* This allows multiple Auth0Providers to be nested within the same application, the context value can then be
* passed to useAuth0, withAuth0, or withAuthenticationRequired to use that specific Auth0Provider to access
* auth state and methods specifically tied to the provider that the context belongs to.
*
* When using multiple Auth0Providers in a single application you should do the following to ensure sessions are not
* overwritten:
*
* * Configure a different redirect_uri for each Auth0Provider, and set skipRedirectCallback for each provider to ignore
* the others redirect_uri
* * If using localstorage for both Auth0Providers, ensure that the audience and scope are different for so that the key
* used to store data is different
*
* For a sample on using multiple Auth0Providers review the [React Account Linking Sample](https://github.com/auth0-samples/auth0-link-accounts-sample/tree/react-variant)
*/
context?: React.Context<Auth0ContextInterface<TUser>>;
}
/**
* Replaced by the package version at build time.
* @ignore
*/
declare const __VERSION__: string;
/**
* @ignore
*/
const toAuth0ClientOptions = (
opts: Auth0ProviderOptions
): Auth0ClientOptions => {
deprecateRedirectUri(opts);
return {
...opts,
auth0Client: {
name: 'auth0-react',
version: __VERSION__,
},
};
};
/**
* @ignore
*/
const defaultOnRedirectCallback = (appState?: AppState): void => {
window.history.replaceState(
{},
document.title,
appState!.returnTo ?? window.location.pathname
);
};
/**
* ```jsx
* <Auth0Provider
* domain={domain}
* clientId={clientId}
* authorizationParams={{ redirect_uri: window.location.origin }}>
* <MyApp />
* </Auth0Provider>
* ```
*
* Provides the Auth0Context to its child components.
*/
const Auth0Provider = <TUser extends User = User>(opts: Auth0ProviderOptions<TUser>) => {
const {
children,
skipRedirectCallback,
onRedirectCallback = defaultOnRedirectCallback,
context = Auth0Context,
...clientOpts
} = opts;
const [client] = useState(
() => new Auth0Client(toAuth0ClientOptions(clientOpts))
);
const [state, dispatch] = useReducer(reducer<TUser>, initialAuthState as AuthState<TUser>);
const didInitialise = useRef(false);
const handleError = useCallback((error: Error) => {
dispatch({ type: 'ERROR', error });
return error;
}, []);
useEffect(() => {
if (didInitialise.current) {
return;
}
didInitialise.current = true;
(async (): Promise<void> => {
try {
let user: TUser | undefined;
if (hasAuthParams() && !skipRedirectCallback) {
const { appState = {}, response_type, ...result } = await client.handleRedirectCallback();
user = await client.getUser();
appState.response_type = response_type;
if (response_type === ResponseType.ConnectCode) {
appState.connectedAccount = result as ConnectedAccount;
}
onRedirectCallback(appState, user);
} else {
await client.checkSession();
user = await client.getUser();
}
dispatch({ type: 'INITIALISED', user });
} catch (error) {
handleError(loginError(error));
}
})();
}, [client, onRedirectCallback, skipRedirectCallback, handleError]);
const loginWithRedirect = useCallback(
(opts?: RedirectLoginOptions): Promise<void> => {
deprecateRedirectUri(opts);
return client.loginWithRedirect(opts);
},
[client]
);
const loginWithPopup = useCallback(
async (
options?: PopupLoginOptions,
config?: PopupConfigOptions
): Promise<void> => {
dispatch({ type: 'LOGIN_POPUP_STARTED' });
try {
await client.loginWithPopup(options, config);
} catch (error) {
handleError(loginError(error));
return;
}
const user = await client.getUser();
dispatch({ type: 'LOGIN_POPUP_COMPLETE', user });
},
[client, handleError]
);
const logout = useCallback(
async (opts: LogoutOptions = {}): Promise<void> => {
await client.logout(opts);
if (opts.openUrl || opts.openUrl === false) {
dispatch({ type: 'LOGOUT' });
}
},
[client]
);
const getAccessTokenSilently = useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async (opts?: GetTokenSilentlyOptions): Promise<any> => {
let token;
try {
token = await client.getTokenSilently(opts);
} catch (error) {
throw tokenError(error);
} finally {
dispatch({
type: 'GET_ACCESS_TOKEN_COMPLETE',
user: await client.getUser(),
});
}
return token;
},
[client]
);
const getAccessTokenWithPopup = useCallback(
async (
opts?: GetTokenWithPopupOptions,
config?: PopupConfigOptions
): Promise<string | undefined> => {
let token;
try {
token = await client.getTokenWithPopup(opts, config);
} catch (error) {
throw tokenError(error);
} finally {
dispatch({
type: 'GET_ACCESS_TOKEN_COMPLETE',
user: await client.getUser(),
});
}
return token;
},
[client]
);
const connectAccountWithRedirect = useCallback(
(options: RedirectConnectAccountOptions) =>
client.connectAccountWithRedirect(options),
[client]
);
const getIdTokenClaims = useCallback(
() => client.getIdTokenClaims(),
[client]
);
const handleRedirectCallback = useCallback(
async (
url?: string
): Promise<RedirectLoginResult | ConnectAccountRedirectResult> => {
try {
return await client.handleRedirectCallback(url);
} catch (error) {
throw tokenError(error);
} finally {
dispatch({
type: 'HANDLE_REDIRECT_COMPLETE',
user: await client.getUser(),
});
}
},
[client]
);
const getDpopNonce = useCallback<Auth0Client['getDpopNonce']>(
(id) => client.getDpopNonce(id),
[client]
);
const setDpopNonce = useCallback<Auth0Client['setDpopNonce']>(
(nonce, id) => client.setDpopNonce(nonce, id),
[client]
);
const generateDpopProof = useCallback<Auth0Client['generateDpopProof']>(
(params) => client.generateDpopProof(params),
[client]
);
const createFetcher = useCallback<Auth0Client['createFetcher']>(
(config) => client.createFetcher(config),
[client]
);
const contextValue = useMemo<Auth0ContextInterface<TUser>>(() => {
return {
...state,
getAccessTokenSilently,
getAccessTokenWithPopup,
getIdTokenClaims,
loginWithRedirect,
loginWithPopup,
connectAccountWithRedirect,
logout,
handleRedirectCallback,
getDpopNonce,
setDpopNonce,
generateDpopProof,
createFetcher,
};
}, [
state,
getAccessTokenSilently,
getAccessTokenWithPopup,
getIdTokenClaims,
loginWithRedirect,
loginWithPopup,
connectAccountWithRedirect,
logout,
handleRedirectCallback,
getDpopNonce,
setDpopNonce,
generateDpopProof,
createFetcher,
]);
return <context.Provider value={contextValue}>{children}</context.Provider>;
};
export default Auth0Provider;
+14
View File
@@ -0,0 +1,14 @@
/**
* An OAuth2 error will come from the authorization server and will have at least an `error` property which will
* be the error code. And possibly an `error_description` property
*
* See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.6
*/
export class OAuthError extends Error {
constructor(public error: string, public error_description?: string) {
super(error_description ?? error);
// https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(this, OAuthError.prototype);
}
}
+48
View File
@@ -0,0 +1,48 @@
export {
default as Auth0Provider,
Auth0ProviderOptions,
AppState,
ConnectedAccount
} from './auth0-provider';
export { default as useAuth0 } from './use-auth0';
export { default as withAuth0, WithAuth0Props } from './with-auth0';
export {
default as withAuthenticationRequired,
WithAuthenticationRequiredOptions,
} from './with-authentication-required';
export {
default as Auth0Context,
Auth0ContextInterface,
initialContext,
LogoutOptions,
RedirectLoginOptions,
} from './auth0-context';
export {
AuthorizationParams,
PopupLoginOptions,
PopupConfigOptions,
GetTokenWithPopupOptions,
LogoutUrlOptions,
CacheLocation,
GetTokenSilentlyOptions,
IdToken,
User,
ICache,
InMemoryCache,
LocalStorageCache,
Cacheable,
TimeoutError,
MfaRequiredError,
PopupCancelledError,
PopupTimeoutError,
AuthenticationError,
MissingRefreshTokenError,
GenericError,
UseDpopNonceError,
type FetcherConfig,
RedirectConnectAccountOptions,
ConnectAccountRedirectResult,
ResponseType,
ConnectError
} from '@auth0/auth0-spa-js';
export { OAuthError } from './errors';
+59
View File
@@ -0,0 +1,59 @@
import { User } from '@auth0/auth0-spa-js';
import { AuthState } from './auth-state';
type Action =
| { type: 'LOGIN_POPUP_STARTED' }
| {
type:
| 'INITIALISED'
| 'LOGIN_POPUP_COMPLETE'
| 'GET_ACCESS_TOKEN_COMPLETE'
| 'HANDLE_REDIRECT_COMPLETE';
user: User | undefined;
}
| { type: 'LOGOUT' }
| { type: 'ERROR'; error: Error };
/**
* Handles how that state changes in the `useAuth0` hook.
*/
export const reducer = <TUser extends User = User>(state: AuthState<TUser>, action: Action): AuthState<TUser> => {
switch (action.type) {
case 'LOGIN_POPUP_STARTED':
return {
...state,
isLoading: true,
};
case 'LOGIN_POPUP_COMPLETE':
case 'INITIALISED':
return {
...state,
isAuthenticated: !!action.user,
user: action.user as TUser | undefined,
isLoading: false,
error: undefined,
};
case 'HANDLE_REDIRECT_COMPLETE':
case 'GET_ACCESS_TOKEN_COMPLETE':
if (state.user === action.user) {
return state;
}
return {
...state,
isAuthenticated: !!action.user,
user: action.user as TUser | undefined,
};
case 'LOGOUT':
return {
...state,
isAuthenticated: false,
user: undefined,
};
case 'ERROR':
return {
...state,
isLoading: false,
error: action.error,
};
}
};
+32
View File
@@ -0,0 +1,32 @@
import { useContext } from 'react';
import { User } from '@auth0/auth0-spa-js';
import Auth0Context, { Auth0ContextInterface } from './auth0-context';
/**
* ```js
* const {
* // Auth state:
* error,
* isAuthenticated,
* isLoading,
* user,
* // Auth methods:
* getAccessTokenSilently,
* getAccessTokenWithPopup,
* getIdTokenClaims,
* loginWithRedirect,
* loginWithPopup,
* logout,
* } = useAuth0<TUser>();
* ```
*
* Use the `useAuth0` hook in your components to access the auth state and methods.
*
* TUser is an optional type param to provide a type to the `user` field.
*/
const useAuth0 = <TUser extends User = User>(
context = Auth0Context
): Auth0ContextInterface<TUser> =>
useContext(context) as Auth0ContextInterface<TUser>;
export default useAuth0;
+74
View File
@@ -0,0 +1,74 @@
import { OAuthError } from './errors';
const CODE_RE = /[?&](?:connect_)?code=[^&]+/;
const STATE_RE = /[?&]state=[^&]+/;
const ERROR_RE = /[?&]error=[^&]+/;
interface WithError {
error: string;
}
interface WithErrorAndDescription {
error: string;
error_description: string;
}
export const hasAuthParams = (searchParams = window.location.search): boolean =>
(CODE_RE.test(searchParams) || ERROR_RE.test(searchParams)) &&
STATE_RE.test(searchParams);
const normalizeErrorFn =
(fallbackMessage: string) =>
(error: unknown): Error => {
if (error instanceof Error) {
return error;
}
// try to check errors of the following form: {error: string; error_description?: string}
if (
error !== null &&
typeof error === 'object' &&
'error' in error &&
typeof (error as WithError).error === 'string'
) {
if (
'error_description' in error &&
typeof (error as WithErrorAndDescription).error_description === 'string'
) {
const e = error as WithErrorAndDescription;
return new OAuthError(e.error, e.error_description);
}
const e = error as WithError;
return new OAuthError(e.error);
}
return new Error(fallbackMessage);
};
export const loginError = normalizeErrorFn('Login failed');
export const tokenError = normalizeErrorFn('Get access token failed');
/**
* @ignore
* Helper function to map the v1 `redirectUri` option to the v2 `authorizationParams.redirect_uri`
* and log a warning.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const deprecateRedirectUri = (options?: any) => {
if (options?.redirectUri) {
console.warn(
'Using `redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `redirectUri` will be no longer supported in a future version'
);
options.authorizationParams = options.authorizationParams ?? {};
options.authorizationParams.redirect_uri = options.redirectUri;
delete options.redirectUri;
}
if (options?.authorizationParams?.redirectUri) {
console.warn(
'Using `authorizationParams.redirectUri` has been deprecated, please use `authorizationParams.redirect_uri` instead as `authorizationParams.redirectUri` will be removed in a future version'
);
options.authorizationParams.redirect_uri =
options.authorizationParams.redirectUri;
delete options.authorizationParams.redirectUri;
}
};
+44
View File
@@ -0,0 +1,44 @@
import React, { ComponentType } from 'react';
import Auth0Context, { Auth0ContextInterface } from './auth0-context';
/**
* Components wrapped in `withAuth0` will have an additional `auth0` prop
*/
export interface WithAuth0Props {
auth0: Auth0ContextInterface;
}
/**
* ```jsx
* class MyComponent extends Component {
* render() {
* // Access the auth context from the `auth0` prop
* const { user } = this.props.auth0;
* return <div>Hello {user.name}!</div>
* }
* }
* // Wrap your class component in withAuth0
* export default withAuth0(MyComponent);
* ```
*
* Wrap your class components in this Higher Order Component to give them access to the Auth0Context.
*
* Providing a context as the second argument allows you to configure the Auth0Provider the Auth0Context
* should come from f you have multiple within your application.
*/
const withAuth0 = <P extends WithAuth0Props>(
Component: ComponentType<P>,
context = Auth0Context
): ComponentType<Omit<P, keyof WithAuth0Props>> => {
return function WithAuth(props): React.JSX.Element {
return (
<context.Consumer>
{(auth: Auth0ContextInterface): React.JSX.Element => (
<Component {...(props as P)} auth0={auth} />
)}
</context.Consumer>
);
};
};
export default withAuth0;
+141
View File
@@ -0,0 +1,141 @@
import React, { ComponentType, useEffect, FC } from 'react';
import useAuth0 from './use-auth0';
import Auth0Context, {
Auth0ContextInterface,
RedirectLoginOptions,
} from './auth0-context';
/**
* @ignore
*/
const defaultOnRedirecting = (): React.JSX.Element => <></>;
/**
* @ignore
*/
const defaultOnBeforeAuthentication = async (): Promise<void> => {/* noop */ };
/**
* @ignore
*/
const defaultReturnTo = (): string =>
`${window.location.pathname}${window.location.search}`;
/**
* Options for the withAuthenticationRequired Higher Order Component
*/
export interface WithAuthenticationRequiredOptions {
/**
* ```js
* withAuthenticationRequired(Profile, {
* returnTo: '/profile'
* })
* ```
*
* or
*
* ```js
* withAuthenticationRequired(Profile, {
* returnTo: () => window.location.hash.substr(1)
* })
* ```
*
* Add a path for the `onRedirectCallback` handler to return the user to after login.
*/
returnTo?: string | (() => string);
/**
* ```js
* withAuthenticationRequired(Profile, {
* onRedirecting: () => <div>Redirecting you to the login...</div>
* })
* ```
*
* Render a message to show that the user is being redirected to the login.
*/
onRedirecting?: () => React.JSX.Element;
/**
* ```js
* withAuthenticationRequired(Profile, {
* onBeforeAuthentication: () => { analyticsLibrary.track('login_triggered'); }
* })
* ```
*
* Allows executing logic before the user is redirected to the login page.
*/
onBeforeAuthentication?: () => Promise<void>;
/**
* ```js
* withAuthenticationRequired(Profile, {
* loginOptions: {
* appState: {
* customProp: 'foo'
* }
* }
* })
* ```
*
* Pass additional login options, like extra `appState` to the login page.
* This will be merged with the `returnTo` option used by the `onRedirectCallback` handler.
*/
loginOptions?: RedirectLoginOptions;
/**
* The context to be used when calling useAuth0, this should only be provided if you are using multiple Auth0Providers
* within your application and you wish to tie a specific component to a Auth0Provider other than the Auth0Provider
* associated with the default Auth0Context.
*/
context?: React.Context<Auth0ContextInterface>;
}
/**
* ```js
* const MyProtectedComponent = withAuthenticationRequired(MyComponent);
* ```
*
* When you wrap your components in this Higher Order Component and an anonymous user visits your component
* they will be redirected to the login page; after login they will be returned to the page they were redirected from.
*/
const withAuthenticationRequired = <P extends object>(
Component: ComponentType<P>,
options: WithAuthenticationRequiredOptions = {}
): FC<P> => {
return function WithAuthenticationRequired(props: P): React.JSX.Element {
const {
returnTo = defaultReturnTo,
onRedirecting = defaultOnRedirecting,
onBeforeAuthentication = defaultOnBeforeAuthentication,
loginOptions,
context = Auth0Context,
} = options;
const { isAuthenticated, isLoading, loginWithRedirect } =
useAuth0(context);
useEffect(() => {
if (isLoading || isAuthenticated) {
return;
}
const opts = {
...loginOptions,
appState: {
...loginOptions?.appState,
returnTo: typeof returnTo === 'function' ? returnTo() : returnTo,
},
};
void (async (): Promise<void> => {
await onBeforeAuthentication();
await loginWithRedirect(opts);
})();
}, [
isLoading,
isAuthenticated,
loginWithRedirect,
onBeforeAuthentication,
loginOptions,
returnTo,
]);
return isAuthenticated ? <Component {...props} /> : onRedirecting();
};
};
export default withAuthenticationRequired;
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Auth0, Inc. <support@auth0.com> (http://auth0.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+160
View File
@@ -0,0 +1,160 @@
![Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE.](https://cdn.auth0.com/website/sdks/banners/spa-js-banner.png)
[![npm version](https://img.shields.io/npm/v/@auth0/auth0-spa-js?style=flat-square&logo=npm&logoColor=CB3837)](https://www.npmjs.com/package/@auth0/auth0-spa-js)
[![Codecov](https://img.shields.io/codecov/c/github/auth0/auth0-spa-js)](https://codecov.io/gh/auth0/auth0-spa-js)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/auth0/auth0-spa-js)
![Downloads](https://img.shields.io/npm/dw/@auth0/auth0-spa-js)
[![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://opensource.org/licenses/MIT)
![CircleCI](https://img.shields.io/circleci/build/github/auth0/auth0-spa-js)
📚 [Documentation](#documentation) - 🚀 [Getting Started](#getting-started) - 💻 [API Reference](#api-reference) - 💬 [Feedback](#feedback)
## Documentation
- [Quickstart](https://auth0.com/docs/quickstart/spa/vanillajs/interactive) - our interactive guide for quickly adding login, logout and user information to your app using Auth0.
- [Sample app](https://github.com/auth0-samples/auth0-javascript-samples/tree/master/01-Login) - a full-fledged sample app integrated with Auth0.
- [FAQs](https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md) - frequently asked questions about auth0-spa-js SDK.
- [Examples](https://github.com/auth0/auth0-spa-js/blob/main/EXAMPLES.md) - code samples for common scenarios.
- [Docs Site](https://auth0.com/docs) - explore our Docs site and learn more about Auth0.
## Getting Started
### Installation
Using [npm](https://npmjs.org) in your project directory run the following command:
```sh
npm install @auth0/auth0-spa-js
```
From the CDN:
```html
<script src="https://cdn.auth0.com/js/auth0-spa-js/2.9/auth0-spa-js.production.js"></script>
```
### Configure Auth0
Create a **Single Page Application** in the [Auth0 Dashboard](https://manage.auth0.com/#/applications).
> **If you're using an existing application**, verify that you have configured the following settings in your Single Page Application:
>
> - Click on the "Settings" tab of your application's page.
> - Scroll down and click on the "Show Advanced Settings" link.
> - Under "Advanced Settings", click on the "OAuth" tab.
> - Ensure that "JsonWebToken Signature Algorithm" is set to `RS256` and that "OIDC Conformant" is enabled.
Next, configure the following URLs for your application under the "Application URIs" section of the "Settings" page:
- **Allowed Callback URLs**: `http://localhost:3000`
- **Allowed Logout URLs**: `http://localhost:3000`
- **Allowed Web Origins**: `http://localhost:3000`
> These URLs should reflect the origins that your application is running on. **Allowed Callback URLs** may also include a path, depending on where you're handling the callback (see below).
Take note of the **Client ID** and **Domain** values under the "Basic Information" section. You'll need these values in the next step.
### Configure the SDK
Create an `Auth0Client` instance before rendering or initializing your application. You should only have one instance of the client.
```js
import { createAuth0Client } from '@auth0/auth0-spa-js';
//with async/await
const auth0 = await createAuth0Client({
domain: '<AUTH0_DOMAIN>',
clientId: '<AUTH0_CLIENT_ID>',
authorizationParams: {
redirect_uri: '<MY_CALLBACK_URL>'
}
});
//or, you can just instantiate the client on its own
import { Auth0Client } from '@auth0/auth0-spa-js';
const auth0 = new Auth0Client({
domain: '<AUTH0_DOMAIN>',
clientId: '<AUTH0_CLIENT_ID>',
authorizationParams: {
redirect_uri: '<MY_CALLBACK_URL>'
}
});
//if you do this, you'll need to check the session yourself
try {
await auth0.getTokenSilently();
} catch (error) {
if (error.error !== 'login_required') {
throw error;
}
}
```
### Logging In
You can then use login using the `Auth0Client` instance you created:
```html
<button id="login">Click to Login</button>
```
```js
//redirect to the Universal Login Page
document.getElementById('login').addEventListener('click', async () => {
await auth0.loginWithRedirect();
});
//in your callback route (<MY_CALLBACK_URL>)
window.addEventListener('load', async () => {
const redirectResult = await auth0.handleRedirectCallback();
//logged in. you can get the user profile like this:
const user = await auth0.getUser();
console.log(user);
});
```
For other comprehensive examples, see the [EXAMPLES.md](https://github.com/auth0/auth0-spa-js/blob/main/EXAMPLES.md) document.
## API Reference
Explore API Methods available in auth0-spa-js.
- [Configuration Options](https://auth0.github.io/auth0-spa-js/interfaces/Auth0ClientOptions.html)
- [Auth0Client](https://auth0.github.io/auth0-spa-js/classes/Auth0Client.html)
- [createAuth0Client](https://auth0.github.io/auth0-spa-js/functions/createAuth0Client.html)
## Feedback
### Contributing
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
- [This repo's contribution guide](https://github.com/auth0/auth0-spa-js/blob/main/CONTRIBUTING.md)
### Raise an issue
To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-spa-js/issues).
### Vulnerability Reporting
Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
## What is Auth0?
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150">
<source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
<img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
</picture>
</p>
<p align="center">
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a>
</p>
<p align="center">
This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-spa-js/blob/main/LICENSE"> LICENSE</a> file for more info.
</p>
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.development.js","sources":["../node_modules/tslib/tslib.es6.js","../node_modules/browser-tabs-lock/processLock.js","../node_modules/browser-tabs-lock/index.js","../src/version.ts","../src/constants.ts","../src/errors.ts","../src/utils.ts","../node_modules/dpop/src/index.ts","../src/dpop/utils.ts","../src/worker/worker.utils.ts","../src/http.ts","../src/api.ts","../src/scope.ts","../src/cache/shared.ts","../src/cache/cache-localstorage.ts","../src/cache/cache-memory.ts","../src/cache/cache-manager.ts","../src/transaction-manager.ts","../src/jwt.ts","../node_modules/es-cookie/src/es-cookie.js","../src/storage.ts","../src/global.ts","../src/promise-utils.ts","../src/cache/key-manifest.ts","../src/Auth0Client.utils.ts","../src/dpop/storage.ts","../src/dpop/dpop.ts","../src/fetcher.ts","../src/MyAccountApiClient.ts","../src/Auth0Client.ts","../src/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n contLine truncated
+2
View File
@@ -0,0 +1,2 @@
function e(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]])}return n}"function"==typeof SuppressedError&&SuppressedError;var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function o(e,t){return e(t={exports:{}},t.exports),t.exports}var i=o((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,n){var o=e.locked.get(t);void 0===o?void 0===n?e.locked.set(t,[]):e.locked.set(t,[n]):void 0!==n&&(o.unshift(n),e.locked.set(t,o))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(n,o){e.isLocked(t)?e.addToLocked(t,n):(e.addToLocked(t),n())}))},this.unlock=function(t){var n=e.locked.get(t);if(void 0!==n&&0!==n.length){var o=n.pop();e.locked.set(t,n),void 0!==o&&setTimeout(o,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return n.getInstance()}}));n(i);var r=n(o((function(e,n){var o=t&&t.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function s(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new n((function(t){t(e.value)})).then(s,a)}c((o=o.apply(e,t||[])).next())}))},r=t&&t.__generator||function(e,t){var n,o,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,o=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=t;Object.defineProperty(n,"__esModule",{value:!0});var a="browser-tabs-lock-key",c={key:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},getItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},clear:function(){return o(s,void 0,void 0,(function(){return r(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},setItem:function(e,t){return o(s,void 0,void 0,(function(){return r(this,(function(e){throw new Error("Unsupported")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",n="",o=0;o<e;o++){n+=t[Math.floor(Math.random()*t.length)]}return n}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototype.acquireLock=function(t,n){return void 0===n&&(n=5e3),o(this,void 0,void 0,(function(){var o,i,s,h,l,p,m;return r(this,(function(r){switch(r.label){case 0:o=Date.now()+d(4),i=Date.now()+n,s=a+"-"+t,h=void 0===this.storageHandler?c:this.storageHandler,r.label=1;case 1:return Date.now()<i?[4,u(30)]:[3,8];case 2:return r.sent(),null!==h.getItemSync(s)?[3,5]:(l=this.id+"-"+t+"-"+o,[4,u(Math.floor(25*Math.randomLine truncated
//# sourceMappingURL=auth0-spa-js.production.esm.js.map
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.production.esm.js","sources":["../node_modules/tslib/tslib.es6.js","../node_modules/browser-tabs-lock/processLock.js","../node_modules/browser-tabs-lock/index.js","../src/constants.ts","../src/version.ts","../src/errors.ts","../src/utils.ts","../node_modules/dpop/src/index.ts","../src/dpop/utils.ts","../src/worker/worker.utils.ts","../src/http.ts","../src/api.ts","../src/scope.ts","../src/cache/shared.ts","../src/cache/cache-localstorage.ts","../src/cache/cache-memory.ts","../src/cache/cache-manager.ts","../src/transaction-manager.ts","../src/jwt.ts","../node_modules/es-cookie/src/es-cookie.js","../src/storage.ts","../src/global.ts","../src/promise-utils.ts","../src/cache/key-manifest.ts","../src/Auth0Client.utils.ts","../src/dpop/storage.ts","../src/dpop/dpop.ts","../src/fetcher.ts","../src/MyAccountApiClient.ts","../src/Auth0Client.ts","../src/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n cLine truncated
+2
View File
@@ -0,0 +1,2 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).auth0={})}(this,(function(e){"use strict";function t(e,t){var o={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(o[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(o[n[i]]=e[n[i]])}return o}"function"==typeof SuppressedError&&SuppressedError;var o="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function i(e,t){return e(t={exports:{}},t.exports),t.exports}var r=i((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(){var e=this;this.locked=new Map,this.addToLocked=function(t,o){var n=e.locked.get(t);void 0===n?void 0===o?e.locked.set(t,[]):e.locked.set(t,[o]):void 0!==o&&(n.unshift(o),e.locked.set(t,n))},this.isLocked=function(t){return e.locked.has(t)},this.lock=function(t){return new Promise((function(o,n){e.isLocked(t)?e.addToLocked(t,o):(e.addToLocked(t),o())}))},this.unlock=function(t){var o=e.locked.get(t);if(void 0!==o&&0!==o.length){var n=o.pop();e.locked.set(t,o),void 0!==n&&setTimeout(n,0)}else e.locked.delete(t)}}return e.getInstance=function(){return void 0===e.instance&&(e.instance=new e),e.instance},e}();t.default=function(){return o.getInstance()}}));n(r);var s=i((function(e,t){var n=o&&o.__awaiter||function(e,t,o,n){return new(o||(o=Promise))((function(i,r){function s(e){try{c(n.next(e))}catch(e){r(e)}}function a(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){e.done?i(e.value):new o((function(t){t(e.value)})).then(s,a)}c((n=n.apply(e,t||[])).next())}))},i=o&&o.__generator||function(e,t){var o,n,i,r,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(o)throw new TypeError("Generator is already executing.");for(;s;)try{if(o=1,n&&(i=2&r[0]?n.return:r[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,r[1])).done)return i;switch(n=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,n=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){s.label=r[1];break}if(6===r[0]&&s.label<i[1]){s.label=i[1],i=r;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(r);break}i[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],n=0}finally{o=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}},s=o;Object.defineProperty(t,"__esModule",{value:!0});var a="browser-tabs-lock-key",c={key:function(e){return n(s,void 0,void 0,(function(){return i(this,(function(e){throw new Error("Unsupported")}))}))},getItem:function(e){return n(s,void 0,void 0,(function(){return i(this,(function(e){throw new Error("Unsupported")}))}))},clear:function(){return n(s,void 0,void 0,(function(){return i(this,(function(e){return[2,window.localStorage.clear()]}))}))},removeItem:function(e){return n(s,void 0,void 0,(function(){return i(this,(function(e){throw new Error("Unsupported")}))}))},setItem:function(e,t){return n(s,void 0,void 0,(function(){return i(this,(function(e){throw new Error("Unsupported")}))}))},keySync:function(e){return window.localStorage.key(e)},getItemSync:function(e){return window.localStorage.getItem(e)},clearSync:function(){return window.localStorage.clear()},removeItemSync:function(e){return window.localStorage.removeItem(e)},setItemSync:function(e,t){return window.localStorage.setItem(e,t)}};function u(e){return new Promise((function(t){return setTimeout(t,e)}))}function d(e){for(var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",o="",n=0;n<e;n++){o+=t[Math.floor(Math.random()*t.length)]}return o}var h=function(){function e(t){this.acquiredIatSet=new Set,this.storageHandler=void 0,this.id=Date.now().toString()+d(15),this.acquireLock=this.acquireLock.bind(this),this.releaseLock=this.releaseLock.bind(this),this.releaseLock__private__=this.releaseLock__private__.bind(this),this.waitForSomethingToChange=this.waitForSomethingToChange.bind(this),this.refreshLockWhileAcquired=this.refreshLockWhileAcquired.bind(this),this.storageHandler=t,void 0===e.waiters&&(e.waiters=[])}return e.prototype.acquireLock=function(t,o){return void 0===o&&(o=5e3),n(this,void 0,void 0,(function(){var n,r,s,h,l,p,m;return i(this,(function(i){switch(i.label){case 0:n=Date.now()+d(4),r=Line truncated
//# sourceMappingURL=auth0-spa-js.production.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.production.js","sources":["../node_modules/tslib/tslib.es6.js","../node_modules/browser-tabs-lock/processLock.js","../node_modules/browser-tabs-lock/index.js","../src/constants.ts","../src/version.ts","../src/errors.ts","../src/utils.ts","../node_modules/dpop/src/index.ts","../src/dpop/utils.ts","../src/worker/worker.utils.ts","../src/http.ts","../src/api.ts","../src/scope.ts","../src/cache/shared.ts","../src/cache/cache-localstorage.ts","../src/cache/cache-memory.ts","../src/cache/cache-manager.ts","../src/transaction-manager.ts","../src/jwt.ts","../node_modules/es-cookie/src/es-cookie.js","../src/storage.ts","../src/global.ts","../src/promise-utils.ts","../src/cache/key-manifest.ts","../src/Auth0Client.utils.ts","../src/dpop/storage.ts","../src/dpop/dpop.ts","../src/fetcher.ts","../src/MyAccountApiClient.ts","../src/Auth0Client.ts","../src/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n conteLine truncated
@@ -0,0 +1,164 @@
(function(factory) {
typeof define === "function" && define.amd ? define(factory) : factory();
})((function() {
"use strict";
class GenericError extends Error {
constructor(error, error_description) {
super(error_description);
this.error = error;
this.error_description = error_description;
Object.setPrototypeOf(this, GenericError.prototype);
}
static fromPayload({error: error, error_description: error_description}) {
return new GenericError(error, error_description);
}
}
class MissingRefreshTokenError extends GenericError {
constructor(audience, scope) {
super("missing_refresh_token", `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [ "default" ])}', scope: '${valueOrEmptyString(scope)}')`);
this.audience = audience;
this.scope = scope;
Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);
}
}
function valueOrEmptyString(value, exclude = []) {
return value && !exclude.includes(value) ? value : "";
}
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
}
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
const stripUndefined = params => Object.keys(params).filter((k => typeof params[k] !== "undefined")).reduce(((acc, key) => Object.assign(Object.assign({}, acc), {
[key]: params[key]
})), {});
const createQueryParams = _a => {
var {clientId: client_id} = _a, params = __rest(_a, [ "clientId" ]);
return new URLSearchParams(stripUndefined(Object.assign({
client_id: client_id
}, params))).toString();
};
const fromEntries = iterable => [ ...iterable ].reduce(((obj, [key, val]) => {
obj[key] = val;
return obj;
}), {});
let refreshTokens = {};
const cacheKey = (audience, scope) => `${audience}|${scope}`;
const cacheKeyContainsAudience = (audience, cacheKey) => cacheKey.startsWith(`${audience}|`);
const getRefreshToken = (audience, scope) => refreshTokens[cacheKey(audience, scope)];
const setRefreshToken = (refreshToken, audience, scope) => refreshTokens[cacheKey(audience, scope)] = refreshToken;
const deleteRefreshToken = (audience, scope) => delete refreshTokens[cacheKey(audience, scope)];
const wait = time => new Promise((resolve => setTimeout(resolve, time)));
const formDataToObject = formData => {
const queryParams = new URLSearchParams(formData);
const parsedQuery = {};
queryParams.forEach(((val, key) => {
parsedQuery[key] = val;
}));
return parsedQuery;
};
const updateRefreshTokens = (oldRefreshToken, newRefreshToken) => {
Object.entries(refreshTokens).forEach((([key, token]) => {
if (token === oldRefreshToken) {
refreshTokens[key] = newRefreshToken;
}
}));
};
const checkDownscoping = (scope, audience) => {
const findCoincidence = Object.keys(refreshTokens).find((key => {
if (key !== "latest_refresh_token") {
const isSameAudience = cacheKeyContainsAudience(audience, key);
const scopesKey = key.split("|")[1].split(" ");
const requestedScopes = scope.split(" ");
const scopesAreIncluded = requestedScopes.every((key => scopesKey.includes(key)));
return isSameAudience && scopesAreIncluded;
}
}));
return findCoincidence ? true : false;
};
const messageHandler = async ({data: {timeout: timeout, auth: auth, fetchUrl: fetchUrl, fetchOptions: fetchOptions, useFormData: useFormData, useMrrt: useMrrt}, ports: [port]}) => {
let headers = {};
let json;
let refreshToken;
const {audience: audience, scope: scope} = auth || {};
try {
const body = useFormData ? formDataToObject(fetchOptions.body) : JSON.parse(fetchOptions.body);
if (!body.refresh_token && body.grant_type === "refresh_token") {
refreshToken = getRefreshToken(audience, scope);
if (!refreshToken && useMrrt) {
const latestRefreshToken = refreshTokens["latest_refresh_token"];
const isDownscoping = checkDownscoping(scope, audience);
if (latestRefreshToken && !isDownscoping) {
refreshToken = latestRefreshToken;
}
}
if (!refreshToken) {
throw new MissingRefreshTokenError(audience, scope);
}
fetchOptions.body = useFormData ? createQueryParams(Object.assign(Object.assign({}, body), {
refresh_token: refreshToken
})) : JSON.stringify(Object.assign(Object.assign({}, body), {
refresh_token: refreshToken
}));
}
let abortController;
if (typeof AbortController === "function") {
abortController = new AbortController;
fetchOptions.signal = abortController.signal;
}
let response;
try {
response = await Promise.race([ wait(timeout), fetch(fetchUrl, Object.assign({}, fetchOptions)) ]);
} catch (error) {
port.postMessage({
error: error.message
});
return;
}
if (!response) {
if (abortController) abortController.abort();
port.postMessage({
error: "Timeout when executing 'fetch'"
});
return;
}
headers = fromEntries(response.headers);
json = await response.json();
if (json.refresh_token) {
if (useMrrt) {
refreshTokens["latest_refresh_token"] = json.refresh_token;
updateRefreshTokens(refreshToken, json.refresh_token);
}
setRefreshToken(json.refresh_token, audience, scope);
delete json.refresh_token;
} else {
deleteRefreshToken(audience, scope);
}
port.postMessage({
ok: response.ok,
json: json,
headers: headers
});
} catch (error) {
port.postMessage({
ok: false,
json: {
error: error.error,
error_description: error.message
},
headers: headers
});
}
};
{
addEventListener("message", messageHandler);
}
}));
//# sourceMappingURL=auth0-spa-js.worker.development.js.map
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.worker.development.js","sources":["../src/errors.ts","../node_modules/tslib/tslib.es6.js","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('usLine truncated
@@ -0,0 +1,2 @@
!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";class e extends Error{constructor(t,r){super(r),this.error=t,this.error_description=r,Object.setPrototypeOf(this,e.prototype)}static fromPayload({error:t,error_description:r}){return new e(t,r)}}class t extends e{constructor(e,s){super("missing_refresh_token",`Missing Refresh Token (audience: '${r(e,["default"])}', scope: '${r(s)}')`),this.audience=e,this.scope=s,Object.setPrototypeOf(this,t.prototype)}}function r(e,t=[]){return e&&!t.includes(e)?e:""}"function"==typeof SuppressedError&&SuppressedError;const s=e=>{var{clientId:t}=e,r=function(e,t){var r={};for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&t.indexOf(s)<0&&(r[s]=e[s]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(s=Object.getOwnPropertySymbols(e);o<s.length;o++)t.indexOf(s[o])<0&&Object.prototype.propertyIsEnumerable.call(e,s[o])&&(r[s[o]]=e[s[o]])}return r}(e,["clientId"]);return new URLSearchParams((e=>Object.keys(e).filter((t=>void 0!==e[t])).reduce(((t,r)=>Object.assign(Object.assign({},t),{[r]:e[r]})),{}))(Object.assign({client_id:t},r))).toString()};let o={};const n=(e,t)=>`${e}|${t}`;addEventListener("message",(async({data:{timeout:e,auth:r,fetchUrl:i,fetchOptions:c,useFormData:a,useMrrt:f},ports:[p]})=>{let u,d,h={};const{audience:l,scope:y}=r||{};try{const r=a?(e=>{const t=new URLSearchParams(e),r={};return t.forEach(((e,t)=>{r[t]=e})),r})(c.body):JSON.parse(c.body);if(!r.refresh_token&&"refresh_token"===r.grant_type){if(d=((e,t)=>o[n(e,t)])(l,y),!d&&f){const e=o.latest_refresh_token,t=((e,t)=>{const r=Object.keys(o).find((r=>{if("latest_refresh_token"!==r){const s=((e,t)=>t.startsWith(`${e}|`))(t,r),o=r.split("|")[1].split(" "),n=e.split(" ").every((e=>o.includes(e)));return s&&n}}));return!!r})(y,l);e&&!t&&(d=e)}if(!d)throw new t(l,y);c.body=a?s(Object.assign(Object.assign({},r),{refresh_token:d})):JSON.stringify(Object.assign(Object.assign({},r),{refresh_token:d}))}let j,k;"function"==typeof AbortController&&(j=new AbortController,c.signal=j.signal);try{k=await Promise.race([(_=e,new Promise((e=>setTimeout(e,_)))),fetch(i,Object.assign({},c))])}catch(e){return void p.postMessage({error:e.message})}if(!k)return j&&j.abort(),void p.postMessage({error:"Timeout when executing 'fetch'"});g=k.headers,h=[...g].reduce(((e,[t,r])=>(e[t]=r,e)),{}),u=await k.json(),u.refresh_token?(f&&(o.latest_refresh_token=u.refresh_token,O=d,b=u.refresh_token,Object.entries(o).forEach((([e,t])=>{t===O&&(o[e]=b)}))),((e,t,r)=>{o[n(t,r)]=e})(u.refresh_token,l,y),delete u.refresh_token):((e,t)=>{delete o[n(e,t)]})(l,y),p.postMessage({ok:k.ok,json:u,headers:h})}catch(e){p.postMessage({ok:!1,json:{error:e.error,error_description:e.message},headers:h})}var O,b,g,_}))}));
//# sourceMappingURL=auth0-spa-js.worker.production.js.map
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.worker.production.js","sources":["../src/errors.ts","../node_modules/tslib/tslib.es6.js","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('useLine truncated
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth0-spa-js.cjs.js","sources":["../../node_modules/tslib/tslib.es6.js","../../node_modules/browser-tabs-lock/processLock.js","../../node_modules/browser-tabs-lock/index.js","../../src/version.ts","../../src/constants.ts","../../src/errors.ts","../../src/utils.ts","../../node_modules/dpop/src/index.ts","../../src/dpop/utils.ts","../../src/worker/worker.utils.ts","../../src/http.ts","../../src/api.ts","../../src/scope.ts","../../src/cache/shared.ts","../../src/cache/cache-localstorage.ts","../../src/cache/cache-memory.ts","../../src/cache/cache-manager.ts","../../src/transaction-manager.ts","../../src/jwt.ts","../../node_modules/es-cookie/src/es-cookie.js","../../src/storage.ts","../../src/global.ts","../../src/promise-utils.ts","../../src/cache/key-manifest.ts","../../src/Auth0Client.utils.ts","../../src/dpop/storage.ts","../../src/dpop/dpop.ts","../../src/fetcher.ts","../../src/MyAccountApiClient.ts","../../src/Auth0Client.ts","../../src/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n forLine truncated
+323
View File
@@ -0,0 +1,323 @@
import { Auth0ClientOptions, RedirectLoginOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, User, IdToken, GetTokenSilentlyVerboseResponse, TokenEndpointResponse, ConnectAccountRedirectResult, RedirectConnectAccountOptions } from './global';
import { CustomTokenExchangeOptions } from './TokenExchange';
import { Dpop } from './dpop/dpop';
import { Fetcher, type FetcherConfig, type CustomFetchMinimalOutput } from './fetcher';
/**
* Auth0 SDK for Single Page Applications using [Authorization Code Grant Flow with PKCE](https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce).
*/
export declare class Auth0Client {
private readonly transactionManager;
private readonly cacheManager;
private readonly domainUrl;
private readonly tokenIssuer;
private readonly scope;
private readonly cookieStorage;
private readonly dpop;
private readonly sessionCheckExpiryDays;
private readonly orgHintCookieName;
private readonly isAuthenticatedCookieName;
private readonly nowProvider;
private readonly httpTimeoutMs;
private readonly options;
private readonly userCache;
private readonly myAccountApi;
private worker?;
private readonly activeLockKeys;
private readonly defaultOptions;
constructor(options: Auth0ClientOptions);
private _url;
private _authorizeUrl;
private _verifyIdToken;
private _processOrgHint;
private _prepareAuthorizeUrl;
/**
* ```js
* try {
* await auth0.loginWithPopup(options);
* } catch(e) {
* if (e instanceof PopupCancelledError) {
* // Popup was closed before login completed
* }
* }
* ```
*
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*
* IMPORTANT: This method has to be called from an event handler
* that was started by the user like a button click, for example,
* otherwise the popup will be blocked in most browsers.
*
* @param options
* @param config
*/
loginWithPopup(options?: PopupLoginOptions, config?: PopupConfigOptions): Promise<void>;
/**
* ```js
* const user = await auth0.getUser();
* ```
*
* Returns the user information if available (decoded
* from the `id_token`).
*
* @typeparam TUser The type to return, has to extend {@link User}.
*/
getUser<TUser extends User>(): Promise<TUser | undefined>;
/**
* ```js
* const claims = await auth0.getIdTokenClaims();
* ```
*
* Returns all claims from the id_token if available.
*/
getIdTokenClaims(): Promise<IdToken | undefined>;
/**
* ```js
* await auth0.loginWithRedirect(options);
* ```
*
* Performs a redirect to `/authorize` using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated.
*
* @param options
*/
loginWithRedirect<TAppState = any>(options?: RedirectLoginOptions<TAppState>): Promise<void>;
/**
* After the browser redirects back to the callback page,
* call `handleRedirectCallback` to handle success and error
* responses from Auth0. If the response is successful, results
* will be valid according to their expiration times.
*/
handleRedirectCallback<TAppState = any>(url?: string): Promise<RedirectLoginResult<TAppState> | ConnectAccountRedirectResult<TAppState>>;
/**
* Handles the redirect callback from the login flow.
*
* @template AppState - The application state persisted from the /authorize redirect.
* @param {string} authenticationResult - The parsed authentication result from the URL.
* @param {string} transaction - The login transaction.
*
* @returns {RedirectLoginResult} Resolves with the persisted app state.
* @throws {GenericError | Error} If the transaction is missing, invalid, or the code exchange fails.
*/
private _handleLoginRedirectCallback;
/**
* Handles the redirect callback from the connect account flow.
* This works the same as the redirect from the login flow expect it verifies the `connect_code`
* with the My Account API rather than the `code` with the Authorization Server.
*
* @template AppState - The application state persisted from the connect redirect.
* @param {string} connectResult - The parsed connect accounts result from the URL.
* @param {string} transaction - The login transaction.
* @returns {Promise<ConnectAccountRedirectResult>} The result of the My Account API, including any persisted app state.
* @throws {GenericError | MyAccountApiError} If the transaction is missing, invalid, or an error is returned from the My Account API.
*/
private _handleConnectAccountRedirectCallback;
/**
* ```js
* await auth0.checkSession();
* ```
*
* Check if the user is logged in using `getTokenSilently`. The difference
* with `getTokenSilently` is that this doesn't return a token, but it will
* pre-fill the token cache.
*
* This method also heeds the `auth0.{clientId}.is.authenticated` cookie, as an optimization
* to prevent calling Auth0 unnecessarily. If the cookie is not present because
* there was no previous login (or it has expired) then tokens will not be refreshed.
*
* It should be used for silently logging in the user when you instantiate the
* `Auth0Client` constructor. You should not need this if you are using the
* `createAuth0Client` factory.
*
* **Note:** the cookie **may not** be present if running an app using a private tab, as some
* browsers clear JS cookie data and local storage when the tab or page is closed, or on page reload. This effectively
* means that `checkSession` could silently return without authenticating the user on page refresh when
* using a private tab, despite having previously logged in. As a workaround, use `getTokenSilently` instead
* and handle the possible `login_required` error [as shown in the readme](https://github.com/auth0/auth0-spa-js#creating-the-client).
*
* @param options
*/
checkSession(options?: GetTokenSilentlyOptions): Promise<void>;
/**
* Fetches a new access token and returns the response from the /oauth/token endpoint, omitting the refresh token.
*
* @param options
*/
getTokenSilently(options: GetTokenSilentlyOptions & {
detailedResponse: true;
}): Promise<GetTokenSilentlyVerboseResponse>;
/**
* Fetches a new access token and returns it.
*
* @param options
*/
getTokenSilently(options?: GetTokenSilentlyOptions): Promise<string>;
private _getTokenSilently;
/**
* ```js
* const token = await auth0.getTokenWithPopup(options);
* ```
* Opens a popup with the `/authorize` URL using the parameters
* provided as arguments. Random and secure `state` and `nonce`
* parameters will be auto-generated. If the response is successful,
* results will be valid according to their expiration times.
*
* @param options
* @param config
*/
getTokenWithPopup(options?: GetTokenWithPopupOptions, config?: PopupConfigOptions): Promise<string | undefined>;
/**
* ```js
* const isAuthenticated = await auth0.isAuthenticated();
* ```
*
* Returns `true` if there's valid information stored,
* otherwise returns `false`.
*
*/
isAuthenticated(): Promise<boolean>;
/**
* ```js
* await auth0.buildLogoutUrl(options);
* ```
*
* Builds a URL to the logout endpoint using the parameters provided as arguments.
* @param options
*/
private _buildLogoutUrl;
/**
* ```js
* await auth0.logout(options);
* ```
*
* Clears the application session and performs a redirect to `/v2/logout`, using
* the parameters provided as arguments, to clear the Auth0 session.
*
* If the `federated` option is specified it also clears the Identity Provider session.
* [Read more about how Logout works at Auth0](https://auth0.com/docs/logout).
*
* @param options
*/
logout(options?: LogoutOptions): Promise<void>;
private _getTokenFromIFrame;
private _getTokenUsingRefreshToken;
private _saveEntryInCache;
private _getIdTokenFromCache;
private _getEntryFromCache;
/**
* Releases any locks acquired by the current page that are not released yet
*
* Get's called on the `pagehide` event.
* https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event
*/
private _releaseLockOnPageHide;
private _requestToken;
/**
* Exchanges an external subject token for an Auth0 token via a token exchange request.
*
* @param {CustomTokenExchangeOptions} options - The options required to perform the token exchange.
*
* @returns {Promise<TokenEndpointResponse>} A promise that resolves to the token endpoint response,
* which contains the issued Auth0 tokens.
*
* This method implements the token exchange grant as specified in RFC 8693 by first validating
* the provided subject token type and then constructing a token request to the /oauth/token endpoint.
* The request includes the following parameters:
*
* - `grant_type`: Hard-coded to "urn:ietf:params:oauth:grant-type:token-exchange".
* - `subject_token`: The external token provided via the options.
* - `subject_token_type`: The type of the external token (validated by this function).
* - `scope`: A unique set of scopes, generated by merging the scopes supplied in the options
* with the SDK’s default scopes.
* - `audience`: The target audience from the options, with fallback to the SDK's authorization configuration.
*
* **Example Usage:**
*
* ```
* // Define the token exchange options
* const options: CustomTokenExchangeOptions = {
* subject_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp...',
* subject_token_type: 'urn:acme:legacy-system-token',
* scope: "openid profile"
* };
*
* // Exchange the external token for Auth0 tokens
* try {
* const tokenResponse = await instance.exchangeToken(options);
* // Use tokenResponse.access_token, tokenResponse.id_token, etc.
* } catch (error) {
* // Handle token exchange error
* }
* ```
*/
exchangeToken(options: CustomTokenExchangeOptions): Promise<TokenEndpointResponse>;
protected _assertDpop(dpop: Dpop | undefined): asserts dpop is Dpop;
/**
* Returns the current DPoP nonce used for making requests to Auth0.
*
* It can return `undefined` because when starting fresh it will not
* be populated until after the first response from the server.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will get the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
getDpopNonce(id?: string): Promise<string | undefined>;
/**
* Sets the current DPoP nonce used for making requests to Auth0.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*
* @param nonce The nonce value.
* @param id The identifier of a nonce: if absent, it will set the nonce
* used for requests to Auth0. Otherwise, it will be used to
* select a specific non-Auth0 nonce.
*/
setDpopNonce(nonce: string, id?: string): Promise<void>;
/**
* Returns a string to be used to demonstrate possession of the private
* key used to cryptographically bind access tokens with DPoP.
*
* It requires enabling the {@link Auth0ClientOptions.useDpop} option.
*/
generateDpopProof(params: {
url: string;
method: string;
nonce?: string;
accessToken: string;
}): Promise<string>;
/**
* Returns a new `Fetcher` class that will contain a `fetchWithAuth()` method.
* This is a drop-in replacement for the Fetch API's `fetch()` method, but will
* handle certain authentication logic for you, like building the proper auth
* headers or managing DPoP nonces and retries automatically.
*
* Check the `EXAMPLES.md` file for a deeper look into this method.
*/
createFetcher<TOutput extends CustomFetchMinimalOutput = Response>(config?: FetcherConfig<TOutput>): Fetcher<TOutput>;
/**
* Initiates a redirect to connect the user's account with a specified connection.
* This method generates PKCE parameters, creates a transaction, and redirects to the /connect endpoint.
*
* You must enable `Offline Access` from the Connection Permissions settings to be able to use the connection with Connected Accounts.
*
* @template TAppState - The application state to persist through the transaction.
* @param {RedirectConnectAccountOptions<TAppState>} options - Options for the connect account redirect flow.
* @param {string} options.connection - The name of the connection to link (e.g. 'google-oauth2').
* @param {string[]} [options.scopes] - Array of scopes to request from the Identity Provider during the connect account flow.
* @param {AuthorizationParams} [options.authorization_params] - Additional authorization parameters for the request to the upstream IdP.
* @param {string} [options.redirectUri] - The URI to redirect back to after connecting the account.
* @param {TAppState} [options.appState] - Application state to persist through the transaction.
* @param {(url: string) => Promise<void>} [options.openUrl] - Custom function to open the URL.
*
* @returns {Promise<void>} Resolves when the redirect is initiated.
* @throws {MyAccountApiError} If the connect request to the My Account API fails.
*/
connectAccountWithRedirect<TAppState = any>(options: RedirectConnectAccountOptions<TAppState>): Promise<void>;
}
+78
View File
@@ -0,0 +1,78 @@
import { ICache } from './cache';
import { Auth0ClientOptions, AuthorizationParams, AuthorizeOptions, ClientAuthorizationParams, LogoutOptions } from './global';
/**
* @ignore
*/
export declare const GET_TOKEN_SILENTLY_LOCK_KEY = "auth0.lock.getTokenSilently";
/**
* @ignore
*/
export declare const buildGetTokenSilentlyLockKey: (clientId: string, audience: string) => string;
/**
* @ignore
*/
export declare const buildOrganizationHintCookieName: (clientId: string) => string;
/**
* @ignore
*/
export declare const OLD_IS_AUTHENTICATED_COOKIE_NAME = "auth0.is.authenticated";
/**
* @ignore
*/
export declare const buildIsAuthenticatedCookieName: (clientId: string) => string;
/**
* @ignore
*/
export declare const cacheFactory: (location: string) => () => ICache;
/**
* @ignore
*/
export declare const getAuthorizeParams: (clientOptions: Auth0ClientOptions & {
authorizationParams: ClientAuthorizationParams;
}, scope: Record<string, string>, authorizationParams: AuthorizationParams & {
scope?: string | undefined;
}, state: string, nonce: string, code_challenge: string, redirect_uri: string | undefined, response_mode: string | undefined, thumbprint: string | undefined) => AuthorizeOptions;
/**
* @ignore
*
* Function used to provide support for the deprecated onRedirect through openUrl.
*/
export declare const patchOpenUrlWithOnRedirect: <T extends Pick<LogoutOptions, "openUrl" | "onRedirect">>(options: T) => T;
/**
* @ignore
*
* Checks if all scopes are included inside other array of scopes
*/
export declare const allScopesAreIncluded: (scopeToInclude?: string, scopes?: string) => boolean;
/**
* @ignore
*
* Returns the scopes that are missing after a refresh
*/
export declare const getMissingScopes: (requestedScope?: string, respondedScope?: string) => string;
/**
* @ignore
*
* For backward compatibility we are going to check if we are going to downscope while doing a refresh request
* while MRRT is allowed. If the audience is the same for the refresh_token we are going to use and it has
* lower scopes than the ones originally in the token, we are going to return the scopes that were stored
* with the refresh_token in the tokenset.
* @param useMrrt Setting that the user can activate to use MRRT in their requests
* @param authorizationParams Contains the audience and scope that the user requested to obtain a token
* @param cachedAudience Audience stored with the refresh_token wich we are going to use in the request
* @param cachedScope Scope stored with the refresh_token wich we are going to use in the request
*/
export declare const getScopeToRequest: (useMrrt: boolean | undefined, authorizationParams: {
audience?: string;
scope: string;
}, cachedAudience?: string, cachedScope?: string) => string;
/**
* @ignore
*
* Checks if the refresh request has been done using MRRT
* @param cachedAudience Audience from the refresh token used to refresh
* @param cachedScope Scopes from the refresh token used to refresh
* @param requestAudience Audience sent to the server
* @param requestScope Scopes sent to the server
*/
export declare const isRefreshWithMrrt: (cachedAudience: string | undefined, cachedScope: string | undefined, requestAudience: string | undefined, requestScope: string) => boolean;
+92
View File
@@ -0,0 +1,92 @@
import { AuthorizationParams } from './global';
import { Fetcher } from './fetcher';
interface ConnectRequest {
/** The name of the connection to link the account with (e.g., 'google-oauth2', 'facebook'). */
connection: string;
/** Array of scopes to request from the Identity Provider during the connect account flow. */
scopes?: string[];
/** The URI to redirect to after the connection process completes. */
redirect_uri: string;
/** An opaque value used to maintain state between the request and callback. */
state?: string;
/** The PKCE code challenge derived from the code verifier. */
code_challenge?: string;
/** The method used to derive the code challenge. Required when code_challenge is provided. */
code_challenge_method?: 'S256';
authorization_params?: AuthorizationParams;
}
interface ConnectResponse {
/** The base URI to initiate the account connection flow. */
connect_uri: string;
/** The authentication session identifier. */
auth_session: string;
/** Parameters to be used with the connect URI. */
connect_params: {
/** The ticket identifier to be used with the connection URI. */
ticket: string;
};
/** The number of seconds until the ticket expires. */
expires_in: number;
}
interface CompleteRequest {
/** The authentication session identifier */
auth_session: string;
/** The authorization code returned from the connect flow */
connect_code: string;
/** The redirect URI used in the original request */
redirect_uri: string;
/** The PKCE code verifier */
code_verifier?: string;
}
export interface CompleteResponse {
/** The unique identifier of the connected account */
id: string;
/** The connection name */
connection: string;
/** The access type, always 'offline' */
access_type: 'offline';
/** Array of scopes granted */
scopes?: string[];
/** ISO date string of when the connected account was created */
created_at: string;
/** ISO date string of when the refresh token expires (optional) */
expires_at?: string;
}
export interface ErrorResponse {
type: string;
status: number;
title: string;
detail: string;
validation_errors?: {
detail: string;
field?: string;
pointer?: string;
source?: string;
}[];
}
/**
* Subset of the MyAccount API that handles the connect accounts flow.
*/
export declare class MyAccountApiClient {
private myAccountFetcher;
private apiBase;
constructor(myAccountFetcher: Fetcher<Response>, apiBase: string);
/**
* Get a ticket for the connect account flow.
*/
connectAccount(params: ConnectRequest): Promise<ConnectResponse>;
/**
* Verify the redirect from the connect account flow and complete the connecting of the account.
*/
completeAccount(params: CompleteRequest): Promise<CompleteResponse>;
private _handleResponse;
}
export declare class MyAccountApiError extends Error {
readonly type: string;
readonly status: number;
readonly title: string;
readonly detail: string;
readonly validation_errors?: ErrorResponse['validation_errors'];
constructor({ type, status, title, detail, validation_errors }: ErrorResponse);
}
export {};
+71
View File
@@ -0,0 +1,71 @@
/**
* Represents the configuration options required for initiating a Custom Token Exchange request
* following RFC 8693 specifications.
*
* @see {@link https://www.rfc-editor.org/rfc/rfc8693 | RFC 8693: OAuth 2.0 Token Exchange}
*/
export type CustomTokenExchangeOptions = {
/**
* The type identifier for the subject token being exchanged
*
* @pattern
* - Must be a namespaced URI under your organization's control
* - Forbidden patterns:
* - `^urn:ietf:params:oauth:*` (IETF reserved)
* - `^https:\/\/auth0\.com/*` (Auth0 reserved)
* - `^urn:auth0:*` (Auth0 reserved)
*
* @example
* "urn:acme:legacy-system-token"
* "https://api.yourcompany.com/token-type/v1"
*/
subject_token_type: string;
/**
* The opaque token value being exchanged for Auth0 tokens
*
* @security
* - Must be validated in Auth0 Actions using strong cryptographic verification
* - Implement replay attack protection
* - Recommended validation libraries: `jose`, `jsonwebtoken`
*
* @example
* "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
*/
subject_token: string;
/**
* The target audience for the requested Auth0 token
*
* @remarks
* Must match exactly with an API identifier configured in your Auth0 tenant.
* If not provided, falls back to the client's default audience.
*
* @example
* "https://api.your-service.com/v1"
*/
audience?: string;
/**
* Space-separated list of OAuth 2.0 scopes being requested
*
* @remarks
* Subject to API authorization policies configured in Auth0
*
* @example
* "openid profile email read:data write:data"
*/
scope?: string;
/**
* Additional custom parameters for Auth0 Action processing
*
* @remarks
* Accessible in Action code via `event.request.body`
*
* @example
* ```typescript
* {
* custom_parameter: "session_context",
* device_fingerprint: "a3d8f7...",
* }
* ```
*/
[key: string]: unknown;
};
+2
View File
@@ -0,0 +1,2 @@
import { TokenEndpointOptions, TokenEndpointResponse } from './global';
export declare function oauthToken({ baseUrl, timeout, audience, scope, auth0Client, useFormData, useMrrt, dpop, ...options }: TokenEndpointOptions, worker?: Worker): Promise<TokenEndpointResponse>;
@@ -0,0 +1,7 @@
import { ICache, Cacheable, MaybePromise } from './shared';
export declare class LocalStorageCache implements ICache {
set<T = Cacheable>(key: string, entry: T): void;
get<T = Cacheable>(key: string): MaybePromise<T | undefined>;
remove(key: string): void;
allKeys(): string[];
}
+52
View File
@@ -0,0 +1,52 @@
import { CacheKeyManifest } from './key-manifest';
import { CacheEntry, ICache, CacheKey, DecodedToken, IdTokenEntry } from './shared';
export declare class CacheManager {
private cache;
private keyManifest?;
private nowProvider;
constructor(cache: ICache, keyManifest?: CacheKeyManifest | undefined, nowProvider?: () => number | Promise<number>);
setIdToken(clientId: string, idToken: string, decodedToken: DecodedToken): Promise<void>;
getIdToken(cacheKey: CacheKey): Promise<IdTokenEntry | undefined>;
get(cacheKey: CacheKey, expiryAdjustmentSeconds?: number, useMrrt?: boolean, cacheMode?: string): Promise<Partial<CacheEntry> | undefined>;
private modifiedCachedEntry;
set(entry: CacheEntry): Promise<void>;
remove(client_id: string, audience?: string, scope?: string): Promise<void>;
clear(clientId?: string): Promise<void>;
private wrapCacheEntry;
private getCacheKeys;
/**
* Returns the cache key to be used to store the id token
* @param clientId The client id used to link to the id token
* @returns The constructed cache key, as a string, to store the id token
*/
private getIdTokenCacheKey;
/**
* Finds the corresponding key in the cache based on the provided cache key.
* The keys inside the cache are in the format {prefix}::{clientId}::{audience}::{scope}.
* The first key in the cache that satisfies the following conditions is returned
* - `prefix` is strict equal to Auth0's internally configured `keyPrefix`
* - `clientId` is strict equal to the `cacheKey.clientId`
* - `audience` is strict equal to the `cacheKey.audience`
* - `scope` contains at least all the `cacheKey.scope` values
* *
* @param keyToMatch The provided cache key
* @param allKeys A list of existing cache keys
*/
private matchExistingCacheKey;
/**
* Returns the first entry that contains a refresh_token that satisfies the following conditions
* The keys inside the cache are in the format {prefix}::{clientId}::{audience}::{scope}.
* - `prefix` is strict equal to Auth0's internally configured `keyPrefix`
* - `clientId` is strict equal to the `cacheKey.clientId`
* @param keyToMatch The provided cache key
* @param allKeys A list of existing cache keys
*/
private getEntryWithRefreshToken;
/**
* Updates in the cache all entries that has a match with previous refresh_token with the
* new refresh_token obtained from the server
* @param oldRefreshToken Old refresh_token used on refresh
* @param newRefreshToken New refresh_token obtained from the server after refresh
*/
updateEntry(oldRefreshToken: string, newRefreshToken: string): Promise<void>;
}
@@ -0,0 +1,4 @@
import { ICache } from './shared';
export declare class InMemoryCache {
enclosedCache: ICache;
}
+4
View File
@@ -0,0 +1,4 @@
export * from './cache-localstorage';
export * from './cache-memory';
export * from './cache-manager';
export * from './shared';
+12
View File
@@ -0,0 +1,12 @@
import { ICache, KeyManifestEntry, MaybePromise } from './shared';
export declare class CacheKeyManifest {
private cache;
private clientId;
private readonly manifestKey;
constructor(cache: ICache, clientId: string);
add(key: string): Promise<void>;
remove(key: string): Promise<void>;
get(): MaybePromise<KeyManifestEntry | undefined>;
clear(): MaybePromise<void>;
private createManifestKeyFrom;
}
+68
View File
@@ -0,0 +1,68 @@
import { IdToken, User } from '../global';
export declare const CACHE_KEY_PREFIX = "@@auth0spajs@@";
export declare const CACHE_KEY_ID_TOKEN_SUFFIX = "@@user@@";
export type CacheKeyData = {
audience?: string;
scope?: string;
clientId: string;
};
export declare class CacheKey {
prefix: string;
suffix?: string | undefined;
clientId: string;
scope?: string;
audience?: string;
constructor(data: CacheKeyData, prefix?: string, suffix?: string | undefined);
/**
* Converts this `CacheKey` instance into a string for use in a cache
* @returns A string representation of the key
*/
toKey(): string;
/**
* Converts a cache key string into a `CacheKey` instance.
* @param key The key to convert
* @returns An instance of `CacheKey`
*/
static fromKey(key: string): CacheKey;
/**
* Utility function to build a `CacheKey` instance from a cache entry
* @param entry The entry
* @returns An instance of `CacheKey`
*/
static fromCacheEntry(entry: CacheEntry): CacheKey;
}
export interface DecodedToken {
claims: IdToken;
user: User;
}
export interface IdTokenEntry {
id_token: string;
decodedToken: DecodedToken;
}
export type CacheEntry = {
id_token?: string;
token_type?: string;
access_token: string;
expires_in: number;
decodedToken?: DecodedToken;
audience: string;
scope: string;
client_id: string;
refresh_token?: string;
oauthTokenScope?: string;
};
export type WrappedCacheEntry = {
body: Partial<CacheEntry>;
expiresAt: number;
};
export type KeyManifestEntry = {
keys: string[];
};
export type Cacheable = WrappedCacheEntry | KeyManifestEntry;
export type MaybePromise<T> = Promise<T> | T;
export interface ICache {
set<T = Cacheable>(key: string, entry: T): MaybePromise<void>;
get<T = Cacheable>(key: string): MaybePromise<T | undefined>;
remove(key: string): MaybePromise<void>;
allKeys?(): MaybePromise<string[]>;
}
+48
View File
@@ -0,0 +1,48 @@
import { PopupConfigOptions } from './global';
/**
* @ignore
*/
export declare const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
/**
* @ignore
*/
export declare const DEFAULT_POPUP_CONFIG_OPTIONS: PopupConfigOptions;
/**
* @ignore
*/
export declare const DEFAULT_SILENT_TOKEN_RETRY_COUNT = 3;
/**
* @ignore
*/
export declare const CLEANUP_IFRAME_TIMEOUT_IN_SECONDS = 2;
/**
* @ignore
*/
export declare const DEFAULT_FETCH_TIMEOUT_MS = 10000;
export declare const CACHE_LOCATION_MEMORY = "memory";
export declare const CACHE_LOCATION_LOCAL_STORAGE = "localstorage";
/**
* @ignore
*/
export declare const MISSING_REFRESH_TOKEN_ERROR_MESSAGE = "Missing Refresh Token";
/**
* @ignore
*/
export declare const INVALID_REFRESH_TOKEN_ERROR_MESSAGE = "invalid refresh token";
/**
* @ignore
*/
export declare const DEFAULT_SCOPE = "openid profile email";
/**
* @ignore
*/
export declare const DEFAULT_SESSION_CHECK_EXPIRY_DAYS = 1;
/**
* @ignore
*/
export declare const DEFAULT_AUTH0_CLIENT: {
name: string;
version: string;
};
export declare const DEFAULT_NOW_PROVIDER: () => number;
export declare const DEFAULT_AUDIENCE = "default";
+17
View File
@@ -0,0 +1,17 @@
import { DpopStorage } from './storage';
import * as dpopUtils from './utils';
export declare class Dpop {
protected readonly storage: DpopStorage;
constructor(clientId: string);
getNonce(id?: string): Promise<string | undefined>;
setNonce(nonce: string, id?: string): Promise<void>;
protected getOrGenerateKeyPair(): Promise<dpopUtils.KeyPair>;
generateProof(params: {
url: string;
method: string;
nonce?: string;
accessToken?: string;
}): Promise<string>;
calculateThumbprint(): Promise<string>;
clear(): Promise<void>;
}
+27
View File
@@ -0,0 +1,27 @@
import { type KeyPair } from './utils';
declare const TABLES: {
readonly NONCE: "nonce";
readonly KEYPAIR: "keypair";
};
type Table = (typeof TABLES)[keyof typeof TABLES];
export declare class DpopStorage {
protected readonly clientId: string;
protected dbHandle: IDBDatabase | undefined;
constructor(clientId: string);
protected getVersion(): number;
protected createDbHandle(): Promise<IDBDatabase>;
protected getDbHandle(): Promise<IDBDatabase>;
protected executeDbRequest<T = unknown>(table: string, mode: IDBTransactionMode, requestFactory: (table: IDBObjectStore) => IDBRequest<T>): Promise<T>;
protected buildKey(id?: string): string;
setNonce(nonce: string, id?: string): Promise<void>;
setKeyPair(keyPair: KeyPair): Promise<void>;
protected save(table: Table, key: IDBValidKey, obj: unknown): Promise<void>;
findNonce(id?: string): Promise<string | undefined>;
findKeyPair(): Promise<KeyPair | undefined>;
protected find<T = unknown>(table: Table, key: IDBValidKey): Promise<T | undefined>;
protected deleteBy(table: Table, predicate: (key: IDBValidKey) => boolean): Promise<void>;
protected deleteByClientId(table: Table, clientId: string): Promise<void>;
clearNonces(): Promise<void>;
clearKeyPairs(): Promise<void>;
}
export {};
+15
View File
@@ -0,0 +1,15 @@
import * as dpopLib from 'dpop';
export declare const DPOP_NONCE_HEADER = "dpop-nonce";
export type KeyPair = Readonly<dpopLib.KeyPair>;
type GenerateProofParams = {
keyPair: KeyPair;
url: string;
method: string;
nonce?: string;
accessToken?: string;
};
export declare function generateKeyPair(): Promise<KeyPair>;
export declare function calculateThumbprint(keyPair: Pick<KeyPair, 'publicKey'>): Promise<string>;
export declare function generateProof({ keyPair, url, method, nonce, accessToken }: GenerateProofParams): Promise<string>;
export declare function isGrantTypeSupported(grantType: string): boolean;
export {};
+79
View File
@@ -0,0 +1,79 @@
/**
* Thrown when network requests to the Auth server fail.
*/
export declare class GenericError extends Error {
error: string;
error_description: string;
constructor(error: string, error_description: string);
static fromPayload({ error, error_description }: {
error: string;
error_description: string;
}): GenericError;
}
/**
* Thrown when handling the redirect callback fails, will be one of Auth0's
* Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses
*/
export declare class AuthenticationError extends GenericError {
state: string;
appState: any;
constructor(error: string, error_description: string, state: string, appState?: any);
}
/**
* Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's
* Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses
*/
export declare class ConnectError extends GenericError {
connection: string;
state: string;
appState: any;
constructor(error: string, error_description: string, connection: string, state: string, appState?: any);
}
/**
* Thrown when silent auth times out (usually due to a configuration issue) or
* when network requests to the Auth server timeout.
*/
export declare class TimeoutError extends GenericError {
constructor();
}
/**
* Error thrown when the login popup times out (if the user does not complete auth)
*/
export declare class PopupTimeoutError extends TimeoutError {
popup: Window;
constructor(popup: Window);
}
export declare class PopupCancelledError extends GenericError {
popup: Window;
constructor(popup: Window);
}
/**
* Error thrown when the token exchange results in a `mfa_required` error
*/
export declare class MfaRequiredError extends GenericError {
mfa_token: string;
constructor(error: string, error_description: string, mfa_token: string);
}
/**
* Error thrown when there is no refresh token to use
*/
export declare class MissingRefreshTokenError extends GenericError {
audience: string;
scope: string;
constructor(audience: string, scope: string);
}
/**
* Error thrown when there are missing scopes after refreshing a token
*/
export declare class MissingScopesError extends GenericError {
audience: string;
scope: string;
constructor(audience: string, scope: string);
}
/**
* Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.
*/
export declare class UseDpopNonceError extends GenericError {
newDpopNonce: string | undefined;
constructor(newDpopNonce: string | undefined);
}
+54
View File
@@ -0,0 +1,54 @@
import { GetTokenSilentlyVerboseResponse } from './global';
export type ResponseHeaders = Record<string, string | null | undefined> | [string, string][] | {
get(name: string): string | null | undefined;
};
export type CustomFetchMinimalOutput = {
status: number;
headers: ResponseHeaders;
};
export type CustomFetchImpl<TOutput extends CustomFetchMinimalOutput> = (req: Request) => Promise<TOutput>;
export type AuthParams = {
scope?: string[];
audience?: string;
};
type AccessTokenFactory = (authParams?: AuthParams) => Promise<string | GetTokenSilentlyVerboseResponse>;
export type FetcherConfig<TOutput extends CustomFetchMinimalOutput> = {
getAccessToken?: AccessTokenFactory;
baseUrl?: string;
fetch?: CustomFetchImpl<TOutput>;
dpopNonceId?: string;
};
export type FetcherHooks = {
isDpopEnabled: () => boolean;
getAccessToken: AccessTokenFactory;
getDpopNonce: () => Promise<string | undefined>;
setDpopNonce: (nonce: string) => Promise<void>;
generateDpopProof: (params: {
url: string;
method: string;
nonce?: string;
accessToken: string;
}) => Promise<string>;
};
export type FetchWithAuthCallbacks<TOutput> = {
onUseDpopNonceError?(): Promise<TOutput>;
};
export declare class Fetcher<TOutput extends CustomFetchMinimalOutput> {
protected readonly config: Omit<FetcherConfig<TOutput>, 'fetch'> & Required<Pick<FetcherConfig<TOutput>, 'fetch'>>;
protected readonly hooks: FetcherHooks;
constructor(config: FetcherConfig<TOutput>, hooks: FetcherHooks);
protected isAbsoluteUrl(url: string): boolean;
protected buildUrl(baseUrl: string | undefined, url: string | undefined): string;
protected getAccessToken(authParams?: AuthParams): Promise<string | GetTokenSilentlyVerboseResponse>;
protected extractUrl(info: RequestInfo | URL): string;
protected buildBaseRequest(info: RequestInfo | URL, init: RequestInit | undefined): Request;
protected setAuthorizationHeader(request: Request, accessToken: string, tokenType?: string): void;
protected setDpopProofHeader(request: Request, accessToken: string): Promise<void>;
protected prepareRequest(request: Request, authParams?: AuthParams): Promise<void>;
protected getHeader(headers: ResponseHeaders, name: string): string;
protected hasUseDpopNonceError(response: TOutput): boolean;
protected handleResponse(response: TOutput, callbacks: FetchWithAuthCallbacks<TOutput>): Promise<TOutput>;
protected internalFetchWithAuth(info: RequestInfo | URL, init: RequestInit | undefined, callbacks: FetchWithAuthCallbacks<TOutput>, authParams?: AuthParams): Promise<TOutput>;
fetchWithAuth(info: RequestInfo | URL, init?: RequestInit, authParams?: AuthParams): Promise<TOutput>;
}
export {};
+715
View File
@@ -0,0 +1,715 @@
import { ICache } from './cache';
import type { Dpop } from './dpop/dpop';
import { CompleteResponse } from './MyAccountApiClient';
export interface AuthorizationParams {
/**
* - `'page'`: displays the UI with a full page view
* - `'popup'`: displays the UI with a popup window
* - `'touch'`: displays the UI in a way that leverages a touch interface
* - `'wap'`: displays the UI with a "feature phone" type interface
*/
display?: 'page' | 'popup' | 'touch' | 'wap';
/**
* - `'none'`: do not prompt user for login or consent on reauthentication
* - `'login'`: prompt user for reauthentication
* - `'consent'`: prompt user for consent before processing request
* - `'select_account'`: prompt user to select an account
*/
prompt?: 'none' | 'login' | 'consent' | 'select_account';
/**
* Maximum allowable elapsed time (in seconds) since authentication.
* If the last time the user authenticated is greater than this value,
* the user must be reauthenticated.
*/
max_age?: string | number;
/**
* The space-separated list of language tags, ordered by preference.
* For example: `'fr-CA fr en'`.
*/
ui_locales?: string;
/**
* Previously issued ID Token.
*/
id_token_hint?: string;
/**
* Provides a hint to Auth0 as to what flow should be displayed.
* The default behavior is to show a login page but you can override
* this by passing 'signup' to show the signup page instead.
*
* This only affects the New Universal Login Experience.
*/
screen_hint?: 'signup' | 'login' | string;
/**
* The user's email address or other identifier. When your app knows
* which user is trying to authenticate, you can provide this parameter
* to pre-fill the email box or select the right session for sign-in.
*
* This currently only affects the classic Lock experience.
*/
login_hint?: string;
acr_values?: string;
/**
* The default scope to be used on authentication requests.
*
* This defaults to `profile email` if not set. If you are setting extra scopes and require
* `profile` and `email` to be included then you must include them in the provided scope.
*
* Note: The `openid` scope is **always applied** regardless of this setting.
*/
scope?: string;
/**
* The default audience to be used for requesting API access.
*/
audience?: string;
/**
* The name of the connection configured for your application.
* If null, it will redirect to the Auth0 Login Page and show
* the Login Widget.
*/
connection?: string;
/**
* The organization to log in to.
*
* This will specify an `organization` parameter in your user's login request.
*
* - 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.
* - 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.
* To use an Organization Name you must have "Allow Organization Names in Authentication API" switched on in your Auth0 settings dashboard.
* More information is available on the [Auth0 documentation portal](https://auth0.com/docs/manage-users/organizations/configure-organizations/use-org-name-authentication-api)
*
*/
organization?: string;
/**
* The Id of an invitation to accept. This is available from the user invitation URL that is given when participating in a user invitation flow.
*/
invitation?: string;
/**
* The default URL where Auth0 will redirect your browser to with
* the authentication result. It must be whitelisted in
* the "Allowed Callback URLs" field in your Auth0 Application's
* settings. If not provided here, it should be provided in the other
* methods that provide authentication.
*/
redirect_uri?: string;
/**
* If you need to send custom parameters to the Authorization Server,
* make sure to use the original parameter name.
*/
[key: string]: any;
}
export interface ClientAuthorizationParams extends Omit<AuthorizationParams, 'scope'> {
scope?: string | Record<string, string>;
}
interface BaseLoginOptions {
/**
* URL parameters that will be sent back to the Authorization Server. This can be known parameters
* defined by Auth0 or custom parameters that you define.
*/
authorizationParams?: AuthorizationParams;
}
export interface Auth0ClientOptions {
/**
* Your Auth0 account domain such as `'example.auth0.com'`,
* `'example.eu.auth0.com'` or , `'example.mycompany.com'`
* (when using [custom domains](https://auth0.com/docs/custom-domains))
*/
domain: string;
/**
* The issuer to be used for validation of JWTs, optionally defaults to the domain above
*/
issuer?: string;
/**
* The Client ID found on your Application settings page
*/
clientId: string;
/**
* The value in seconds used to account for clock skew in JWT expirations.
* Typically, this value is no more than a minute or two at maximum.
* Defaults to 60s.
*/
leeway?: number;
/**
* The location to use when storing cache data. Valid values are `memory` or `localstorage`.
* The default setting is `memory`.
*
* Read more about [changing storage options in the Auth0 docs](https://auth0.com/docs/libraries/auth0-single-page-app-sdk#change-storage-options)
*/
cacheLocation?: CacheLocation;
/**
* Specify a custom cache implementation to use for token storage and retrieval. This setting takes precedence over `cacheLocation` if they are both specified.
*/
cache?: ICache;
/**
* If true, refresh tokens are used to fetch new access tokens from the Auth0 server. If false, the legacy technique of using a hidden iframe and the `authorization_code` grant with `prompt=none` is used.
* The default setting is `false`.
*
* **Note**: Use of refresh tokens must be enabled by an administrator on your Auth0 client application.
*/
useRefreshTokens?: boolean;
/**
* If true, fallback to the technique of using a hidden iframe and the `authorization_code` grant with `prompt=none` when unable to use refresh tokens. If false, the iframe fallback is not used and
* errors relating to a failed `refresh_token` grant should be handled appropriately. The default setting is `false`.
*
* **Note**: There might be situations where doing silent auth with a Web Message response from an iframe is not possible,
* like when you're serving your application from the file system or a custom protocol (like in a Desktop or Native app).
* In situations like this you can disable the iframe fallback and handle the failed `refresh_token` grant and prompt the user to login interactively with `loginWithRedirect` or `loginWithPopup`."
*
* E.g. Using the `file:` protocol in an Electron application does not support that legacy technique.
*
* @example
* let token: string;
* try {
* token = await auth0.getTokenSilently();
* } catch (e) {
* if (e.error === 'missing_refresh_token' || e.error === 'invalid_grant') {
* auth0.loginWithRedirect();
* }
* }
*/
useRefreshTokensFallback?: boolean;
/**
* A maximum number of seconds to wait before declaring background calls to /authorize as failed for timeout
* Defaults to 60s.
*/
authorizeTimeoutInSeconds?: number;
/**
* Specify the timeout for HTTP calls using `fetch`. The default is 10 seconds.
*/
httpTimeoutInSeconds?: number;
/**
* Internal property to send information about the client to the authorization server.
* @internal
*/
auth0Client?: {
name: string;
version: string;
env?: {
[key: string]: string;
};
};
/**
* Sets an additional cookie with no SameSite attribute to support legacy browsers
* that are not compatible with the latest SameSite changes.
* This will log a warning on modern browsers, you can disable the warning by setting
* this to false but be aware that some older useragents will not work,
* See https://www.chromium.org/updates/same-site/incompatible-clients
* Defaults to true
*/
legacySameSiteCookie?: boolean;
/**
* If `true`, the SDK will use a cookie when storing information about the auth transaction while
* the user is going through the authentication flow on the authorization server.
*
* The default is `false`, in which case the SDK will use session storage.
*
* @notes
*
* You might want to enable this if you rely on your users being able to authenticate using flows that
* may end up spanning across multiple tabs (e.g. magic links) or you cannot otherwise rely on session storage being available.
*/
useCookiesForTransactions?: boolean;
/**
* Number of days until the cookie `auth0.is.authenticated` will expire
* Defaults to 1.
*/
sessionCheckExpiryDays?: number;
/**
* The domain the cookie is accessible from. If not set, the cookie is scoped to
* the current domain, including the subdomain.
*
* Note: setting this incorrectly may cause silent authentication to stop working
* on page load.
*
*
* To keep a user logged in across multiple subdomains set this to your
* top-level domain and prefixed with a `.` (eg: `.example.com`).
*/
cookieDomain?: string;
/**
* If true, data to the token endpoint is transmitted as x-www-form-urlencoded data, if false it will be transmitted as JSON. The default setting is `true`.
*
* **Note:** Setting this to `false` may affect you if you use Auth0 Rules and are sending custom, non-primitive data. If you disable this,
* please verify that your Auth0 Rules continue to work as intended.
*/
useFormData?: boolean;
/**
* Modify the value used as the current time during the token validation.
*
* **Note**: Using this improperly can potentially compromise the token validation.
*/
nowProvider?: () => Promise<number> | number;
/**
* 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
* 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
* at `<module_path>/dist/auth0-spa-js.worker.production.js`, from the same host as your application or using the Auth0 CDN
* `https://cdn.auth0.com/js/auth0-spa-js/<version>/auth0-spa-js.worker.production.js`.
*
* **Note**: The worker is only used when `useRefreshTokens: true`, `cacheLocation: 'memory'`, and the `cache` is not custom.
*/
workerUrl?: string;
/**
* If `true`, the SDK will allow the refreshing of tokens using MRRT
*/
useMrrt?: boolean;
/**
* If `true`, DPoP (OAuth 2.0 Demonstrating Proof of Possession, RFC9449)
* will be used to cryptographically bind tokens to this specific browser
* so they can't be used from a different device in case of a leak.
*
* The default setting is `false`.
*/
useDpop?: boolean;
/**
* URL parameters that will be sent back to the Authorization Server. This can be known parameters
* defined by Auth0 or custom parameters that you define.
*/
authorizationParams?: ClientAuthorizationParams;
}
/**
* The possible locations where tokens can be stored
*/
export type CacheLocation = 'memory' | 'localstorage';
/**
* @ignore
*/
export interface AuthorizeOptions extends AuthorizationParams {
response_type: string;
response_mode: string;
redirect_uri?: string;
nonce: string;
state: string;
scope: string;
code_challenge: string;
code_challenge_method: string;
}
export interface RedirectLoginOptions<TAppState = any> extends BaseLoginOptions {
/**
* Used to store state before doing the redirect
*/
appState?: TAppState;
/**
* Used to add to the URL fragment before redirecting
*/
fragment?: string;
/**
* Used to control the redirect and not rely on the SDK to do the actual redirect.
*
* @example
* const client = new Auth0Client({
* async onRedirect(url) {
* window.location.replace(url);
* }
* });
* @deprecated since v2.0.1, use `openUrl` instead.
*/
onRedirect?: (url: string) => Promise<void>;
/**
* Used to control the redirect and not rely on the SDK to do the actual redirect.
*
* @example
* const client = new Auth0Client({
* openUrl(url) {
* window.location.replace(url);
* }
* });
*
* @example
* import { Browser } from '@capacitor/browser';
*
* const client = new Auth0Client({
* async openUrl(url) {
* await Browser.open({ url });
* }
* });
*/
openUrl?: (url: string) => Promise<void> | void;
}
/**
* The types of responses expected from the authorization server.
* - `code`: used for the standard login flow.
* - `connect_code`: used for the connect account flow.
*/
export declare enum ResponseType {
Code = "code",
ConnectCode = "connect_code"
}
export interface RedirectLoginResult<TAppState = any> {
/**
* State stored when the redirect request was made
*/
appState?: TAppState;
/**
* The type of response, for login it will be `code`
*/
response_type: ResponseType.Code;
}
export interface PopupLoginOptions extends BaseLoginOptions {
}
export interface PopupConfigOptions {
/**
* The number of seconds to wait for a popup response before
* throwing a timeout error. Defaults to 60s
*/
timeoutInSeconds?: number;
/**
* Accepts an already-created popup window to use. If not specified, the SDK
* will create its own. This may be useful for platforms like iOS that have
* security restrictions around when popups can be invoked (e.g. from a user click event)
*/
popup?: any;
}
export interface GetTokenSilentlyOptions {
/**
* When `off`, ignores the cache and always sends a
* request to Auth0.
* When `cache-only`, only reads from the cache and never sends a request to Auth0.
* Defaults to `on`, where it both reads from the cache and sends a request to Auth0 as needed.
*/
cacheMode?: 'on' | 'off' | 'cache-only';
/**
* Parameters that will be sent back to Auth0 as part of a request.
*/
authorizationParams?: {
/**
* There's no actual redirect when getting a token silently,
* but, according to the spec, a `redirect_uri` param is required.
* Auth0 uses this parameter to validate that the current `origin`
* matches the `redirect_uri` `origin` when sending the response.
* It must be whitelisted in the "Allowed Web Origins" in your
* Auth0 Application's settings.
*/
redirect_uri?: string;
/**
* The scope that was used in the authentication request
*/
scope?: string;
/**
* The audience that was used in the authentication request
*/
audience?: string;
/**
* If you need to send custom parameters to the Authorization Server,
* make sure to use the original parameter name.
*/
[key: string]: any;
};
/** A maximum number of seconds to wait before declaring the background /authorize call as failed for timeout
* Defaults to 60s.
*/
timeoutInSeconds?: number;
/**
* If true, the full response from the /oauth/token endpoint (or the cache, if the cache was used) is returned
* (minus `refresh_token` if one was issued). Otherwise, just the access token is returned.
*
* The default is `false`.
*/
detailedResponse?: boolean;
}
export interface GetTokenWithPopupOptions extends PopupLoginOptions {
/**
* When `off`, ignores the cache and always sends a request to Auth0.
* When `cache-only`, only reads from the cache and never sends a request to Auth0.
* Defaults to `on`, where it both reads from the cache and sends a request to Auth0 as needed.
*/
cacheMode?: 'on' | 'off' | 'cache-only';
}
export interface LogoutUrlOptions {
/**
* The `clientId` of your application.
*
* If this property is not set, then the `clientId` that was used during initialization of the SDK is sent to the logout endpoint.
*
* If this property is set to `null`, then no client ID value is sent to the logout endpoint.
*
* [Read more about how redirecting after logout works](https://auth0.com/docs/logout/guides/redirect-users-after-logout)
*/
clientId?: string | null;
/**
* Parameters to pass to the logout endpoint. This can be known parameters defined by Auth0 or custom parameters
* you wish to provide.
*/
logoutParams?: {
/**
* When supported by the upstream identity provider,
* forces the user to logout of their identity provider
* and from Auth0.
* [Read more about how federated logout works at Auth0](https://auth0.com/docs/logout/guides/logout-idps)
*/
federated?: boolean;
/**
* The URL where Auth0 will redirect your browser to after the logout.
*
* **Note**: If the `client_id` parameter is included, the
* `returnTo` URL that is provided must be listed in the
* Application's "Allowed Logout URLs" in the Auth0 dashboard.
* However, if the `client_id` parameter is not included, the
* `returnTo` URL must be listed in the "Allowed Logout URLs" at
* the account level in the Auth0 dashboard.
*
* [Read more about how redirecting after logout works](https://auth0.com/docs/logout/guides/redirect-users-after-logout)
*/
returnTo?: string;
/**
* If you need to send custom parameters to the logout endpoint, make sure to use the original parameter name.
*/
[key: string]: any;
};
}
export interface LogoutOptions extends LogoutUrlOptions {
/**
* Used to control the redirect and not rely on the SDK to do the actual redirect.
*
* @example
* await auth0.logout({
* async onRedirect(url) {
* window.location.replace(url);
* }
* });
* @deprecated since v2.0.1, use `openUrl` instead.
*/
onRedirect?: (url: string) => Promise<void>;
/**
* Used to control the redirect and not rely on the SDK to do the actual redirect.
*
* Set to `false` to disable the redirect, or provide a function to handle the actual redirect yourself.
*
* @example
* await auth0.logout({
* openUrl(url) {
* window.location.replace(url);
* }
* });
*
* @example
* import { Browser } from '@capacitor/browser';
*
* await auth0.logout({
* async openUrl(url) {
* await Browser.open({ url });
* }
* });
*/
openUrl?: false | ((url: string) => Promise<void> | void);
}
export interface RedirectConnectAccountOptions<TAppState = any> {
/**
* The name of the connection to link (e.g. 'google-oauth2').
*/
connection: string;
/**
* Array of scopes to request from the Identity Provider during the connect account flow.
*
* @example
* await auth0.connectAccountWithRedirect({
* connection: 'google-oauth2',
* scopes: ['https://www.googleapis.com/auth/calendar']
* });
*/
scopes?: string[];
/**
* Additional authorization parameters for the request.
*
* @example
* await auth0.connectAccountWithRedirect({
* connection: 'github',
* authorization_params: {
* audience: 'https://api.github.com'
* }
* });
*/
authorization_params?: AuthorizationParams;
/**
* The URI to redirect back to after connecting the account.
*/
redirectUri?: string;
/**
* Optional application state to persist through the transaction.
*
* @example
* await auth0.connectAccountWithRedirect({
* connection: 'google-oauth2',
* appState: { returnTo: '/settings' }
* });
*/
appState?: TAppState;
/**
* Optional function to handle the redirect URL.
*
* @example
* await auth0.connectAccountWithRedirect({
* connection: 'google-oauth2',
* openUrl: async (url) => { myBrowserApi.open(url); }
* });
*/
openUrl?: (url: string) => Promise<void>;
}
/**
* The result returned after a successful account connection redirect.
*
* Combines the redirect login result (including any persisted app state)
* with the complete response from the My Account API.
*
* @template TAppState - The type of application state persisted through the transaction.
* @example
* const result = await auth0.connectAccountWithRedirect(options);
* console.log(result.appState); // Access persisted app state
* console.log(result.connection); // The connection of the account you connected to.
* console.log(result.response_type === 'connect_code'); // The response type will be 'connect_code'
*/
export type ConnectAccountRedirectResult<TAppState = any> = CompleteResponse & {
/**
* State stored when the redirect request was made
*/
appState?: TAppState;
/**
* The type of response, for connect account it will be `connect_code`
*/
response_type: ResponseType.ConnectCode;
};
/**
* @ignore
*/
export interface AuthenticationResult {
state: string;
code?: string;
/**
* This is for the redirect from the connect account flow.
*/
connect_code?: string;
error?: string;
error_description?: string;
}
/**
* @ignore
*/
export interface TokenEndpointOptions {
baseUrl: string;
client_id: string;
grant_type: string;
timeout?: number;
auth0Client: any;
useFormData?: boolean;
dpop?: Pick<Dpop, 'generateProof' | 'getNonce' | 'setNonce'>;
[key: string]: any;
}
export type TokenEndpointResponse = {
id_token: string;
token_type: string;
access_token: string;
refresh_token?: string;
expires_in: number;
scope?: string;
};
/**
* @ignore
*/
export interface OAuthTokenOptions extends TokenEndpointOptions {
code_verifier: string;
code: string;
redirect_uri: string;
audience: string;
scope: string;
}
/**
* @ignore
*/
export interface RefreshTokenOptions extends TokenEndpointOptions {
refresh_token: string;
}
/**
* @ignore
*/
export interface JWTVerifyOptions {
iss: string;
aud: string;
id_token: string;
nonce?: string;
leeway?: number;
max_age?: number;
organization?: string;
now?: number;
}
export interface IdToken {
__raw: string;
name?: string;
given_name?: string;
family_name?: string;
middle_name?: string;
nickname?: string;
preferred_username?: string;
profile?: string;
picture?: string;
website?: string;
email?: string;
email_verified?: boolean;
gender?: string;
birthdate?: string;
zoneinfo?: string;
locale?: string;
phone_number?: string;
phone_number_verified?: boolean;
address?: string;
updated_at?: string;
iss?: string;
aud?: string;
exp?: number;
nbf?: number;
iat?: number;
jti?: string;
azp?: string;
nonce?: string;
auth_time?: string;
at_hash?: string;
c_hash?: string;
acr?: string;
amr?: string[];
sub_jwk?: string;
cnf?: string;
sid?: string;
org_id?: string;
org_name?: string;
[key: string]: any;
}
export declare class User {
name?: string;
given_name?: string;
family_name?: string;
middle_name?: string;
nickname?: string;
preferred_username?: string;
profile?: string;
picture?: string;
website?: string;
email?: string;
email_verified?: boolean;
gender?: string;
birthdate?: string;
zoneinfo?: string;
locale?: string;
phone_number?: string;
phone_number_verified?: boolean;
address?: string;
updated_at?: string;
sub?: string;
[key: string]: any;
}
/**
* @ignore
*/
export type FetchOptions = {
method?: string;
headers?: Record<string, string>;
credentials?: 'include' | 'omit';
body?: string;
signal?: AbortSignal;
};
/**
* @ignore
*/
export type FetchResponse = {
ok: boolean;
headers: Record<string, string | undefined>;
json: any;
};
export type GetTokenSilentlyVerboseResponse = Omit<TokenEndpointResponse, 'refresh_token'>;
export {};
+5
View File
@@ -0,0 +1,5 @@
import { FetchOptions } from './global';
import { Dpop } from './dpop/dpop';
export declare const createAbortController: () => AbortController;
export declare const switchFetch: (fetchUrl: string, audience: string, scope: string, fetchOptions: FetchOptions, worker?: Worker, useFormData?: boolean, timeout?: number, useMrrt?: boolean) => Promise<any>;
export declare function getJSON<T>(url: string, timeout: number | undefined, audience: string, scope: string, options: FetchOptions, worker?: Worker, useFormData?: boolean, useMrrt?: boolean, dpop?: Pick<Dpop, 'generateProof' | 'getNonce' | 'setNonce'>, isDpopRetry?: boolean): Promise<T>;
+20
View File
@@ -0,0 +1,20 @@
import { Auth0Client } from './Auth0Client';
import { Auth0ClientOptions } from './global';
import './global';
export * from './global';
/**
* Asynchronously creates the Auth0Client instance and calls `checkSession`.
*
* **Note:** There are caveats to using this in a private browser tab, which may not silently authenticae
* a user on page refresh. Please see [the checkSession docs](https://auth0.github.io/auth0-spa-js/classes/Auth0Client.html#checksession) for more info.
*
* @param options The client options
* @returns An instance of Auth0Client
*/
export declare function createAuth0Client(options: Auth0ClientOptions): Promise<Auth0Client>;
export { Auth0Client };
export { ConnectError, GenericError, AuthenticationError, TimeoutError, PopupTimeoutError, PopupCancelledError, MfaRequiredError, MissingRefreshTokenError, UseDpopNonceError } from './errors';
export { ICache, LocalStorageCache, InMemoryCache, Cacheable, DecodedToken, CacheEntry, WrappedCacheEntry, KeyManifestEntry, MaybePromise, CacheKey, CacheKeyData } from './cache';
export { type FetcherConfig } from './fetcher';
export { MyAccountApiError } from './MyAccountApiClient';
export { CustomTokenExchangeOptions } from './TokenExchange';
+21
View File
@@ -0,0 +1,21 @@
import { IdToken, JWTVerifyOptions } from './global';
export declare const decode: (token: string) => {
encoded: {
header: string;
payload: string;
signature: string;
};
header: any;
claims: IdToken;
user: any;
};
export declare const verify: (options: JWTVerifyOptions) => {
encoded: {
header: string;
payload: string;
signature: string;
};
header: any;
claims: IdToken;
user: any;
};
+2
View File
@@ -0,0 +1,2 @@
export declare const singlePromise: <T>(cb: () => Promise<T>, key: string) => Promise<T>;
export declare const retryPromise: (cb: () => Promise<boolean>, maxNumberOfRetries?: number) => Promise<boolean>;
+35
View File
@@ -0,0 +1,35 @@
/**
* @ignore
*/
/**
* Returns a string of unique scopes by removing duplicates and unnecessary whitespace.
*
* @param {...(string | undefined)[]} scopes - A list of scope strings or undefined values.
* @returns {string} A string containing unique scopes separated by a single space.
*/
export declare const getUniqueScopes: (...scopes: (string | undefined)[]) => string;
/**
* @ignore
*/
/**
* We will check if the developer has created the client with a string or object of audience:scopes. We will inject
* the base scopes to each audience, and store the base ones inside default key. As well, if the developer created the Auth0Client
* with a string of scopes, we will store the requested ones with the base scopes inside the default key as well.
* @param authScopes The scopes requested by the user when creating the Auth0Client
* @param openIdScope openId scope
* @param extraScopes Other scopes to accumulate such as offline_access
* @returns {Record<string, string>} An object with all scopes that are going to be accumulated.
*/
export declare const injectDefaultScopes: (authScopes: string | Record<string, string> | undefined, openIdScope: string, ...extraScopes: string[]) => Record<string, string>;
/**
* @ignore
*/
/**
* Will return a string of scopes. If a specific audience was requested and it exist inside the scopes object, we will return those
* related to that audience that we want to accumulate. If not, we will return the ones stored inside the default key.
* @param authScopes Object of audience:scopes that are going to be accumulated
* @param methodScopes The scopes requested for the developer in a specific request
* @param audience The audience the developer requested for an specific request or the one they configured in the Auth0Client
* @returns {string} A combination of Auth0Client scopes and the ones requested by the developer for a specific request
*/
export declare const scopesToRequest: (authScopes: Record<string, string>, methodScopes: string | undefined, audience: string | undefined) => string;
+26
View File
@@ -0,0 +1,26 @@
interface ClientStorageOptions {
daysUntilExpire?: number;
cookieDomain?: string;
}
/**
* Defines a type that handles storage to/from a storage location
*/
export type ClientStorage = {
get<T extends Object>(key: string): T | undefined;
save(key: string, value: any, options?: ClientStorageOptions): void;
remove(key: string, options?: ClientStorageOptions): void;
};
/**
* A storage protocol for marshalling data to/from cookies
*/
export declare const CookieStorage: ClientStorage;
/**
* Cookie storage that creates a cookie for modern and legacy browsers.
* See: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
*/
export declare const CookieStorageWithLegacySameSite: ClientStorage;
/**
* A storage protocol for marshalling data to/from session storage
*/
export declare const SessionStorage: ClientStorage;
export {};
+33
View File
@@ -0,0 +1,33 @@
import { ClientStorage } from './storage';
export interface LoginTransaction {
nonce: string;
scope: string;
audience: string;
appState?: any;
code_verifier: string;
redirect_uri?: string;
organization?: string;
state?: string;
response_type: 'code';
}
export interface ConnectAccountTransaction {
appState?: any;
audience?: string;
auth_session: string;
code_verifier: string;
redirect_uri: string;
scope?: string;
state: string;
connection: string;
response_type: 'connect_code';
}
export declare class TransactionManager {
private storage;
private clientId;
private cookieDomain?;
private storageKey;
constructor(storage: ClientStorage, clientId: string, cookieDomain?: string | undefined);
create<T extends Object = LoginTransaction>(transaction: T): void;
get<T extends Object = LoginTransaction>(): T | undefined;
remove(): void;
}
+35
View File
@@ -0,0 +1,35 @@
import { AuthenticationResult, PopupConfigOptions } from './global';
export declare const parseAuthenticationResult: (queryString: string) => AuthenticationResult;
export declare const runIframe: (authorizeUrl: string, eventOrigin: string, timeoutInSeconds?: number) => Promise<AuthenticationResult>;
export declare const openPopup: (url: string) => Window | null;
export declare const runPopup: (config: PopupConfigOptions) => Promise<AuthenticationResult>;
export declare const getCrypto: () => Crypto;
export declare const createRandomString: () => string;
export declare const encode: (value: string) => string;
export declare const decode: (value: string) => string;
/**
* Strips any property that is not present in ALLOWED_AUTH0CLIENT_PROPERTIES
* @param auth0Client - The full auth0Client object
* @returns The stripped auth0Client object
*/
export declare const stripAuth0Client: (auth0Client: any) => any;
export declare const createQueryParams: ({ clientId: client_id, ...params }: any) => string;
export declare const sha256: (s: string) => Promise<any>;
export declare const urlDecodeB64: (input: string) => string;
export declare const bufferToBase64UrlEncoded: (input: number[] | Uint8Array) => string;
export declare const validateCrypto: () => void;
/**
* @ignore
*/
export declare const getDomain: (domainUrl: string) => string;
/**
* @ignore
*/
export declare const getTokenIssuer: (issuer: string | undefined, domainUrl: string) => string;
export declare const parseNumber: (value: any) => number | undefined;
/**
* Ponyfill for `Object.fromEntries()`, which is not available until ES2020.
*
* When the target of this project reaches ES2020, this can be removed.
*/
export declare const fromEntries: <T = any>(iterable: Iterable<[PropertyKey, T]>) => Record<PropertyKey, T>;
+2
View File
@@ -0,0 +1,2 @@
declare const _default: "2.9.1";
export default _default;
@@ -0,0 +1 @@
export {};
+15
View File
@@ -0,0 +1,15 @@
import { FetchOptions } from '../global';
/**
* @ts-ignore
*/
export type WorkerRefreshTokenMessage = {
timeout: number;
fetchUrl: string;
fetchOptions: FetchOptions;
useFormData?: boolean;
useMrrt?: boolean;
auth: {
audience: string;
scope: string;
};
};
@@ -0,0 +1,7 @@
import { WorkerRefreshTokenMessage } from './worker.types';
/**
* Sends the specified message to the web worker
* @param message The message to send
* @param to The worker to send the message to
*/
export declare const sendMessage: (message: WorkerRefreshTokenMessage, to: Worker) => Promise<unknown>;
+126
View File
@@ -0,0 +1,126 @@
{
"author": "Auth0",
"name": "@auth0/auth0-spa-js",
"description": "Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE",
"license": "MIT",
"version": "2.9.1",
"main": "dist/lib/auth0-spa-js.cjs.js",
"types": "dist/typings/index.d.ts",
"module": "dist/auth0-spa-js.production.esm.js",
"ccu": {
"name": "auth0-spa-js",
"cdn": "https://cdn.auth0.com",
"bucket": "assets.us.auth0.com",
"localPath": "dist",
"mainBundleFile": "auth0-spa-js.production.js",
"digest": {
"hashes": [
"sha384"
],
"extensions": [
".js"
]
}
},
"dependencies": {
"browser-tabs-lock": "^1.2.15",
"dpop": "^2.1.1",
"es-cookie": "~1.3.2"
},
"scripts": {
"dev": "rimraf dist && rollup -c --watch",
"start": "npm run dev",
"docs": "typedoc --options ./typedoc.js src",
"build": "rimraf dist && rollup -m -c --environment NODE_ENV:production && npm run test:es-check",
"build:stats": "rimraf dist && rollup -m -c --environment NODE_ENV:production --environment WITH_STATS:true && npm run test:es-check && open bundle-stats/index.html",
"lint": "eslint --ext .jsx,.js src/",
"lint:security": "eslint ./src --ext ts --no-eslintrc --config ./.eslintrc.security",
"test": "jest --coverage --silent",
"test:watch": "jest --coverage --watch",
"test:debug": "node --inspect node_modules/.bin/jest --runInBand",
"test:open:integration": "cypress open",
"test:watch:integration": "concurrently --raw npm:dev 'npm:test:open:integration'",
"test:es-check": "npm run test:es-check:es2017 && npm run test:es-check:es2017:module",
"test:es-check:es2017": "es-check es2017 'dist/auth0-spa-js.production.js'",
"test:es-check:es2017:module": "es-check es2017 'dist/auth0-spa-js.production.esm.js' --module ",
"test:integration:server": "npm run dev",
"test:integration:tests": "wait-on http://localhost:3000/ && cypress run",
"test:integration": "concurrently --raw --kill-others --success first npm:test:integration:server npm:test:integration:tests",
"serve:coverage": "serve coverage/lcov-report -n",
"serve:stats": "serve bundle-stats -n",
"print-bundle-size": "node ./scripts/print-bundle-size.mjs",
"prepack": "npm run build && node ./scripts/prepack",
"publish:cdn": "ccu --trace"
},
"devDependencies": {
"@auth0/component-cdn-uploader": "^2.4.0",
"@rollup/plugin-replace": "^4.0.0",
"@types/cypress": "^1.1.3",
"@types/jest": "^28.1.7",
"@typescript-eslint/eslint-plugin-tslint": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"browserstack-cypress-cli": "1.32.8",
"cli-table": "^0.3.6",
"concurrently": "^7.3.0",
"cypress": "13.17.0",
"es-check": "^7.0.1",
"eslint": "^8.22.0",
"eslint-plugin-security": "^1.5.0",
"fake-indexeddb": "^6.0.1",
"gzip-size": "^7.0.0",
"husky": "^7.0.4",
"idtoken-verifier": "^2.2.2",
"jest": "^28.1.3",
"jest-environment-jsdom": "^28.1.3",
"jest-fetch-mock": "^3.0.3",
"jest-junit": "^14.0.0",
"jest-localstorage-mock": "^2.4.22",
"jsonwebtoken": "^9.0.0",
"oidc-provider": "^7.14.0",
"prettier": "^2.7.1",
"pretty-quick": "^3.1.2",
"rimraf": "^3.0.2",
"rollup": "^2.78.0",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-dev": "^1.1.3",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.36.0",
"rollup-plugin-visualizer": "^5.7.1",
"rollup-plugin-web-worker-loader": "^1.6.1",
"serve": "^14.0.1",
"ts-jest": "^28.0.8",
"tslib": "^2.4.0",
"typedoc": "^0.25.1",
"typescript": "^4.7.4",
"wait-on": "^7.2.0"
},
"files": [
"src",
"dist"
],
"repository": {
"type": "git",
"url": "git://github.com/auth0/auth0-spa-js.git"
},
"bugs": {
"url": "https://github.com/auth0/auth0-spa-js/issues"
},
"homepage": "https://github.com/auth0/auth0-spa-js#readme",
"keywords": [
"auth0",
"login",
"Authorization Code Grant Flow",
"PKCE",
"Single Page Application authentication",
"SPA authentication"
],
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
}
}
File diff suppressed because it is too large. Load diff
+187
View File
@@ -0,0 +1,187 @@
import { ICache, InMemoryCache, LocalStorageCache } from './cache';
import {
Auth0ClientOptions,
AuthorizationParams,
AuthorizeOptions,
ClientAuthorizationParams,
LogoutOptions
} from './global';
import { scopesToRequest } from './scope';
/**
* @ignore
*/
export const GET_TOKEN_SILENTLY_LOCK_KEY = 'auth0.lock.getTokenSilently';
/**
* @ignore
*/
export const buildGetTokenSilentlyLockKey = (
clientId: string,
audience: string
) => `${GET_TOKEN_SILENTLY_LOCK_KEY}.${clientId}.${audience}`;
/**
* @ignore
*/
export const buildOrganizationHintCookieName = (clientId: string) =>
`auth0.${clientId}.organization_hint`;
/**
* @ignore
*/
export const OLD_IS_AUTHENTICATED_COOKIE_NAME = 'auth0.is.authenticated';
/**
* @ignore
*/
export const buildIsAuthenticatedCookieName = (clientId: string) =>
`auth0.${clientId}.is.authenticated`;
/**
* @ignore
*/
const cacheLocationBuilders: Record<string, () => ICache> = {
memory: () => new InMemoryCache().enclosedCache,
localstorage: () => new LocalStorageCache()
};
/**
* @ignore
*/
export const cacheFactory = (location: string) => {
return cacheLocationBuilders[location];
};
/**
* @ignore
*/
export const getAuthorizeParams = (
clientOptions: Auth0ClientOptions & {
authorizationParams: ClientAuthorizationParams;
},
scope: Record<string, string>,
authorizationParams: AuthorizationParams & { scope?: string },
state: string,
nonce: string,
code_challenge: string,
redirect_uri: string | undefined,
response_mode: string | undefined,
thumbprint: string | undefined
): AuthorizeOptions => {
return {
client_id: clientOptions.clientId,
...clientOptions.authorizationParams,
...authorizationParams,
scope: scopesToRequest(scope, authorizationParams.scope, authorizationParams.audience),
response_type: 'code',
response_mode: response_mode || 'query',
state,
nonce,
redirect_uri:
redirect_uri || clientOptions.authorizationParams.redirect_uri,
code_challenge,
code_challenge_method: 'S256',
dpop_jkt: thumbprint
};
};
/**
* @ignore
*
* Function used to provide support for the deprecated onRedirect through openUrl.
*/
export const patchOpenUrlWithOnRedirect = <
T extends Pick<LogoutOptions, 'openUrl' | 'onRedirect'>
>(
options: T
) => {
const { openUrl, onRedirect, ...originalOptions } = options;
const result = {
...originalOptions,
openUrl: openUrl === false || openUrl ? openUrl : onRedirect
};
return result as T;
};
/**
* @ignore
*
* Checks if all scopes are included inside other array of scopes
*/
export const allScopesAreIncluded = (scopeToInclude?: string, scopes?: string): boolean => {
const scopeGroup = scopes?.split(" ") || [];
const scopesToInclude = scopeToInclude?.split(" ") || [];
return scopesToInclude.every((key) => scopeGroup.includes(key));
}
/**
* @ignore
*
* Returns the scopes that are missing after a refresh
*/
export const getMissingScopes = (requestedScope?: string, respondedScope?: string): string => {
const requestedScopes = requestedScope?.split(" ") || [];
const respondedScopes = respondedScope?.split(" ") || [];
const missingScopes = requestedScopes.filter((scope) => respondedScopes.indexOf(scope) == -1);
return missingScopes.join(",");
}
/**
* @ignore
*
* For backward compatibility we are going to check if we are going to downscope while doing a refresh request
* while MRRT is allowed. If the audience is the same for the refresh_token we are going to use and it has
* lower scopes than the ones originally in the token, we are going to return the scopes that were stored
* with the refresh_token in the tokenset.
* @param useMrrt Setting that the user can activate to use MRRT in their requests
* @param authorizationParams Contains the audience and scope that the user requested to obtain a token
* @param cachedAudience Audience stored with the refresh_token wich we are going to use in the request
* @param cachedScope Scope stored with the refresh_token wich we are going to use in the request
*/
export const getScopeToRequest = (
useMrrt: boolean | undefined,
authorizationParams: { audience?: string, scope: string },
cachedAudience?: string,
cachedScope?: string
): string => {
if (useMrrt && cachedAudience && cachedScope) {
if (authorizationParams.audience !== cachedAudience) {
return authorizationParams.scope;
}
const cachedScopes = cachedScope.split(" ");
const newScopes = authorizationParams.scope?.split(" ") || [];
const newScopesAreIncluded = newScopes.every((scope) => cachedScopes.includes(scope));
return cachedScopes.length >= newScopes.length && newScopesAreIncluded ? cachedScope : authorizationParams.scope;
}
return authorizationParams.scope;
}
/**
* @ignore
*
* Checks if the refresh request has been done using MRRT
* @param cachedAudience Audience from the refresh token used to refresh
* @param cachedScope Scopes from the refresh token used to refresh
* @param requestAudience Audience sent to the server
* @param requestScope Scopes sent to the server
*/
export const isRefreshWithMrrt = (
cachedAudience: string | undefined,
cachedScope: string | undefined,
requestAudience: string | undefined,
requestScope: string,
): boolean => {
if (cachedAudience !== requestAudience) {
return true;
}
return !allScopesAreIncluded(requestScope, cachedScope);
}
+158
View File
@@ -0,0 +1,158 @@
import { AuthorizationParams } from './global';
import { Fetcher } from './fetcher';
interface ConnectRequest {
/** The name of the connection to link the account with (e.g., 'google-oauth2', 'facebook'). */
connection: string;
/** Array of scopes to request from the Identity Provider during the connect account flow. */
scopes?: string[];
/** The URI to redirect to after the connection process completes. */
redirect_uri: string;
/** An opaque value used to maintain state between the request and callback. */
state?: string;
/** The PKCE code challenge derived from the code verifier. */
code_challenge?: string;
/** The method used to derive the code challenge. Required when code_challenge is provided. */
code_challenge_method?: 'S256';
authorization_params?: AuthorizationParams;
}
interface ConnectResponse {
/** The base URI to initiate the account connection flow. */
connect_uri: string;
/** The authentication session identifier. */
auth_session: string;
/** Parameters to be used with the connect URI. */
connect_params: {
/** The ticket identifier to be used with the connection URI. */
ticket: string;
};
/** The number of seconds until the ticket expires. */
expires_in: number;
}
interface CompleteRequest {
/** The authentication session identifier */
auth_session: string;
/** The authorization code returned from the connect flow */
connect_code: string;
/** The redirect URI used in the original request */
redirect_uri: string;
/** The PKCE code verifier */
code_verifier?: string;
}
export interface CompleteResponse {
/** The unique identifier of the connected account */
id: string;
/** The connection name */
connection: string;
/** The access type, always 'offline' */
access_type: 'offline';
/** Array of scopes granted */
scopes?: string[];
/** ISO date string of when the connected account was created */
created_at: string;
/** ISO date string of when the refresh token expires (optional) */
expires_at?: string;
}
// Validation error returned from MyAccount API
export interface ErrorResponse {
type: string;
status: number;
title: string;
detail: string;
validation_errors?: {
detail: string;
field?: string;
pointer?: string;
source?: string;
}[];
}
/**
* Subset of the MyAccount API that handles the connect accounts flow.
*/
export class MyAccountApiClient {
constructor(
private myAccountFetcher: Fetcher<Response>,
private apiBase: string
) {}
/**
* Get a ticket for the connect account flow.
*/
async connectAccount(params: ConnectRequest): Promise<ConnectResponse> {
const res = await this.myAccountFetcher.fetchWithAuth(
`${this.apiBase}v1/connected-accounts/connect`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
}
);
return this._handleResponse(res);
}
/**
* Verify the redirect from the connect account flow and complete the connecting of the account.
*/
async completeAccount(params: CompleteRequest): Promise<CompleteResponse> {
const res = await this.myAccountFetcher.fetchWithAuth(
`${this.apiBase}v1/connected-accounts/complete`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
}
);
return this._handleResponse(res);
}
private async _handleResponse(res: Response) {
let body: any;
try {
body = await res.text();
body = JSON.parse(body);
} catch (err) {
throw new MyAccountApiError({
type: 'invalid_json',
status: res.status,
title: 'Invalid JSON response',
detail: body || String(err)
});
}
if (res.ok) {
return body;
} else {
throw new MyAccountApiError(body);
}
}
}
export class MyAccountApiError extends Error {
public readonly type: string;
public readonly status: number;
public readonly title: string;
public readonly detail: string;
public readonly validation_errors?: ErrorResponse['validation_errors'];
constructor({
type,
status,
title,
detail,
validation_errors
}: ErrorResponse) {
super(detail);
this.name = 'MyAccountApiError';
this.type = type;
this.status = status;
this.title = title;
this.detail = detail;
this.validation_errors = validation_errors;
Object.setPrototypeOf(this, MyAccountApiError.prototype);
}
}
+75
View File
@@ -0,0 +1,75 @@
/**
* Represents the configuration options required for initiating a Custom Token Exchange request
* following RFC 8693 specifications.
*
* @see {@link https://www.rfc-editor.org/rfc/rfc8693 | RFC 8693: OAuth 2.0 Token Exchange}
*/
export type CustomTokenExchangeOptions = {
/**
* The type identifier for the subject token being exchanged
*
* @pattern
* - Must be a namespaced URI under your organization's control
* - Forbidden patterns:
* - `^urn:ietf:params:oauth:*` (IETF reserved)
* - `^https:\/\/auth0\.com/*` (Auth0 reserved)
* - `^urn:auth0:*` (Auth0 reserved)
*
* @example
* "urn:acme:legacy-system-token"
* "https://api.yourcompany.com/token-type/v1"
*/
subject_token_type: string;
/**
* The opaque token value being exchanged for Auth0 tokens
*
* @security
* - Must be validated in Auth0 Actions using strong cryptographic verification
* - Implement replay attack protection
* - Recommended validation libraries: `jose`, `jsonwebtoken`
*
* @example
* "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
*/
subject_token: string;
/**
* The target audience for the requested Auth0 token
*
* @remarks
* Must match exactly with an API identifier configured in your Auth0 tenant.
* If not provided, falls back to the client's default audience.
*
* @example
* "https://api.your-service.com/v1"
*/
audience?: string;
/**
* Space-separated list of OAuth 2.0 scopes being requested
*
* @remarks
* Subject to API authorization policies configured in Auth0
*
* @example
* "openid profile email read:data write:data"
*/
scope?: string;
/**
* Additional custom parameters for Auth0 Action processing
*
* @remarks
* Accessible in Action code via `event.request.body`
*
* @example
* ```typescript
* {
* custom_parameter: "session_context",
* device_fingerprint: "a3d8f7...",
* }
* ```
*/
[key: string]: unknown;
};
+61
View File
@@ -0,0 +1,61 @@
import { TokenEndpointOptions, TokenEndpointResponse } from './global';
import { DEFAULT_AUTH0_CLIENT, DEFAULT_AUDIENCE } from './constants';
import * as dpopUtils from './dpop/utils';
import { getJSON } from './http';
import { createQueryParams, stripAuth0Client } from './utils';
export async function oauthToken(
{
baseUrl,
timeout,
audience,
scope,
auth0Client,
useFormData,
useMrrt,
dpop,
...options
}: TokenEndpointOptions,
worker?: Worker
) {
const isTokenExchange =
options.grant_type === 'urn:ietf:params:oauth:grant-type:token-exchange';
const refreshWithMrrt = options.grant_type === 'refresh_token' && useMrrt;
const allParams = {
...options,
...(isTokenExchange && audience && { audience }),
...(isTokenExchange && scope && { scope }),
...(refreshWithMrrt && { audience, scope })
};
const body = useFormData
? createQueryParams(allParams)
: JSON.stringify(allParams);
const isDpopSupported = dpopUtils.isGrantTypeSupported(options.grant_type);
return await getJSON<TokenEndpointResponse>(
`${baseUrl}/oauth/token`,
timeout,
audience || DEFAULT_AUDIENCE,
scope,
{
method: 'POST',
body,
headers: {
'Content-Type': useFormData
? 'application/x-www-form-urlencoded'
: 'application/json',
'Auth0-Client': btoa(
JSON.stringify(stripAuth0Client(auth0Client || DEFAULT_AUTH0_CLIENT))
)
}
},
worker,
useFormData,
useMrrt,
isDpopSupported ? dpop : undefined
);
}
+31
View File
@@ -0,0 +1,31 @@
import { ICache, Cacheable, CACHE_KEY_PREFIX, MaybePromise } from './shared';
export class LocalStorageCache implements ICache {
public set<T = Cacheable>(key: string, entry: T) {
localStorage.setItem(key, JSON.stringify(entry));
}
public get<T = Cacheable>(key: string): MaybePromise<T | undefined> {
const json = window.localStorage.getItem(key);
if (!json) return;
try {
const payload = JSON.parse(json) as T;
return payload;
/* c8 ignore next 3 */
} catch (e) {
return;
}
}
public remove(key: string) {
localStorage.removeItem(key);
}
public allKeys() {
return Object.keys(window.localStorage).filter(key =>
key.startsWith(CACHE_KEY_PREFIX)
);
}
}
+299
View File
@@ -0,0 +1,299 @@
import { DEFAULT_NOW_PROVIDER } from '../constants';
import { CacheKeyManifest } from './key-manifest';
import {
CacheEntry,
ICache,
CacheKey,
CACHE_KEY_PREFIX,
WrappedCacheEntry,
DecodedToken,
CACHE_KEY_ID_TOKEN_SUFFIX,
IdTokenEntry
} from './shared';
const DEFAULT_EXPIRY_ADJUSTMENT_SECONDS = 0;
export class CacheManager {
private nowProvider: () => number | Promise<number>;
constructor(
private cache: ICache,
private keyManifest?: CacheKeyManifest,
nowProvider?: () => number | Promise<number>
) {
this.nowProvider = nowProvider || DEFAULT_NOW_PROVIDER;
}
async setIdToken(
clientId: string,
idToken: string,
decodedToken: DecodedToken
): Promise<void> {
const cacheKey = this.getIdTokenCacheKey(clientId);
await this.cache.set(cacheKey, {
id_token: idToken,
decodedToken
});
await this.keyManifest?.add(cacheKey);
}
async getIdToken(cacheKey: CacheKey): Promise<IdTokenEntry | undefined> {
const entry = await this.cache.get<IdTokenEntry>(
this.getIdTokenCacheKey(cacheKey.clientId)
);
if (!entry && cacheKey.scope && cacheKey.audience) {
const entryByScope = await this.get(cacheKey);
if (!entryByScope) {
return;
}
if (!entryByScope.id_token || !entryByScope.decodedToken) {
return;
}
return {
id_token: entryByScope.id_token,
decodedToken: entryByScope.decodedToken
};
}
if (!entry) {
return;
}
return { id_token: entry.id_token, decodedToken: entry.decodedToken };
}
async get(
cacheKey: CacheKey,
expiryAdjustmentSeconds = DEFAULT_EXPIRY_ADJUSTMENT_SECONDS,
useMrrt = false,
cacheMode?: string
): Promise<Partial<CacheEntry> | undefined> {
let wrappedEntry = await this.cache.get<WrappedCacheEntry>(
cacheKey.toKey()
);
if (!wrappedEntry) {
const keys = await this.getCacheKeys();
if (!keys) return;
const matchedKey = this.matchExistingCacheKey(cacheKey, keys);
if (matchedKey) {
wrappedEntry = await this.cache.get<WrappedCacheEntry>(matchedKey);
}
// To refresh using MRRT we need to send a request to the server
// If cacheMode is 'cache-only', this will make us unable to call the server
// so it won't be needed to find a valid refresh token
if (!matchedKey && useMrrt && cacheMode !== 'cache-only') {
return this.getEntryWithRefreshToken(cacheKey, keys);
}
}
// If we still don't have an entry, exit.
if (!wrappedEntry) {
return;
}
const now = await this.nowProvider();
const nowSeconds = Math.floor(now / 1000);
if (wrappedEntry.expiresAt - expiryAdjustmentSeconds < nowSeconds) {
if (wrappedEntry.body.refresh_token) {
return this.modifiedCachedEntry(wrappedEntry, cacheKey);
}
await this.cache.remove(cacheKey.toKey());
await this.keyManifest?.remove(cacheKey.toKey());
return;
}
return wrappedEntry.body;
}
private async modifiedCachedEntry(wrappedEntry: WrappedCacheEntry, cacheKey: CacheKey): Promise<Partial<CacheEntry>> {
// We need to keep audience and scope in order to check them later when doing refresh
// using MRRT. See getScopeToRequest method.
wrappedEntry.body = {
refresh_token: wrappedEntry.body.refresh_token,
audience: wrappedEntry.body.audience,
scope: wrappedEntry.body.scope,
};
await this.cache.set(cacheKey.toKey(), wrappedEntry);
return {
refresh_token: wrappedEntry.body.refresh_token,
audience: wrappedEntry.body.audience,
scope: wrappedEntry.body.scope,
};
}
async set(entry: CacheEntry): Promise<void> {
const cacheKey = new CacheKey({
clientId: entry.client_id,
scope: entry.scope,
audience: entry.audience
});
const wrappedEntry = await this.wrapCacheEntry(entry);
await this.cache.set(cacheKey.toKey(), wrappedEntry);
await this.keyManifest?.add(cacheKey.toKey());
}
async remove(
client_id: string,
audience?: string,
scope?: string,
): Promise<void> {
const cacheKey = new CacheKey({
clientId: client_id,
scope: scope,
audience: audience
});
await this.cache.remove(cacheKey.toKey());
}
async clear(clientId?: string): Promise<void> {
const keys = await this.getCacheKeys();
/* c8 ignore next */
if (!keys) return;
await keys
.filter(key => (clientId ? key.includes(clientId) : true))
.reduce(async (memo, key) => {
await memo;
await this.cache.remove(key);
}, Promise.resolve());
await this.keyManifest?.clear();
}
private async wrapCacheEntry(entry: CacheEntry): Promise<WrappedCacheEntry> {
const now = await this.nowProvider();
const expiresInTime = Math.floor(now / 1000) + entry.expires_in;
return {
body: entry,
expiresAt: expiresInTime
};
}
private async getCacheKeys(): Promise<string[] | undefined> {
if (this.keyManifest) {
return (await this.keyManifest.get())?.keys;
} else if (this.cache.allKeys) {
return this.cache.allKeys();
}
}
/**
* Returns the cache key to be used to store the id token
* @param clientId The client id used to link to the id token
* @returns The constructed cache key, as a string, to store the id token
*/
private getIdTokenCacheKey(clientId: string) {
return new CacheKey(
{ clientId },
CACHE_KEY_PREFIX,
CACHE_KEY_ID_TOKEN_SUFFIX
).toKey();
}
/**
* Finds the corresponding key in the cache based on the provided cache key.
* The keys inside the cache are in the format {prefix}::{clientId}::{audience}::{scope}.
* The first key in the cache that satisfies the following conditions is returned
* - `prefix` is strict equal to Auth0's internally configured `keyPrefix`
* - `clientId` is strict equal to the `cacheKey.clientId`
* - `audience` is strict equal to the `cacheKey.audience`
* - `scope` contains at least all the `cacheKey.scope` values
* *
* @param keyToMatch The provided cache key
* @param allKeys A list of existing cache keys
*/
private matchExistingCacheKey(keyToMatch: CacheKey, allKeys: Array<string>) {
return allKeys.filter(key => {
const cacheKey = CacheKey.fromKey(key);
const scopeSet = new Set(cacheKey.scope && cacheKey.scope.split(' '));
const scopesToMatch = keyToMatch.scope?.split(' ') || [];
const hasAllScopes =
cacheKey.scope &&
scopesToMatch.reduce(
(acc, current) => acc && scopeSet.has(current),
true
);
return (
cacheKey.prefix === CACHE_KEY_PREFIX &&
cacheKey.clientId === keyToMatch.clientId &&
cacheKey.audience === keyToMatch.audience &&
hasAllScopes
);
})[0];
}
/**
* Returns the first entry that contains a refresh_token that satisfies the following conditions
* The keys inside the cache are in the format {prefix}::{clientId}::{audience}::{scope}.
* - `prefix` is strict equal to Auth0's internally configured `keyPrefix`
* - `clientId` is strict equal to the `cacheKey.clientId`
* @param keyToMatch The provided cache key
* @param allKeys A list of existing cache keys
*/
private async getEntryWithRefreshToken(keyToMatch: CacheKey, allKeys: Array<string>): Promise<Partial<CacheEntry> | undefined> {
for (const key of allKeys) {
const cacheKey = CacheKey.fromKey(key);
if (cacheKey.prefix === CACHE_KEY_PREFIX &&
cacheKey.clientId === keyToMatch.clientId) {
const cachedEntry = await this.cache.get<WrappedCacheEntry>(key);
if (cachedEntry?.body?.refresh_token) {
return this.modifiedCachedEntry(cachedEntry, keyToMatch);
}
}
}
return undefined;
}
/**
* Updates in the cache all entries that has a match with previous refresh_token with the
* new refresh_token obtained from the server
* @param oldRefreshToken Old refresh_token used on refresh
* @param newRefreshToken New refresh_token obtained from the server after refresh
*/
async updateEntry(
oldRefreshToken: string,
newRefreshToken: string,
): Promise<void> {
const allKeys = await this.getCacheKeys();
if (!allKeys) return;
for (const key of allKeys) {
const entry = await this.cache.get<WrappedCacheEntry>(key);
if (entry?.body?.refresh_token === oldRefreshToken) {
const cacheEntry = {
...entry.body,
refresh_token: newRefreshToken,
} as CacheEntry;
await this.set(cacheEntry);
}
}
}
}
+31
View File
@@ -0,0 +1,31 @@
import { Cacheable, ICache, MaybePromise } from './shared';
export class InMemoryCache {
public enclosedCache: ICache = (function () {
let cache: Record<string, unknown> = {};
return {
set<T = Cacheable>(key: string, entry: T) {
cache[key] = entry;
},
get<T = Cacheable>(key: string): MaybePromise<T | undefined> {
const cacheEntry = cache[key] as T;
if (!cacheEntry) {
return;
}
return cacheEntry;
},
remove(key: string) {
delete cache[key];
},
allKeys(): string[] {
return Object.keys(cache);
}
};
})();
}
+4
View File
@@ -0,0 +1,4 @@
export * from './cache-localstorage';
export * from './cache-memory';
export * from './cache-manager';
export * from './shared';
+53
View File
@@ -0,0 +1,53 @@
import {
CACHE_KEY_PREFIX,
ICache,
KeyManifestEntry,
MaybePromise
} from './shared';
export class CacheKeyManifest {
private readonly manifestKey: string;
constructor(private cache: ICache, private clientId: string) {
this.manifestKey = this.createManifestKeyFrom(this.clientId);
}
async add(key: string): Promise<void> {
const keys = new Set(
(await this.cache.get<KeyManifestEntry>(this.manifestKey))?.keys || []
);
keys.add(key);
await this.cache.set<KeyManifestEntry>(this.manifestKey, {
keys: [...keys]
});
}
async remove(key: string): Promise<void> {
const entry = await this.cache.get<KeyManifestEntry>(this.manifestKey);
if (entry) {
const keys = new Set(entry.keys);
keys.delete(key);
if (keys.size > 0) {
return await this.cache.set(this.manifestKey, { keys: [...keys] });
}
return await this.cache.remove(this.manifestKey);
}
}
get(): MaybePromise<KeyManifestEntry | undefined> {
return this.cache.get<KeyManifestEntry>(this.manifestKey);
}
clear(): MaybePromise<void> {
return this.cache.remove(this.manifestKey);
}
private createManifestKeyFrom(clientId: string): string {
return `${CACHE_KEY_PREFIX}::${clientId}`;
}
}
+105
View File
@@ -0,0 +1,105 @@
import { IdToken, User } from '../global';
export const CACHE_KEY_PREFIX = '@@auth0spajs@@';
export const CACHE_KEY_ID_TOKEN_SUFFIX = '@@user@@';
export type CacheKeyData = {
audience?: string;
scope?: string;
clientId: string;
};
export class CacheKey {
public clientId: string;
public scope?: string;
public audience?: string;
constructor(
data: CacheKeyData,
public prefix: string = CACHE_KEY_PREFIX,
public suffix?: string
) {
this.clientId = data.clientId;
this.scope = data.scope;
this.audience = data.audience;
}
/**
* Converts this `CacheKey` instance into a string for use in a cache
* @returns A string representation of the key
*/
toKey(): string {
return [this.prefix, this.clientId, this.audience, this.scope, this.suffix]
.filter(Boolean)
.join('::');
}
/**
* Converts a cache key string into a `CacheKey` instance.
* @param key The key to convert
* @returns An instance of `CacheKey`
*/
static fromKey(key: string): CacheKey {
const [prefix, clientId, audience, scope] = key.split('::');
return new CacheKey({ clientId, scope, audience }, prefix);
}
/**
* Utility function to build a `CacheKey` instance from a cache entry
* @param entry The entry
* @returns An instance of `CacheKey`
*/
static fromCacheEntry(entry: CacheEntry): CacheKey {
const { scope, audience, client_id: clientId } = entry;
return new CacheKey({
scope,
audience,
clientId
});
}
}
export interface DecodedToken {
claims: IdToken;
user: User;
}
export interface IdTokenEntry {
id_token: string;
decodedToken: DecodedToken;
}
export type CacheEntry = {
id_token?: string;
token_type?: string;
access_token: string;
expires_in: number;
decodedToken?: DecodedToken;
audience: string;
scope: string;
client_id: string;
refresh_token?: string;
oauthTokenScope?: string;
};
export type WrappedCacheEntry = {
body: Partial<CacheEntry>;
expiresAt: number;
};
export type KeyManifestEntry = {
keys: string[];
};
export type Cacheable = WrappedCacheEntry | KeyManifestEntry;
export type MaybePromise<T> = Promise<T> | T;
export interface ICache {
set<T = Cacheable>(key: string, entry: T): MaybePromise<void>;
get<T = Cacheable>(key: string): MaybePromise<T | undefined>;
remove(key: string): MaybePromise<void>;
allKeys?(): MaybePromise<string[]>;
}
+64
View File
@@ -0,0 +1,64 @@
import { PopupConfigOptions } from './global';
import version from './version';
/**
* @ignore
*/
export const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
/**
* @ignore
*/
export const DEFAULT_POPUP_CONFIG_OPTIONS: PopupConfigOptions = {
timeoutInSeconds: DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS
};
/**
* @ignore
*/
export const DEFAULT_SILENT_TOKEN_RETRY_COUNT = 3;
/**
* @ignore
*/
export const CLEANUP_IFRAME_TIMEOUT_IN_SECONDS = 2;
/**
* @ignore
*/
export const DEFAULT_FETCH_TIMEOUT_MS = 10000;
export const CACHE_LOCATION_MEMORY = 'memory';
export const CACHE_LOCATION_LOCAL_STORAGE = 'localstorage';
/**
* @ignore
*/
export const MISSING_REFRESH_TOKEN_ERROR_MESSAGE = 'Missing Refresh Token';
/**
* @ignore
*/
export const INVALID_REFRESH_TOKEN_ERROR_MESSAGE = 'invalid refresh token';
/**
* @ignore
*/
export const DEFAULT_SCOPE = 'openid profile email';
/**
* @ignore
*/
export const DEFAULT_SESSION_CHECK_EXPIRY_DAYS = 1;
/**
* @ignore
*/
export const DEFAULT_AUTH0_CLIENT = {
name: 'auth0-spa-js',
version: version
};
export const DEFAULT_NOW_PROVIDER = () => Date.now();
export const DEFAULT_AUDIENCE = 'default';
+56
View File
@@ -0,0 +1,56 @@
import { DpopStorage } from './storage';
import * as dpopUtils from './utils';
export class Dpop {
protected readonly storage: DpopStorage;
public constructor(clientId: string) {
this.storage = new DpopStorage(clientId);
}
public getNonce(id?: string): Promise<string | undefined> {
return this.storage.findNonce(id);
}
public setNonce(nonce: string, id?: string): Promise<void> {
return this.storage.setNonce(nonce, id);
}
protected async getOrGenerateKeyPair(): Promise<dpopUtils.KeyPair> {
let keyPair = await this.storage.findKeyPair();
if (!keyPair) {
keyPair = await dpopUtils.generateKeyPair();
await this.storage.setKeyPair(keyPair);
}
return keyPair;
}
public async generateProof(params: {
url: string;
method: string;
nonce?: string;
accessToken?: string;
}): Promise<string> {
const keyPair = await this.getOrGenerateKeyPair();
return dpopUtils.generateProof({
keyPair,
...params
});
}
public async calculateThumbprint(): Promise<string> {
const keyPair = await this.getOrGenerateKeyPair();
return dpopUtils.calculateThumbprint(keyPair);
}
public async clear(): Promise<void> {
await Promise.all([
this.storage.clearNonces(),
this.storage.clearKeyPairs()
]);
}
}
+134
View File
@@ -0,0 +1,134 @@
import { type KeyPair } from './utils';
const VERSION = 1;
const NAME = 'auth0-spa-js';
const TABLES = {
NONCE: 'nonce',
KEYPAIR: 'keypair'
} as const;
const AUTH0_NONCE_ID = 'auth0';
type Table = (typeof TABLES)[keyof typeof TABLES];
export class DpopStorage {
protected readonly clientId: string;
protected dbHandle: IDBDatabase | undefined;
constructor(clientId: string) {
this.clientId = clientId;
}
protected getVersion(): number {
return VERSION;
}
protected createDbHandle(): Promise<IDBDatabase> {
const req = window.indexedDB.open(NAME, this.getVersion());
return new Promise((resolve, reject) => {
req.onupgradeneeded = () =>
Object.values(TABLES).forEach(t => req.result.createObjectStore(t));
req.onerror = () => reject(req.error);
req.onsuccess = () => resolve(req.result);
});
}
protected async getDbHandle(): Promise<IDBDatabase> {
if (!this.dbHandle) {
this.dbHandle = await this.createDbHandle();
}
return this.dbHandle;
}
protected async executeDbRequest<T = unknown>(
table: string,
mode: IDBTransactionMode,
requestFactory: (table: IDBObjectStore) => IDBRequest<T>
): Promise<T> {
const db = await this.getDbHandle();
const txn = db.transaction(table, mode);
const store = txn.objectStore(table);
const request = requestFactory(store);
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
protected buildKey(id?: string): string {
const finalId = id
? `_${id}` // prefix to avoid collisions
: AUTH0_NONCE_ID;
return `${this.clientId}::${finalId}`;
}
public setNonce(nonce: string, id?: string): Promise<void> {
return this.save(TABLES.NONCE, this.buildKey(id), nonce);
}
public setKeyPair(keyPair: KeyPair): Promise<void> {
return this.save(TABLES.KEYPAIR, this.buildKey(), keyPair);
}
protected async save(
table: Table,
key: IDBValidKey,
obj: unknown
): Promise<void> {
return void await this.executeDbRequest(table, 'readwrite', table =>
table.put(obj, key)
);
}
public findNonce(id?: string): Promise<string | undefined> {
return this.find(TABLES.NONCE, this.buildKey(id));
}
public findKeyPair(): Promise<KeyPair | undefined> {
return this.find(TABLES.KEYPAIR, this.buildKey());
}
protected find<T = unknown>(
table: Table,
key: IDBValidKey
): Promise<T | undefined> {
return this.executeDbRequest(table, 'readonly', table => table.get(key));
}
protected async deleteBy(
table: Table,
predicate: (key: IDBValidKey) => boolean
): Promise<void> {
const allKeys = await this.executeDbRequest(table, 'readonly', table =>
table.getAllKeys()
);
allKeys
?.filter(predicate)
.map(k =>
this.executeDbRequest(table, 'readwrite', table => table.delete(k))
);
}
protected deleteByClientId(table: Table, clientId: string): Promise<void> {
return this.deleteBy(
table,
k => typeof k === 'string' && k.startsWith(`${clientId}::`)
);
}
public clearNonces(): Promise<void> {
return this.deleteByClientId(TABLES.NONCE, this.clientId);
}
public clearKeyPairs(): Promise<void> {
return this.deleteByClientId(TABLES.KEYPAIR, this.clientId);
}
}
Loaded 100 of 3481 files, more files were not shown because too many files have changed in this diff. Show more