diff --git a/packages/auth/__tests__/providers/cognito/utils/oauth/completeOAuthFlow.test.ts b/packages/auth/__tests__/providers/cognito/utils/oauth/completeOAuthFlow.test.ts index 8d62c014a94..5478a230394 100644 --- a/packages/auth/__tests__/providers/cognito/utils/oauth/completeOAuthFlow.test.ts +++ b/packages/auth/__tests__/providers/cognito/utils/oauth/completeOAuthFlow.test.ts @@ -151,6 +151,8 @@ describe('completeOAuthFlow', () => { token_type: 'token_type', expires_in: 'expires_in', }; + const executionOrder: string[] = []; + mockValidateState.mockReturnValueOnce('myState-valid_state'); (oAuthStore.loadPKCE as jest.Mock).mockResolvedValueOnce('pkce23234a'); const mockJsonMethod = jest.fn(() => Promise.resolve(expectedTokens)); @@ -162,6 +164,12 @@ describe('completeOAuthFlow', () => { mockFetch.mockResolvedValueOnce({ json: mockJsonMethod, }); + mockReplaceState.mockImplementation((..._args) => + executionOrder.push('replaceState'), + ); + mockHubDispatch.mockImplementation(() => + executionOrder.push('hubDispatch'), + ); await completeOAuthFlow(testInput); @@ -180,17 +188,27 @@ describe('completeOAuthFlow', () => { TokenType: expectedTokens.token_type, ExpiresIn: expectedTokens.expires_in, }); + + expect(oAuthStore.clearOAuthData).toHaveBeenCalledTimes(1); + expect(oAuthStore.storeOAuthSignIn).toHaveBeenCalledWith(true, undefined); + + expect(mockResolveAndClearInflightPromises).toHaveBeenCalledTimes(1); + expect(mockReplaceState).toHaveBeenCalledWith( 'http://localhost:3000/?code=aaaa-111-222&state=aaaaa', '', testInput.redirectUri, ); - expect(oAuthStore.clearOAuthData).toHaveBeenCalledTimes(1); - expect(oAuthStore.storeOAuthSignIn).toHaveBeenCalledWith(true, undefined); - expect(mockHubDispatch).toHaveBeenCalledTimes(3); - expect(mockResolveAndClearInflightPromises).toHaveBeenCalledTimes(1); + + // Verify we replace browser tab location before dispatching hub events + expect(executionOrder).toEqual([ + 'replaceState', + 'hubDispatch', + 'hubDispatch', + 'hubDispatch', + ]); }); it('throws when `fetch` call resolves error', async () => { diff --git a/packages/auth/src/providers/cognito/utils/oauth/completeOAuthFlow.ts b/packages/auth/src/providers/cognito/utils/oauth/completeOAuthFlow.ts index f374ed98156..e82e152dab3 100644 --- a/packages/auth/src/providers/cognito/utils/oauth/completeOAuthFlow.ts +++ b/packages/auth/src/providers/cognito/utils/oauth/completeOAuthFlow.ts @@ -239,6 +239,9 @@ const completeFlow = async ({ // `fetchAuthSession` can be resolved resolveAndClearInflightPromises(); + // clear history before sending out final Hub events + clearHistory(redirectUri); + if (isCustomState(state)) { Hub.dispatch( 'auth', @@ -252,7 +255,6 @@ const completeFlow = async ({ } Hub.dispatch('auth', { event: 'signInWithRedirect' }, 'Auth', AMPLIFY_SYMBOL); await dispatchSignedInHubEvent(); - clearHistory(redirectUri); }; const isCustomState = (state: string): boolean => {