From 1f460701ab9cef676a4748ca3cd2f9f38411f2d1 Mon Sep 17 00:00:00 2001 From: Kurt Weiberth <kweiberth@users.noreply.github.com> Date: Thu, 23 Dec 2021 07:41:06 -0500 Subject: [PATCH] Avoid potential multiple invocations of loginWithRedirect (#311) * Avoid potential multiple invocations of loginWithRedirect Resolves https://github.com/auth0/auth0-react/issues/309 * add test to assert single call * remove comment --- .../with-authentication-required.test.tsx | 23 +++++++++++++++++++ src/with-authentication-required.tsx | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/__tests__/with-authentication-required.test.tsx b/__tests__/with-authentication-required.test.tsx index 0c1a12b8..0a447110 100644 --- a/__tests__/with-authentication-required.test.tsx +++ b/__tests__/with-authentication-required.test.tsx @@ -189,4 +189,27 @@ describe('withAuthenticationRequired', () => { ) ); }); + + it('should call loginWithRedirect only once even if parent state changes', async () => { + mockClient.getUser.mockResolvedValue(undefined); + const MyComponent = (): JSX.Element => <>Private</>; + const WrappedComponent = withAuthenticationRequired(MyComponent); + const App = ({ foo }: { foo: number }): JSX.Element => ( + <div> + {foo} + <Auth0Provider clientId="__test_client_id__" domain="__test_domain__"> + <WrappedComponent /> + </Auth0Provider> + </div> + ); + const { rerender } = render(<App foo={1} />); + await waitFor(() => + expect(mockClient.loginWithRedirect).toHaveBeenCalled() + ); + mockClient.loginWithRedirect.mockClear(); + rerender(<App foo={2} />); + await waitFor(() => + expect(mockClient.loginWithRedirect).not.toHaveBeenCalled() + ); + }); }); diff --git a/src/with-authentication-required.tsx b/src/with-authentication-required.tsx index dd24624a..5510a96a 100644 --- a/src/with-authentication-required.tsx +++ b/src/with-authentication-required.tsx @@ -84,8 +84,8 @@ const withAuthenticationRequired = <P extends object>( const { returnTo = defaultReturnTo, onRedirecting = defaultOnRedirecting, - loginOptions = {}, claimCheck = (): boolean => true, + loginOptions, } = options; /** @@ -101,7 +101,7 @@ const withAuthenticationRequired = <P extends object>( const opts = { ...loginOptions, appState: { - ...loginOptions.appState, + ...(loginOptions && loginOptions.appState), returnTo: typeof returnTo === 'function' ? returnTo() : returnTo, }, };