@versini/auth0-react-thin 2.22.1 → 2.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/auth0-context.d.ts +9 -0
- package/dist/auth0-context.d.ts.map +1 -1
- package/dist/auth0-provider.d.ts +5 -0
- package/dist/auth0-provider.d.ts.map +1 -1
- package/dist/auth0-react.cjs.js +173 -42
- package/dist/auth0-react.cjs.js.map +1 -1
- package/dist/auth0-react.esm.js +160 -48
- package/dist/auth0-react.esm.js.map +1 -1
- package/dist/auth0-react.js +172 -42
- package/dist/auth0-react.js.map +1 -1
- package/dist/auth0-react.min.js +1 -1
- package/dist/auth0-react.min.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/use-auth0-suspense.d.ts +35 -0
- package/dist/use-auth0-suspense.d.ts.map +1 -0
- package/dist/with-authentication-required.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/auth0-context.tsx +10 -0
- package/src/auth0-provider.tsx +87 -10
- package/src/index.tsx +4 -0
- package/src/use-auth0-suspense.tsx +71 -0
- package/src/with-authentication-required.tsx +8 -2
package/dist/auth0-react.esm.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import React__default, { createContext, useState, useReducer, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
|
|
2
4
|
import { Auth0Client, ResponseType } from '@auth0/auth0-spa-js';
|
|
3
5
|
export { AuthenticationError, ConnectError, GenericError, InMemoryCache, InvalidConfigurationError, LocalStorageCache, MfaChallengeError, MfaEnrollmentError, MfaEnrollmentFactorsError, MfaError, MfaListAuthenticatorsError, MfaRequiredError, MfaVerifyError, MissingRefreshTokenError, MissingScopesError, MyAccountApiError, PasskeyChallengeError, PasskeyError, PasskeyGetTokenError, PasskeyRegisterError, PopupCancelledError, PopupOpenError, PopupTimeoutError, RefreshTokenMode, ResponseType, TimeoutError, UseDpopNonceError, User } from '@auth0/auth0-spa-js';
|
|
4
6
|
|
|
@@ -254,7 +256,7 @@ var toAuth0ClientOptions = function (opts) {
|
|
|
254
256
|
deprecateRedirectUri(opts);
|
|
255
257
|
return __assign(__assign({}, opts), { auth0Client: {
|
|
256
258
|
name: 'auth0-react',
|
|
257
|
-
version: '2.
|
|
259
|
+
version: '2.24.0',
|
|
258
260
|
} });
|
|
259
261
|
};
|
|
260
262
|
/**
|
|
@@ -264,6 +266,22 @@ var defaultOnRedirectCallback = function (appState) {
|
|
|
264
266
|
var _a;
|
|
265
267
|
window.history.replaceState({}, document.title, (_a = appState.returnTo) !== null && _a !== void 0 ? _a : window.location.pathname);
|
|
266
268
|
};
|
|
269
|
+
/**
|
|
270
|
+
* @ignore
|
|
271
|
+
*/
|
|
272
|
+
var createInitDeferred = function () {
|
|
273
|
+
var resolve;
|
|
274
|
+
var reject;
|
|
275
|
+
var promise = new Promise(function (res, rej) {
|
|
276
|
+
resolve = res;
|
|
277
|
+
reject = rej;
|
|
278
|
+
});
|
|
279
|
+
// Avoid unhandled-rejection warnings when no one is consuming the promise
|
|
280
|
+
// (i.e. useAuth0Suspense is not used). useAuth0Suspense attaches its own
|
|
281
|
+
// handler via use().
|
|
282
|
+
promise.catch(function () { return undefined; });
|
|
283
|
+
return { promise: promise, resolve: resolve, reject: reject };
|
|
284
|
+
};
|
|
267
285
|
/**
|
|
268
286
|
* ```jsx
|
|
269
287
|
* <Auth0Provider
|
|
@@ -275,6 +293,11 @@ var defaultOnRedirectCallback = function (appState) {
|
|
|
275
293
|
* ```
|
|
276
294
|
*
|
|
277
295
|
* Provides the Auth0Context to its child components.
|
|
296
|
+
*
|
|
297
|
+
* The SDK is a client-only module (its published ESM and CommonJS bundles ship the
|
|
298
|
+
* `'use client'` directive), so in a Next.js App Router app you can import and render
|
|
299
|
+
* `Auth0Provider` directly from a Server Component such as `app/layout.tsx`.
|
|
300
|
+
* Components that call hooks like `useAuth0` must still be Client Components.
|
|
278
301
|
*/
|
|
279
302
|
var Auth0Provider = function (opts) {
|
|
280
303
|
var _a = opts, children = _a.children, skipRedirectCallback = _a.skipRedirectCallback, _b = _a.onRedirectCallback, onRedirectCallback = _b === void 0 ? defaultOnRedirectCallback : _b, _c = _a.context, context = _c === void 0 ? Auth0Context : _c, providedClient = _a.client, clientOpts = __rest(_a, ["children", "skipRedirectCallback", "onRedirectCallback", "context", "client"]);
|
|
@@ -285,55 +308,94 @@ var Auth0Provider = function (opts) {
|
|
|
285
308
|
}
|
|
286
309
|
var client = useState(function () { return providedClient !== null && providedClient !== void 0 ? providedClient : new Auth0Client(toAuth0ClientOptions(clientOpts)); })[0];
|
|
287
310
|
var _d = useReducer((reducer), initialAuthState), state = _d[0], dispatch = _d[1];
|
|
311
|
+
// In state so the init retry below can swap in a fresh, non-rejected promise.
|
|
312
|
+
// Without that swap the first rejection would re-throw on every later render,
|
|
313
|
+
// making Error Boundary retries useless.
|
|
314
|
+
var _e = useState(createInitDeferred), initDeferred = _e[0], setInitDeferred = _e[1];
|
|
315
|
+
// Set only once initialization has genuinely rejected. State, not a ref, so
|
|
316
|
+
// the retry effect re-evaluates when init fails *after* the app has become
|
|
317
|
+
// authenticated by some other means.
|
|
318
|
+
var _f = useState(false), initFailed = _f[0], setInitFailed = _f[1];
|
|
319
|
+
// Guards against retrying more than once: a retry that also fails would
|
|
320
|
+
// otherwise re-trigger the effect for as long as the user stays signed in.
|
|
321
|
+
var initRetried = useRef(false);
|
|
288
322
|
var didInitialise = useRef(false);
|
|
289
323
|
var handleError = useCallback(function (error) {
|
|
290
324
|
dispatch({ type: 'ERROR', error: error });
|
|
291
325
|
return error;
|
|
292
326
|
}, []);
|
|
327
|
+
// Settles `deferred` according to what initialization actually did, so
|
|
328
|
+
// `_initPromise` never claims success that did not happen. `allowRedirect`
|
|
329
|
+
// is false on a retry: the redirect callback is single-use, so a retry can
|
|
330
|
+
// only re-verify the session.
|
|
331
|
+
var runInit = useCallback(function (deferred, allowRedirect) { return __awaiter(void 0, void 0, void 0, function () {
|
|
332
|
+
var user, _a, _b, appState, response_type, result, error_1, err;
|
|
333
|
+
return __generator(this, function (_c) {
|
|
334
|
+
switch (_c.label) {
|
|
335
|
+
case 0:
|
|
336
|
+
_c.trys.push([0, 7, , 8]);
|
|
337
|
+
user = void 0;
|
|
338
|
+
if (!(allowRedirect && hasAuthParams() && !skipRedirectCallback)) return [3 /*break*/, 3];
|
|
339
|
+
return [4 /*yield*/, client.handleRedirectCallback()];
|
|
340
|
+
case 1:
|
|
341
|
+
_a = _c.sent(), _b = _a.appState, appState = _b === void 0 ? {} : _b, response_type = _a.response_type, result = __rest(_a, ["appState", "response_type"]);
|
|
342
|
+
return [4 /*yield*/, client.getUser()];
|
|
343
|
+
case 2:
|
|
344
|
+
user = _c.sent();
|
|
345
|
+
appState.response_type = response_type;
|
|
346
|
+
if (response_type === ResponseType.ConnectCode) {
|
|
347
|
+
appState.connectedAccount = result;
|
|
348
|
+
}
|
|
349
|
+
onRedirectCallback(appState, user);
|
|
350
|
+
return [3 /*break*/, 6];
|
|
351
|
+
case 3: return [4 /*yield*/, client.checkSession()];
|
|
352
|
+
case 4:
|
|
353
|
+
_c.sent();
|
|
354
|
+
return [4 /*yield*/, client.getUser()];
|
|
355
|
+
case 5:
|
|
356
|
+
user = _c.sent();
|
|
357
|
+
_c.label = 6;
|
|
358
|
+
case 6:
|
|
359
|
+
dispatch({ type: 'INITIALISED', user: user });
|
|
360
|
+
deferred.resolve();
|
|
361
|
+
return [3 /*break*/, 8];
|
|
362
|
+
case 7:
|
|
363
|
+
error_1 = _c.sent();
|
|
364
|
+
err = loginError(error_1);
|
|
365
|
+
handleError(err);
|
|
366
|
+
setInitFailed(true);
|
|
367
|
+
deferred.reject(err);
|
|
368
|
+
return [3 /*break*/, 8];
|
|
369
|
+
case 8: return [2 /*return*/];
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}); }, [client, onRedirectCallback, skipRedirectCallback, handleError]);
|
|
293
373
|
useEffect(function () {
|
|
294
374
|
if (didInitialise.current) {
|
|
295
375
|
return;
|
|
296
376
|
}
|
|
297
377
|
didInitialise.current = true;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
case 4:
|
|
320
|
-
_c.sent();
|
|
321
|
-
return [4 /*yield*/, client.getUser()];
|
|
322
|
-
case 5:
|
|
323
|
-
user = _c.sent();
|
|
324
|
-
_c.label = 6;
|
|
325
|
-
case 6:
|
|
326
|
-
dispatch({ type: 'INITIALISED', user: user });
|
|
327
|
-
return [3 /*break*/, 8];
|
|
328
|
-
case 7:
|
|
329
|
-
error_1 = _c.sent();
|
|
330
|
-
handleError(loginError(error_1));
|
|
331
|
-
return [3 /*break*/, 8];
|
|
332
|
-
case 8: return [2 /*return*/];
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
}); })();
|
|
336
|
-
}, [client, onRedirectCallback, skipRedirectCallback, handleError]);
|
|
378
|
+
// Always the first deferred: `didInitialise` means this only ever runs once,
|
|
379
|
+
// so a later swap by the retry effect re-runs this effect but returns above.
|
|
380
|
+
void runInit(initDeferred, true);
|
|
381
|
+
}, [runInit, initDeferred]);
|
|
382
|
+
// A rejected promise stays rejected forever, so React.use() would re-throw on
|
|
383
|
+
// every later render and an Error Boundary retry could never recover. Once
|
|
384
|
+
// init has failed but the app has since become authenticated by some other
|
|
385
|
+
// means (loginWithPopup, a silent token, a passkey login), re-run the session
|
|
386
|
+
// check against a fresh deferred. The promise then reflects a real
|
|
387
|
+
// checkSession() outcome rather than an assumption that things are fine --
|
|
388
|
+
// if the session is still bad it rejects again and the boundary keeps showing
|
|
389
|
+
// the error.
|
|
390
|
+
useEffect(function () {
|
|
391
|
+
if (!initFailed || initRetried.current || !state.isAuthenticated) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
initRetried.current = true;
|
|
395
|
+
var retry = createInitDeferred();
|
|
396
|
+
setInitDeferred(retry);
|
|
397
|
+
void runInit(retry, false);
|
|
398
|
+
}, [initFailed, state.isAuthenticated, runInit]);
|
|
337
399
|
var loginWithRedirect = useCallback(function (opts) {
|
|
338
400
|
deprecateRedirectUri(opts);
|
|
339
401
|
return client.loginWithRedirect(opts);
|
|
@@ -617,7 +679,7 @@ var Auth0Provider = function (opts) {
|
|
|
617
679
|
}); }, [client]);
|
|
618
680
|
var passkey = useMemo(function () { return ({ signup: passkeySignup, login: passkeyLogin }); }, [passkeySignup, passkeyLogin]);
|
|
619
681
|
var contextValue = useMemo(function () {
|
|
620
|
-
return __assign(__assign({}, state), { getAccessTokenSilently: getAccessTokenSilently, getAccessTokenWithPopup: getAccessTokenWithPopup, getIdTokenClaims: getIdTokenClaims, loginWithCustomTokenExchange: loginWithCustomTokenExchange, customTokenExchange: customTokenExchange, exchangeToken: exchangeToken, loginWithRedirect: loginWithRedirect, loginWithPopup: loginWithPopup, connectAccountWithRedirect: connectAccountWithRedirect, logout: logout, revokeRefreshToken: revokeRefreshToken, handleRedirectCallback: handleRedirectCallback, getDpopNonce: getDpopNonce, setDpopNonce: setDpopNonce, generateDpopProof: generateDpopProof, createFetcher: createFetcher, getConfiguration: getConfiguration, mfa: mfa, passkey: passkey, myAccount: myAccount });
|
|
682
|
+
return __assign(__assign({}, state), { getAccessTokenSilently: getAccessTokenSilently, getAccessTokenWithPopup: getAccessTokenWithPopup, getIdTokenClaims: getIdTokenClaims, loginWithCustomTokenExchange: loginWithCustomTokenExchange, customTokenExchange: customTokenExchange, exchangeToken: exchangeToken, loginWithRedirect: loginWithRedirect, loginWithPopup: loginWithPopup, connectAccountWithRedirect: connectAccountWithRedirect, logout: logout, revokeRefreshToken: revokeRefreshToken, handleRedirectCallback: handleRedirectCallback, getDpopNonce: getDpopNonce, setDpopNonce: setDpopNonce, generateDpopProof: generateDpopProof, createFetcher: createFetcher, getConfiguration: getConfiguration, mfa: mfa, passkey: passkey, myAccount: myAccount, _initPromise: initDeferred.promise });
|
|
621
683
|
}, [
|
|
622
684
|
state,
|
|
623
685
|
getAccessTokenSilently,
|
|
@@ -640,8 +702,9 @@ var Auth0Provider = function (opts) {
|
|
|
640
702
|
mfa,
|
|
641
703
|
passkey,
|
|
642
704
|
myAccount,
|
|
705
|
+
initDeferred,
|
|
643
706
|
]);
|
|
644
|
-
return
|
|
707
|
+
return React__default.createElement(context.Provider, { value: contextValue }, children);
|
|
645
708
|
};
|
|
646
709
|
|
|
647
710
|
/**
|
|
@@ -673,6 +736,50 @@ var useAuth0 = function (context) {
|
|
|
673
736
|
return useContext(context);
|
|
674
737
|
};
|
|
675
738
|
|
|
739
|
+
/**
|
|
740
|
+
* ```jsx
|
|
741
|
+
* <Suspense fallback={<Spinner />}>
|
|
742
|
+
* <Profile />
|
|
743
|
+
* </Suspense>
|
|
744
|
+
*
|
|
745
|
+
* function Profile() {
|
|
746
|
+
* const { user, isAuthenticated } = useAuth0Suspense();
|
|
747
|
+
* return isAuthenticated ? <p>Hello {user.name}</p> : <p>Please log in</p>;
|
|
748
|
+
* }
|
|
749
|
+
* ```
|
|
750
|
+
*
|
|
751
|
+
* Suspense-enabled variant of `useAuth0`. Suspends the component until Auth0
|
|
752
|
+
* initialization completes (letting the nearest `<Suspense>` fallback render),
|
|
753
|
+
* and throws initialization errors so the nearest Error Boundary can handle
|
|
754
|
+
* them. Requires React 19 or later.
|
|
755
|
+
*
|
|
756
|
+
* If initialization fails and the app later becomes authenticated by other
|
|
757
|
+
* means, the session is re-checked once; retrying the Error Boundary then
|
|
758
|
+
* renders if that check succeeded, or throws again if it did not.
|
|
759
|
+
*
|
|
760
|
+
* TUser is an optional type param to provide a type to the `user` field.
|
|
761
|
+
*/
|
|
762
|
+
var useAuth0Suspense = function (context) {
|
|
763
|
+
if (context === void 0) { context = Auth0Context; }
|
|
764
|
+
if (typeof React.use !== 'function') {
|
|
765
|
+
throw new Error('useAuth0Suspense requires React 19 or later (React.use is unavailable).');
|
|
766
|
+
}
|
|
767
|
+
var ctx = React.useContext(context);
|
|
768
|
+
if (!ctx._initPromise) {
|
|
769
|
+
throw new Error('useAuth0Suspense must be used within an <Auth0Provider>.');
|
|
770
|
+
}
|
|
771
|
+
// Suspends until the init promise resolves; re-throws if it rejected.
|
|
772
|
+
React.use(ctx._initPromise);
|
|
773
|
+
// Memoized so the returned object is referentially stable across renders,
|
|
774
|
+
// matching useAuth0, which hands back the provider's memoized context.
|
|
775
|
+
// Without this, `useEffect(..., [auth])` in a consumer re-runs every render.
|
|
776
|
+
return React.useMemo(function () {
|
|
777
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
778
|
+
ctx.isLoading; ctx._initPromise; var rest = __rest(ctx, ["isLoading", "_initPromise"]);
|
|
779
|
+
return rest;
|
|
780
|
+
}, [ctx]);
|
|
781
|
+
};
|
|
782
|
+
|
|
676
783
|
/**
|
|
677
784
|
* ```jsx
|
|
678
785
|
* class MyComponent extends Component {
|
|
@@ -694,14 +801,14 @@ var useAuth0 = function (context) {
|
|
|
694
801
|
var withAuth0 = function (Component, context) {
|
|
695
802
|
if (context === void 0) { context = Auth0Context; }
|
|
696
803
|
return function WithAuth(props) {
|
|
697
|
-
return (
|
|
804
|
+
return (React__default.createElement(context.Consumer, null, function (auth) { return (React__default.createElement(Component, __assign({}, props, { auth0: auth }))); }));
|
|
698
805
|
};
|
|
699
806
|
};
|
|
700
807
|
|
|
701
808
|
/**
|
|
702
809
|
* @ignore
|
|
703
810
|
*/
|
|
704
|
-
var defaultOnRedirecting = function () { return
|
|
811
|
+
var defaultOnRedirecting = function () { return React__default.createElement(React__default.Fragment, null); };
|
|
705
812
|
/**
|
|
706
813
|
* @ignore
|
|
707
814
|
*/
|
|
@@ -712,7 +819,12 @@ var defaultOnBeforeAuthentication = function () { return __awaiter(void 0, void
|
|
|
712
819
|
* @ignore
|
|
713
820
|
*/
|
|
714
821
|
var defaultReturnTo = function () {
|
|
715
|
-
|
|
822
|
+
// Normalize the pathname to prevent protocol-relative open redirects.
|
|
823
|
+
// A URL like https://app.example.com//evil.com produces a pathname of
|
|
824
|
+
// //evil.com, which routers (react-router, next.js, gatsby) interpret as a
|
|
825
|
+
// protocol-relative URL and redirect the user to an external host.
|
|
826
|
+
var pathname = window.location.pathname.replace(/^\/\/+/, '/');
|
|
827
|
+
return "".concat(pathname).concat(window.location.search);
|
|
716
828
|
};
|
|
717
829
|
/**
|
|
718
830
|
* ```js
|
|
@@ -754,9 +866,9 @@ var withAuthenticationRequired = function (Component, options) {
|
|
|
754
866
|
loginOptions,
|
|
755
867
|
returnTo,
|
|
756
868
|
]);
|
|
757
|
-
return isAuthenticated ?
|
|
869
|
+
return isAuthenticated ? React__default.createElement(Component, __assign({}, props)) : onRedirecting();
|
|
758
870
|
};
|
|
759
871
|
};
|
|
760
872
|
|
|
761
|
-
export { Auth0Context, Auth0Provider, OAuthError, initialContext, useAuth0, withAuth0, withAuthenticationRequired };
|
|
873
|
+
export { Auth0Context, Auth0Provider, OAuthError, initialContext, useAuth0, useAuth0Suspense, withAuth0, withAuthenticationRequired };
|
|
762
874
|
//# sourceMappingURL=auth0-react.esm.js.map
|