Skip to content

Commit

Permalink
chore: add invalid mfa code tests to authenticator
Browse files Browse the repository at this point in the history
  • Loading branch information
khatruong2009 committed Oct 22, 2024
1 parent d5ec3c3 commit e355d02
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ void main() {

group('sign-in-email-mfa', () {
testRunner.withEnvironment(mfaRequiredEmail, (env) {
// Scenario: Sign in using a totp code
testWidgets('Setup & Sign in with EMAIL MFA', (tester) async {
// Scenario: Sign in using a valid email MFA code
testWidgets('Sign in with valid EMAIL MFA code', (tester) async {
final username = env.generateUsername();
final password = generatePassword();

Expand Down Expand Up @@ -57,7 +57,7 @@ void main() {
// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the totp setup page
// Then I will be redirected to the email MFA code page
await confirmSignInPage.expectConfirmSignInWithEmailMfaCodeIsPresent();

final otpResult = await getOtpCode(
Expand Down Expand Up @@ -106,6 +106,59 @@ void main() {

await tester.bloc.close();
});

// Scenario: Sign in using an invalid email MFA code
testWidgets('Sign in with invalid EMAIL MFA code', (tester) async {
final username = env.generateUsername();
final password = generatePassword();

await adminCreateUser(
username,
password,
autoConfirm: true,
attributes: {
AuthUserAttributeKey.email: username,
},
autoFillAttributes: false,
);

await loadAuthenticator(tester: tester);

expect(
tester.bloc.stream,
emitsInOrder([
UnauthenticatedState.signIn,
UnauthenticatedState.confirmSignInWithEmailMfaCode,
emitsDone,
]),
);

final signInPage = SignInPage(tester: tester);
final confirmSignInPage = ConfirmSignInPage(tester: tester);

// When I type my "username"
await signInPage.enterUsername(username);

// And I type my password
await signInPage.enterPassword(password);

// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the EMAIL OTP code page
await confirmSignInPage.expectConfirmSignInWithEmailMfaCodeIsPresent();

// And I type an invalid confirmation code
await confirmSignInPage.enterVerificationCode('123456');

// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignIn();

// Then I see "The code entered is not correct."
confirmSignInPage.expectInvalidVerificationCode();

await tester.bloc.close();
});
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ void main() {
UnauthenticatedState.continueSignInWithEmailMfaSetup,
UnauthenticatedState.confirmSignInWithEmailMfaCode,
isA<AuthenticatedState>(),
UnauthenticatedState.signIn,
isA<ContinueSignInWithMfaSelection>(),
UnauthenticatedState.confirmSignInWithTotpMfaCode,
isA<AuthenticatedState>(),
emitsDone,
]),
);
Expand All @@ -62,7 +58,7 @@ void main() {
// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the confirm email mfa page
// Then I will be redirected to the MFA setup selection page
await confirmSignInPage
.expectContinueSignInWithMfaSetupSelectionIsPresent();

Expand All @@ -72,7 +68,7 @@ void main() {
// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();

// Then I will be redirected to the EMAIL mfa setup page
// Then I will be redirected to the EMAIL MFA setup page
await emailMfaSetupPage.expectEmailMfaSetupIsPresent();

// When I type a valid email
Expand All @@ -90,15 +86,44 @@ void main() {
// Then I see the authenticated app
await signInPage.expectAuthenticated();

// When I enable TOTP for MFA instead of the default set up by cognito (EMAIL)
await setUpTotp();
await tester.bloc.close();
});

// And I sign out using Auth.signOut()
await Amplify.Auth.signOut();
await tester.pumpAndSettle();
// Scenario: Select TOTP MFA to set up from the setup selection page
testWidgets('can select TOTP MFA to set up', (tester) async {
final username = env.generateUsername();
final password = generatePassword();
late String sharedSecret;

await adminCreateUser(
username,
password,
autoConfirm: true,
verifyAttributes: false,
autoFillAttributes: false,
);

await loadAuthenticator(tester: tester);

tester.bloc.stream.listen((event) {
if (event is ContinueSignInTotpSetup) {
sharedSecret = event.totpSetupDetails.sharedSecret;
}
});

expect(
tester.bloc.stream,
emitsInOrder([
UnauthenticatedState.signIn,
isA<ContinueSignInWithMfaSetupSelection>(),
isA<ContinueSignInTotpSetup>(),
isA<AuthenticatedState>(),
emitsDone,
]),
);

// Then I see the sign in page
signInPage.expectUsername();
final signInPage = SignInPage(tester: tester);
final confirmSignInPage = ConfirmSignInPage(tester: tester);

// When I type my "username"
await signInPage.enterUsername(username);
Expand All @@ -109,22 +134,23 @@ void main() {
// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the MFA selection page
await confirmSignInPage.expectConfirmSignInMfaSelectionIsPresent();
// Then I will be redirected to the MFA setup selection page
await confirmSignInPage
.expectContinueSignInWithMfaSetupSelectionIsPresent();

// When I select "TOTP"
await confirmSignInPage.selectMfaMethod(mfaMethod: MfaType.totp);
await confirmSignInPage.selectMfaSetupMethod(mfaMethod: MfaType.totp);

// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignInMfaSelection();
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();

// Then I will be redirected to the TOTP MFA code page
await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent();
// Then I will be redirected to the TOTP MFA setup page
await confirmSignInPage.expectSignInTotpSetupIsPresent();

final code_2 = await generateTotpCode();
final totpCode = await generateTotpCode(sharedSecret);

// When I type a valid TOTP code
await confirmSignInPage.enterVerificationCode(code_2);
await confirmSignInPage.enterVerificationCode(totpCode);

// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignIn();
Expand All @@ -135,8 +161,8 @@ void main() {
await tester.bloc.close();
});

// Scenario: Sign in using a EMAIL code when both EMAIL and TOTP are enabled
testWidgets('can select TOTP MFA to set up', (tester) async {
// Scenario: Sign in using an invalid TOTP code
testWidgets('sign in with invalid TOTP code', (tester) async {
final username = env.generateUsername();
final password = generatePassword();
late String sharedSecret;
Expand Down Expand Up @@ -166,7 +192,6 @@ void main() {
isA<AuthenticatedState>(),
UnauthenticatedState.signIn,
UnauthenticatedState.confirmSignInWithTotpMfaCode,
isA<AuthenticatedState>(),
emitsDone,
]),
);
Expand All @@ -183,7 +208,7 @@ void main() {
// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the confirm email mfa page
// Then I will be redirected to the MFA setup selection page
await confirmSignInPage
.expectContinueSignInWithMfaSetupSelectionIsPresent();

Expand All @@ -193,12 +218,12 @@ void main() {
// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();

// Then I will be redirected to the TOTP mfa setup page
// Then I will be redirected to the TOTP MFA setup page
await confirmSignInPage.expectSignInTotpSetupIsPresent();

final totpCode = await generateTotpCode(sharedSecret);

// And I type a valid TOTP code
// When I type a valid TOTP code
await confirmSignInPage.enterVerificationCode(totpCode);

// And I click the "Confirm" button
Expand All @@ -207,35 +232,27 @@ void main() {
// Then I see the authenticated app
await signInPage.expectAuthenticated();

// And I sign out using Auth.signOut()
// Sign out to test invalid TOTP code during sign-in
await Amplify.Auth.signOut();
await tester.pumpAndSettle();

// Then I see the sign in page
signInPage.expectUsername();

// When I type my "username"
// When I attempt to sign in again
await signInPage.enterUsername(username);

// And I type my password
await signInPage.enterPassword(password);

// And I click the "Sign in" button
await signInPage.submitSignIn();

// Then I will be redirected to the TOTP MFA code page
await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent();
await confirmSignInPage
.expectConfirmSignInWithTotpMfaCodeIsPresent();

final code_2 = await generateTotpCode(sharedSecret);

// When I type a valid TOTP code
await confirmSignInPage.enterVerificationCode(code_2);
// When I type an invalid TOTP code
await confirmSignInPage.enterVerificationCode('000000');

// And I click the "Confirm" button
await confirmSignInPage.submitConfirmSignIn();

// Then I see the authenticated app
await signInPage.expectAuthenticated();
// Then I see "Invalid code" error message
confirmSignInPage.expectInvalidVerificationCode();

await tester.bloc.close();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ class ConfirmSignInPage extends AuthenticatorPage {
expect(newPasswordField, findsOneWidget);
}

/// Then I see "Invalid verification code"
@override
void expectInvalidVerificationCode() {
expectError('Invalid code');
}

/// When I enter a verification code
Future<void> enterVerificationCode(String code) async {
await tester.ensureVisible(verificationField);
Expand Down

0 comments on commit e355d02

Please sign in to comment.