Skip to content

Commit

Permalink
Apply Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jjarvisp committed Aug 28, 2024
1 parent 2cdfe15 commit 33a98c8
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 410 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,11 @@

import { Amplify } from '@aws-amplify/core';

import {
confirmSignIn,
getCurrentUser,
signIn,
} from '../../../src/providers/cognito';
import { getCurrentUser, signIn } from '../../../src/providers/cognito';
import * as signInHelpers from '../../../src/providers/cognito/utils/signInHelpers';
import * as clients from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider';
import { signInStore } from '../../../src/providers/cognito/utils/signInStore';
import {
AssociateSoftwareTokenCommandOutput,
RespondToAuthChallengeCommandOutput,
} from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider/types';
import { RespondToAuthChallengeCommandOutput } from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider/types';
import { cognitoUserPoolsTokenProvider } from '../../../src/providers/cognito/tokenProvider';
import { mfaSetupStore } from '../../../src/providers/cognito/utils/mfaSetupStore';

import { authAPITestParams } from './testUtils/authApiTestParams';

Expand Down Expand Up @@ -120,190 +111,3 @@ describe('local sign-in state management tests', () => {
mockedGetCurrentUser.mockClear();
});
});

describe('mfa setup state management tests', () => {
const handleChallengeNameSpy = jest.spyOn(
signInHelpers,
'handleChallengeName',
);
const handleUserSRPAuthFlowSpy = jest.spyOn(
signInHelpers,
'handleUserSRPAuthFlow',
);

beforeAll(() => {
Amplify.configure({ Auth: authConfig });
});

test('mfa setup state should initialize as undefined', () => {
const mfaSetupState = mfaSetupStore.getState();

expect(mfaSetupState).toStrictEqual(undefined);
});

test('mfa setup state should be updated with options during first MFA_SETUP challenge', async () => {
jest.spyOn(signInHelpers, 'handleUserSRPAuthFlow').mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> => ({
ChallengeName: 'MFA_SETUP',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
MFAS_CAN_SETUP: '["SMS_MFA","SOFTWARE_TOKEN_MFA", "EMAIL_OTP"]',
},
}),
);

await signIn({ username, password });

const mfaSetupState = mfaSetupStore.getState();

expect(mfaSetupState).toStrictEqual({
status: 'IN_PROGRESS',
options: ['TOTP', 'EMAIL'],
});
});

test('mfa setup state should be updated with selected value during second MFA_SETUP challenge', async () => {
jest.spyOn(signInHelpers, 'handleUserSRPAuthFlow').mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> => ({
ChallengeName: 'MFA_SETUP',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
MFAS_CAN_SETUP: '["SMS_MFA","SOFTWARE_TOKEN_MFA", "EMAIL_OTP"]',
},
}),
);

await signIn({ username, password });

await confirmSignIn({
challengeResponse: 'EMAIL',
});

expect(mfaSetupStore.getState()).toStrictEqual({
status: 'COMPLETE',
options: ['TOTP', 'EMAIL'],
value: 'EMAIL',
});
});

test('mfa setup state should be cleared with successful sign in', async () => {
handleUserSRPAuthFlowSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeMultipleMfaSetupOutput,
);

await signIn({ username, password });

await confirmSignIn({
challengeResponse: 'EMAIL',
});

handleChallengeNameSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> => ({
ChallengeName: 'EMAIL_OTP',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
CODE_DELIVERY_DELIVERY_MEDIUM: 'EMAIL',
CODE_DELIVERY_DESTINATION: 'j***@a***',
},
}),
);

await confirmSignIn({
challengeResponse: 'j***@a***',
});

handleChallengeNameSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeCommandOutput,
);

await confirmSignIn({
challengeResponse: '123456',
});

const mfaSetupState = mfaSetupStore.getState();

expect(mfaSetupState).toStrictEqual(undefined);
});

test('mfa setup state should be reset with each sign in attempt', async () => {
handleUserSRPAuthFlowSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeMultipleMfaSetupOutput,
);

await signIn({ username, password });

await confirmSignIn({
challengeResponse: 'EMAIL',
});

expect(mfaSetupStore.getState()).toStrictEqual({
status: 'COMPLETE',
options: ['TOTP', 'EMAIL'],
value: 'EMAIL',
});

handleUserSRPAuthFlowSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeCommandOutput,
);

await signIn({ username, password });

expect(mfaSetupStore.getState()).toStrictEqual(undefined);
});

test('mfa setup state should autocomplete when only one allowed MFA setup option is available (EMAIL_OTP)', async () => {
handleUserSRPAuthFlowSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> => ({
ChallengeName: 'MFA_SETUP',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
MFAS_CAN_SETUP: '["SMS_MFA", "EMAIL_OTP"]',
},
}),
);

await signIn({ username, password });

expect(mfaSetupStore.getState()).toStrictEqual({
status: 'COMPLETE',
options: ['EMAIL'],
value: 'EMAIL',
});
});
test('mfa setup state should autocomplete when only one allowed MFA setup option is available (SOFTWARE_TOKEN_MFA)', async () => {
handleUserSRPAuthFlowSpy.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> => ({
ChallengeName: 'MFA_SETUP',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
MFAS_CAN_SETUP: '["SMS_MFA", "SOFTWARE_TOKEN_MFA"]',
},
}),
);

jest.spyOn(clients, 'associateSoftwareToken').mockImplementationOnce(
async (): Promise<AssociateSoftwareTokenCommandOutput> => ({
SecretCode: 'secret-code',
Session: '12341234',
$metadata: {},
}),
);

await signIn({ username, password });

expect(mfaSetupStore.getState()).toStrictEqual({
status: 'COMPLETE',
options: ['TOTP'],
value: 'TOTP',
});
});
});
2 changes: 0 additions & 2 deletions packages/auth/src/providers/cognito/apis/confirmSignIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -111,7 +110,6 @@ export async function confirmSignIn(

if (AuthenticationResult) {
cleanActiveSignInState();
resetMfaSetupState();
await cacheCognitoTokens({
username,
...AuthenticationResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -65,7 +64,6 @@ export async function signInWithCustomAuth(
);

try {
resetMfaSetupState();
const {
ChallengeName: retriedChallengeName,
ChallengeParameters: retiredChallengeParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -68,7 +67,6 @@ export async function signInWithCustomSRPAuth(
);

try {
resetMfaSetupState();
const {
ChallengeName: handledChallengeName,
ChallengeParameters: handledChallengeParameters,
Expand Down
2 changes: 0 additions & 2 deletions packages/auth/src/providers/cognito/apis/signInWithSRP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -68,7 +67,6 @@ export async function signInWithSRP(
);

try {
resetMfaSetupState();
const {
ChallengeName: handledChallengeName,
ChallengeParameters: handledChallengeParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -65,7 +64,6 @@ export async function signInWithUserPassword(
);

try {
resetMfaSetupState();
const {
ChallengeName: retiredChallengeName,
ChallengeParameters: retriedChallengeParameters,
Expand Down
77 changes: 0 additions & 77 deletions packages/auth/src/providers/cognito/utils/mfaSetupStore.ts

This file was deleted.

Loading

0 comments on commit 33a98c8

Please sign in to comment.