From d3fe0b57a8d9d87ba23982de605f56d9c4b293f4 Mon Sep 17 00:00:00 2001 From: kevin fernandes Date: Tue, 23 Jun 2026 16:38:28 +0530 Subject: [PATCH 1/2] feat(auth): improve invalid password guidance for OAuth accounts --- .../react/src/auth/oauth/oauth-button.test.tsx | 12 ++++++++++-- .../src/components/oauth-button.test.tsx | 18 +++++++++++++++--- packages/translations/src/index.test.ts | 4 +++- packages/translations/src/locales/en-gb.ts | 3 ++- packages/translations/src/locales/en-us.ts | 3 ++- packages/translations/src/mapping.test.ts | 4 +++- packages/translations/src/types.ts | 2 +- 7 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/react/src/auth/oauth/oauth-button.test.tsx b/packages/react/src/auth/oauth/oauth-button.test.tsx index faf06e2d6..966c937d7 100644 --- a/packages/react/src/auth/oauth/oauth-button.test.tsx +++ b/packages/react/src/auth/oauth/oauth-button.test.tsx @@ -429,7 +429,13 @@ describe("useSignInWithProvider", () => { // First call fails, second call succeeds mockSignInWithProvider .mockRejectedValueOnce( - new FirebaseUIError(ui.get(), new FirebaseError("auth/wrong-password", "Incorrect password")) + new FirebaseUIError( + ui.get(), + new FirebaseError( + "auth/wrong-password", + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ) + ) ) .mockResolvedValueOnce({} as UserCredential); @@ -444,7 +450,9 @@ describe("useSignInWithProvider", () => { await result.current.callback(); }); - expect(result.current.error).toBe("Incorrect password"); + expect(result.current.error).toBe( + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ); // Second call - should clear error await act(async () => { diff --git a/packages/shadcn/src/components/oauth-button.test.tsx b/packages/shadcn/src/components/oauth-button.test.tsx index 9692ea7ce..5b6425b08 100644 --- a/packages/shadcn/src/components/oauth-button.test.tsx +++ b/packages/shadcn/src/components/oauth-button.test.tsx @@ -268,7 +268,13 @@ describe("", () => { // First call fails, second call succeeds mockSignInWithProvider .mockRejectedValueOnce( - new FirebaseUIError(ui.get(), new FirebaseError("auth/wrong-password", "Incorrect password")) + new FirebaseUIError( + ui.get(), + new FirebaseError( + "auth/wrong-password", + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ) + ) ) .mockResolvedValueOnce({} as UserCredential); @@ -284,14 +290,20 @@ describe("", () => { fireEvent.click(button); await waitFor(() => { - const errorMessage = screen.getByText("Incorrect password"); + const errorMessage = screen.getByText( + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ); expect(errorMessage).toBeDefined(); }); // Second click - should clear error fireEvent.click(button); await waitFor(() => { - expect(screen.queryByText("Incorrect password")).toBeNull(); + expect( + screen.queryByText( + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ) + ).toBeNull(); }); }); diff --git a/packages/translations/src/index.test.ts b/packages/translations/src/index.test.ts index 667a91879..0d28339fa 100644 --- a/packages/translations/src/index.test.ts +++ b/packages/translations/src/index.test.ts @@ -678,7 +678,9 @@ describe("index.ts", () => { it("should have valid error translations", () => { const errors = enUs.translations.errors; expect(errors?.userNotFound).toBe("No account found with this email address"); - expect(errors?.wrongPassword).toBe("Incorrect password"); + expect(errors?.wrongPassword).toBe( + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ); expect(errors?.invalidEmail).toBe("Please enter a valid email address"); expect(errors?.unknownError).toBe("An unexpected error occurred"); }); diff --git a/packages/translations/src/locales/en-gb.ts b/packages/translations/src/locales/en-gb.ts index aa681627d..bcad2ab0c 100644 --- a/packages/translations/src/locales/en-gb.ts +++ b/packages/translations/src/locales/en-gb.ts @@ -20,7 +20,8 @@ import { type Translations } from "../types"; export const enGB = { errors: { userNotFound: "No account found with this email address", - wrongPassword: "Incorrect password", + wrongPassword: + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead.", invalidEmail: "Please enter a valid email address", userDisabled: "This account has been disabled", networkRequestFailed: "Unable to connect to the server. Please check your internet connection", diff --git a/packages/translations/src/locales/en-us.ts b/packages/translations/src/locales/en-us.ts index f1f2e08c1..c7103facf 100644 --- a/packages/translations/src/locales/en-us.ts +++ b/packages/translations/src/locales/en-us.ts @@ -20,7 +20,8 @@ import { type Translations } from "../types"; export const enUS = { errors: { userNotFound: "No account found with this email address", - wrongPassword: "Incorrect password", + wrongPassword: + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead.", invalidEmail: "Please enter a valid email address", userDisabled: "This account has been disabled", networkRequestFailed: "Unable to connect to the server. Please check your internet connection", diff --git a/packages/translations/src/mapping.test.ts b/packages/translations/src/mapping.test.ts index b6cff2b86..68e41175c 100644 --- a/packages/translations/src/mapping.test.ts +++ b/packages/translations/src/mapping.test.ts @@ -154,7 +154,9 @@ describe("mapping.ts", () => { expect(getTranslation(locale, "errors", "userNotFound")).toBe("Custom error message"); // Should fall back to English when not available - expect(getTranslation(locale, "errors", "wrongPassword")).toBe("Incorrect password"); + expect(getTranslation(locale, "errors", "wrongPassword")).toBe( + "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + ); expect(getTranslation(locale, "labels", "emailAddress")).toBe("Email Address"); }); diff --git a/packages/translations/src/types.ts b/packages/translations/src/types.ts index 7cd41537f..dcb2395da 100644 --- a/packages/translations/src/types.ts +++ b/packages/translations/src/types.ts @@ -44,7 +44,7 @@ export type Translations = { errors?: { /** Translation for when a user is not found. */ userNotFound?: string; - /** Translation for incorrect password. */ + /** Translation for incorrect password or OAuth accounts. */ wrongPassword?: string; /** Translation for invalid email address. */ invalidEmail?: string; From ab05ee0995dffec4f63066ce8c6fe4c7b0223edd Mon Sep 17 00:00:00 2001 From: kevin fernandes Date: Tue, 23 Jun 2026 23:56:09 +0530 Subject: [PATCH 2/2] test: reuse enUs wrongPassword translation --- packages/react/src/auth/oauth/oauth-button.test.tsx | 4 ++-- packages/shadcn/src/components/oauth-button.test.tsx | 8 ++++---- packages/translations/src/index.test.ts | 4 +--- packages/translations/src/mapping.test.ts | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/react/src/auth/oauth/oauth-button.test.tsx b/packages/react/src/auth/oauth/oauth-button.test.tsx index 966c937d7..dbb558d3e 100644 --- a/packages/react/src/auth/oauth/oauth-button.test.tsx +++ b/packages/react/src/auth/oauth/oauth-button.test.tsx @@ -433,7 +433,7 @@ describe("useSignInWithProvider", () => { ui.get(), new FirebaseError( "auth/wrong-password", - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ) ) ) @@ -451,7 +451,7 @@ describe("useSignInWithProvider", () => { }); expect(result.current.error).toBe( - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ); // Second call - should clear error diff --git a/packages/shadcn/src/components/oauth-button.test.tsx b/packages/shadcn/src/components/oauth-button.test.tsx index 5b6425b08..f24016d3a 100644 --- a/packages/shadcn/src/components/oauth-button.test.tsx +++ b/packages/shadcn/src/components/oauth-button.test.tsx @@ -18,7 +18,7 @@ import { describe, it, expect, vi, afterEach, beforeEach } from "vitest"; import { render, screen, fireEvent, cleanup, waitFor } from "@testing-library/react"; import { OAuthButton } from "./oauth-button"; import { createMockUI } from "../../tests/utils"; -import { registerLocale } from "@firebase-oss/ui-translations"; +import { registerLocale, enUs } from "@firebase-oss/ui-translations"; import type { AuthProvider, UserCredential } from "firebase/auth"; import { ComponentProps } from "react"; @@ -272,7 +272,7 @@ describe("", () => { ui.get(), new FirebaseError( "auth/wrong-password", - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ) ) ) @@ -291,7 +291,7 @@ describe("", () => { await waitFor(() => { const errorMessage = screen.getByText( - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ); expect(errorMessage).toBeDefined(); }); @@ -301,7 +301,7 @@ describe("", () => { await waitFor(() => { expect( screen.queryByText( - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ) ).toBeNull(); }); diff --git a/packages/translations/src/index.test.ts b/packages/translations/src/index.test.ts index 0d28339fa..d898c5571 100644 --- a/packages/translations/src/index.test.ts +++ b/packages/translations/src/index.test.ts @@ -678,9 +678,7 @@ describe("index.ts", () => { it("should have valid error translations", () => { const errors = enUs.translations.errors; expect(errors?.userNotFound).toBe("No account found with this email address"); - expect(errors?.wrongPassword).toBe( - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." - ); + expect(errors?.wrongPassword).toBe(enUs.translations.errors!.wrongPassword!); expect(errors?.invalidEmail).toBe("Please enter a valid email address"); expect(errors?.unknownError).toBe("An unexpected error occurred"); }); diff --git a/packages/translations/src/mapping.test.ts b/packages/translations/src/mapping.test.ts index 68e41175c..11ec89b4f 100644 --- a/packages/translations/src/mapping.test.ts +++ b/packages/translations/src/mapping.test.ts @@ -155,7 +155,7 @@ describe("mapping.ts", () => { // Should fall back to English when not available expect(getTranslation(locale, "errors", "wrongPassword")).toBe( - "Incorrect email or password. If you previously signed in using another provider, try using that sign-in method instead." + enUs.translations.errors!.wrongPassword! ); expect(getTranslation(locale, "labels", "emailAddress")).toBe("Email Address"); });