diff --git a/__tests__/with-authentication-required.test.tsx b/__tests__/with-authentication-required.test.tsx index 28de08b6..46617103 100644 --- a/__tests__/with-authentication-required.test.tsx +++ b/__tests__/with-authentication-required.test.tsx @@ -66,6 +66,26 @@ describe('withAuthenticationRequired', () => { ); }); + it('should call onBeforeAuthentication before loginWithRedirect', async () => { + const callOrder: string[] = []; + mockClient.getUser.mockResolvedValue(undefined); + mockClient.loginWithRedirect.mockImplementationOnce(async ()=>{ callOrder.push('loginWithRedirect') }); + const MyComponent = (): JSX.Element => <>Private; + const OnBeforeAuthentication = jest.fn().mockImplementationOnce(async ()=>{ callOrder.push('onBeforeAuthentication') }); + const WrappedComponent = withAuthenticationRequired(MyComponent, { + onBeforeAuthentication: OnBeforeAuthentication, + }); + render( + + + + ); + + await waitFor(() => expect(OnBeforeAuthentication).toHaveBeenCalledTimes(1)); + await waitFor(() => expect(mockClient.loginWithRedirect).toHaveBeenCalledTimes(1)); + await waitFor(() => expect(callOrder).toEqual(['onBeforeAuthentication', 'loginWithRedirect'])); + }); + it('should pass additional options on to loginWithRedirect', async () => { mockClient.getUser.mockResolvedValue(undefined); const MyComponent = (): JSX.Element => <>Private; diff --git a/src/with-authentication-required.tsx b/src/with-authentication-required.tsx index 42022632..2f914c72 100644 --- a/src/with-authentication-required.tsx +++ b/src/with-authentication-required.tsx @@ -10,6 +10,11 @@ import Auth0Context, { */ const defaultOnRedirecting = (): JSX.Element => <>; +/** +* @ignore +*/ +const defaultOnBeforeAuthentication = async (): Promise => {/* noop */}; + /** * @ignore */ @@ -48,6 +53,16 @@ export interface WithAuthenticationRequiredOptions { * Render a message to show that the user is being redirected to the login. */ onRedirecting?: () => JSX.Element; + /** + * ```js + * withAuthenticationRequired(Profile, { + * onBeforeAuthentication: () => { analyticsLibrary.track('login_triggered'); } + * }) + * ``` + * + * Allows executing logic before the user is redirected to the login page. + */ + onBeforeAuthentication?: () => Promise; /** * ```js * withAuthenticationRequired(Profile, { @@ -87,6 +102,7 @@ const withAuthenticationRequired =

( const { returnTo = defaultReturnTo, onRedirecting = defaultOnRedirecting, + onBeforeAuthentication = defaultOnBeforeAuthentication, loginOptions, context = Auth0Context, } = options; @@ -106,12 +122,14 @@ const withAuthenticationRequired =

( }, }; (async (): Promise => { + await onBeforeAuthentication(); await loginWithRedirect(opts); })(); }, [ isLoading, isAuthenticated, loginWithRedirect, + onBeforeAuthentication, loginOptions, returnTo, ]);