Skip to content

Commit 35dae2a

Browse files
authored
chore(rwa): convert AuthChallengeNames enum to string union (#2544)
1 parent ba9818f commit 35dae2a

File tree

9 files changed

+70
-62
lines changed

9 files changed

+70
-62
lines changed

.changeset/gentle-ads-hang.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@aws-amplify/ui-react": patch
3+
"@aws-amplify/ui": patch
4+
"@aws-amplify/ui-vue": patch
5+
"@aws-amplify/ui-angular": patch
6+
---
7+
8+
chore(rwa): convert AuthChallengeNames enum to string union

packages/angular/projects/ui-angular/src/lib/components/authenticator/components/confirm-sign-in/confirm-sign-in.component.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Component, HostBinding, OnInit } from '@angular/core';
22
import { Logger } from 'aws-amplify';
33
import {
4-
AuthChallengeNames,
54
FormFieldsArray,
65
getActorContext,
76
getFormDataFromEvent,
@@ -40,10 +39,10 @@ export class ConfirmSignInComponent implements OnInit {
4039
const actorContext = getActorContext(state) as SignInContext;
4140
const { challengeName } = actorContext;
4241
switch (challengeName) {
43-
case AuthChallengeNames.SOFTWARE_TOKEN_MFA:
42+
case 'SOFTWARE_TOKEN_MFA':
4443
this.headerText = translate('Confirm TOTP Code');
4544
break;
46-
case AuthChallengeNames.SMS_MFA:
45+
case 'SMS_MFA':
4746
this.headerText = translate('Confirm SMS Code');
4847
break;
4948
default:

packages/react/src/components/Authenticator/ConfirmSignIn/ConfirmSignIn.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { AuthChallengeNames, getActorState, translate } from '@aws-amplify/ui';
2+
import { getActorState, translate } from '@aws-amplify/ui';
33

44
import { Flex } from '../../../primitives/Flex';
55
import { Heading } from '../../../primitives/Heading';
@@ -61,10 +61,10 @@ function Header() {
6161
let headerText: string;
6262

6363
switch (challengeName) {
64-
case AuthChallengeNames.SMS_MFA:
64+
case 'SMS_MFA':
6565
headerText = translate('Confirm SMS Code');
6666
break;
67-
case AuthChallengeNames.SOFTWARE_TOKEN_MFA:
67+
case 'SOFTWARE_TOKEN_MFA':
6868
headerText = translate('Confirm TOTP Code');
6969
break;
7070
default:

packages/ui/src/machines/authenticator/actors/signIn.ts

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { Auth } from 'aws-amplify';
22
import get from 'lodash/get';
33
import isEmpty from 'lodash/isEmpty';
44
import { createMachine, sendUpdate } from 'xstate';
5-
import { AuthChallengeNames, AuthEvent, SignInContext } from '../../../types';
5+
import {
6+
AuthChallengeName,
7+
AuthEvent,
8+
CognitoUserAmplify,
9+
SignInContext,
10+
} from '../../../types';
611
import { runValidators } from '../../../validators';
712
import {
813
clearAttributeToVerify,
@@ -34,6 +39,22 @@ export type SignInMachineOptions = {
3439
services?: Partial<typeof defaultServices>;
3540
};
3641

42+
const MFA_CHALLENGE_NAMES: AuthChallengeName[] = [
43+
'SMS_MFA',
44+
'SOFTWARE_TOKEN_MFA',
45+
];
46+
47+
const getChallengeName = (event: AuthEvent): AuthChallengeName =>
48+
get(event, 'data.challengeName');
49+
50+
const isExpectedChallengeName = (
51+
challengeName: AuthChallengeName,
52+
expectedChallengeName: AuthChallengeName
53+
) => challengeName === expectedChallengeName;
54+
55+
const isMfaChallengeName = (challengeName: AuthChallengeName) =>
56+
MFA_CHALLENGE_NAMES.includes(challengeName);
57+
3758
export function signInActor({ services }: SignInMachineOptions) {
3859
return createMachine<SignInContext, AuthEvent>(
3960
{
@@ -461,13 +482,7 @@ export function signInActor({ services }: SignInMachineOptions) {
461482
},
462483
guards: {
463484
shouldConfirmSignIn: (_, event): boolean => {
464-
const challengeName = get(event, 'data.challengeName');
465-
const validChallengeNames = [
466-
AuthChallengeNames.SMS_MFA,
467-
AuthChallengeNames.SOFTWARE_TOKEN_MFA,
468-
];
469-
470-
return validChallengeNames.includes(challengeName);
485+
return isMfaChallengeName(getChallengeName(event));
471486
},
472487
shouldAutoSignIn: (context) => {
473488
return context?.intent === 'autoSignIn';
@@ -479,14 +494,13 @@ export function signInActor({ services }: SignInMachineOptions) {
479494
return event.data.code === 'PasswordResetRequiredException';
480495
},
481496
shouldSetupTOTP: (_, event): boolean => {
482-
const challengeName = get(event, 'data.challengeName');
483-
484-
return challengeName === AuthChallengeNames.MFA_SETUP;
497+
return isExpectedChallengeName(getChallengeName(event), 'MFA_SETUP');
485498
},
486499
shouldForceChangePassword: (_, event): boolean => {
487-
const challengeName = get(event, 'data.challengeName');
488-
489-
return challengeName === AuthChallengeNames.NEW_PASSWORD_REQUIRED;
500+
return isExpectedChallengeName(
501+
getChallengeName(event),
502+
'NEW_PASSWORD_REQUIRED'
503+
);
490504
},
491505
shouldRequestVerification: (_, event): boolean => {
492506
const { unverified, verified } = event.data;
@@ -511,22 +525,18 @@ export function signInActor({ services }: SignInMachineOptions) {
511525
password,
512526
});
513527
},
514-
async confirmSignIn(context, event) {
528+
async confirmSignIn(context) {
515529
const { challengeName, user } = context;
516530
const { confirmation_code: code } = context.formValues;
517531

518-
let mfaType;
519-
if (
520-
challengeName === AuthChallengeNames.SMS_MFA ||
521-
challengeName === AuthChallengeNames.SOFTWARE_TOKEN_MFA
522-
) {
523-
mfaType = challengeName;
524-
}
532+
const mfaType = isMfaChallengeName(challengeName)
533+
? challengeName
534+
: undefined;
525535

526536
await services.handleConfirmSignIn({ user, code, mfaType });
527537
return await Auth.currentAuthenticatedUser();
528538
},
529-
async forceNewPassword(context, event) {
539+
async forceNewPassword(context) {
530540
const { user, formValues } = context;
531541
let {
532542
password,
@@ -545,7 +555,7 @@ export function signInActor({ services }: SignInMachineOptions) {
545555

546556
try {
547557
// complete forceNewPassword flow and get updated CognitoUser
548-
const newUser = await Auth.completeNewPassword(
558+
const newUser: CognitoUserAmplify = await Auth.completeNewPassword(
549559
user,
550560
password,
551561
rest
@@ -569,9 +579,9 @@ export function signInActor({ services }: SignInMachineOptions) {
569579
return Promise.reject(err);
570580
}
571581
},
572-
async verifyTotpToken(context, event) {
573-
const { user } = context;
574-
const { confirmation_code } = context.formValues;
582+
async verifyTotpToken(context) {
583+
const { formValues, user } = context;
584+
const { confirmation_code } = formValues;
575585

576586
return Auth.verifyTotpToken(user, confirmation_code);
577587
},
@@ -580,21 +590,21 @@ export function signInActor({ services }: SignInMachineOptions) {
580590

581591
return await Auth.federatedSignIn({ provider });
582592
},
583-
async checkVerifiedContact(context, event) {
593+
async checkVerifiedContact(context) {
584594
const { user } = context;
585595
const result = await Auth.verifiedContact(user);
586596

587597
return result;
588598
},
589-
async verifyUser(context, event) {
599+
async verifyUser(context) {
590600
const { unverifiedAttr } = context.formValues;
591601
const result = await Auth.verifyCurrentUserAttribute(unverifiedAttr);
592602

593603
context.attributeToVerify = unverifiedAttr;
594604

595605
return result;
596606
},
597-
async confirmVerifyUser(context, event) {
607+
async confirmVerifyUser(context) {
598608
const { attributeToVerify } = context;
599609
const { confirmation_code } = context.formValues;
600610

@@ -603,7 +613,7 @@ export function signInActor({ services }: SignInMachineOptions) {
603613
confirmation_code
604614
);
605615
},
606-
async validateFields(context, event) {
616+
async validateFields(context) {
607617
return runValidators(
608618
context.formValues,
609619
context.touched,

packages/ui/src/machines/authenticator/defaultServices.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Amplify, Auth } from 'aws-amplify';
22
import { hasSpecialChars } from '../../helpers';
33

44
import {
5-
AuthChallengeNames,
5+
AuthChallengeName,
66
PasswordSettings,
77
SignInResult,
88
ValidatorResult,
@@ -36,9 +36,14 @@ export const defaultServices = {
3636
}: {
3737
user: any;
3838
code: string;
39-
mfaType: AuthChallengeNames.SMS_MFA | AuthChallengeNames.SOFTWARE_TOKEN_MFA;
39+
mfaType: AuthChallengeName;
4040
}): Promise<any> {
41-
return Auth.confirmSignIn(user, code, mfaType);
41+
return Auth.confirmSignIn(
42+
user,
43+
code,
44+
// cast due to restrictive typing of Auth.confirmSignIn
45+
mfaType as 'SMS_MFA' | 'SOFTWARE_TOKEN_MFA'
46+
);
4247
},
4348
async handleConfirmSignUp({
4449
username,

packages/ui/src/types/authenticator/stateMachine/context.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ValidationError } from '../validator';
22
import { AuthFormData, AuthFormFields } from '../form';
3-
import { AuthChallengeNames, CognitoUserAmplify } from '../user';
3+
import { AuthChallengeName, CognitoUserAmplify } from '../user';
44
import { CodeDeliveryDetails as CognitoCodeDeliveryDetails } from 'amazon-cognito-identity-js';
55
import { LoginMechanism, SignUpAttribute, SocialProvider } from '../attributes';
66
import { defaultServices } from '../../../machines/authenticator/defaultServices';
@@ -37,7 +37,7 @@ export interface AuthContext {
3737
username?: string;
3838
password?: string;
3939
code?: string;
40-
mfaType?: AuthChallengeNames.SMS_MFA | AuthChallengeNames.SOFTWARE_TOKEN_MFA;
40+
mfaType?: 'SMS_MFA' | 'SOFTWARE_TOKEN_MFA';
4141
actorDoneData?: Omit<ActorDoneData, 'user'>; // data returned from actors when they finish and reach their final state
4242
hasSetup?: boolean;
4343
}
@@ -51,7 +51,7 @@ interface BaseFormContext {
5151
/** Any user attributes set that needs to persist between states */
5252
authAttributes?: Record<string, any>;
5353
/** Current challengeName issued by Cognnito */
54-
challengeName?: AuthChallengeNames;
54+
challengeName?: AuthChallengeName;
5555
/** Required attributes for form submission */
5656
requiredAttributes?: Array<string>;
5757
/** Maps each input name to tis value */
@@ -98,7 +98,7 @@ export interface ResetPasswordContext extends BaseFormContext {
9898

9999
export interface SignOutContext {
100100
authAttributes?: Record<string, any>;
101-
challengeName?: AuthChallengeNames;
101+
challengeName?: AuthChallengeName;
102102
unverifiedAttributes?: Record<string, string>;
103103
user?: CognitoUserAmplify;
104104
formFields?: AuthFormFields;

packages/ui/src/types/authenticator/user.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
import { CognitoUser } from 'amazon-cognito-identity-js';
1+
import { ChallengeName, CognitoUser } from 'amazon-cognito-identity-js';
22

3-
/** Enum of known challenge names */
4-
export enum AuthChallengeNames {
5-
SMS_MFA = 'SMS_MFA',
6-
SOFTWARE_TOKEN_MFA = 'SOFTWARE_TOKEN_MFA',
7-
NEW_PASSWORD_REQUIRED = 'NEW_PASSWORD_REQUIRED',
8-
RESET_REQUIRED = 'RESET_REQUIRED',
9-
MFA_SETUP = 'MFA_SETUP',
10-
}
3+
/** Known challenge names */
4+
export type AuthChallengeName = ChallengeName;
115

126
/** Contact destinations that we can send user confirmation code to */
137
export type ContactMethod = 'Email' | 'Phone Number';

packages/ui/src/types/authenticator/validator.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { PasswordSettings } from '.';
22
import { AuthFormData } from './form';
3-
import { AuthChallengeNames } from './user';
43

54
/**
65
* Maps each input to its validation error, if any
@@ -22,9 +21,3 @@ export type Validator = (
2221
touchData?: AuthFormData,
2322
passwordSettings?: PasswordSettings
2423
) => ValidatorResult | Promise<ValidatorResult>;
25-
26-
export type SignInTypes = (
27-
user: string,
28-
code: string,
29-
mfaType: AuthChallengeNames.SMS_MFA | AuthChallengeNames.SOFTWARE_TOKEN_MFA
30-
) => SignInResult | Promise<SignInResult>;

packages/vue/src/components/confirm-sign-in.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script setup lang="ts">
22
import {
3-
AuthChallengeNames,
43
getActorState,
54
getFormDataFromEvent,
65
SignInState,
@@ -27,7 +26,7 @@ const challengeName = actorState.value.context.challengeName;
2726
2827
let mfaType = 'SMS';
2928
30-
if (challengeName === AuthChallengeNames.SOFTWARE_TOKEN_MFA) {
29+
if (challengeName === 'SOFTWARE_TOKEN_MFA') {
3130
mfaType = 'TOTP';
3231
}
3332
const confirmSignInHeading = `Confirm ${mfaType} Code`;

0 commit comments

Comments
 (0)