@cosmicdrift/kumiko-bundled-features 0.207.0 → 0.208.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -8
- package/src/admin-shell/__tests__/admin-shell.boot.test.ts +1 -1
- package/src/admin-shell/i18n.ts +17 -39
- package/src/admin-shell/web/i18n.ts +6 -11
- package/src/audit/i18n.ts +25 -41
- package/src/audit/web/i18n.ts +5 -9
- package/src/auth-email-password/__tests__/email-templates.test.ts +4 -0
- package/src/auth-email-password/email-templates.ts +97 -149
- package/src/auth-email-password/i18n.ts +6 -265
- package/src/auth-email-password/web/__tests__/confirm-account-unlock-screen.test.tsx +7 -7
- package/src/auth-email-password/web/__tests__/forgot-password-screen.test.tsx +14 -14
- package/src/auth-email-password/web/__tests__/invite-accept-screen.test.tsx +23 -25
- package/src/auth-email-password/web/__tests__/login-screen.test.tsx +60 -68
- package/src/auth-email-password/web/__tests__/request-account-unlock-screen.test.tsx +24 -24
- package/src/auth-email-password/web/__tests__/reset-password-screen.test.tsx +20 -20
- package/src/auth-email-password/web/__tests__/signup-complete-screen.test.tsx +9 -9
- package/src/auth-email-password/web/__tests__/signup-screen.test.tsx +11 -11
- package/src/auth-email-password/web/__tests__/test-utils.tsx +2 -2
- package/src/auth-email-password/web/__tests__/user-menu.test.tsx +3 -3
- package/src/auth-email-password/web/__tests__/verify-email-screen.test.tsx +3 -3
- package/src/auth-email-password/web/invite-accept-screen.tsx +3 -1
- package/src/auth-mfa/__tests__/errors-i18n-parity.test.ts +2 -4
- package/src/auth-mfa/i18n.ts +1 -3
- package/src/auth-mfa/web/__tests__/mfa-enable-screen.test.tsx +15 -15
- package/src/auth-mfa/web/__tests__/mfa-setup-preauth-screen.test.tsx +45 -49
- package/src/auth-mfa/web/__tests__/mfa-verify-screen.test.tsx +10 -10
- package/src/auth-mfa/web/i18n.ts +0 -126
- package/src/cap-counter/i18n.ts +5 -11
- package/src/compliance-profiles/i18n.ts +3 -11
- package/src/compliance-profiles/web/i18n.ts +0 -20
- package/src/config/i18n.ts +5 -5
- package/src/config/web/i18n.ts +1 -19
- package/src/custom-fields/web/i18n.ts +1 -18
- package/src/delivery/i18n.ts +3 -7
- package/src/delivery/web/i18n.ts +0 -20
- package/src/feature-toggles/i18n.ts +3 -11
- package/src/feature-toggles/web/i18n.ts +0 -24
- package/src/folders/web/i18n.ts +1 -51
- package/src/jobs/i18n.ts +40 -68
- package/src/jobs/web/i18n.ts +5 -9
- package/src/managed-pages/i18n.ts +23 -67
- package/src/managed-pages/web/i18n.ts +6 -11
- package/src/notes-history/i18n.ts +1 -1
- package/src/notes-history/web/i18n.ts +1 -17
- package/src/personal-access-tokens/i18n.ts +2 -6
- package/src/personal-access-tokens/web/i18n.ts +0 -72
- package/src/sessions/i18n.ts +17 -21
- package/src/tags/i18n.ts +2 -2
- package/src/tags/web/i18n.ts +1 -52
- package/src/template-resolver/web/__tests__/client-plugin.test.tsx +2 -2
- package/src/template-resolver/web/__tests__/editor-read-only.test.tsx +5 -5
- package/src/template-resolver/web/i18n.ts +0 -28
- package/src/tenant/__tests__/members-screens.boot.test.ts +0 -2
- package/src/tenant/i18n.ts +13 -27
- package/src/tenant/web/i18n.ts +0 -38
- package/src/tier-engine/i18n.ts +3 -39
- package/src/user/i18n.ts +14 -32
- package/src/user-data-rights/__tests__/default-mailers.test.ts +4 -0
- package/src/user-data-rights/__tests__/email-templates.test.ts +4 -0
- package/src/user-data-rights/__tests__/mail-default-bridge.integration.test.ts +2 -0
- package/src/user-data-rights/__tests__/run-export-jobs-cron-context.integration.test.ts +4 -0
- package/src/user-data-rights/email-templates.ts +55 -91
- package/src/user-data-rights/i18n.ts +18 -70
- package/src/user-data-rights/lib/default-mailers.ts +4 -1
- package/src/user-data-rights/web/__tests__/deletion-screens.test.tsx +11 -11
- package/src/user-data-rights/web/__tests__/public-deletion-gate.test.tsx +5 -5
- package/src/user-data-rights/web/i18n.ts +9 -157
- package/src/user-profile/i18n.ts +1 -71
|
@@ -1,145 +1,15 @@
|
|
|
1
1
|
// @runtime client
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
2
|
+
// English UI copy for this feature. emailPasswordClient() mounts it as a
|
|
3
|
+
// LocaleProvider fallback. Apps override keys via
|
|
4
|
+
// `emailPasswordClient({ translations })`. German/Spanish ship in
|
|
5
|
+
// localeDeClient() / localeEsClient(), not in this bundle.
|
|
6
6
|
//
|
|
7
|
-
// Keys
|
|
8
|
-
//
|
|
9
|
-
// (1:1 gespiegelt zu AuthErrors im server-side Feature).
|
|
7
|
+
// Keys: `auth.<area>.<slug>` — `auth.login.*` for the form,
|
|
8
|
+
// `auth.errors.*` for login-handler reason codes (mirrors AuthErrors).
|
|
10
9
|
|
|
11
10
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
12
11
|
|
|
13
12
|
export const defaultTranslations: TranslationsByLocale = {
|
|
14
|
-
de: {
|
|
15
|
-
"auth.login.title": "Anmelden",
|
|
16
|
-
"auth.login.email": "E-Mail",
|
|
17
|
-
"auth.login.password": "Passwort",
|
|
18
|
-
"auth.login.submit": "Einloggen",
|
|
19
|
-
"auth.login.submitting": "…",
|
|
20
|
-
"auth.login.forgotPassword": "Passwort vergessen?",
|
|
21
|
-
"auth.login.unlockAccount": "Konto entsperren?",
|
|
22
|
-
"auth.login.resendVerification": "Bestätigungs-Mail erneut senden",
|
|
23
|
-
"auth.login.resendSuccess": "Wir haben dir eine neue Bestätigungs-Mail geschickt.",
|
|
24
|
-
"auth.login.resendRateLimited": "Bitte warte kurz und versuche es erneut.",
|
|
25
|
-
"auth.login.resendError": "Konnte nicht senden. Bitte erneut versuchen.",
|
|
26
|
-
"auth.errors.invalidCredentials": "E-Mail oder Passwort falsch.",
|
|
27
|
-
"auth.errors.noMembership": "Dieses Konto hat keinen Tenant-Zugang.",
|
|
28
|
-
"auth.errors.accountLocked": "Konto vorübergehend gesperrt.",
|
|
29
|
-
"auth.errors.accountLockedRetry": "Konto gesperrt. Neuer Versuch in {minutes} Minuten.",
|
|
30
|
-
"auth.errors.emailNotVerified": "E-Mail-Adresse noch nicht bestätigt.",
|
|
31
|
-
"auth.errors.accountRestricted":
|
|
32
|
-
"Konto pausiert (Datenschutz Art. 18). Bitte Pause aufheben um wieder einzuloggen.",
|
|
33
|
-
"auth.errors.rateLimited": "Zu viele Login-Versuche. Bitte kurz warten.",
|
|
34
|
-
"auth.errors.invalidBody": "Ungültige Eingabe.",
|
|
35
|
-
"auth.errors.loginFailed": "Login fehlgeschlagen.",
|
|
36
|
-
"auth.errors.mfaNotSupported":
|
|
37
|
-
"Diese App unterstützt keine Zwei-Faktor-Bestätigung. Bitte an den Support wenden.",
|
|
38
|
-
"auth.errors.mfaSetupRequired":
|
|
39
|
-
"Zwei-Faktor-Authentifizierung erforderlich. Bitte an den Administrator wenden.",
|
|
40
|
-
"auth.errors.invalidResetToken":
|
|
41
|
-
"Der Link ist ungültig oder abgelaufen. Bitte fordere einen neuen an.",
|
|
42
|
-
"auth.errors.invalidVerificationToken": "Der Bestätigungs-Link ist ungültig oder abgelaufen.",
|
|
43
|
-
"auth.errors.invalidUnlockToken":
|
|
44
|
-
"Der Entsperren-Link ist ungültig oder abgelaufen. Bitte fordere einen neuen an.",
|
|
45
|
-
"auth.errors.invalidSignupToken":
|
|
46
|
-
"Der Aktivierungs-Link ist ungültig oder abgelaufen. Bitte fordere einen neuen an.",
|
|
47
|
-
"auth.errors.signupEmailAlreadyRegistered":
|
|
48
|
-
"Für diese E-Mail-Adresse existiert bereits ein Konto. Bitte logge dich ein oder setze dein Passwort zurück.",
|
|
49
|
-
"auth.errors.unknownError": "Etwas ist schief gegangen. Bitte erneut versuchen.",
|
|
50
|
-
"auth.errors.originNotAllowed": "Zugriff von dieser Herkunft ist nicht erlaubt.",
|
|
51
|
-
"auth.forgotPassword.title": "Passwort zurücksetzen",
|
|
52
|
-
"auth.forgotPassword.intro":
|
|
53
|
-
"Gib deine E-Mail-Adresse ein. Falls ein Konto existiert, schicken wir dir einen Reset-Link.",
|
|
54
|
-
"auth.forgotPassword.email": "E-Mail",
|
|
55
|
-
"auth.forgotPassword.submit": "Link anfordern",
|
|
56
|
-
"auth.forgotPassword.submitting": "…",
|
|
57
|
-
"auth.forgotPassword.successTitle": "Mail gesendet",
|
|
58
|
-
"auth.forgotPassword.successBody":
|
|
59
|
-
"Falls die E-Mail in unserem System existiert, ist eine Nachricht mit einem Reset-Link unterwegs. Bitte schau in deinen Posteingang.",
|
|
60
|
-
"auth.forgotPassword.backToLogin": "Zurück zum Login",
|
|
61
|
-
"auth.resetPassword.title": "Neues Passwort setzen",
|
|
62
|
-
"auth.resetPassword.intro": "Wähle ein neues Passwort (mindestens 8 Zeichen).",
|
|
63
|
-
"auth.resetPassword.newPassword": "Neues Passwort",
|
|
64
|
-
"auth.resetPassword.confirmPassword": "Passwort bestätigen",
|
|
65
|
-
"auth.resetPassword.mismatch": "Die Passwörter stimmen nicht überein.",
|
|
66
|
-
"auth.resetPassword.tooShort": "Passwort muss mindestens 8 Zeichen lang sein.",
|
|
67
|
-
"auth.resetPassword.submit": "Passwort speichern",
|
|
68
|
-
"auth.resetPassword.submitting": "…",
|
|
69
|
-
"auth.resetPassword.successTitle": "Passwort gesetzt",
|
|
70
|
-
"auth.resetPassword.successBody": "Du kannst dich jetzt mit deinem neuen Passwort anmelden.",
|
|
71
|
-
"auth.resetPassword.goToLogin": "Zum Login",
|
|
72
|
-
"auth.resetPassword.missingToken":
|
|
73
|
-
"Der Reset-Link enthält keinen Token. Bitte fordere einen neuen an.",
|
|
74
|
-
"auth.verifyEmail.verifying": "E-Mail wird bestätigt …",
|
|
75
|
-
"auth.verifyEmail.successTitle": "E-Mail bestätigt",
|
|
76
|
-
"auth.verifyEmail.successBody": "Danke! Du kannst dich jetzt anmelden.",
|
|
77
|
-
"auth.verifyEmail.errorTitle": "Bestätigung fehlgeschlagen",
|
|
78
|
-
"auth.verifyEmail.errorBody":
|
|
79
|
-
"Der Link ist ungültig oder abgelaufen. Bitte fordere eine neue Bestätigungs-Mail an.",
|
|
80
|
-
"auth.verifyEmail.goToLogin": "Zum Login",
|
|
81
|
-
"auth.verifyEmail.missingToken": "Der Bestätigungs-Link enthält keinen Token.",
|
|
82
|
-
"auth.requestUnlock.title": "Konto entsperren",
|
|
83
|
-
"auth.requestUnlock.intro":
|
|
84
|
-
"Gib deine E-Mail-Adresse ein. Falls dein Konto gesperrt ist, schicken wir dir einen Entsperren-Link.",
|
|
85
|
-
"auth.requestUnlock.email": "E-Mail",
|
|
86
|
-
"auth.requestUnlock.submit": "Link anfordern",
|
|
87
|
-
"auth.requestUnlock.submitting": "…",
|
|
88
|
-
"auth.requestUnlock.successTitle": "Mail gesendet",
|
|
89
|
-
"auth.requestUnlock.successBody":
|
|
90
|
-
"Falls die E-Mail in unserem System existiert und gesperrt ist, ist eine Nachricht mit einem Entsperren-Link unterwegs. Bitte schau in deinen Posteingang.",
|
|
91
|
-
"auth.requestUnlock.backToLogin": "Zurück zum Login",
|
|
92
|
-
"auth.requestUnlock.rateLimited": "Zu viele Anfragen. Neuer Versuch in {minutes} Minuten.",
|
|
93
|
-
"auth.unlockAccount.verifying": "Konto wird entsperrt …",
|
|
94
|
-
"auth.unlockAccount.successTitle": "Konto entsperrt",
|
|
95
|
-
"auth.unlockAccount.successBody":
|
|
96
|
-
"Dein Konto ist wieder entsperrt. Du kannst dich jetzt anmelden.",
|
|
97
|
-
"auth.unlockAccount.errorTitle": "Entsperren fehlgeschlagen",
|
|
98
|
-
"auth.unlockAccount.errorBody":
|
|
99
|
-
"Der Link ist ungültig oder abgelaufen. Bitte fordere einen neuen Entsperren-Link an.",
|
|
100
|
-
"auth.unlockAccount.goToLogin": "Zum Login",
|
|
101
|
-
"auth.unlockAccount.missingToken": "Der Entsperren-Link enthält keinen Token.",
|
|
102
|
-
"auth.signup.title": "Account erstellen",
|
|
103
|
-
"auth.signup.intro":
|
|
104
|
-
"Gib deine E-Mail-Adresse ein. Wir schicken dir einen Aktivierungs-Link, mit dem du dein Passwort setzt.",
|
|
105
|
-
"auth.signup.email": "E-Mail",
|
|
106
|
-
"auth.signup.submit": "Aktivierungs-Link senden",
|
|
107
|
-
"auth.signup.submitting": "…",
|
|
108
|
-
"auth.signup.successTitle": "Mail gesendet",
|
|
109
|
-
"auth.signup.successBody":
|
|
110
|
-
"Wir haben dir einen Aktivierungs-Link an deine E-Mail-Adresse geschickt. Klicke ihn an, um dein Passwort zu setzen und dich einzuloggen.",
|
|
111
|
-
"auth.signup.resend": "Mail erneut senden",
|
|
112
|
-
"auth.signup.haveAccount": "Bereits einen Account? Anmelden",
|
|
113
|
-
"auth.signupComplete.title": "Passwort setzen",
|
|
114
|
-
"auth.signupComplete.intro":
|
|
115
|
-
"Wähle ein Passwort (mindestens 8 Zeichen) für deinen neuen Account.",
|
|
116
|
-
"auth.signupComplete.password": "Passwort",
|
|
117
|
-
"auth.signupComplete.confirmPassword": "Passwort bestätigen",
|
|
118
|
-
"auth.signupComplete.tooShort": "Passwort muss mindestens 8 Zeichen lang sein.",
|
|
119
|
-
"auth.signupComplete.mismatch": "Die Passwörter stimmen nicht überein.",
|
|
120
|
-
"auth.signupComplete.submit": "Account aktivieren",
|
|
121
|
-
"auth.signupComplete.submitting": "…",
|
|
122
|
-
"auth.signupComplete.missingToken":
|
|
123
|
-
"Der Aktivierungs-Link enthält keinen Token. Bitte fordere einen neuen an.",
|
|
124
|
-
"auth.inviteAccept.title": "Einladung annehmen",
|
|
125
|
-
"auth.inviteAccept.intro":
|
|
126
|
-
"Du wurdest zu einem Workspace eingeladen. Klicke auf 'Annehmen' um Mitglied zu werden.",
|
|
127
|
-
"auth.inviteAccept.loggedInAs": "Du bist eingeloggt — klicke 'Annehmen' um Mitglied zu werden.",
|
|
128
|
-
"auth.inviteAccept.email": "E-Mail",
|
|
129
|
-
"auth.inviteAccept.password": "Passwort",
|
|
130
|
-
"auth.inviteAccept.acceptButton": "Annehmen",
|
|
131
|
-
"auth.inviteAccept.submit": "Annehmen + Anmelden",
|
|
132
|
-
"auth.inviteAccept.submitting": "…",
|
|
133
|
-
"auth.inviteAccept.useOtherAccount": "Mit anderem Account anmelden",
|
|
134
|
-
"auth.inviteAccept.toggleNew": "Ich habe noch keinen Account",
|
|
135
|
-
"auth.inviteAccept.toggleExisting": "Ich habe schon einen Account",
|
|
136
|
-
"auth.inviteAccept.missingToken": "Der Einladungs-Link enthält keinen Token oder ist ungültig.",
|
|
137
|
-
"auth.inviteAccept.goToLogin": "Zum Login",
|
|
138
|
-
"auth.user.menu.label": "Konto",
|
|
139
|
-
"auth.user.menu.logout": "Abmelden",
|
|
140
|
-
"auth.tenant.switcher.label": "Tenant",
|
|
141
|
-
"auth.tenant.switcher.none": "Kein Tenant",
|
|
142
|
-
},
|
|
143
13
|
en: {
|
|
144
14
|
"auth.login.title": "Sign in",
|
|
145
15
|
"auth.login.email": "Email",
|
|
@@ -263,135 +133,6 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
263
133
|
"auth.tenant.switcher.label": "Tenant",
|
|
264
134
|
"auth.tenant.switcher.none": "No tenant",
|
|
265
135
|
},
|
|
266
|
-
es: {
|
|
267
|
-
"auth.login.title": "Iniciar sesión",
|
|
268
|
-
"auth.login.email": "Correo electrónico",
|
|
269
|
-
"auth.login.password": "Contraseña",
|
|
270
|
-
"auth.login.submit": "Iniciar sesión",
|
|
271
|
-
"auth.login.submitting": "…",
|
|
272
|
-
"auth.login.forgotPassword": "¿Olvidaste tu contraseña?",
|
|
273
|
-
"auth.login.unlockAccount": "¿Desbloquear cuenta?",
|
|
274
|
-
"auth.login.resendVerification": "Reenviar correo de confirmación",
|
|
275
|
-
"auth.login.resendSuccess": "Te hemos enviado un nuevo correo de confirmación.",
|
|
276
|
-
"auth.login.resendRateLimited": "Espera un momento e inténtalo de nuevo.",
|
|
277
|
-
"auth.login.resendError": "No se pudo enviar. Inténtalo de nuevo.",
|
|
278
|
-
"auth.errors.invalidCredentials": "Correo electrónico o contraseña incorrectos.",
|
|
279
|
-
"auth.errors.noMembership": "Esta cuenta no tiene acceso a ningún tenant.",
|
|
280
|
-
"auth.errors.accountLocked": "Cuenta bloqueada temporalmente.",
|
|
281
|
-
"auth.errors.accountLockedRetry": "Cuenta bloqueada. Vuelve a intentarlo en {minutes} minutos.",
|
|
282
|
-
"auth.errors.emailNotVerified": "El correo electrónico aún no está confirmado.",
|
|
283
|
-
"auth.errors.accountRestricted":
|
|
284
|
-
"Cuenta pausada (protección de datos, art. 18). Levanta la pausa para volver a iniciar sesión.",
|
|
285
|
-
"auth.errors.rateLimited": "Demasiados intentos de inicio de sesión. Espera un momento.",
|
|
286
|
-
"auth.errors.invalidBody": "Entrada no válida.",
|
|
287
|
-
"auth.errors.loginFailed": "Error al iniciar sesión.",
|
|
288
|
-
"auth.errors.mfaNotSupported":
|
|
289
|
-
"Esta aplicación no admite la verificación en dos pasos. Contacta con soporte.",
|
|
290
|
-
"auth.errors.mfaSetupRequired":
|
|
291
|
-
"Se requiere autenticación en dos pasos. Contacta con el administrador.",
|
|
292
|
-
"auth.errors.invalidResetToken": "El enlace no es válido o ha caducado. Solicita uno nuevo.",
|
|
293
|
-
"auth.errors.invalidVerificationToken": "El enlace de confirmación no es válido o ha caducado.",
|
|
294
|
-
"auth.errors.invalidUnlockToken":
|
|
295
|
-
"El enlace de desbloqueo no es válido o ha caducado. Solicita uno nuevo.",
|
|
296
|
-
"auth.errors.invalidSignupToken":
|
|
297
|
-
"El enlace de activación no es válido o ha caducado. Solicita uno nuevo.",
|
|
298
|
-
"auth.errors.signupEmailAlreadyRegistered":
|
|
299
|
-
"Ya existe una cuenta con este correo electrónico. Inicia sesión o restablece tu contraseña.",
|
|
300
|
-
"auth.errors.unknownError": "Algo salió mal. Inténtalo de nuevo.",
|
|
301
|
-
"auth.errors.originNotAllowed": "El acceso desde este origen no está permitido.",
|
|
302
|
-
"auth.forgotPassword.title": "Restablecer contraseña",
|
|
303
|
-
"auth.forgotPassword.intro":
|
|
304
|
-
"Introduce tu correo electrónico. Si existe una cuenta, te enviaremos un enlace para restablecer la contraseña.",
|
|
305
|
-
"auth.forgotPassword.email": "Correo electrónico",
|
|
306
|
-
"auth.forgotPassword.submit": "Solicitar enlace",
|
|
307
|
-
"auth.forgotPassword.submitting": "…",
|
|
308
|
-
"auth.forgotPassword.successTitle": "Correo enviado",
|
|
309
|
-
"auth.forgotPassword.successBody":
|
|
310
|
-
"Si el correo existe en nuestro sistema, te hemos enviado un mensaje con un enlace para restablecer la contraseña. Revisa tu bandeja de entrada.",
|
|
311
|
-
"auth.forgotPassword.backToLogin": "Volver al inicio de sesión",
|
|
312
|
-
"auth.resetPassword.title": "Establecer nueva contraseña",
|
|
313
|
-
"auth.resetPassword.intro": "Elige una nueva contraseña (al menos 8 caracteres).",
|
|
314
|
-
"auth.resetPassword.newPassword": "Nueva contraseña",
|
|
315
|
-
"auth.resetPassword.confirmPassword": "Confirmar contraseña",
|
|
316
|
-
"auth.resetPassword.mismatch": "Las contraseñas no coinciden.",
|
|
317
|
-
"auth.resetPassword.tooShort": "La contraseña debe tener al menos 8 caracteres.",
|
|
318
|
-
"auth.resetPassword.submit": "Guardar contraseña",
|
|
319
|
-
"auth.resetPassword.submitting": "…",
|
|
320
|
-
"auth.resetPassword.successTitle": "Contraseña establecida",
|
|
321
|
-
"auth.resetPassword.successBody": "Ya puedes iniciar sesión con tu nueva contraseña.",
|
|
322
|
-
"auth.resetPassword.goToLogin": "Ir a iniciar sesión",
|
|
323
|
-
"auth.resetPassword.missingToken":
|
|
324
|
-
"El enlace de restablecimiento no contiene ningún token. Solicita uno nuevo.",
|
|
325
|
-
"auth.verifyEmail.verifying": "Confirmando correo electrónico …",
|
|
326
|
-
"auth.verifyEmail.successTitle": "Correo confirmado",
|
|
327
|
-
"auth.verifyEmail.successBody": "¡Gracias! Ya puedes iniciar sesión.",
|
|
328
|
-
"auth.verifyEmail.errorTitle": "Error al confirmar",
|
|
329
|
-
"auth.verifyEmail.errorBody":
|
|
330
|
-
"El enlace no es válido o ha caducado. Solicita un nuevo correo de confirmación.",
|
|
331
|
-
"auth.verifyEmail.goToLogin": "Ir a iniciar sesión",
|
|
332
|
-
"auth.verifyEmail.missingToken": "El enlace de confirmación no contiene ningún token.",
|
|
333
|
-
"auth.requestUnlock.title": "Desbloquear cuenta",
|
|
334
|
-
"auth.requestUnlock.intro":
|
|
335
|
-
"Introduce tu correo electrónico. Si tu cuenta está bloqueada, te enviaremos un enlace de desbloqueo.",
|
|
336
|
-
"auth.requestUnlock.email": "Correo electrónico",
|
|
337
|
-
"auth.requestUnlock.submit": "Solicitar enlace",
|
|
338
|
-
"auth.requestUnlock.submitting": "…",
|
|
339
|
-
"auth.requestUnlock.successTitle": "Correo enviado",
|
|
340
|
-
"auth.requestUnlock.successBody":
|
|
341
|
-
"Si ese correo existe en nuestro sistema y está bloqueado, te hemos enviado un mensaje con un enlace de desbloqueo. Revisa tu bandeja de entrada.",
|
|
342
|
-
"auth.requestUnlock.backToLogin": "Volver al inicio de sesión",
|
|
343
|
-
"auth.requestUnlock.rateLimited":
|
|
344
|
-
"Demasiadas solicitudes. Vuelve a intentarlo en {minutes} minutos.",
|
|
345
|
-
"auth.unlockAccount.verifying": "Desbloqueando cuenta …",
|
|
346
|
-
"auth.unlockAccount.successTitle": "Cuenta desbloqueada",
|
|
347
|
-
"auth.unlockAccount.successBody": "Tu cuenta ha sido desbloqueada. Ya puedes iniciar sesión.",
|
|
348
|
-
"auth.unlockAccount.errorTitle": "Error al desbloquear",
|
|
349
|
-
"auth.unlockAccount.errorBody":
|
|
350
|
-
"El enlace no es válido o ha caducado. Solicita un nuevo enlace de desbloqueo.",
|
|
351
|
-
"auth.unlockAccount.goToLogin": "Ir a iniciar sesión",
|
|
352
|
-
"auth.unlockAccount.missingToken": "El enlace de desbloqueo no contiene ningún token.",
|
|
353
|
-
"auth.signup.title": "Crear cuenta",
|
|
354
|
-
"auth.signup.intro":
|
|
355
|
-
"Introduce tu correo electrónico. Te enviaremos un enlace de activación con el que podrás establecer tu contraseña.",
|
|
356
|
-
"auth.signup.email": "Correo electrónico",
|
|
357
|
-
"auth.signup.submit": "Enviar enlace de activación",
|
|
358
|
-
"auth.signup.submitting": "…",
|
|
359
|
-
"auth.signup.successTitle": "Correo enviado",
|
|
360
|
-
"auth.signup.successBody":
|
|
361
|
-
"Te hemos enviado un enlace de activación a tu correo electrónico. Haz clic en él para establecer tu contraseña e iniciar sesión.",
|
|
362
|
-
"auth.signup.resend": "Reenviar correo",
|
|
363
|
-
"auth.signup.haveAccount": "¿Ya tienes una cuenta? Inicia sesión",
|
|
364
|
-
"auth.signupComplete.title": "Establecer contraseña",
|
|
365
|
-
"auth.signupComplete.intro":
|
|
366
|
-
"Elige una contraseña (al menos 8 caracteres) para tu nueva cuenta.",
|
|
367
|
-
"auth.signupComplete.password": "Contraseña",
|
|
368
|
-
"auth.signupComplete.confirmPassword": "Confirmar contraseña",
|
|
369
|
-
"auth.signupComplete.tooShort": "La contraseña debe tener al menos 8 caracteres.",
|
|
370
|
-
"auth.signupComplete.mismatch": "Las contraseñas no coinciden.",
|
|
371
|
-
"auth.signupComplete.submit": "Activar cuenta",
|
|
372
|
-
"auth.signupComplete.submitting": "…",
|
|
373
|
-
"auth.signupComplete.missingToken":
|
|
374
|
-
"El enlace de activación no contiene ningún token. Solicita uno nuevo.",
|
|
375
|
-
"auth.inviteAccept.title": "Aceptar invitación",
|
|
376
|
-
"auth.inviteAccept.intro":
|
|
377
|
-
"Te han invitado a un espacio de trabajo. Haz clic en 'Aceptar' para unirte.",
|
|
378
|
-
"auth.inviteAccept.loggedInAs": "Has iniciado sesión — haz clic en 'Aceptar' para unirte.",
|
|
379
|
-
"auth.inviteAccept.email": "Correo electrónico",
|
|
380
|
-
"auth.inviteAccept.password": "Contraseña",
|
|
381
|
-
"auth.inviteAccept.acceptButton": "Aceptar",
|
|
382
|
-
"auth.inviteAccept.submit": "Aceptar e iniciar sesión",
|
|
383
|
-
"auth.inviteAccept.submitting": "…",
|
|
384
|
-
"auth.inviteAccept.useOtherAccount": "Iniciar sesión con otra cuenta",
|
|
385
|
-
"auth.inviteAccept.toggleNew": "Todavía no tengo una cuenta",
|
|
386
|
-
"auth.inviteAccept.toggleExisting": "Ya tengo una cuenta",
|
|
387
|
-
"auth.inviteAccept.missingToken":
|
|
388
|
-
"El enlace de invitación no contiene ningún token o no es válido.",
|
|
389
|
-
"auth.inviteAccept.goToLogin": "Ir a iniciar sesión",
|
|
390
|
-
"auth.user.menu.label": "Cuenta",
|
|
391
|
-
"auth.user.menu.logout": "Cerrar sesión",
|
|
392
|
-
"auth.tenant.switcher.label": "Tenant",
|
|
393
|
-
"auth.tenant.switcher.none": "Sin tenant",
|
|
394
|
-
},
|
|
395
136
|
};
|
|
396
137
|
|
|
397
138
|
// Kanonische Implementierung lebt jetzt im Renderer (neben
|
|
@@ -9,8 +9,8 @@ installFetchMock();
|
|
|
9
9
|
describe("ConfirmAccountUnlockScreen", () => {
|
|
10
10
|
test("ohne Token → missing-token page", () => {
|
|
11
11
|
renderWithProviders(<ConfirmAccountUnlockScreen />);
|
|
12
|
-
expect(screen.getByText(/
|
|
13
|
-
expect(screen.getByRole("link", { name: "
|
|
12
|
+
expect(screen.getByText(/missing a token/i)).toBeTruthy();
|
|
13
|
+
expect(screen.getByRole("link", { name: "Go to sign in" }).getAttribute("href")).toBe("/login");
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
test("mit Token + 200 → success after auto-submit", async () => {
|
|
@@ -29,9 +29,9 @@ describe("ConfirmAccountUnlockScreen", () => {
|
|
|
29
29
|
body: JSON.stringify({ token: "unlock-tok" }),
|
|
30
30
|
}),
|
|
31
31
|
);
|
|
32
|
-
expect(screen.getByText("
|
|
32
|
+
expect(screen.getByText("Account unlocked")).toBeTruthy();
|
|
33
33
|
});
|
|
34
|
-
expect(screen.getByRole("link", { name: "
|
|
34
|
+
expect(screen.getByRole("link", { name: "Go to sign in" }).getAttribute("href")).toBe("/home");
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
test("mit Token + 422 → error state", async () => {
|
|
@@ -43,14 +43,14 @@ describe("ConfirmAccountUnlockScreen", () => {
|
|
|
43
43
|
renderWithProviders(<ConfirmAccountUnlockScreen token="bad" />);
|
|
44
44
|
|
|
45
45
|
await waitFor(() => {
|
|
46
|
-
expect(screen.getByText("
|
|
46
|
+
expect(screen.getByText("Unlock failed")).toBeTruthy();
|
|
47
47
|
});
|
|
48
|
-
expect(screen.getByRole("link", { name: "
|
|
48
|
+
expect(screen.getByRole("link", { name: "Go to sign in" })).toBeTruthy();
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
test("custom title on missing-token uses errorTitle slot only when set", () => {
|
|
52
52
|
renderWithProviders(<ConfirmAccountUnlockScreen title="Unlock kaputt" />);
|
|
53
53
|
expect(screen.getByText("Unlock kaputt")).toBeTruthy();
|
|
54
|
-
expect(screen.queryByText("
|
|
54
|
+
expect(screen.queryByText("Unlock failed")).toBeNull();
|
|
55
55
|
});
|
|
56
56
|
});
|
|
@@ -9,9 +9,9 @@ installFetchMock();
|
|
|
9
9
|
describe("ForgotPasswordScreen", () => {
|
|
10
10
|
test("rendert title + email-input + submit-button (de)", () => {
|
|
11
11
|
renderWithProviders(<ForgotPasswordScreen />);
|
|
12
|
-
expect(screen.getByText("
|
|
13
|
-
expect(screen.getByLabelText(/^
|
|
14
|
-
expect(screen.getByRole("button", { name: "
|
|
12
|
+
expect(screen.getByText("Reset password")).toBeTruthy();
|
|
13
|
+
expect(screen.getByLabelText(/^Email/)).toBeTruthy();
|
|
14
|
+
expect(screen.getByRole("button", { name: "Request link" })).toBeTruthy();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
test("submit ruft /api/auth/request-password-reset mit der Email", async () => {
|
|
@@ -19,10 +19,10 @@ describe("ForgotPasswordScreen", () => {
|
|
|
19
19
|
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
20
20
|
|
|
21
21
|
renderWithProviders(<ForgotPasswordScreen />);
|
|
22
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
22
|
+
fireEvent.change(screen.getByLabelText(/^Email/), {
|
|
23
23
|
target: { value: "user@example.com" },
|
|
24
24
|
});
|
|
25
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
25
|
+
fireEvent.click(screen.getByRole("button", { name: "Request link" }));
|
|
26
26
|
|
|
27
27
|
await waitFor(() => {
|
|
28
28
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
@@ -35,17 +35,17 @@ describe("ForgotPasswordScreen", () => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
test("nach erfolgreichem Submit: success-Banner + '
|
|
38
|
+
test("nach erfolgreichem Submit: success-Banner + 'Back to login'-Link", async () => {
|
|
39
39
|
renderWithProviders(<ForgotPasswordScreen />);
|
|
40
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
40
|
+
fireEvent.change(screen.getByLabelText(/^Email/), {
|
|
41
41
|
target: { value: "user@example.com" },
|
|
42
42
|
});
|
|
43
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
43
|
+
fireEvent.click(screen.getByRole("button", { name: "Request link" }));
|
|
44
44
|
|
|
45
45
|
await waitFor(() => {
|
|
46
|
-
expect(screen.getByText("
|
|
46
|
+
expect(screen.getByText("Email sent")).toBeTruthy();
|
|
47
47
|
});
|
|
48
|
-
expect(screen.getByRole("link", { name: /
|
|
48
|
+
expect(screen.getByRole("link", { name: /Back to sign in/i })).toBeTruthy();
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
test("server 5xx → error-banner statt Success-State", async () => {
|
|
@@ -54,14 +54,14 @@ describe("ForgotPasswordScreen", () => {
|
|
|
54
54
|
) as unknown as typeof fetch;
|
|
55
55
|
|
|
56
56
|
renderWithProviders(<ForgotPasswordScreen />);
|
|
57
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
57
|
+
fireEvent.change(screen.getByLabelText(/^Email/), {
|
|
58
58
|
target: { value: "user@example.com" },
|
|
59
59
|
});
|
|
60
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
60
|
+
fireEvent.click(screen.getByRole("button", { name: "Request link" }));
|
|
61
61
|
|
|
62
62
|
await waitFor(() => {
|
|
63
|
-
expect(screen.getByRole("alert").textContent).toContain("
|
|
63
|
+
expect(screen.getByRole("alert").textContent).toContain("wrong");
|
|
64
64
|
});
|
|
65
|
-
expect(screen.queryByText("
|
|
65
|
+
expect(screen.queryByText("Email sent")).toBeNull();
|
|
66
66
|
});
|
|
67
67
|
});
|
|
@@ -15,7 +15,7 @@ import { defaultTranslations } from "../../i18n";
|
|
|
15
15
|
import { InviteAcceptScreen } from "../invite-accept-screen";
|
|
16
16
|
import { makeSessionApi, renderWithProviders } from "./test-utils";
|
|
17
17
|
|
|
18
|
-
const resolver = createStaticLocaleResolver({ locale: "
|
|
18
|
+
const resolver = createStaticLocaleResolver({ locale: "en" });
|
|
19
19
|
|
|
20
20
|
function renderWithoutSessionProvider(token: string) {
|
|
21
21
|
return render(
|
|
@@ -51,18 +51,16 @@ afterEach(() => {
|
|
|
51
51
|
describe("InviteAcceptScreen — no <SessionProvider> ancestor (632/1)", () => {
|
|
52
52
|
test("renders the anonymous accept-form instead of throwing", () => {
|
|
53
53
|
renderWithoutSessionProvider("tok-123");
|
|
54
|
-
expect(screen.getByText("
|
|
55
|
-
expect(screen.getByLabelText(/^
|
|
54
|
+
expect(screen.getByText("Accept invitation")).toBeTruthy();
|
|
55
|
+
expect(screen.getByLabelText(/^Password/)).toBeTruthy();
|
|
56
56
|
// Anon default mode is "anon-existing" — email field is shown too.
|
|
57
|
-
expect(screen.getByLabelText(/^
|
|
57
|
+
expect(screen.getByLabelText(/^Email/)).toBeTruthy();
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
test("missing token still renders (no session access needed for that branch)", () => {
|
|
61
61
|
renderWithoutSessionProvider("");
|
|
62
|
-
expect(
|
|
63
|
-
|
|
64
|
-
).toBeTruthy();
|
|
65
|
-
expect(screen.getByRole("link", { name: "Zum Login" }).getAttribute("href")).toBe("/login");
|
|
62
|
+
expect(screen.getByText("The invitation link is missing or invalid.")).toBeTruthy();
|
|
63
|
+
expect(screen.getByRole("link", { name: "Go to sign in" }).getAttribute("href")).toBe("/login");
|
|
66
64
|
});
|
|
67
65
|
});
|
|
68
66
|
|
|
@@ -71,9 +69,9 @@ describe("InviteAcceptScreen — logged-in branch", () => {
|
|
|
71
69
|
renderWithProviders(<InviteAcceptScreen token="tok-123" />, {
|
|
72
70
|
session: makeSessionApi({ status: "authenticated" }),
|
|
73
71
|
});
|
|
74
|
-
expect(screen.getByText(/
|
|
75
|
-
expect(screen.getByRole("button", { name: "
|
|
76
|
-
expect(screen.queryByLabelText(/^
|
|
72
|
+
expect(screen.getByText(/user@example.com/)).toBeTruthy();
|
|
73
|
+
expect(screen.getByRole("button", { name: "Accept" })).toBeTruthy();
|
|
74
|
+
expect(screen.queryByLabelText(/^Email/)).toBeNull();
|
|
77
75
|
});
|
|
78
76
|
|
|
79
77
|
test("accept logged-in success redirects via loggedInHref function", async () => {
|
|
@@ -87,7 +85,7 @@ describe("InviteAcceptScreen — logged-in branch", () => {
|
|
|
87
85
|
<InviteAcceptScreen token="tok-123" loggedInHref={({ tenantId }) => `/${tenantId}/home`} />,
|
|
88
86
|
{ session: makeSessionApi({ status: "authenticated" }) },
|
|
89
87
|
);
|
|
90
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
88
|
+
fireEvent.click(screen.getByRole("button", { name: "Accept" }));
|
|
91
89
|
await waitFor(() => {
|
|
92
90
|
expect(assign).toHaveBeenCalledWith("/tenant-new/home");
|
|
93
91
|
});
|
|
@@ -100,7 +98,7 @@ describe("InviteAcceptScreen — logged-in branch", () => {
|
|
|
100
98
|
renderWithProviders(<InviteAcceptScreen token="bad" />, {
|
|
101
99
|
session: makeSessionApi({ status: "authenticated" }),
|
|
102
100
|
});
|
|
103
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
101
|
+
fireEvent.click(screen.getByRole("button", { name: "Accept" }));
|
|
104
102
|
await waitFor(() => {
|
|
105
103
|
expect(screen.getByRole("alert").textContent).toContain("auth.errors.invalidInviteToken");
|
|
106
104
|
});
|
|
@@ -110,8 +108,8 @@ describe("InviteAcceptScreen — logged-in branch", () => {
|
|
|
110
108
|
renderWithProviders(<InviteAcceptScreen token="tok-123" />, {
|
|
111
109
|
session: makeSessionApi({ status: "authenticated" }),
|
|
112
110
|
});
|
|
113
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
114
|
-
expect(screen.getByLabelText(/^
|
|
111
|
+
fireEvent.click(screen.getByRole("button", { name: "Sign in with a different account" }));
|
|
112
|
+
expect(screen.getByLabelText(/^Email/)).toBeTruthy();
|
|
115
113
|
});
|
|
116
114
|
});
|
|
117
115
|
|
|
@@ -122,9 +120,9 @@ describe("InviteAcceptScreen — anonymous branches", () => {
|
|
|
122
120
|
);
|
|
123
121
|
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
124
122
|
renderWithoutSessionProvider("tok-123");
|
|
125
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
126
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
127
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
123
|
+
fireEvent.change(screen.getByLabelText(/^Email/), { target: { value: "a@example.com" } });
|
|
124
|
+
fireEvent.change(screen.getByLabelText(/^Password/), { target: { value: "secret123" } });
|
|
125
|
+
fireEvent.click(screen.getByRole("button", { name: "Accept + sign in" }));
|
|
128
126
|
await waitFor(() => {
|
|
129
127
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
130
128
|
"/api/auth/invite-accept-with-login",
|
|
@@ -142,10 +140,10 @@ describe("InviteAcceptScreen — anonymous branches", () => {
|
|
|
142
140
|
);
|
|
143
141
|
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
144
142
|
renderWithoutSessionProvider("tok-123");
|
|
145
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
146
|
-
expect(screen.queryByLabelText(/^
|
|
147
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
148
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
143
|
+
fireEvent.click(screen.getByRole("button", { name: "I don't have an account yet" }));
|
|
144
|
+
expect(screen.queryByLabelText(/^Email/)).toBeNull();
|
|
145
|
+
fireEvent.change(screen.getByLabelText(/^Password/), { target: { value: "newpass123" } });
|
|
146
|
+
fireEvent.click(screen.getByRole("button", { name: "Accept + sign in" }));
|
|
149
147
|
await waitFor(() => {
|
|
150
148
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
151
149
|
"/api/auth/invite-signup-complete",
|
|
@@ -161,9 +159,9 @@ describe("InviteAcceptScreen — anonymous branches", () => {
|
|
|
161
159
|
async () => new Response(null, { status: 422 }),
|
|
162
160
|
) as unknown as typeof fetch;
|
|
163
161
|
renderWithoutSessionProvider("tok-123");
|
|
164
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
165
|
-
fireEvent.change(screen.getByLabelText(/^
|
|
166
|
-
fireEvent.click(screen.getByRole("button", { name: "
|
|
162
|
+
fireEvent.change(screen.getByLabelText(/^Email/), { target: { value: "a@example.com" } });
|
|
163
|
+
fireEvent.change(screen.getByLabelText(/^Password/), { target: { value: "wrong" } });
|
|
164
|
+
fireEvent.click(screen.getByRole("button", { name: "Accept + sign in" }));
|
|
167
165
|
await waitFor(() => {
|
|
168
166
|
expect(screen.getByRole("alert").textContent).toContain("auth.errors.invalidInviteToken");
|
|
169
167
|
});
|