Skip to content

Commit 1972ebc

Browse files
committed
fix(*): Add MFA Assertion prompt
1 parent 51b50c0 commit 1972ebc

File tree

8 files changed

+37
-12
lines changed

8 files changed

+37
-12
lines changed

packages/angular/src/lib/auth/forms/multi-factor-auth-assertion-form.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ describe("<fui-multi-factor-auth-assertion-form>", () => {
3030
mfaSmsVerification: "SMS Verification",
3131
mfaTotpVerification: "TOTP Verification",
3232
},
33+
prompts: {
34+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
35+
},
3336
};
3437
return () => mockTranslations[category]?.[key] || `${category}.${key}`;
3538
});
@@ -68,6 +71,7 @@ describe("<fui-multi-factor-auth-assertion-form>", () => {
6871
imports: [MultiFactorAuthAssertionFormComponent],
6972
});
7073

74+
expect(screen.getByText("Please choose a multi-factor authentication method")).toBeInTheDocument();
7175
expect(screen.getByRole("button", { name: "SMS Verification" })).toBeInTheDocument();
7276
expect(screen.getByRole("button", { name: "TOTP Verification" })).toBeInTheDocument();
7377

packages/angular/src/lib/auth/forms/multi-factor-auth-assertion-form.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { ButtonComponent } from "../../components/button";
4040
<fui-totp-multi-factor-assertion-form [hint]="selectedHint()!" (onSuccess)="onSuccess.emit($event)" />
4141
}
4242
} @else {
43-
<p>TODO: Select a multi-factor authentication method</p>
43+
<p>{{ mfaAssertionFactorPrompt() }}</p>
4444
@for (hint of resolver().hints; track hint.factorId) {
4545
@if (hint.factorId === totpFactorId()) {
4646
<button fui-button (click)="selectHint(hint)">
@@ -78,6 +78,7 @@ export class MultiFactorAuthAssertionFormComponent {
7878

7979
smsVerificationLabel = injectTranslation("labels", "mfaSmsVerification");
8080
totpVerificationLabel = injectTranslation("labels", "mfaTotpVerification");
81+
mfaAssertionFactorPrompt = injectTranslation("prompts", "mfaAssertionFactorPrompt");
8182

8283
selectHint(hint: MultiFactorInfo) {
8384
this.selectedHint.set(hint);

packages/react/src/auth/forms/multi-factor-auth-assertion-form.test.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ describe("<MultiFactorAuthAssertionForm />", () => {
201201
mfaTotpVerification: "TOTP Verification",
202202
mfaSmsVerification: "SMS Verification",
203203
},
204+
prompts: {
205+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
206+
},
204207
}),
205208
});
206209
ui.get().setMultiFactorResolver(mockResolver as unknown as MultiFactorResolver);
@@ -211,7 +214,7 @@ describe("<MultiFactorAuthAssertionForm />", () => {
211214
</CreateFirebaseUIProvider>
212215
);
213216

214-
expect(screen.getByText("TODO: Select a multi-factor authentication method")).toBeDefined();
217+
expect(screen.getByText("Please choose a multi-factor authentication method")).toBeDefined();
215218
expect(screen.getAllByTestId("mfa-button")).toHaveLength(2);
216219
expect(screen.getByText("TOTP Verification")).toBeDefined();
217220
expect(screen.getByText("SMS Verification")).toBeDefined();
@@ -357,6 +360,9 @@ describe("<MultiFactorAuthAssertionForm />", () => {
357360
mfaTotpVerification: "TOTP Verification",
358361
mfaSmsVerification: "SMS Verification",
359362
},
363+
prompts: {
364+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
365+
},
360366
}),
361367
});
362368
ui.get().setMultiFactorResolver(mockResolver as unknown as MultiFactorResolver);
@@ -367,12 +373,10 @@ describe("<MultiFactorAuthAssertionForm />", () => {
367373
</CreateFirebaseUIProvider>
368374
);
369375

370-
// Initially shows selection UI
371-
expect(screen.getByText("TODO: Select a multi-factor authentication method")).toBeDefined();
376+
expect(screen.getByText("Please choose a multi-factor authentication method")).toBeDefined();
372377
expect(screen.queryByTestId("sms-assertion-form")).toBeNull();
373378
expect(screen.queryByTestId("totp-assertion-form")).toBeNull();
374379

375-
// Click SMS button
376380
const smsButton = screen.getByText("SMS Verification");
377381
fireEvent.click(smsButton);
378382

@@ -385,7 +389,7 @@ describe("<MultiFactorAuthAssertionForm />", () => {
385389
// Should now show SMS form
386390
expect(screen.getByTestId("sms-assertion-form")).toBeDefined();
387391
expect(screen.queryByTestId("totp-assertion-form")).toBeNull();
388-
expect(screen.queryByText("TODO: Select a multi-factor authentication method")).toBeNull();
392+
expect(screen.queryByText("Please choose a multi-factor authentication method")).toBeNull();
389393
});
390394

391395
it("handles unknown factor types gracefully", () => {
@@ -400,7 +404,13 @@ describe("<MultiFactorAuthAssertionForm />", () => {
400404
},
401405
],
402406
};
403-
const ui = createMockUI();
407+
const ui = createMockUI({
408+
locale: registerLocale("test", {
409+
prompts: {
410+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
411+
},
412+
}),
413+
});
404414
ui.get().setMultiFactorResolver(mockResolver as unknown as MultiFactorResolver);
405415

406416
render(
@@ -410,7 +420,7 @@ describe("<MultiFactorAuthAssertionForm />", () => {
410420
);
411421

412422
// Should show selection UI for unknown factor
413-
expect(screen.getByText("TODO: Select a multi-factor authentication method")).toBeDefined();
423+
expect(screen.getByText("Please choose a multi-factor authentication method")).toBeDefined();
414424
expect(screen.queryByTestId("sms-assertion-form")).toBeNull();
415425
expect(screen.queryByTestId("totp-assertion-form")).toBeNull();
416426
});

packages/react/src/auth/forms/multi-factor-auth-assertion-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type MultiFactorAuthAssertionFormProps = {
1818
export function MultiFactorAuthAssertionForm(props: MultiFactorAuthAssertionFormProps) {
1919
const ui = useUI();
2020
const resolver = ui.multiFactorResolver;
21+
const mfaAssertionFactorPrompt = getTranslation(ui, "prompts", "mfaAssertionFactorPrompt");
2122

2223
if (!resolver) {
2324
throw new Error("MultiFactorAuthAssertionForm requires a multi-factor resolver");
@@ -54,7 +55,7 @@ export function MultiFactorAuthAssertionForm(props: MultiFactorAuthAssertionForm
5455

5556
return (
5657
<div className="fui-content">
57-
<p>TODO: Select a multi-factor authentication method</p>
58+
<p>{mfaAssertionFactorPrompt}</p>
5859
{resolver.hints.map((hint) => {
5960
if (hint.factorId === TotpMultiFactorGenerator.FACTOR_ID) {
6061
return <TotpButton key={hint.factorId} onClick={() => setHint(hint)} />;

packages/shadcn/src/components/multi-factor-auth-assertion-form.test.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@ describe("<MultiFactorAuthAssertionForm />", () => {
173173
],
174174
} as MultiFactorResolver;
175175

176-
const ui = createMockUI();
176+
const ui = createMockUI({
177+
locale: registerLocale("test", {
178+
prompts: {
179+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
180+
},
181+
}),
182+
});
177183
ui.get().setMultiFactorResolver(mockResolver as unknown as MultiFactorResolver);
178184

179185
render(
@@ -183,7 +189,7 @@ describe("<MultiFactorAuthAssertionForm />", () => {
183189
})
184190
);
185191

186-
expect(screen.getByText("TODO:Select a multi-factor authentication method")).toBeInTheDocument();
192+
expect(screen.getByText("Please choose a multi-factor authentication method")).toBeInTheDocument();
187193
});
188194

189195
it("calls onSuccess with credential when SMS form succeeds", () => {

packages/shadcn/src/components/multi-factor-auth-assertion-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type MultiFactorAuthAssertionFormProps = {
2121
export function MultiFactorAuthAssertionForm({ onSuccess }: MultiFactorAuthAssertionFormProps) {
2222
const ui = useUI();
2323
const resolver = ui.multiFactorResolver;
24+
const mfaAssertionFactorPrompt = getTranslation(ui, "prompts", "mfaAssertionFactorPrompt");
2425

2526
if (!resolver) {
2627
throw new Error("MultiFactorAuthAssertionForm requires a multi-factor resolver");
@@ -43,7 +44,7 @@ export function MultiFactorAuthAssertionForm({ onSuccess }: MultiFactorAuthAsser
4344

4445
return (
4546
<div className="flex flex-col gap-2">
46-
<p className="text-sm text-muted-foreground">TODO:Select a multi-factor authentication method</p>
47+
<p className="text-sm text-muted-foreground">{mfaAssertionFactorPrompt}</p>
4748
{resolver.hints.map((hint) => {
4849
if (hint.factorId === TotpMultiFactorGenerator.FACTOR_ID) {
4950
return <TotpButton key={hint.factorId} onClick={() => setHint(hint)} />;

packages/translations/src/locales/en-us.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,6 @@ export const enUS = {
9898
enterEmailForLink: "Enter your email to receive a sign-in link",
9999
mfaEnrollmentPrompt: "Select a new multi-factor enrollment method",
100100
mfaAssertionPrompt: "Please complete the multi-factor authentication process",
101+
mfaAssertionFactorPrompt: "Please choose a multi-factor authentication method",
101102
},
102103
} satisfies Translations;

packages/translations/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,6 @@ export type Translations = {
104104
enterEmailForLink?: string;
105105
mfaEnrollmentPrompt?: string;
106106
mfaAssertionPrompt?: string;
107+
mfaAssertionFactorPrompt?: string;
107108
};
108109
};

0 commit comments

Comments
 (0)