{passwordComplexitySettings.minLength != undefined ? (
- {hasMinLength ? check : cross}
+ {renderIcon(hasMinLength, t)}
- Password length {passwordComplexitySettings.minLength.toString()}
+
) : (
)}
- {hasSymbol ? check : cross}
- has Symbol
+ {renderIcon(hasSymbol, t)}
+
+
+
- {hasNumber ? check : cross}
- has Number
+ {renderIcon(hasNumber, t)}
+
+
+
- {hasUppercase ? check : cross}
- has uppercase
+ {renderIcon(hasUppercase, t)}
+
+
+
- {hasLowercase ? check : cross}
- has lowercase
+ {renderIcon(hasLowercase, t)}
+
+
+
- {equals ? check : cross}
- equals
+ {renderIcon(equals, t)}
+
+
+
);
diff --git a/apps/login/src/components/password-form.tsx b/apps/login/src/components/password-form.tsx
index 1b4c73b95..9f4b27fe8 100644
--- a/apps/login/src/components/password-form.tsx
+++ b/apps/login/src/components/password-form.tsx
@@ -52,9 +52,8 @@ export function PasswordForm({ loginSettings, loginName, organization, requestId
}),
requestId,
})
- .catch((error) => {
- setError("Could not verify password");
- console.error("Error verifying password:", error);
+ .catch(() => {
+ setError(t("verify.errors.couldNotVerifyPassword"));
return;
})
.finally(() => {
@@ -82,7 +81,7 @@ export function PasswordForm({ loginSettings, loginName, organization, requestId
requestId,
})
.catch(() => {
- setError("Could not reset password");
+ setError(t("verify.errors.couldNotResetPassword"));
return;
})
.finally(() => {
@@ -94,7 +93,7 @@ export function PasswordForm({ loginSettings, loginName, organization, requestId
return;
}
- setInfo("Password was reset. Please check your email.");
+ setInfo(t("verify.info.passwordResetSent"));
const params = new URLSearchParams({
loginName: loginName,
diff --git a/apps/login/src/components/register-form.tsx b/apps/login/src/components/register-form.tsx
index a8f8b0962..968424c79 100644
--- a/apps/login/src/components/register-form.tsx
+++ b/apps/login/src/components/register-form.tsx
@@ -72,7 +72,7 @@ export function RegisterForm({
requestId: requestId,
})
.catch(() => {
- setError("Could not register user");
+ setError(t("errors.couldNotRegisterUser"));
return;
})
.finally(() => {
diff --git a/apps/login/src/components/set-password-form.tsx b/apps/login/src/components/set-password-form.tsx
index ab09c9c19..3c6783fcd 100644
--- a/apps/login/src/components/set-password-form.tsx
+++ b/apps/login/src/components/set-password-form.tsx
@@ -77,7 +77,7 @@ export function SetPasswordForm({
requestId,
})
.catch(() => {
- setError("Could not reset password");
+ setError(t("set.errors.couldNotResetPassword"));
return;
})
.finally(() => {
@@ -104,7 +104,7 @@ export function SetPasswordForm({
const changeResponse = await changePassword(payload)
.catch(() => {
- setError("Could not set password");
+ setError(t("set.errors.couldNotSetPassword"));
return;
})
.finally(() => {
@@ -117,7 +117,7 @@ export function SetPasswordForm({
}
if (!changeResponse) {
- setError("Could not set password");
+ setError(t("set.errors.couldNotSetPassword"));
return;
}
@@ -141,7 +141,7 @@ export function SetPasswordForm({
requestId,
})
.catch(() => {
- setError("Could not verify password");
+ setError(t("set.errors.couldNotVerifyPassword"));
return;
})
.finally(() => {
diff --git a/apps/login/src/components/set-register-password-form.tsx b/apps/login/src/components/set-register-password-form.tsx
index 8d17f1dfc..eedebc495 100644
--- a/apps/login/src/components/set-register-password-form.tsx
+++ b/apps/login/src/components/set-register-password-form.tsx
@@ -71,7 +71,7 @@ export function SetRegisterPasswordForm({
password: values.password,
})
.catch(() => {
- setError("Could not register user");
+ setError(t("errors.couldNotRegisterUser"));
return;
})
.finally(() => {
diff --git a/apps/login/src/components/username-form.tsx b/apps/login/src/components/username-form.tsx
index f5a8a721d..78ae33ad4 100644
--- a/apps/login/src/components/username-form.tsx
+++ b/apps/login/src/components/username-form.tsx
@@ -60,7 +60,7 @@ export function UsernameForm({
suffix,
})
.catch(() => {
- setError("An internal error occurred");
+ setError(t("errors.internalError"));
return;
})
.finally(() => {
diff --git a/apps/login/src/components/verify-form.tsx b/apps/login/src/components/verify-form.tsx
index 575f401e3..eac265924 100644
--- a/apps/login/src/components/verify-form.tsx
+++ b/apps/login/src/components/verify-form.tsx
@@ -57,7 +57,7 @@ export function VerifyForm({
isInvite: isInvite,
})
.catch(() => {
- setError("Could not resend email");
+ setError(t("errors.couldNotResendEmail"));
return;
})
.finally(() => {
@@ -87,7 +87,7 @@ export function VerifyForm({
requestId: requestId,
})
.catch(() => {
- setError("Could not verify user");
+ setError(t("errors.couldNotVerifyUser"));
return;
})
.finally(() => {
diff --git a/apps/login/src/lib/server/loginname.test.ts b/apps/login/src/lib/server/loginname.test.ts
index a394e4805..b483aa0d7 100644
--- a/apps/login/src/lib/server/loginname.test.ts
+++ b/apps/login/src/lib/server/loginname.test.ts
@@ -42,6 +42,11 @@ vi.mock("./host", () => ({
getOriginalHost: vi.fn(),
}));
+// this returns the key itself that can be checked not the translated value
+vi.mock("next-intl/server", () => ({
+ getTranslations: vi.fn(() => (key: string) => key),
+}));
+
describe("sendLoginname", () => {
// Mock modules
let mockHeaders: any;
@@ -116,7 +121,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "Could not get login settings" });
+ expect(result).toEqual({ error: "errors.couldNotGetLoginSettings" });
});
test("should return error when user search fails", async () => {
@@ -138,7 +143,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "Could not search users" });
+ expect(result).toEqual({ error: "errors.couldNotSearchUsers" });
});
test("should return error when more than one user found", async () => {
@@ -154,7 +159,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "More than one user found. Provide a unique identifier." });
+ expect(result).toEqual({ error: "errors.moreThanOneUserFound" });
});
});
@@ -250,7 +255,7 @@ describe("sendLoginname", () => {
});
expect(result).toEqual({
- error: "Username Password not allowed! Contact your administrator for more information.",
+ error: "errors.usernamePasswordNotAllowed",
});
});
@@ -282,7 +287,7 @@ describe("sendLoginname", () => {
});
expect(result).toEqual({
- error: "Passkeys not allowed! Contact your administrator for more information.",
+ error: "errors.passkeysNotAllowed",
});
});
@@ -374,7 +379,7 @@ describe("sendLoginname", () => {
});
expect(result).toEqual({
- error: "Username Password not allowed! Contact your administrator for more information.",
+ error: "errors.usernamePasswordNotAllowed",
});
});
});
@@ -450,7 +455,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "User not found in the system" });
+ expect(result).toEqual({ error: "errors.userNotFound" });
});
});
@@ -473,7 +478,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "Could not create session for user" });
+ expect(result).toEqual({ error: "errors.couldNotCreateSession" });
});
test("should handle initial user state", async () => {
@@ -504,7 +509,7 @@ describe("sendLoginname", () => {
loginName: "user@example.com",
});
- expect(result).toEqual({ error: "Initial User not supported" });
+ expect(result).toEqual({ error: "errors.initialUserNotSupported" });
});
test("should handle organization parameter in all redirects", async () => {
diff --git a/apps/login/src/lib/server/loginname.ts b/apps/login/src/lib/server/loginname.ts
index 9f243a86d..b56bedc77 100644
--- a/apps/login/src/lib/server/loginname.ts
+++ b/apps/login/src/lib/server/loginname.ts
@@ -3,6 +3,7 @@
import { create } from "@zitadel/client";
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
+import { getTranslations } from "next-intl/server";
import { headers } from "next/headers";
import { idpTypeToIdentityProviderType, idpTypeToSlug } from "../idp";
@@ -36,13 +37,15 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+ const t = await getTranslations("loginname");
+
const loginSettingsByContext = await getLoginSettings({
serviceUrl,
organization: command.organization,
});
if (!loginSettingsByContext) {
- return { error: "Could not get login settings" };
+ return { error: t("errors.couldNotGetLoginSettings") };
}
let searchUsersRequest: SearchUsersCommand = {
@@ -60,7 +63,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
}
if (!("result" in searchResult)) {
- return { error: "Could not search users" };
+ return { error: t("errors.couldNotSearchUsers") };
}
const { result: potentialUsers } = searchResult;
@@ -108,7 +111,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
});
if (!url) {
- return { error: "Could not start IDP flow" };
+ return { error: t("errors.couldNotStartIDPFlow") };
}
return { redirect: url };
@@ -138,7 +141,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const idpType = idp?.type;
if (!idp || !idpType) {
- throw new Error("Could not find identity provider");
+ throw new Error(t("errors.couldNotFindIdentityProvider"));
}
const identityProviderType = idpTypeToIdentityProviderType(idpType);
@@ -170,7 +173,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
});
if (!url) {
- return { error: "Could not start IDP flow" };
+ return { error: t("errors.couldNotStartIDPFlow") };
}
return { redirect: url };
@@ -178,7 +181,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
};
if (potentialUsers.length > 1) {
- return { error: "More than one user found. Provide a unique identifier." };
+ return { error: t("errors.moreThanOneUserFound") };
} else if (potentialUsers.length == 1 && potentialUsers[0].userId) {
const user = potentialUsers[0];
const userId = potentialUsers[0].userId;
@@ -196,15 +199,15 @@ export async function sendLoginname(command: SendLoginnameCommand) {
// recheck login settings after user discovery, as the search might have been done without org scope
if (userLoginSettings?.disableLoginWithEmail && userLoginSettings?.disableLoginWithPhone) {
if (user.preferredLoginName !== concatLoginname) {
- return { error: "User not found in the system!" };
+ return { error: t("errors.userNotFound") };
}
} else if (userLoginSettings?.disableLoginWithEmail) {
if (user.preferredLoginName !== concatLoginname || humanUser?.phone?.phone !== command.loginName) {
- return { error: "User not found in the system!" };
+ return { error: t("errors.userNotFound") };
}
} else if (userLoginSettings?.disableLoginWithPhone) {
if (user.preferredLoginName !== concatLoginname || humanUser?.email?.email !== command.loginName) {
- return { error: "User not found in the system!" };
+ return { error: t("errors.userNotFound") };
}
}
@@ -212,18 +215,29 @@ export async function sendLoginname(command: SendLoginnameCommand) {
user: { search: { case: "userId", value: userId } },
});
- const session = await createSessionAndUpdateCookie({
+ const sessionOrError = await createSessionAndUpdateCookie({
checks,
requestId: command.requestId,
+ }).catch((error) => {
+ if (error?.rawMessage === "Errors.User.NotActive (SESSION-Gj4ko)") {
+ return { error: t("errors.userNotActive") };
+ }
+ throw error;
});
+ if ("error" in sessionOrError) {
+ return sessionOrError;
+ }
+
+ const session = sessionOrError;
+
if (!session.factors?.user?.id) {
- return { error: "Could not create session for user" };
+ return { error: t("errors.couldNotCreateSession") };
}
// TODO: check if handling of userstate INITIAL is needed
if (user.state === UserState.INITIAL) {
- return { error: "Initial User not supported" };
+ return { error: t("errors.initialUserNotSupported") };
}
const methods = await listAuthenticationMethodTypes({
@@ -262,7 +276,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
}
return {
- error: "Username Password not allowed! Contact your administrator for more information.",
+ error: t("errors.usernamePasswordNotAllowed"),
};
}
@@ -287,7 +301,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
case AuthenticationMethodType.PASSKEY: // AuthenticationMethodType.AUTHENTICATION_METHOD_TYPE_PASSKEY
if (userLoginSettings?.passkeysType === PasskeysType.NOT_ALLOWED) {
return {
- error: "Passkeys not allowed! Contact your administrator for more information.",
+ error: t("errors.passkeysNotAllowed"),
};
}
@@ -366,7 +380,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
if (resp) {
return resp;
}
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
} else if (loginSettingsByContext?.allowRegister && loginSettingsByContext?.allowUsernamePassword) {
let orgToRegisterOn: string | undefined = command.organization;
@@ -429,5 +443,5 @@ export async function sendLoginname(command: SendLoginnameCommand) {
// fallbackToPassword
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
}
diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts
index 166a11d5f..a9b4d29c6 100644
--- a/apps/login/src/lib/server/password.ts
+++ b/apps/login/src/lib/server/password.ts
@@ -31,6 +31,7 @@ import {
checkUserVerification,
} from "../verify-helper";
import { createServerTransport } from "../zitadel";
+import { getTranslations } from "next-intl/server";
type ResetPasswordCommand = {
loginName: string;
@@ -42,6 +43,8 @@ export async function resetPassword(command: ResetPasswordCommand) {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+ const t = await getTranslations("password");
+
// Get the original host that the user sees with protocol
const hostWithProtocol = await getOriginalHostWithProtocol();
@@ -52,7 +55,7 @@ export async function resetPassword(command: ResetPasswordCommand) {
});
if (!users.details || users.details.totalResult !== BigInt(1) || !users.result[0].userId) {
- return { error: "Could not send Password Reset Link" };
+ return { error: t("errors.couldNotSendResetLink") };
}
const userId = users.result[0].userId;
@@ -77,6 +80,7 @@ export type UpdateSessionCommand = {
export async function sendPassword(command: UpdateSessionCommand): Promise<{ error: string } | { redirect: string }> {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+ const t = await getTranslations("password");
let sessionCookie = await getSessionCookieByLoginName({
loginName: command.loginName,
@@ -122,20 +126,28 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
orgId: command.organization,
});
+ const hasLimit =
+ lockoutSettings?.maxPasswordAttempts !== undefined && lockoutSettings?.maxPasswordAttempts > BigInt(0);
+ const locked = hasLimit && error.failedAttempts >= lockoutSettings?.maxPasswordAttempts;
+ const messageKey = hasLimit ? "errors.failedToAuthenticate" : "errors.failedToAuthenticateNoLimit";
+
return {
- error:
- `Failed to authenticate. You had ${error.failedAttempts} of ${lockoutSettings?.maxPasswordAttempts} password attempts.` +
- (lockoutSettings?.maxPasswordAttempts && error.failedAttempts >= lockoutSettings?.maxPasswordAttempts
- ? "Contact your administrator to unlock your account"
- : ""),
+ error: t(messageKey, {
+ failedAttempts: error.failedAttempts,
+ maxPasswordAttempts: hasLimit ? (lockoutSettings?.maxPasswordAttempts).toString() : "?",
+ lockoutMessage: locked ? t("errors.accountLockedContactAdmin") : "",
+ }),
};
}
- return { error: "Could not create session for user" };
+ return { error: t("errors.couldNotCreateSessionForUser") };
}
} else {
// this is a fake error message to hide that the user does not even exist
return { error: "Could not verify password" };
}
+
+ // this is a fake error message to hide that the user does not even exist
+ return { error: t("errors.couldNotVerifyPassword") };
} else {
loginSettings = await getLoginSettings({
serviceUrl,
@@ -170,19 +182,24 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
orgId: command.organization,
});
+ const hasLimit =
+ lockoutSettings?.maxPasswordAttempts !== undefined && lockoutSettings?.maxPasswordAttempts > BigInt(0);
+ const locked = hasLimit && error.failedAttempts >= lockoutSettings?.maxPasswordAttempts;
+ const messageKey = hasLimit ? "errors.failedToAuthenticate" : "errors.failedToAuthenticateNoLimit";
+
return {
- error:
- `Failed to authenticate. You had ${error.failedAttempts} of ${lockoutSettings?.maxPasswordAttempts} password attempts.` +
- (lockoutSettings?.maxPasswordAttempts && error.failedAttempts >= lockoutSettings?.maxPasswordAttempts
- ? " Contact your administrator to unlock your account"
- : ""),
+ error: t(messageKey, {
+ failedAttempts: error.failedAttempts,
+ maxPasswordAttempts: hasLimit ? (lockoutSettings?.maxPasswordAttempts).toString() : "?",
+ lockoutMessage: locked ? t("errors.accountLockedContactAdmin") : "",
+ }),
};
}
throw error;
}
if (!session?.factors?.user?.id) {
- return { error: "Could not create session for user" };
+ return { error: t("errors.couldNotCreateSessionForUser") };
}
const userResponse = await getUserByID({
@@ -191,7 +208,7 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
});
if (!userResponse.user) {
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
}
user = userResponse.user;
@@ -204,8 +221,8 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
});
}
- if (!session?.factors?.user?.id) {
- return { error: "Could not create session for user" };
+ if (!session?.factors?.user?.id || !sessionCookie) {
+ return { error: t("errors.couldNotCreateSessionForUser") };
}
const humanUser = user.type.case === "human" ? user.type.value : undefined;
@@ -230,7 +247,7 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
// throw error if user is in initial state here and do not continue
if (user.state === UserState.INITIAL) {
- return { error: "Initial User not supported" };
+ return { error: t("errors.initialUserNotSupported") };
}
// check to see if user was verified
@@ -253,7 +270,7 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
}
if (!authMethods) {
- return { error: "Could not verify password!" };
+ return { error: t("errors.couldNotVerifyPassword") };
}
const mfaFactorCheck = await checkMFAFactors(
@@ -315,6 +332,7 @@ export async function sendPassword(command: UpdateSessionCommand): Promise<{ err
export async function changePassword(command: { code?: string; userId: string; password: string }) {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+ const t = await getTranslations("password");
// check for init state
const { user } = await getUserByID({
@@ -323,12 +341,12 @@ export async function changePassword(command: { code?: string; userId: string; p
});
if (!user || user.userId !== command.userId) {
- return { error: "Could not send Password Reset Link" };
+ return { error: t("errors.couldNotSendResetLink") };
}
const userId = user.userId;
if (user.state === UserState.INITIAL) {
- return { error: "User Initial State is not supported" };
+ return { error: t("errors.userInitialStateNotSupported") };
}
// check if the user has no password set in order to set a password
@@ -341,7 +359,7 @@ export async function changePassword(command: { code?: string; userId: string; p
// if the user has no authmethods set, we need to check if the user was verified
if (authmethods.authMethodTypes.length !== 0) {
return {
- error: "You have to provide a code or have a valid User Verification Check",
+ error: t("errors.codeOrVerificationRequired"),
};
}
@@ -349,7 +367,7 @@ export async function changePassword(command: { code?: string; userId: string; p
const hasValidUserVerificationCheck = await checkUserVerification(user.userId);
if (!hasValidUserVerificationCheck) {
- return { error: "User Verification Check has to be done" };
+ return { error: t("errors.verificationRequired") };
}
}
@@ -369,6 +387,7 @@ type CheckSessionAndSetPasswordCommand = {
export async function checkSessionAndSetPassword({ sessionId, password }: CheckSessionAndSetPasswordCommand) {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+ const t = await getTranslations("password");
let sessionCookie;
try {
@@ -392,7 +411,7 @@ export async function checkSessionAndSetPassword({ sessionId, password }: CheckS
}
if (!session || !session.factors?.user?.id) {
- return { error: "Could not load session" };
+ return { error: t("errors.couldNotLoadSession") };
}
const payload = create(SetPasswordRequestSchema, {
@@ -415,7 +434,7 @@ export async function checkSessionAndSetPassword({ sessionId, password }: CheckS
}
if (!authmethods) {
- return { error: "Could not load auth methods" };
+ return { error: t("errors.couldNotLoadAuthMethods") };
}
let loginSettings;
@@ -437,7 +456,7 @@ export async function checkSessionAndSetPassword({ sessionId, password }: CheckS
return setPassword({ serviceUrl, payload }).catch((error) => {
// throw error if failed precondition (ex. User is not yet initialized)
if (error.code === 9 && error.message) {
- return { error: "Failed precondition" };
+ return { error: t("errors.failedPrecondition") };
}
return { error: "Could not set password" };
});
@@ -464,7 +483,7 @@ export async function checkSessionAndSetPassword({ sessionId, password }: CheckS
.catch((error: ConnectError) => {
console.log(error);
if (error.code === 7) {
- return { error: "Session is not valid." };
+ return { error: t("errors.sessionNotValid") };
}
return { error: "Could not set the password" };
});
diff --git a/apps/login/src/lib/server/register.ts b/apps/login/src/lib/server/register.ts
index 74647a387..fb6656f9d 100644
--- a/apps/login/src/lib/server/register.ts
+++ b/apps/login/src/lib/server/register.ts
@@ -6,11 +6,12 @@ import { create } from "@zitadel/client";
import { Factors } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { ChecksJson, ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { cookies, headers } from "next/headers";
-import crypto from "crypto";
-import { completeFlowOrGetUrl } from "../client";
+import { getTranslations } from "next-intl/server";
import { getServiceUrlFromHeaders } from "../service-url";
import { checkEmailVerification, checkMFAFactors } from "../verify-helper";
import { getOrSetFingerprintId } from "../fingerprint";
+import crypto from "crypto";
+import { completeFlowOrGetUrl } from "../client";
type RegisterUserCommand = {
email: string;
@@ -27,6 +28,7 @@ export type RegisterUserResponse = {
factors: Factors | undefined;
};
export async function registerUser(command: RegisterUserCommand) {
+ const t = await getTranslations("register");
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
@@ -40,7 +42,7 @@ export async function registerUser(command: RegisterUserCommand) {
});
if (!addResponse) {
- return { error: "Could not create user" };
+ return { error: t("errors.couldNotCreateUser") };
}
const loginSettings = await getLoginSettings({
@@ -68,7 +70,7 @@ export async function registerUser(command: RegisterUserCommand) {
});
if (!session || !session.factors?.user) {
- return { error: "Could not create session" };
+ return { error: t("errors.couldNotCreateSession") };
}
if (!command.password) {
@@ -104,7 +106,7 @@ export async function registerUser(command: RegisterUserCommand) {
});
if (!userResponse.user) {
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
}
const humanUser = userResponse.user.type.case === "human" ? userResponse.user.type.value : undefined;
@@ -157,6 +159,8 @@ export type registerUserAndLinkToIDPResponse = {
factors: Factors | undefined;
};
export async function registerUserAndLinkToIDP(command: RegisterUserAndLinkToIDPommand) {
+ const t = await getTranslations("register");
+
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
@@ -169,7 +173,7 @@ export async function registerUserAndLinkToIDP(command: RegisterUserAndLinkToIDP
});
if (!addUserResponse) {
- return { error: "Could not create user" };
+ return { error: t("errors.couldNotCreateUser") };
}
const loginSettings = await getLoginSettings({
@@ -188,7 +192,7 @@ export async function registerUserAndLinkToIDP(command: RegisterUserAndLinkToIDP
});
if (!idpLink) {
- return { error: "Could not link IDP to user" };
+ return { error: t("errors.couldNotLinkIDP") };
}
const session = await createSessionForIdpAndUpdateCookie({
@@ -199,7 +203,7 @@ export async function registerUserAndLinkToIDP(command: RegisterUserAndLinkToIDP
});
if (!session || !session.factors?.user) {
- return { error: "Could not create session" };
+ return { error: t("errors.couldNotCreateSession") };
}
// const userResponse = await getUserByID({
diff --git a/apps/login/src/lib/server/verify.ts b/apps/login/src/lib/server/verify.ts
index 8326c428d..3fb450666 100644
--- a/apps/login/src/lib/server/verify.ts
+++ b/apps/login/src/lib/server/verify.ts
@@ -25,6 +25,7 @@ import { loadMostRecentSession } from "../session";
import { checkMFAFactors } from "../verify-helper";
import { createSessionAndUpdateCookie } from "./cookie";
import { getOriginalHostWithProtocol } from "./host";
+import { getTranslations } from "next-intl/server";
export async function verifyTOTP(code: string, loginName?: string, organization?: string) {
const _headers = await headers();
@@ -59,6 +60,7 @@ type VerifyUserByEmailCommand = {
};
export async function sendVerification(command: VerifyUserByEmailCommand) {
+ const t = await getTranslations("verify");
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
@@ -69,7 +71,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
verificationCode: command.code,
}).catch((error) => {
console.warn(error);
- return { error: "Could not verify invite" };
+ return { error: t("errors.couldNotVerifyInvite") };
})
: await verifyEmail({
serviceUrl,
@@ -77,7 +79,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
verificationCode: command.code,
}).catch((error) => {
console.warn(error);
- return { error: "Could not verify email" };
+ return { error: t("errors.couldNotVerifyEmail") };
});
if ("error" in verifyResponse) {
@@ -85,7 +87,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
}
if (!verifyResponse) {
- return { error: "Could not verify" };
+ return { error: t("errors.couldNotVerify") };
}
let session: Session | undefined;
@@ -95,7 +97,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
});
if (!userResponse || !userResponse.user) {
- return { error: "Could not load user" };
+ return { error: t("errors.couldNotLoadUser") };
}
const user = userResponse.user;
@@ -126,7 +128,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
});
if (!authMethodResponse || !authMethodResponse.authMethodTypes) {
- return { error: "Could not load possible authenticators" };
+ return { error: t("errors.couldNotLoadAuthenticators") };
}
// if no authmethods are found on the user, redirect to set one up
@@ -148,7 +150,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
}
if (!session) {
- return { error: "Could not create session" };
+ return { error: t("errors.couldNotCreateSession") };
}
const params = new URLSearchParams({
@@ -249,6 +251,7 @@ type resendVerifyEmailCommand = {
};
export async function resendVerification(command: resendVerifyEmailCommand) {
+ const t = await getTranslations("verify");
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const hostWithProtocol = await getOriginalHostWithProtocol();
@@ -264,9 +267,9 @@ export async function resendVerification(command: resendVerifyEmailCommand) {
(command.requestId ? `&requestId=${command.requestId}` : ""),
}).catch((error) => {
if (error.code === 9) {
- return { error: "User is already verified!" };
+ return { error: t("errors.userAlreadyVerified") };
}
- return { error: "Could not resend invite" };
+ return { error: t("errors.couldNotResendInvite") };
})
: zitadelSendEmailCode({
userId: command.userId,
diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts
index ae2a12770..b289fc3cf 100644
--- a/apps/login/src/lib/zitadel.ts
+++ b/apps/login/src/lib/zitadel.ts
@@ -30,6 +30,7 @@ import {
VerifyU2FRegistrationRequest,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { unstable_cacheLife as cacheLife } from "next/cache";
+import { getTranslations } from "next-intl/server";
import { getUserAgent } from "./fingerprint";
import { setSAMLFormCookie } from "./saml";
import { createServiceForHost } from "./service";
@@ -614,6 +615,8 @@ const EmailQuery = (searchValue: string) =>
export async function searchUsers({ serviceUrl, searchValue, loginSettings, organizationId, suffix }: SearchUsersCommand) {
const queries: SearchQuery[] = [];
+ const t = await getTranslations("zitadel");
+
// if a suffix is provided, we search for the userName concatenated with the suffix
if (suffix) {
const searchValueWithSuffix = `${searchValue}@${suffix}`;
@@ -642,11 +645,11 @@ export async function searchUsers({ serviceUrl, searchValue, loginSettings, orga
const loginNameResult = await userService.listUsers({ queries });
if (!loginNameResult || !loginNameResult.details) {
- return { error: "An error occurred." };
+ return { error: t("errors.errorOccured") };
}
if (loginNameResult.result.length > 1) {
- return { error: "Multiple users found" };
+ return { error: t("errors.multipleUsersFound") };
}
if (loginNameResult.result.length == 1) {
@@ -655,7 +658,7 @@ export async function searchUsers({ serviceUrl, searchValue, loginSettings, orga
const emailAndPhoneQueries: SearchQuery[] = [];
if (loginSettings.disableLoginWithEmail && loginSettings.disableLoginWithPhone) {
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
} else if (loginSettings.disableLoginWithEmail && searchValue.length <= 20) {
const phoneQuery = PhoneQuery(searchValue);
emailAndPhoneQueries.push(phoneQuery);
@@ -704,18 +707,18 @@ export async function searchUsers({ serviceUrl, searchValue, loginSettings, orga
});
if (!emailOrPhoneResult || !emailOrPhoneResult.details) {
- return { error: "An error occurred." };
+ return { error: t("errors.errorOccured") };
}
if (emailOrPhoneResult.result.length > 1) {
- return { error: "Multiple users found." };
+ return { error: t("errors.multipleUsersFound") };
}
if (emailOrPhoneResult.result.length == 1) {
return emailOrPhoneResult;
}
- return { error: "User not found in the system" };
+ return { error: t("errors.userNotFound") };
}
export async function getDefaultOrg({ serviceUrl }: { serviceUrl: string }): Promise