mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-27 17:52:14 +00:00
feat(login): translations (#10849)
# Which Problems Are Solved Replace this example text with a concise list of problems that this PR solves. For example: - password complexity requirements have hardcoded English text - password, loginname, register and verify components have hardcoded Engilsh error messages/alerts # How the Problems Are Solved Replace this example text with a concise list of changes that this PR introduces. For example: - adds i18n for password complexity requirements - adds i18n for password, loginname, register and verify components error messages/alerts # Additional Changes - small change in code/styles for icons in PasswordComplexity to make sure that icons keep size # Additional Context N.A --------- Co-authored-by: Adam Kida <[email protected]>
This commit is contained in:
co-authored by
Adam Kida
parent
794054c075
commit
64e14de091
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "Dieses Feld ist erforderlich"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "Ein interner Fehler ist aufgetreten",
|
||||
"couldNotGetLoginSettings": "Anmeldeeinstellungen konnten nicht abgerufen werden",
|
||||
"couldNotSearchUsers": "Benutzer konnten nicht durchsucht werden",
|
||||
"couldNotGetDomain": "Domain konnte nicht abgerufen werden",
|
||||
"couldNotGetHost": "Host konnte nicht abgerufen werden",
|
||||
"couldNotStartIDPFlow": "IDP-Ablauf konnte nicht gestartet werden",
|
||||
"moreThanOneUserFound": "Mehr als ein Benutzer gefunden. Bitte geben Sie einen eindeutigen Identifikator an.",
|
||||
"userNotFound": "Benutzer im System nicht gefunden",
|
||||
"couldNotCreateSession": "Sitzung für Benutzer konnte nicht erstellt werden",
|
||||
"initialUserNotSupported": "Initialer Benutzer wird nicht unterstützt",
|
||||
"usernamePasswordNotAllowed": "Benutzername und Passwort nicht zulässig! Wenden Sie sich für weitere Informationen an Ihren Administrator.",
|
||||
"passkeysNotAllowed": "Passkeys nicht zulässig! Wenden Sie sich für weitere Informationen an Ihren Administrator.",
|
||||
"couldNotFindIdentityProvider": "Identitätsanbieter konnte nicht gefunden werden.",
|
||||
"userNotActive": "Das Benutzerkonto ist inaktiv. Wenden Sie sich für weitere Informationen an Ihren Administrator."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "Ein Fehler ist aufgetreten",
|
||||
"multipleUsersFound": "Mehrere Benutzer gefunden",
|
||||
"userNotFound": "Benutzer im System nicht gefunden"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "Dieses Feld ist erforderlich"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "Passwort konnte nicht verifiziert werden",
|
||||
"couldNotResetPassword": "Passwort konnte nicht zurückgesetzt werden"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "Passwort wurde zurückgesetzt. Bitte prüfen Sie Ihre E-Mails"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "Dieses Feld ist erforderlich",
|
||||
"newPassword": "Bitte geben Sie ein Passwort ein!",
|
||||
"confirmPassword": "Dieses Feld ist erforderlich"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "Passwort konnte nicht gesetzt werden",
|
||||
"couldNotResetPassword": "Passwort konnte nicht zurückgesetzt werden",
|
||||
"couldNotVerifyPassword": "Passwort konnte nicht verifiziert werden"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "Bitte geben Sie ein neues Passwort ein!",
|
||||
"confirmPassword": "Dieses Feld ist erforderlich"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "Passwort konnte nicht geändert werden",
|
||||
"couldNotVerifyPassword": "Passwort konnte nicht verifiziert werden",
|
||||
"unknownError": "Unbekannter Fehler"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Muss mindestens {minLength} Zeichen lang sein.",
|
||||
"hasSymbol": "Muss ein Symbol enthalten.",
|
||||
"hasNumber": "Muss eine Zahl enthalten.",
|
||||
"hasUppercase": "Muss einen Großbuchstaben enthalten.",
|
||||
"hasLowercase": "Muss einen Kleinbuchstaben enthalten.",
|
||||
"equals": "Passwortbestätigung stimmt überein.",
|
||||
"matches": "Stimmt überein",
|
||||
"doesNotMatch": "Stimmt nicht überein"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "Kein Host gefunden",
|
||||
"couldNotSendResetLink": "Passwort-Zurücksetzungslink konnte nicht gesendet werden",
|
||||
"couldNotCreateSessionForUser": "Sitzung für Benutzer konnte nicht erstellt werden",
|
||||
"couldNotVerifyPassword": "Passwort konnte nicht verifiziert werden",
|
||||
"failedToAuthenticate": "Authentifizierung fehlgeschlagen. Sie haben {failedAttempts} von {maxPasswordAttempts} Passwortversuchen.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Authentifizierung fehlgeschlagen.",
|
||||
"accountLockedContactAdmin": " Kontaktieren Sie Ihren Administrator, um Ihr Konto zu entsperren",
|
||||
"userNotFound": "Benutzer nicht im System gefunden",
|
||||
"initialUserNotSupported": "Initialbenutzer wird nicht unterstützt",
|
||||
"userInitialStateNotSupported": "Anfangszustand des Benutzers wird nicht unterstützt",
|
||||
"codeOrVerificationRequired": "Sie müssen einen Code angeben oder eine gültige Benutzerverifizierung durchführen",
|
||||
"verificationRequired": "Die Benutzerverifizierung muss durchgeführt werden",
|
||||
"couldNotLoadSession": "Sitzung konnte nicht geladen werden",
|
||||
"couldNotLoadAuthMethods": "Authentifizierungsmethoden konnten nicht geladen werden",
|
||||
"failedPrecondition": "Vorbedingung fehlgeschlagen",
|
||||
"sessionNotValid": "Sitzung ist nicht gültig"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "Dieses Feld ist erforderlich",
|
||||
"lastname": "Dieses Feld ist erforderlich",
|
||||
"email": "Dieses Feld ist erforderlich"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "Benutzer konnte nicht erstellt werden",
|
||||
"couldNotCreateSession": "Sitzung konnte nicht erstellt werden",
|
||||
"userNotFound": "Benutzer nicht im System gefunden",
|
||||
"couldNotLinkIDP": "IDP konnte nicht mit dem Benutzer verknüpft werden",
|
||||
"couldNotRegisterUser": "Benutzer konnte nicht registriert werden"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "Dieses Feld ist erforderlich"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "E-Mail konnte nicht erneut gesendet werden",
|
||||
"couldNotVerifyUser": "Benutzer konnte nicht verifiziert werden",
|
||||
"couldNotVerifyInvite": "Einladung konnte nicht verifiziert werden",
|
||||
"couldNotVerifyEmail": "E-Mail konnte nicht verifiziert werden",
|
||||
"couldNotVerify": "Konnte nicht verifizieren",
|
||||
"couldNotLoadUser": "Benutzer konnte nicht geladen werden",
|
||||
"couldNotLoadAuthenticators": "Mögliche Authentifikatoren konnten nicht geladen werden",
|
||||
"couldNotCreateSession": "Sitzung konnte nicht erstellt werden",
|
||||
"noHostFound": "Kein Host gefunden",
|
||||
"userAlreadyVerified": "Benutzer ist bereits verifiziert!",
|
||||
"couldNotResendInvite": "Einladung konnte nicht erneut gesendet werden"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "This field is required"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "An internal error occurred",
|
||||
"couldNotGetLoginSettings": "Could not get login settings",
|
||||
"couldNotSearchUsers": "Could not search users",
|
||||
"couldNotGetDomain": "Could not get domain",
|
||||
"couldNotGetHost": "Could not get host",
|
||||
"couldNotStartIDPFlow": "Could not start IDP flow",
|
||||
"moreThanOneUserFound": "More than one user found. Provide a unique identifier.",
|
||||
"userNotFound": "User not found in the system",
|
||||
"couldNotCreateSession": "Could not create session for user",
|
||||
"initialUserNotSupported": "Initial User not supported",
|
||||
"usernamePasswordNotAllowed": "Username Password not allowed! Contact your administrator for more information.",
|
||||
"passkeysNotAllowed": "Passkeys not allowed! Contact your administrator for more information.",
|
||||
"couldNotFindIdentityProvider": "Could not find identity provider.",
|
||||
"userNotActive": "User is not active. Contact your administrator for more information."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "An error occurred",
|
||||
"multipleUsersFound": "Multiple users found",
|
||||
"userNotFound": "User not found in the system"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "This field is required"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "Could not verify password",
|
||||
"couldNotResetPassword": "Could not reset password"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "Password was reset. Please check your email"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "This field is required",
|
||||
"newPassword": "You have to provide a password!",
|
||||
"confirmPassword": "This field is required"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "Could not set password",
|
||||
"couldNotResetPassword": "Could not reset password",
|
||||
"couldNotVerifyPassword": "Could not verify password"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "You have to provide a new password!",
|
||||
"confirmPassword": "This field is required"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "Could not change password",
|
||||
"couldNotVerifyPassword": "Could not verify password",
|
||||
"unknownError": "Unknown error"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Must be at least {minLength} characters long.",
|
||||
"hasSymbol": "Must include a symbol.",
|
||||
"hasNumber": "Must include a number.",
|
||||
"hasUppercase": "Must include an uppercase letter.",
|
||||
"hasLowercase": "Must include a lowercase letter.",
|
||||
"equals": "Password confirmation matched.",
|
||||
"matches": "Matches",
|
||||
"doesNotMatch": "Doesn't match"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "No host found",
|
||||
"couldNotSendResetLink": "Could not send Password Reset Link",
|
||||
"couldNotCreateSessionForUser": "Could not create session for user",
|
||||
"couldNotVerifyPassword": "Could not verify password",
|
||||
"failedToAuthenticate": "Failed to authenticate. You had {failedAttempts} of {maxPasswordAttempts} password attempts.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Failed to authenticate.",
|
||||
"accountLockedContactAdmin": " Contact your administrator to unlock your account",
|
||||
"userNotFound": "User not found in the system",
|
||||
"initialUserNotSupported": "Initial User not supported",
|
||||
"userInitialStateNotSupported": "User Initial State is not supported",
|
||||
"codeOrVerificationRequired": "You have to provide a code or have a valid User Verification Check",
|
||||
"verificationRequired": "User Verification Check has to be done",
|
||||
"couldNotLoadSession": "Could not load session",
|
||||
"couldNotLoadAuthMethods": "Could not load auth methods",
|
||||
"failedPrecondition": "Failed precondition",
|
||||
"sessionNotValid": "Session is not valid"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "This field is required",
|
||||
"lastname": "This field is required",
|
||||
"email": "This field is required"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "Could not create user",
|
||||
"couldNotCreateSession": "Could not create session",
|
||||
"userNotFound": "User not found in the system",
|
||||
"couldNotLinkIDP": "Could not link IDP to user",
|
||||
"couldNotRegisterUser": "Could not register user"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "This field is required"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "Could not resend email",
|
||||
"couldNotVerifyUser": "Could not verify user",
|
||||
"couldNotVerifyInvite": "Could not verify invite",
|
||||
"couldNotVerifyEmail": "Could not verify email",
|
||||
"couldNotVerify": "Could not verify",
|
||||
"couldNotLoadUser": "Could not load user",
|
||||
"couldNotLoadAuthenticators": "Could not load possible authenticators",
|
||||
"couldNotCreateSession": "Could not create session",
|
||||
"noHostFound": "No host found",
|
||||
"userAlreadyVerified": "User is already verified!",
|
||||
"couldNotResendInvite": "Could not resend invite"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "Este campo es obligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "Se produjo un error interno",
|
||||
"couldNotGetLoginSettings": "No se pudieron obtener los ajustes de inicio de sesión",
|
||||
"couldNotSearchUsers": "No se pudieron buscar usuarios",
|
||||
"couldNotGetDomain": "No se pudo obtener el dominio",
|
||||
"couldNotGetHost": "No se pudo obtener el host",
|
||||
"couldNotStartIDPFlow": "No se pudo iniciar el flujo de IDP",
|
||||
"moreThanOneUserFound": "Se encontró más de un usuario. Proporcione un identificador único.",
|
||||
"userNotFound": "Usuario no encontrado en el sistema",
|
||||
"couldNotCreateSession": "No se pudo crear la sesión para el usuario",
|
||||
"initialUserNotSupported": "Usuario inicial no admitido",
|
||||
"usernamePasswordNotAllowed": "El inicio de sesión con usuario y contraseña no está permitido. Contacte con su administrador para más información.",
|
||||
"passkeysNotAllowed": "Las passkeys no están permitidas. Contacte con su administrador para más información.",
|
||||
"couldNotFindIdentityProvider": "No se pudo encontrar el proveedor de identidad.",
|
||||
"userNotActive": "El usuario no está activo. Contacte con su administrador para más información."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "Ocurrió un error",
|
||||
"multipleUsersFound": "Se encontraron varios usuarios",
|
||||
"userNotFound": "Usuario no encontrado en el sistema"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "Este campo es obligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "No se pudo verificar la contraseña",
|
||||
"couldNotResetPassword": "No se pudo restablecer la contraseña"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "Se restableció la contraseña. Por favor, revise su correo electrónico"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "Este campo es obligatorio",
|
||||
"newPassword": "¡Debes proporcionar una contraseña!",
|
||||
"confirmPassword": "Este campo es obligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "No se pudo establecer la contraseña",
|
||||
"couldNotResetPassword": "No se pudo restablecer la contraseña",
|
||||
"couldNotVerifyPassword": "No se pudo verificar la contraseña"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "¡Debes proporcionar una nueva contraseña!",
|
||||
"confirmPassword": "Este campo es obligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "No se pudo cambiar la contraseña",
|
||||
"couldNotVerifyPassword": "No se pudo verificar la contraseña",
|
||||
"unknownError": "Error desconocido"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Debe tener al menos {minLength} caracteres de longitud.",
|
||||
"hasSymbol": "Debe incluir un símbolo.",
|
||||
"hasNumber": "Debe incluir un número.",
|
||||
"hasUppercase": "Debe incluir una letra mayúscula.",
|
||||
"hasLowercase": "Debe incluir una letra minúscula.",
|
||||
"equals": "La confirmación de la contraseña coincide.",
|
||||
"matches": "Coincide",
|
||||
"doesNotMatch": "No coincide"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "No se encontró el host",
|
||||
"couldNotSendResetLink": "No se pudo enviar el enlace de restablecimiento de contraseña",
|
||||
"couldNotCreateSessionForUser": "No se pudo crear la sesión para el usuario",
|
||||
"couldNotVerifyPassword": "No se pudo verificar la contraseña",
|
||||
"failedToAuthenticate": "Error al autenticar. Tuvo {failedAttempts} de {maxPasswordAttempts} intentos de contraseña.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Error al autenticar.",
|
||||
"accountLockedContactAdmin": " Comuníquese con su administrador para desbloquear su cuenta",
|
||||
"userNotFound": "Usuario no encontrado en el sistema",
|
||||
"initialUserNotSupported": "Usuario inicial no compatible",
|
||||
"userInitialStateNotSupported": "El estado inicial del usuario no es compatible",
|
||||
"codeOrVerificationRequired": "Debe proporcionar un código o tener una verificación de usuario válida",
|
||||
"verificationRequired": "Se debe realizar la verificación de usuario",
|
||||
"couldNotLoadSession": "No se pudo cargar la sesión",
|
||||
"couldNotLoadAuthMethods": "No se pudieron cargar los métodos de autenticación",
|
||||
"failedPrecondition": "Precondición fallida",
|
||||
"sessionNotValid": "La sesión no es válida"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "Este campo es obligatorio",
|
||||
"lastname": "Este campo es obligatorio",
|
||||
"email": "Este campo es obligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "No se pudo crear el usuario",
|
||||
"couldNotCreateSession": "No se pudo crear la sesión",
|
||||
"userNotFound": "Usuario no encontrado en el sistema",
|
||||
"couldNotLinkIDP": "No se pudo vincular el IdP al usuario",
|
||||
"couldNotRegisterUser": "No se pudo registrar el usuario"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "Este campo es obligatorio"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "No se pudo reenviar el correo electrónico",
|
||||
"couldNotVerifyUser": "No se pudo verificar al usuario",
|
||||
"couldNotVerifyInvite": "No se pudo verificar la invitación",
|
||||
"couldNotVerifyEmail": "No se pudo verificar el correo electrónico",
|
||||
"couldNotVerify": "No se pudo verificar",
|
||||
"couldNotLoadUser": "No se pudo cargar al usuario",
|
||||
"couldNotLoadAuthenticators": "No se pudieron cargar los autenticadores posibles",
|
||||
"couldNotCreateSession": "No se pudo crear la sesión",
|
||||
"noHostFound": "No se encontró el host",
|
||||
"userAlreadyVerified": "¡El usuario ya está verificado!",
|
||||
"couldNotResendInvite": "No se pudo reenviar la invitación"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "Questo campo è obbligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "Si è verificato un errore interno",
|
||||
"couldNotGetLoginSettings": "Impossibile ottenere le impostazioni di accesso",
|
||||
"couldNotSearchUsers": "Impossibile cercare gli utenti",
|
||||
"couldNotGetDomain": "Impossibile ottenere il dominio",
|
||||
"couldNotGetHost": "Impossibile ottenere l'host",
|
||||
"couldNotStartIDPFlow": "Impossibile avviare il flusso IDP",
|
||||
"moreThanOneUserFound": "È stato trovato più di un utente. Fornisci un identificatore univoco.",
|
||||
"userNotFound": "Utente non trovato nel sistema",
|
||||
"couldNotCreateSession": "Impossibile creare la sessione per l'utente",
|
||||
"initialUserNotSupported": "Utente iniziale non supportato",
|
||||
"usernamePasswordNotAllowed": "Nome utente e password non consentiti! Contatta l'amministratore per maggiori informazioni.",
|
||||
"passkeysNotAllowed": "Passkey non consentite! Contatta l'amministratore per maggiori informazioni.",
|
||||
"couldNotFindIdentityProvider": "Impossibile trovare il provider di identità.",
|
||||
"userNotActive": "L'utente non è attivo. Contatta l'amministratore per maggiori informazioni."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "Si è verificato un errore",
|
||||
"multipleUsersFound": "Trovati più utenti",
|
||||
"userNotFound": "Utente non trovato nel sistema"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "Questo campo è obbligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "Impossibile verificare la password",
|
||||
"couldNotResetPassword": "Impossibile reimpostare la password"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "La password è stata reimpostata. Controlla la tua e-mail"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "Questo campo è obbligatorio",
|
||||
"newPassword": "Devi fornire una password!",
|
||||
"confirmPassword": "Questo campo è obbligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "Impossibile impostare la password",
|
||||
"couldNotResetPassword": "Impossibile reimpostare la password",
|
||||
"couldNotVerifyPassword": "Impossibile verificare la password"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "Devi fornire una nuova password!",
|
||||
"confirmPassword": "Questo campo è obbligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "Impossibile modificare la password",
|
||||
"couldNotVerifyPassword": "Impossibile verificare la password",
|
||||
"unknownError": "Errore sconosciuto"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Deve contenere almeno {minLength} caratteri.",
|
||||
"hasSymbol": "Deve includere un simbolo.",
|
||||
"hasNumber": "Deve includere un numero.",
|
||||
"hasUppercase": "Deve includere una lettera maiuscola.",
|
||||
"hasLowercase": "Deve includere una lettera minuscola.",
|
||||
"equals": "La conferma della password corrisponde.",
|
||||
"matches": "Corrisponde",
|
||||
"doesNotMatch": "Non corrisponde"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "Nessun host trovato",
|
||||
"couldNotSendResetLink": "Impossibile inviare il link per il ripristino della password",
|
||||
"couldNotCreateSessionForUser": "Impossibile creare una sessione per l'utente",
|
||||
"couldNotVerifyPassword": "Impossibile verificare la password",
|
||||
"failedToAuthenticate": "Autenticazione non riuscita. Hai effettuato {failedAttempts} di {maxPasswordAttempts} tentativi di password.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Autenticazione non riuscita.",
|
||||
"accountLockedContactAdmin": " Contatta l'amministratore per sbloccare il tuo account",
|
||||
"userNotFound": "Utente non trovato nel sistema",
|
||||
"initialUserNotSupported": "Utente iniziale non supportato",
|
||||
"userInitialStateNotSupported": "Lo stato iniziale dell'utente non è supportato",
|
||||
"codeOrVerificationRequired": "Devi fornire un codice o avere una verifica utente valida",
|
||||
"verificationRequired": "È necessario effettuare la verifica utente",
|
||||
"couldNotLoadSession": "Impossibile caricare la sessione",
|
||||
"couldNotLoadAuthMethods": "Impossibile caricare i metodi di autenticazione",
|
||||
"failedPrecondition": "Precondizione non soddisfatta",
|
||||
"sessionNotValid": "La sessione non è valida"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "Questo campo è obbligatorio",
|
||||
"lastname": "Questo campo è obbligatorio",
|
||||
"email": "Questo campo è obbligatorio"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "Impossibile creare l'utente",
|
||||
"couldNotCreateSession": "Impossibile creare la sessione",
|
||||
"userNotFound": "Utente non trovato nel sistema",
|
||||
"couldNotLinkIDP": "Impossibile collegare l'IDP all'utente",
|
||||
"couldNotRegisterUser": "Impossibile registrare l'utente"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "Questo campo è obbligatorio"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "Impossibile reinviare l'email",
|
||||
"couldNotVerifyUser": "Impossibile verificare l'utente",
|
||||
"couldNotVerifyInvite": "Impossibile verificare l'invito",
|
||||
"couldNotVerifyEmail": "Impossibile verificare l'email",
|
||||
"couldNotVerify": "Impossibile verificare",
|
||||
"couldNotLoadUser": "Impossibile caricare l'utente",
|
||||
"couldNotLoadAuthenticators": "Impossibile caricare gli autenticatori possibili",
|
||||
"couldNotCreateSession": "Impossibile creare la sessione",
|
||||
"noHostFound": "Nessun host trovato",
|
||||
"userAlreadyVerified": "L'utente è già verificato!",
|
||||
"couldNotResendInvite": "Impossibile reinviare l'invito"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "To pole jest wymagane"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "Wystąpił błąd wewnętrzny",
|
||||
"couldNotGetLoginSettings": "Nie udało się pobrać ustawień logowania",
|
||||
"couldNotSearchUsers": "Nie udało się wyszukać użytkowników",
|
||||
"couldNotGetDomain": "Nie udało się pobrać domeny",
|
||||
"couldNotGetHost": "Nie udało się pobrać hosta",
|
||||
"couldNotStartIDPFlow": "Nie udało się rozpocząć procesu IDP",
|
||||
"moreThanOneUserFound": "Znaleziono więcej niż jednego użytkownika. Podaj unikalny identyfikator.",
|
||||
"userNotFound": "Użytkownik nie został znaleziony w systemie",
|
||||
"couldNotCreateSession": "Nie udało się utworzyć sesji dla użytkownika",
|
||||
"initialUserNotSupported": "Użytkownik inicjalny nie jest obsługiwany",
|
||||
"usernamePasswordNotAllowed": "Logowanie przy użyciu nazwy użytkownika i hasła jest niedozwolone! Skontaktuj się z administratorem, aby uzyskać więcej informacji.",
|
||||
"passkeysNotAllowed": "Klucze dostępu są niedozwolone! Skontaktuj się z administratorem, aby uzyskać więcej informacji.",
|
||||
"couldNotFindIdentityProvider": "Nie udało się znaleźć dostawcy tożsamości.",
|
||||
"userNotActive": "Użytkownik jest nieaktywny. Skontaktuj się z administratorem, aby uzyskać więcej informacji."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "Wystąpił błąd",
|
||||
"multipleUsersFound": "Znaleziono wielu użytkowników",
|
||||
"userNotFound": "Użytkownik nie został znaleziony w systemie"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "To pole jest wymagane"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "Nie można zweryfikować hasła",
|
||||
"couldNotResetPassword": "Nie można zresetować hasła"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "Hasło zostało zresetowane. Sprawdź swoją pocztę e-mail"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "To pole jest wymagane",
|
||||
"newPassword": "Musisz podać hasło!",
|
||||
"confirmPassword": "To pole jest wymagane"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "Nie można ustawić hasła",
|
||||
"couldNotResetPassword": "Nie można zresetować hasła",
|
||||
"couldNotVerifyPassword": "Nie można zweryfikować hasła"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "Musisz podać nowe hasło!",
|
||||
"confirmPassword": "To pole jest wymagane"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "Nie można zmienić hasła",
|
||||
"couldNotVerifyPassword": "Nie można zweryfikować hasła",
|
||||
"unknownError": "Nieznany błąd"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Musi zawierać co najmniej {minLength} znaków.",
|
||||
"hasSymbol": "Musi zawierać symbol.",
|
||||
"hasNumber": "Musi zawierać numer.",
|
||||
"hasUppercase": "Musi zawierać dużą literę.",
|
||||
"hasLowercase": "Musi zawierać małą literę.",
|
||||
"equals": "Potwierdzenie hasła pasuje.",
|
||||
"matches": "Pasuje",
|
||||
"doesNotMatch": "Nie pasuje"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "Nie znaleziono hosta",
|
||||
"couldNotSendResetLink": "Nie można wysłać linku do resetowania hasła",
|
||||
"couldNotCreateSessionForUser": "Nie można utworzyć sesji dla użytkownika",
|
||||
"couldNotVerifyPassword": "Nie można zweryfikować hasła",
|
||||
"failedToAuthenticate": "Uwierzytelnianie nie powiodło się. Wykorzystałeś {failedAttempts} z {maxPasswordAttempts} prób wprowadzenia hasła.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Uwierzytelnianie nie powiodło się.",
|
||||
"accountLockedContactAdmin": " Skontaktuj się z administratorem, aby odblokować konto",
|
||||
"userNotFound": "Użytkownik nie został znaleziony w systemie",
|
||||
"initialUserNotSupported": "Użytkownik początkowy nie jest obsługiwany",
|
||||
"userInitialStateNotSupported": "Początkowy stan użytkownika nie jest obsługiwany",
|
||||
"codeOrVerificationRequired": "Musisz podać kod lub mieć ważną weryfikację użytkownika",
|
||||
"verificationRequired": "Wymagana jest weryfikacja użytkownika",
|
||||
"couldNotLoadSession": "Nie można załadować sesji",
|
||||
"couldNotLoadAuthMethods": "Nie można załadować metod uwierzytelniania",
|
||||
"failedPrecondition": "Nie spełniono warunków wstępnych",
|
||||
"sessionNotValid": "Sesja jest nieważna"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "To pole jest wymagane",
|
||||
"lastname": "To pole jest wymagane",
|
||||
"email": "To pole jest wymagane"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "Nie udało się utworzyć użytkownika",
|
||||
"couldNotCreateSession": "Nie udało się utworzyć sesji",
|
||||
"userNotFound": "Nie znaleziono użytkownika w systemie",
|
||||
"couldNotLinkIDP": "Nie udało się powiązać IDP z użytkownikiem",
|
||||
"couldNotRegisterUser": "Nie udało się zarejestrować użytkownika"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "To pole jest wymagane"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "Nie udało się ponownie wysłać wiadomości e-mail",
|
||||
"couldNotVerifyUser": "Nie udało się zweryfikować użytkownika",
|
||||
"couldNotVerifyInvite": "Nie udało się zweryfikować zaproszenia",
|
||||
"couldNotVerifyEmail": "Nie udało się zweryfikować adresu e-mail",
|
||||
"couldNotVerify": "Nie udało się zweryfikować",
|
||||
"couldNotLoadUser": "Nie udało się załadować użytkownika",
|
||||
"couldNotLoadAuthenticators": "Nie udało się wczytać dostępnych metod uwierzytelniania",
|
||||
"couldNotCreateSession": "Nie udało się utworzyć sesji",
|
||||
"noHostFound": "Nie znaleziono hosta",
|
||||
"userAlreadyVerified": "Użytkownik jest już zweryfikowany!",
|
||||
"couldNotResendInvite": "Nie udało się ponownie wysłać zaproszenia"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "Это поле обязательно для заполнения"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "Произошла внутренняя ошибка",
|
||||
"couldNotGetLoginSettings": "Не удалось получить настройки входа",
|
||||
"couldNotSearchUsers": "Не удалось выполнить поиск пользователей",
|
||||
"couldNotGetDomain": "Не удалось получить домен",
|
||||
"couldNotGetHost": "Не удалось получить хост",
|
||||
"couldNotStartIDPFlow": "Не удалось запустить поток IDP",
|
||||
"moreThanOneUserFound": "Найдено более одного пользователя. Укажите уникальный идентификатор.",
|
||||
"userNotFound": "Пользователь не найден в системе",
|
||||
"couldNotCreateSession": "Не удалось создать сессию для пользователя",
|
||||
"initialUserNotSupported": "Начальный пользователь не поддерживается",
|
||||
"usernamePasswordNotAllowed": "Использование имени пользователя и пароля не разрешено! Обратитесь к администратору за дополнительной информацией.",
|
||||
"passkeysNotAllowed": "Ключи доступа не разрешены! Обратитесь к администратору за дополнительной информацией.",
|
||||
"couldNotFindIdentityProvider": "Не удалось найти поставщика удостоверений.",
|
||||
"userNotActive": "Пользователь неактивен. Обратитесь к администратору за дополнительной информацией."
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "Произошла ошибка",
|
||||
"multipleUsersFound": "Найдено несколько пользователей",
|
||||
"userNotFound": "Пользователь не найден в системе"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "Это поле обязательно для заполнения"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||||
"couldNotResetPassword": "Не удалось сбросить пароль"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "Пароль был сброшен. Пожалуйста, проверьте свою электронную почту"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "Это поле обязательно для заполнения",
|
||||
"newPassword": "Вы должны указать пароль!",
|
||||
"confirmPassword": "Это поле обязательно для заполнения"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "Не удалось установить пароль",
|
||||
"couldNotResetPassword": "Не удалось сбросить пароль",
|
||||
"couldNotVerifyPassword": "Не удалось проверить пароль"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "Вы должны указать новый пароль!",
|
||||
"confirmPassword": "Это поле обязательно для заполнения"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "Не удалось изменить пароль",
|
||||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||||
"unknownError": "Неизвестная ошибка"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "Минимум {minLength} символов.",
|
||||
"hasSymbol": "Должен содержать специальный символ.",
|
||||
"hasNumber": "Должен содержать цифру.",
|
||||
"hasUppercase": "Должен содержать заглавную букву.",
|
||||
"hasLowercase": "Должен содержать строчную букву.",
|
||||
"equals": "Пароли должны совпадать.",
|
||||
"matches": "Совпадает",
|
||||
"doesNotMatch": "Не совпадает"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "Хост не найден",
|
||||
"couldNotSendResetLink": "Не удалось отправить ссылку для сброса пароля",
|
||||
"couldNotCreateSessionForUser": "Не удалось создать сессию для пользователя",
|
||||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||||
"failedToAuthenticate": "Не удалось пройти аутентификацию. У вас было {failedAttempts} из {maxPasswordAttempts} попыток ввода пароля.{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "Не удалось пройти аутентификацию.",
|
||||
"accountLockedContactAdmin": " Свяжитесь с администратором, чтобы разблокировать вашу учетную запись",
|
||||
"userNotFound": "Пользователь не найден в системе",
|
||||
"initialUserNotSupported": "Первичный пользователь не поддерживается",
|
||||
"userInitialStateNotSupported": "Начальное состояние пользователя не поддерживается",
|
||||
"codeOrVerificationRequired": "Вы должны предоставить код или иметь действительную проверку пользователя",
|
||||
"verificationRequired": "Необходимо выполнить проверку пользователя",
|
||||
"couldNotLoadSession": "Не удалось загрузить сессию",
|
||||
"couldNotLoadAuthMethods": "Не удалось загрузить методы аутентификации",
|
||||
"failedPrecondition": "Нарушено предварительное условие",
|
||||
"sessionNotValid": "Сессия недействительна"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,7 +312,14 @@
|
||||
"firstname": "Это поле обязательно для заполнения",
|
||||
"lastname": "Это поле обязательно для заполнения",
|
||||
"email": "Это поле обязательно для заполнения"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "Не удалось создать пользователя",
|
||||
"couldNotCreateSession": "Не удалось создать сессию",
|
||||
"userNotFound": "Пользователь не найден в системе",
|
||||
"couldNotLinkIDP": "Не удалось привязать IDP к пользователю",
|
||||
"couldNotRegisterUser": "Не удалось зарегистрировать пользователя"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
"title": "Пригласить пользователя",
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "Это поле обязательно для заполнения"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "Не удалось повторно отправить электронное письмо",
|
||||
"couldNotVerifyUser": "Не удалось подтвердить пользователя",
|
||||
"couldNotVerifyInvite": "Не удалось подтвердить приглашение",
|
||||
"couldNotVerifyEmail": "Не удалось подтвердить электронную почту",
|
||||
"couldNotVerify": "Не удалось подтвердить",
|
||||
"couldNotLoadUser": "Не удалось загрузить пользователя",
|
||||
"couldNotLoadAuthenticators": "Не удалось загрузить доступные средства аутентификации",
|
||||
"couldNotCreateSession": "Не удалось создать сеанс",
|
||||
"noHostFound": "Хост не найден",
|
||||
"userAlreadyVerified": "Пользователь уже подтверждён!",
|
||||
"couldNotResendInvite": "Не удалось повторно отправить приглашение"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -35,6 +35,29 @@
|
||||
},
|
||||
"required": {
|
||||
"loginName": "此字段为必填项"
|
||||
},
|
||||
"errors": {
|
||||
"internalError": "发生内部错误",
|
||||
"couldNotGetLoginSettings": "无法获取登录设置",
|
||||
"couldNotSearchUsers": "无法搜索用户",
|
||||
"couldNotGetDomain": "无法获取域名",
|
||||
"couldNotGetHost": "无法获取主机",
|
||||
"couldNotStartIDPFlow": "无法启动身份提供者流程",
|
||||
"moreThanOneUserFound": "找到多个用户。请提供唯一标识符。",
|
||||
"userNotFound": "系统中未找到用户",
|
||||
"couldNotCreateSession": "无法为用户创建会话",
|
||||
"initialUserNotSupported": "不支持初始用户",
|
||||
"usernamePasswordNotAllowed": "不允许使用用户名和密码!请联系管理员了解更多信息。",
|
||||
"passkeysNotAllowed": "不允许使用 Passkey!请联系管理员了解更多信息。",
|
||||
"couldNotFindIdentityProvider": "找不到身份提供者。",
|
||||
"userNotActive": "用户未激活。请联系管理员了解更多信息。"
|
||||
}
|
||||
},
|
||||
"zitadel": {
|
||||
"errors": {
|
||||
"errorOccured": "发生错误",
|
||||
"multipleUsersFound": "找到多个用户",
|
||||
"userNotFound": "系统中未找到用户"
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
@@ -48,6 +71,13 @@
|
||||
},
|
||||
"required": {
|
||||
"password": "此字段为必填项"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotVerifyPassword": "无法验证密码",
|
||||
"couldNotResetPassword": "无法重置密码"
|
||||
},
|
||||
"info": {
|
||||
"passwordResetSent": "密码已重置。请检查您的电子邮件"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
@@ -66,6 +96,11 @@
|
||||
"code": "此字段为必填项",
|
||||
"newPassword": "必须提供密码!",
|
||||
"confirmPassword": "此字段为必填项"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotSetPassword": "无法设置密码",
|
||||
"couldNotResetPassword": "无法重置密码",
|
||||
"couldNotVerifyPassword": "无法验证密码"
|
||||
}
|
||||
},
|
||||
"change": {
|
||||
@@ -79,7 +114,40 @@
|
||||
"required": {
|
||||
"newPassword": "必须提供新密码!",
|
||||
"confirmPassword": "此字段为必填项"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotChangePassword": "无法更改密码",
|
||||
"couldNotVerifyPassword": "无法验证密码",
|
||||
"unknownError": "未知错误"
|
||||
}
|
||||
},
|
||||
"complexity": {
|
||||
"length": "必须至少有 {minLength} 个字符。",
|
||||
"hasSymbol": "必须包含一个符号。",
|
||||
"hasNumber": "必须包含一个数字。",
|
||||
"hasUppercase": "必须包含一个大写字母。",
|
||||
"hasLowercase": "必须包含一个小写字母。",
|
||||
"equals": "密码确认匹配。",
|
||||
"matches": "匹配",
|
||||
"doesNotMatch": "不匹配"
|
||||
},
|
||||
"errors": {
|
||||
"noHostFound": "未找到主机",
|
||||
"couldNotSendResetLink": "无法发送密码重置链接",
|
||||
"couldNotCreateSessionForUser": "无法为用户创建会话",
|
||||
"couldNotVerifyPassword": "无法验证密码",
|
||||
"failedToAuthenticate": "身份验证失败。您已尝试输入密码 {failedAttempts} 次,共允许 {maxPasswordAttempts} 次。{lockoutMessage}",
|
||||
"failedToAuthenticateNoLimit": "身份验证失败。",
|
||||
"accountLockedContactAdmin": " 请联系管理员以解锁您的账户",
|
||||
"userNotFound": "系统中未找到用户",
|
||||
"initialUserNotSupported": "不支持初始用户",
|
||||
"userInitialStateNotSupported": "不支持用户初始状态",
|
||||
"codeOrVerificationRequired": "您必须提供验证码或通过有效的用户验证",
|
||||
"verificationRequired": "必须完成用户验证",
|
||||
"couldNotLoadSession": "无法加载会话",
|
||||
"couldNotLoadAuthMethods": "无法加载验证方法",
|
||||
"failedPrecondition": "前置条件失败",
|
||||
"sessionNotValid": "会话无效"
|
||||
}
|
||||
},
|
||||
"idp": {
|
||||
@@ -244,6 +312,13 @@
|
||||
"firstname": "此字段为必填项",
|
||||
"lastname": "此字段为必填项",
|
||||
"email": "此字段为必填项"
|
||||
},
|
||||
"errors": {
|
||||
"couldNotCreateUser": "无法创建用户",
|
||||
"couldNotCreateSession": "无法创建会话",
|
||||
"userNotFound": "系统中未找到用户",
|
||||
"couldNotLinkIDP": "无法将 IDP 关联到用户",
|
||||
"couldNotRegisterUser": "无法注册用户"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -287,6 +362,19 @@
|
||||
"required": {
|
||||
"code": "此字段为必填项"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"couldNotResendEmail": "无法重新发送邮件",
|
||||
"couldNotVerifyUser": "无法验证用户",
|
||||
"couldNotVerifyInvite": "无法验证邀请",
|
||||
"couldNotVerifyEmail": "无法验证邮箱",
|
||||
"couldNotVerify": "无法验证",
|
||||
"couldNotLoadUser": "无法加载用户",
|
||||
"couldNotLoadAuthenticators": "无法加载可用的身份验证器",
|
||||
"couldNotCreateSession": "无法创建会话",
|
||||
"noHostFound": "未找到主机",
|
||||
"userAlreadyVerified": "用户已验证!",
|
||||
"couldNotResendInvite": "无法重新发送邀请"
|
||||
}
|
||||
},
|
||||
"authenticator": {
|
||||
|
||||
@@ -70,7 +70,7 @@ export function ChangePasswordForm({
|
||||
password: values.password,
|
||||
})
|
||||
.catch(() => {
|
||||
setError("Could not change password");
|
||||
setError(t("change.errors.couldNotChangePassword"));
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -81,13 +81,13 @@ export function ChangePasswordForm({
|
||||
setError(
|
||||
typeof changeResponse.error === "string"
|
||||
? changeResponse.error
|
||||
: "Unknown error",
|
||||
: t("change.errors.unknownError")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!changeResponse) {
|
||||
setError("Could not change password");
|
||||
setError(t("change.errors.couldNotChangePassword"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ export function ChangePasswordForm({
|
||||
requestId,
|
||||
})
|
||||
.catch(() => {
|
||||
setError("Could not verify password");
|
||||
setError(t("change.errors.couldNotVerifyPassword"));
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -1,64 +1,148 @@
|
||||
import {
|
||||
cleanup,
|
||||
render,
|
||||
screen,
|
||||
waitFor,
|
||||
within,
|
||||
} from "@testing-library/react";
|
||||
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, test } from "vitest";
|
||||
import { PasswordComplexity } from "./password-complexity";
|
||||
|
||||
const matchesTitle = `Matches`;
|
||||
const doesntMatchTitle = `Doesn't match`;
|
||||
import { NextIntlClientProvider } from "next-intl";
|
||||
|
||||
describe("<PasswordComplexity/>", () => {
|
||||
describe.each`
|
||||
settingsMinLength | password | expectSVGTitle
|
||||
${5} | ${"Password1!"} | ${matchesTitle}
|
||||
${30} | ${"Password1!"} | ${doesntMatchTitle}
|
||||
${0} | ${"Password1!"} | ${matchesTitle}
|
||||
${undefined} | ${"Password1!"} | ${false}
|
||||
`(
|
||||
`With settingsMinLength=$settingsMinLength, password=$password, expectSVGTitle=$expectSVGTitle`,
|
||||
({ settingsMinLength, password, expectSVGTitle }) => {
|
||||
const feedbackElementLabel = /password length/i;
|
||||
beforeEach(() => {
|
||||
render(
|
||||
<PasswordComplexity
|
||||
password={password}
|
||||
equals
|
||||
passwordComplexitySettings={{
|
||||
minLength: settingsMinLength,
|
||||
const messages = {
|
||||
password: {
|
||||
complexity: {
|
||||
length: "Must be at least {minLength} characters long.",
|
||||
hasSymbol: "Must include a symbol.",
|
||||
hasNumber: "Must include a number.",
|
||||
hasUppercase: "Must include an uppercase letter.",
|
||||
hasLowercase: "Must include a lowercase letter.",
|
||||
equals: "Password confirmation matched.",
|
||||
matches: "Matches",
|
||||
doesNotMatch: "Doesn't match",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
test("should render length check when minLength is defined", () => {
|
||||
render(
|
||||
<NextIntlClientProvider locale="en" messages={messages}>
|
||||
<PasswordComplexity
|
||||
password="Password1!"
|
||||
equals
|
||||
passwordComplexitySettings={
|
||||
{
|
||||
minLength: BigInt(5),
|
||||
requiresLowercase: false,
|
||||
requiresUppercase: false,
|
||||
requiresNumber: false,
|
||||
requiresSymbol: false,
|
||||
resourceOwnerType: 0, // ResourceOwnerType.RESOURCE_OWNER_TYPE_UNSPECIFIED,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
afterEach(cleanup);
|
||||
resourceOwnerType: 0,
|
||||
} as any
|
||||
}
|
||||
/>
|
||||
</NextIntlClientProvider>,
|
||||
);
|
||||
|
||||
if (expectSVGTitle === false) {
|
||||
test(`should not render the feedback element`, async () => {
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.queryByText(feedbackElementLabel),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
test(`Should show one SVG with title ${expectSVGTitle}`, async () => {
|
||||
await waitFor(async () => {
|
||||
const svg = within(
|
||||
screen.getByText(feedbackElementLabel)
|
||||
.parentElement as HTMLElement,
|
||||
).findByRole("img");
|
||||
expect(await svg).toHaveTextContent(expectSVGTitle);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
const lengthCheck = screen.getByTestId("length-check");
|
||||
expect(lengthCheck).toBeInTheDocument();
|
||||
expect(lengthCheck.querySelector("svg")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("should not render length check when minLength is undefined", () => {
|
||||
render(
|
||||
<NextIntlClientProvider locale="en" messages={messages}>
|
||||
<PasswordComplexity
|
||||
password="Password1!"
|
||||
equals
|
||||
passwordComplexitySettings={
|
||||
{
|
||||
minLength: BigInt(0),
|
||||
requiresLowercase: false,
|
||||
requiresUppercase: false,
|
||||
requiresNumber: false,
|
||||
requiresSymbol: false,
|
||||
resourceOwnerType: 0,
|
||||
} as any
|
||||
}
|
||||
/>
|
||||
</NextIntlClientProvider>,
|
||||
);
|
||||
|
||||
expect(screen.queryByTestId("length-check")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("should render check icon when password meets length requirement", () => {
|
||||
render(
|
||||
<NextIntlClientProvider locale="en" messages={messages}>
|
||||
<PasswordComplexity
|
||||
password="Password1!"
|
||||
equals
|
||||
passwordComplexitySettings={
|
||||
{
|
||||
minLength: BigInt(5),
|
||||
requiresLowercase: false,
|
||||
requiresUppercase: false,
|
||||
requiresNumber: false,
|
||||
requiresSymbol: false,
|
||||
resourceOwnerType: 0,
|
||||
} as any
|
||||
}
|
||||
/>
|
||||
</NextIntlClientProvider>,
|
||||
);
|
||||
|
||||
const lengthCheck = screen.getByTestId("length-check");
|
||||
const svg = lengthCheck.querySelector("svg");
|
||||
expect(svg).toHaveClass("text-green-500");
|
||||
});
|
||||
|
||||
test("should render cross icon when password does not meet length requirement", () => {
|
||||
render(
|
||||
<NextIntlClientProvider locale="en" messages={messages}>
|
||||
<PasswordComplexity
|
||||
password="Pass"
|
||||
equals
|
||||
passwordComplexitySettings={
|
||||
{
|
||||
minLength: BigInt(10),
|
||||
requiresLowercase: false,
|
||||
requiresUppercase: false,
|
||||
requiresNumber: false,
|
||||
requiresSymbol: false,
|
||||
resourceOwnerType: 0,
|
||||
} as any
|
||||
}
|
||||
/>
|
||||
</NextIntlClientProvider>,
|
||||
);
|
||||
|
||||
const lengthCheck = screen.getByTestId("length-check");
|
||||
const svg = lengthCheck.querySelector("svg");
|
||||
expect(svg).toHaveClass("text-warn-light-500");
|
||||
});
|
||||
|
||||
test("should render all complexity checks", () => {
|
||||
render(
|
||||
<NextIntlClientProvider locale="en" messages={messages}>
|
||||
<PasswordComplexity
|
||||
password="Password1!"
|
||||
equals
|
||||
passwordComplexitySettings={
|
||||
{
|
||||
minLength: BigInt(8),
|
||||
requiresLowercase: true,
|
||||
requiresUppercase: true,
|
||||
requiresNumber: true,
|
||||
requiresSymbol: true,
|
||||
resourceOwnerType: 0,
|
||||
} as any
|
||||
}
|
||||
/>
|
||||
</NextIntlClientProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("length-check")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("symbol-check")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("number-check")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("uppercase-check")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("lowercase-check")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
upperCaseValidator,
|
||||
} from "@/helpers/validators";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Translated } from "@/components/translated";
|
||||
|
||||
type Props = {
|
||||
passwordComplexitySettings: PasswordComplexitySettings;
|
||||
@@ -12,42 +14,55 @@ type Props = {
|
||||
equals: boolean;
|
||||
};
|
||||
|
||||
const check = (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="las la-check mr-2 h-6 w-6 text-lg text-green-500 dark:text-green-500"
|
||||
role="img"
|
||||
>
|
||||
<title>Matches</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4.5 12.75l6 6 9-13.5"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
const cross = (
|
||||
<svg
|
||||
className="las la-times mr-2 h-6 w-6 text-lg text-warn-light-500 dark:text-warn-dark-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
role="img"
|
||||
>
|
||||
<title>Doesn't match</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
function CheckIcon({ title }: { title: string }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="las la-check mr-2 h-6 w-6 flex-none text-lg text-green-500 dark:text-green-500"
|
||||
role="img"
|
||||
>
|
||||
<title>{title}</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4.5 12.75l6 6 9-13.5"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function CrossIcon({ title }: { title: string }) {
|
||||
return (
|
||||
<svg
|
||||
className="las la-times mr-2 h-6 w-6 flex-none text-lg text-warn-light-500 dark:text-warn-dark-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
role="img"
|
||||
>
|
||||
<title>{title}</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function renderIcon(matched: boolean, t: ReturnType<typeof useTranslations>) {
|
||||
return matched ? (
|
||||
<CheckIcon title={t("complexity.matches")} />
|
||||
) : (
|
||||
<CrossIcon title={t("complexity.doesNotMatch")} />
|
||||
);
|
||||
}
|
||||
const desc =
|
||||
"text-14px leading-4 text-input-light-label dark:text-input-dark-label";
|
||||
|
||||
@@ -56,6 +71,7 @@ export function PasswordComplexity({
|
||||
password,
|
||||
equals,
|
||||
}: Props) {
|
||||
const t = useTranslations("password");
|
||||
const hasMinLength = password?.length >= passwordComplexitySettings.minLength;
|
||||
const hasSymbol = symbolValidator(password);
|
||||
const hasNumber = numberValidator(password);
|
||||
@@ -66,33 +82,47 @@ export function PasswordComplexity({
|
||||
<div className="mb-4 grid grid-cols-2 gap-x-8 gap-y-2">
|
||||
{passwordComplexitySettings.minLength != undefined ? (
|
||||
<div className="flex flex-row items-center" data-testid="length-check">
|
||||
{hasMinLength ? check : cross}
|
||||
{renderIcon(hasMinLength, t)}
|
||||
<span className={desc}>
|
||||
Password length {passwordComplexitySettings.minLength.toString()}
|
||||
<Translated
|
||||
i18nKey="complexity.length"
|
||||
namespace="password"
|
||||
data={{ minLength: passwordComplexitySettings.minLength.toString() }}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
<div className="flex flex-row items-center" data-testid="symbol-check">
|
||||
{hasSymbol ? check : cross}
|
||||
<span className={desc}>has Symbol</span>
|
||||
{renderIcon(hasSymbol, t)}
|
||||
<span className={desc}>
|
||||
<Translated i18nKey="complexity.hasSymbol" namespace="password" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-row items-center" data-testid="number-check">
|
||||
{hasNumber ? check : cross}
|
||||
<span className={desc}>has Number</span>
|
||||
{renderIcon(hasNumber, t)}
|
||||
<span className={desc}>
|
||||
<Translated i18nKey="complexity.hasNumber" namespace="password" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-row items-center" data-testid="uppercase-check">
|
||||
{hasUppercase ? check : cross}
|
||||
<span className={desc}>has uppercase</span>
|
||||
{renderIcon(hasUppercase, t)}
|
||||
<span className={desc}>
|
||||
<Translated i18nKey="complexity.hasUppercase" namespace="password" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-row items-center" data-testid="lowercase-check">
|
||||
{hasLowercase ? check : cross}
|
||||
<span className={desc}>has lowercase</span>
|
||||
{renderIcon(hasLowercase, t)}
|
||||
<span className={desc}>
|
||||
<Translated i18nKey="complexity.hasLowercase" namespace="password" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-row items-center" data-testid="equal-check">
|
||||
{equals ? check : cross}
|
||||
<span className={desc}>equals</span>
|
||||
{renderIcon(equals, t)}
|
||||
<span className={desc}>
|
||||
<Translated i18nKey="complexity.equals" namespace="password" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -72,7 +72,7 @@ export function RegisterForm({
|
||||
requestId: requestId,
|
||||
})
|
||||
.catch(() => {
|
||||
setError("Could not register user");
|
||||
setError(t("errors.couldNotRegisterUser"));
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -71,7 +71,7 @@ export function SetRegisterPasswordForm({
|
||||
password: values.password,
|
||||
})
|
||||
.catch(() => {
|
||||
setError("Could not register user");
|
||||
setError(t("errors.couldNotRegisterUser"));
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -60,7 +60,7 @@ export function UsernameForm({
|
||||
suffix,
|
||||
})
|
||||
.catch(() => {
|
||||
setError("An internal error occurred");
|
||||
setError(t("errors.internalError"));
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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: "[email protected]",
|
||||
});
|
||||
|
||||
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: "[email protected]",
|
||||
});
|
||||
|
||||
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: "[email protected]",
|
||||
});
|
||||
|
||||
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: "[email protected]",
|
||||
});
|
||||
|
||||
expect(result).toEqual({ error: "User not found in the system" });
|
||||
expect(result).toEqual({ error: "errors.userNotFound" });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -473,7 +478,7 @@ describe("sendLoginname", () => {
|
||||
loginName: "[email protected]",
|
||||
});
|
||||
|
||||
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: "[email protected]",
|
||||
});
|
||||
|
||||
expect(result).toEqual({ error: "Initial User not supported" });
|
||||
expect(result).toEqual({ error: "errors.initialUserNotSupported" });
|
||||
});
|
||||
|
||||
test("should handle organization parameter in all redirects", async () => {
|
||||
|
||||
@@ -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") };
|
||||
}
|
||||
|
||||
@@ -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" };
|
||||
});
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Organization | null> {
|
||||
|
||||
Reference in New Issue
Block a user