From 7b30970caeca2b63483861990391852b061904d3 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 28 Aug 2024 11:43:31 -0400 Subject: [PATCH] Apply Feedback --- .../providers/cognito/apis/confirmSignIn.ts | 2 - .../cognito/apis/signInWithCustomAuth.ts | 2 - .../cognito/apis/signInWithCustomSRPAuth.ts | 2 - .../providers/cognito/apis/signInWithSRP.ts | 2 - .../cognito/apis/signInWithUserPassword.ts | 2 - .../providers/cognito/utils/mfaSetupStore.ts | 77 -------- .../providers/cognito/utils/signInHelpers.ts | 173 ++++++------------ 7 files changed, 56 insertions(+), 204 deletions(-) delete mode 100644 packages/auth/src/providers/cognito/utils/mfaSetupStore.ts diff --git a/packages/auth/src/providers/cognito/apis/confirmSignIn.ts b/packages/auth/src/providers/cognito/apis/confirmSignIn.ts index 68037e56bcf..badbdf7850e 100644 --- a/packages/auth/src/providers/cognito/apis/confirmSignIn.ts +++ b/packages/auth/src/providers/cognito/apis/confirmSignIn.ts @@ -33,7 +33,6 @@ import { } from '../utils/clients/CognitoIdentityProvider/types'; import { tokenOrchestrator } from '../tokenProvider'; import { dispatchSignedInHubEvent } from '../utils/dispatchSignedInHubEvent'; -import { resetMfaSetupState } from '../utils/mfaSetupStore'; /** * Continues or completes the sign in process when required by the initial call to `signIn`. @@ -111,7 +110,6 @@ export async function confirmSignIn( if (AuthenticationResult) { cleanActiveSignInState(); - resetMfaSetupState(); await cacheCognitoTokens({ username, ...AuthenticationResult, diff --git a/packages/auth/src/providers/cognito/apis/signInWithCustomAuth.ts b/packages/auth/src/providers/cognito/apis/signInWithCustomAuth.ts index 56c12c3c0d7..e55e3f0a50d 100644 --- a/packages/auth/src/providers/cognito/apis/signInWithCustomAuth.ts +++ b/packages/auth/src/providers/cognito/apis/signInWithCustomAuth.ts @@ -32,7 +32,6 @@ import { } from '../utils/clients/CognitoIdentityProvider/types'; import { tokenOrchestrator } from '../tokenProvider'; import { dispatchSignedInHubEvent } from '../utils/dispatchSignedInHubEvent'; -import { resetMfaSetupState } from '../utils/mfaSetupStore'; /** * Signs a user in using a custom authentication flow without password @@ -65,7 +64,6 @@ export async function signInWithCustomAuth( ); try { - resetMfaSetupState(); const { ChallengeName: retriedChallengeName, ChallengeParameters: retiredChallengeParameters, diff --git a/packages/auth/src/providers/cognito/apis/signInWithCustomSRPAuth.ts b/packages/auth/src/providers/cognito/apis/signInWithCustomSRPAuth.ts index 3a09dc451d0..a67fa9f861c 100644 --- a/packages/auth/src/providers/cognito/apis/signInWithCustomSRPAuth.ts +++ b/packages/auth/src/providers/cognito/apis/signInWithCustomSRPAuth.ts @@ -34,7 +34,6 @@ import { } from '../utils/clients/CognitoIdentityProvider/types'; import { tokenOrchestrator } from '../tokenProvider'; import { dispatchSignedInHubEvent } from '../utils/dispatchSignedInHubEvent'; -import { resetMfaSetupState } from '../utils/mfaSetupStore'; /** * Signs a user in using a custom authentication flow with SRP @@ -68,7 +67,6 @@ export async function signInWithCustomSRPAuth( ); try { - resetMfaSetupState(); const { ChallengeName: handledChallengeName, ChallengeParameters: handledChallengeParameters, diff --git a/packages/auth/src/providers/cognito/apis/signInWithSRP.ts b/packages/auth/src/providers/cognito/apis/signInWithSRP.ts index 55803dc93f6..32f0ca11b99 100644 --- a/packages/auth/src/providers/cognito/apis/signInWithSRP.ts +++ b/packages/auth/src/providers/cognito/apis/signInWithSRP.ts @@ -34,7 +34,6 @@ import { import { cacheCognitoTokens } from '../tokenProvider/cacheTokens'; import { tokenOrchestrator } from '../tokenProvider'; import { dispatchSignedInHubEvent } from '../utils/dispatchSignedInHubEvent'; -import { resetMfaSetupState } from '../utils/mfaSetupStore'; /** * Signs a user in @@ -68,7 +67,6 @@ export async function signInWithSRP( ); try { - resetMfaSetupState(); const { ChallengeName: handledChallengeName, ChallengeParameters: handledChallengeParameters, diff --git a/packages/auth/src/providers/cognito/apis/signInWithUserPassword.ts b/packages/auth/src/providers/cognito/apis/signInWithUserPassword.ts index 4d6fcde107b..e1de730cb1c 100644 --- a/packages/auth/src/providers/cognito/apis/signInWithUserPassword.ts +++ b/packages/auth/src/providers/cognito/apis/signInWithUserPassword.ts @@ -32,7 +32,6 @@ import { import { cacheCognitoTokens } from '../tokenProvider/cacheTokens'; import { tokenOrchestrator } from '../tokenProvider'; import { dispatchSignedInHubEvent } from '../utils/dispatchSignedInHubEvent'; -import { resetMfaSetupState } from '../utils/mfaSetupStore'; /** * Signs a user in using USER_PASSWORD_AUTH AuthFlowType @@ -65,7 +64,6 @@ export async function signInWithUserPassword( ); try { - resetMfaSetupState(); const { ChallengeName: retiredChallengeName, ChallengeParameters: retriedChallengeParameters, diff --git a/packages/auth/src/providers/cognito/utils/mfaSetupStore.ts b/packages/auth/src/providers/cognito/utils/mfaSetupStore.ts deleted file mode 100644 index fdb564f0d13..00000000000 --- a/packages/auth/src/providers/cognito/utils/mfaSetupStore.ts +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { AuthMFAType } from '../../../types'; - -import { Reducer, Store } from './types'; - -type MfaSetupInitial = undefined; - -interface MfaSetupSelectionRequired { - status: 'IN_PROGRESS'; - options: AuthMFAType[]; -} -interface MfaSetupSelectionComplete { - status: 'COMPLETE'; - value: AuthMFAType; - options: AuthMFAType[]; -} - -type MfaSetupState = - | MfaSetupInitial - | MfaSetupSelectionRequired - | MfaSetupSelectionComplete; - -type MfaSetupAction = - | { type: 'RESET' } - | { type: 'IN_PROGRESS'; value: AuthMFAType[] } - | { type: 'COMPLETE'; value: AuthMFAType } - | { type: 'AUTO'; value: Omit }; - -const mfaSetupReducer: Reducer = ( - state, - action, -) => { - if (action.type === 'RESET') { - return; - } - if (action.type === 'IN_PROGRESS') { - return { - status: 'IN_PROGRESS', - options: action.value, - }; - } - if (state?.status === 'IN_PROGRESS' && action.type === 'COMPLETE') { - return { - ...state, - status: 'COMPLETE', - value: action.value, - }; - } - if (action.type === 'AUTO') { - return { - status: 'COMPLETE', - options: action.value.options, - value: action.value.value, - }; - } - - return state; -}; - -const createStore: Store = reducer => { - let currentState: MfaSetupState; - - return { - getState: () => currentState, - dispatch: action => { - currentState = reducer(currentState, action); - }, - }; -}; - -export const mfaSetupStore = createStore(mfaSetupReducer); - -export const resetMfaSetupState = () => { - mfaSetupStore.dispatch({ type: 'RESET' }); -}; diff --git a/packages/auth/src/providers/cognito/utils/signInHelpers.ts b/packages/auth/src/providers/cognito/utils/signInHelpers.ts index aa2775117e2..d43c83d8c11 100644 --- a/packages/auth/src/providers/cognito/utils/signInHelpers.ts +++ b/packages/auth/src/providers/cognito/utils/signInHelpers.ts @@ -61,7 +61,6 @@ import { import { BigInteger } from './srp/BigInteger'; import { AuthenticationHelper } from './srp/AuthenticationHelper'; import { getUserContextData } from './userContextData'; -import { mfaSetupStore } from './mfaSetupStore'; const USER_ATTRIBUTES = 'userAttributes.'; @@ -150,76 +149,74 @@ export async function handleMFASetupChallenge({ }: HandleAuthChallengeRequest): Promise { const { userPoolId, userPoolClientId } = config; - const mfaSetupState = mfaSetupStore.getState(); - - if (mfaSetupState?.status === 'IN_PROGRESS') { - if ( - (challengeResponse === 'EMAIL' || challengeResponse === 'TOTP') && - mfaSetupState.options.includes(challengeResponse) - ) { - mfaSetupStore.dispatch({ type: 'COMPLETE', value: challengeResponse }); - - return { - ChallengeName: 'MFA_SETUP', - Session: session, - $metadata: {}, - }; - } + if (challengeResponse === 'EMAIL') { + return { + ChallengeName: 'MFA_SETUP', + Session: session, + ChallengeParameters: { + MFAS_CAN_SETUP: '["EMAIL_MFA"]', + }, + $metadata: {}, + }; } - if (mfaSetupState?.status === 'COMPLETE') { - const challengeResponses: Record = { - USERNAME: username, + if (challengeResponse === 'TOTP') { + return { + ChallengeName: 'MFA_SETUP', + Session: session, + ChallengeParameters: { + MFAS_CAN_SETUP: '["SOFTWARE_TOKEN_MFA"]', + }, + $metadata: {}, }; + } - if (mfaSetupState.value === 'EMAIL') { - challengeResponses.EMAIL = challengeResponse; + const isTOTPCode = /^\d+$/.test(challengeResponse.trim()); - const jsonReq: RespondToAuthChallengeCommandInput = { - ChallengeName: 'MFA_SETUP', - ChallengeResponses: challengeResponses, + const challengeResponses: Record = { + USERNAME: username, + }; + + if (isTOTPCode) { + const { Session } = await verifySoftwareToken( + { + region: getRegion(userPoolId), + userAgentValue: getAuthUserAgentValue(AuthAction.ConfirmSignIn), + }, + { + UserCode: challengeResponse, Session: session, - ClientMetadata: clientMetadata, - ClientId: userPoolClientId, - }; + FriendlyDeviceName: deviceName, + }, + ); - return respondToAuthChallenge({ region: getRegion(userPoolId) }, jsonReq); - } + signInStore.dispatch({ + type: 'SET_SIGN_IN_SESSION', + value: Session, + }); - if (mfaSetupState.value === 'TOTP') { - const { Session } = await verifySoftwareToken( - { - region: getRegion(userPoolId), - userAgentValue: getAuthUserAgentValue(AuthAction.ConfirmSignIn), - }, - { - UserCode: challengeResponse, - Session: session, - FriendlyDeviceName: deviceName, - }, - ); + const jsonReq: RespondToAuthChallengeCommandInput = { + ChallengeName: 'MFA_SETUP', + ChallengeResponses: challengeResponses, + Session, + ClientMetadata: clientMetadata, + ClientId: userPoolClientId, + }; - signInStore.dispatch({ - type: 'SET_SIGN_IN_SESSION', - value: Session, - }); + return respondToAuthChallenge({ region: getRegion(userPoolId) }, jsonReq); + } - const jsonReq: RespondToAuthChallengeCommandInput = { - ChallengeName: 'MFA_SETUP', - ChallengeResponses: challengeResponses, - Session, - ClientMetadata: clientMetadata, - ClientId: userPoolClientId, - }; + challengeResponses.EMAIL = challengeResponse; - return respondToAuthChallenge({ region: getRegion(userPoolId) }, jsonReq); - } - } + const jsonReq: RespondToAuthChallengeCommandInput = { + ChallengeName: 'MFA_SETUP', + ChallengeResponses: challengeResponses, + Session: session, + ClientMetadata: clientMetadata, + ClientId: userPoolClientId, + }; - throw new AuthError({ - name: AuthErrorCodes.SignInException, - message: `Cannot initiate MFA setup from available types: ${mfaSetupState?.options}`, - }); + return respondToAuthChallenge({ region: getRegion(userPoolId) }, jsonReq); } export async function handleSelectMFATypeChallenge({ @@ -732,43 +729,6 @@ export async function getSignInResult(params: { }; case 'MFA_SETUP': { const { signInSession, username } = signInStore.getState(); - const mfaSetupState = mfaSetupStore.getState(); - - if (mfaSetupState?.status === 'COMPLETE') { - if (mfaSetupState.value === 'EMAIL') { - return { - isSignedIn: false, - nextStep: { - signInStep: 'CONTINUE_SIGN_IN_WITH_EMAIL_SETUP', - }, - }; - } - if (mfaSetupState.value === 'TOTP') { - const { Session, SecretCode: secretCode } = - await associateSoftwareToken( - { region: getRegion(authConfig.userPoolId) }, - { - Session: signInSession, - }, - ); - signInStore.dispatch({ - type: 'SET_SIGN_IN_SESSION', - value: Session, - }); - - return { - isSignedIn: false, - nextStep: { - signInStep: 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP', - totpSetupDetails: getTOTPSetupDetails(secretCode!, username), - }, - }; - } - throw new AuthError({ - name: AuthErrorCodes.SignInException, - message: `Cannot initiate MFA setup from available types: ${mfaSetupState.options}`, - }); - } const allowedMfaSetupTypes = getAllowedMfaSetupTypes( challengeParameters.MFAS_CAN_SETUP, @@ -778,11 +738,6 @@ export async function getSignInResult(params: { const isEmailMfaSetupAvailable = allowedMfaSetupTypes.includes('EMAIL'); if (isTotpMfaSetupAvailable && isEmailMfaSetupAvailable) { - mfaSetupStore.dispatch({ - type: 'IN_PROGRESS', - value: allowedMfaSetupTypes, - }); - return { isSignedIn: false, nextStep: { @@ -793,14 +748,6 @@ export async function getSignInResult(params: { } if (isEmailMfaSetupAvailable) { - mfaSetupStore.dispatch({ - type: 'AUTO', - value: { - value: 'EMAIL', - options: allowedMfaSetupTypes, - }, - }); - return { isSignedIn: false, nextStep: { @@ -810,14 +757,6 @@ export async function getSignInResult(params: { } if (isTotpMfaSetupAvailable) { - mfaSetupStore.dispatch({ - type: 'AUTO', - value: { - value: 'TOTP', - options: allowedMfaSetupTypes, - }, - }); - const { Session, SecretCode: secretCode } = await associateSoftwareToken( { region: getRegion(authConfig.userPoolId) },