diff --git a/apps/web/pages/api/auth/[...nextauth].tsx b/apps/web/pages/api/auth/[...nextauth].tsx index 5fc2fe1894..496bfae9d0 100644 --- a/apps/web/pages/api/auth/[...nextauth].tsx +++ b/apps/web/pages/api/auth/[...nextauth].tsx @@ -72,8 +72,9 @@ const providers: Provider[] = [ }, }); + // Don't leak information about it being username or password that is invalid if (!user) { - throw new Error(ErrorCode.UserNotFound); + throw new Error(ErrorCode.IncorrectUsernamePassword); } if (user.identityProvider !== IdentityProvider.CAL) { @@ -81,12 +82,12 @@ const providers: Provider[] = [ } if (!user.password) { - throw new Error(ErrorCode.UserMissingPassword); + throw new Error(ErrorCode.IncorrectUsernamePassword); } const isCorrectPassword = await verifyPassword(credentials.password, user.password); if (!isCorrectPassword) { - throw new Error(ErrorCode.IncorrectPassword); + throw new Error(ErrorCode.IncorrectUsernamePassword); } if (user.twoFactorEnabled) { diff --git a/apps/web/pages/auth/login.tsx b/apps/web/pages/auth/login.tsx index 0d1fa4ac67..8144f48bc9 100644 --- a/apps/web/pages/auth/login.tsx +++ b/apps/web/pages/auth/login.tsx @@ -9,6 +9,7 @@ import { FaGoogle } from "react-icons/fa"; import { SAMLLogin } from "@calcom/features/auth/SAMLLogin"; import { isSAMLLoginEnabled, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml"; +import { ErrorCode, getSession } from "@calcom/lib/auth"; import { WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { useLocale } from "@calcom/lib/hooks/useLocale"; @@ -17,7 +18,6 @@ import prisma from "@calcom/prisma"; import { Alert, Button, EmailField, PasswordField } from "@calcom/ui"; import { FiArrowLeft } from "@calcom/ui/components/icon"; -import { ErrorCode, getSession } from "@lib/auth"; import { inferSSRProps } from "@lib/types/inferSSRProps"; import AddToHomescreen from "@components/AddToHomescreen"; @@ -52,8 +52,8 @@ export default function Login({ const errorMessages: { [key: string]: string } = { // [ErrorCode.SecondFactorRequired]: t("2fa_enabled_instructions"), - [ErrorCode.IncorrectPassword]: `${t("incorrect_password")} ${t("please_try_again")}`, - [ErrorCode.UserNotFound]: t("no_account_exists"), + // Don't leak information about whether an email is registered or not + [ErrorCode.IncorrectUsernamePassword]: t("incorrect_username_password"), [ErrorCode.IncorrectTwoFactorCode]: `${t("incorrect_2fa_code")} ${t("please_try_again")}`, [ErrorCode.InternalServerError]: `${t("something_went_wrong")} ${t("please_try_again_and_contact_us")}`, [ErrorCode.ThirdPartyIdentityProviderEnabled]: t("account_created_with_identity_provider"), diff --git a/apps/web/playwright/login.e2e.ts b/apps/web/playwright/login.e2e.ts index bd65eeadd9..83d37beec7 100644 --- a/apps/web/playwright/login.e2e.ts +++ b/apps/web/playwright/login.e2e.ts @@ -60,7 +60,7 @@ test.describe("Login and logout tests", () => { test.describe("Login flow validations", async () => { test("Should warn when user does not exist", async ({ page }) => { - const alertMessage = (await localize("en"))("no_account_exists"); + const alertMessage = (await localize("en"))("incorrect_username_password"); // Login with a non-existent user const never = "never"; @@ -71,7 +71,7 @@ test.describe("Login and logout tests", () => { }); test("Should warn when password is incorrect", async ({ page, users }) => { - const alertMessage = (await localize("en"))("incorrect_password"); + const alertMessage = (await localize("en"))("incorrect_username_password"); // by default password===username with the users fixture const pro = await users.create({ username: "pro" }); diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index aba2f74997..c7a9b1aa21 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -431,6 +431,7 @@ "password_hint_num": "Contain at least 1 number", "invalid_password_hint": "The password must be a minimum of 7 characters long containing at least one number and have a mixture of uppercase and lowercase letters", "incorrect_password": "Password is incorrect.", + "incorrect_username_password": "Username or password is incorrect.", "24_h": "24h", "use_setting": "Use setting", "am_pm": "am/pm", diff --git a/packages/lib/auth.ts b/packages/lib/auth.ts index 286f2a7048..2b17bb0815 100644 --- a/packages/lib/auth.ts +++ b/packages/lib/auth.ts @@ -73,6 +73,7 @@ export const ensureSession = async (ctxOrReq: CtxOrReq) => { }; export enum ErrorCode { + IncorrectUsernamePassword = "incorrect-username-password", UserNotFound = "user-not-found", IncorrectPassword = "incorrect-password", UserMissingPassword = "missing-password",