Skip to content

Commit

Permalink
Make sure handleRedirectCallback is only called once in StrictMode Re…
Browse files Browse the repository at this point in the history
…act 18 (#355)

* HandleRedirectCallback can only be called once in React 18 StrictMode

* Remove unnessesary assert
  • Loading branch information
adamjmcgrath authored Apr 28, 2022
1 parent ba605cc commit e93343b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 11 deletions.
24 changes: 23 additions & 1 deletion __tests__/auth-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useContext } from 'react';
import React, { StrictMode, useContext } from 'react';
import Auth0Context from '../src/auth0-context';
import { render, waitFor } from '@testing-library/react';
import { renderHook, act } from '@testing-library/react-hooks';
import {
Auth0Client,
GetTokenSilentlyVerboseResponse,
} from '@auth0/auth0-spa-js';
import pkg from '../package.json';
import { createWrapper } from './helpers';
import { Auth0Provider } from '../src';

const clientMock = jest.mocked(new Auth0Client({ client_id: '', domain: '' }));

Expand Down Expand Up @@ -854,4 +856,24 @@ describe('Auth0Provider', () => {

expect(result.current).toBe(memoized);
});

it('should only handle redirect callback once', async () => {
window.history.pushState(
{},
document.title,
'/?code=__test_code__&state=__test_state__'
);
clientMock.handleRedirectCallback.mockResolvedValue({
appState: undefined,
});
render(
<StrictMode>
<Auth0Provider clientId="__test_client_id__" domain="__test_domain__" />
</StrictMode>
);
await waitFor(() => {
expect(clientMock.handleRedirectCallback).toHaveBeenCalledTimes(1);
expect(clientMock.getUser).toHaveBeenCalled();
});
});
});
6 changes: 6 additions & 0 deletions src/auth0-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {
useEffect,
useMemo,
useReducer,
useRef,
useState,
} from 'react';
import {
Expand Down Expand Up @@ -240,8 +241,13 @@ const Auth0Provider = (opts: Auth0ProviderOptions): JSX.Element => {
() => new Auth0Client(toAuth0ClientOptions(clientOpts))
);
const [state, dispatch] = useReducer(reducer, initialAuthState);
const didInitialise = useRef(false);

useEffect(() => {
if (didInitialise.current) {
return;
}
didInitialise.current = true;
(async (): Promise<void> => {
try {
if (hasAuthParams() && !skipRedirectCallback) {
Expand Down
23 changes: 13 additions & 10 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,22 @@
};

return (
<Auth0Provider
domain={identityProvider.domain}
clientId={identityProvider.clientId}
redirectUri={window.location.origin}
useFormData={true}
key={identityProvider.domain}
>
<Playground onChangeIDP={changeIDP} />
</Auth0Provider>
<React.StrictMode>
<Auth0Provider
domain={identityProvider.domain}
clientId={identityProvider.clientId}
redirectUri={window.location.origin}
useFormData={true}
key={identityProvider.domain}
>
<Playground onChangeIDP={changeIDP} />
</Auth0Provider>
</React.StrictMode>
);
};

ReactDOM.render(<App />, document.getElementById('app'));
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<App />);
</script>
</body>
</html>

0 comments on commit e93343b

Please sign in to comment.