@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.
Files changed (68) hide show
  1. package/package.json +9 -8
  2. package/src/admin-shell/__tests__/admin-shell.boot.test.ts +1 -1
  3. package/src/admin-shell/i18n.ts +17 -39
  4. package/src/admin-shell/web/i18n.ts +6 -11
  5. package/src/audit/i18n.ts +25 -41
  6. package/src/audit/web/i18n.ts +5 -9
  7. package/src/auth-email-password/__tests__/email-templates.test.ts +4 -0
  8. package/src/auth-email-password/email-templates.ts +97 -149
  9. package/src/auth-email-password/i18n.ts +6 -265
  10. package/src/auth-email-password/web/__tests__/confirm-account-unlock-screen.test.tsx +7 -7
  11. package/src/auth-email-password/web/__tests__/forgot-password-screen.test.tsx +14 -14
  12. package/src/auth-email-password/web/__tests__/invite-accept-screen.test.tsx +23 -25
  13. package/src/auth-email-password/web/__tests__/login-screen.test.tsx +60 -68
  14. package/src/auth-email-password/web/__tests__/request-account-unlock-screen.test.tsx +24 -24
  15. package/src/auth-email-password/web/__tests__/reset-password-screen.test.tsx +20 -20
  16. package/src/auth-email-password/web/__tests__/signup-complete-screen.test.tsx +9 -9
  17. package/src/auth-email-password/web/__tests__/signup-screen.test.tsx +11 -11
  18. package/src/auth-email-password/web/__tests__/test-utils.tsx +2 -2
  19. package/src/auth-email-password/web/__tests__/user-menu.test.tsx +3 -3
  20. package/src/auth-email-password/web/__tests__/verify-email-screen.test.tsx +3 -3
  21. package/src/auth-email-password/web/invite-accept-screen.tsx +3 -1
  22. package/src/auth-mfa/__tests__/errors-i18n-parity.test.ts +2 -4
  23. package/src/auth-mfa/i18n.ts +1 -3
  24. package/src/auth-mfa/web/__tests__/mfa-enable-screen.test.tsx +15 -15
  25. package/src/auth-mfa/web/__tests__/mfa-setup-preauth-screen.test.tsx +45 -49
  26. package/src/auth-mfa/web/__tests__/mfa-verify-screen.test.tsx +10 -10
  27. package/src/auth-mfa/web/i18n.ts +0 -126
  28. package/src/cap-counter/i18n.ts +5 -11
  29. package/src/compliance-profiles/i18n.ts +3 -11
  30. package/src/compliance-profiles/web/i18n.ts +0 -20
  31. package/src/config/i18n.ts +5 -5
  32. package/src/config/web/i18n.ts +1 -19
  33. package/src/custom-fields/web/i18n.ts +1 -18
  34. package/src/delivery/i18n.ts +3 -7
  35. package/src/delivery/web/i18n.ts +0 -20
  36. package/src/feature-toggles/i18n.ts +3 -11
  37. package/src/feature-toggles/web/i18n.ts +0 -24
  38. package/src/folders/web/i18n.ts +1 -51
  39. package/src/jobs/i18n.ts +40 -68
  40. package/src/jobs/web/i18n.ts +5 -9
  41. package/src/managed-pages/i18n.ts +23 -67
  42. package/src/managed-pages/web/i18n.ts +6 -11
  43. package/src/notes-history/i18n.ts +1 -1
  44. package/src/notes-history/web/i18n.ts +1 -17
  45. package/src/personal-access-tokens/i18n.ts +2 -6
  46. package/src/personal-access-tokens/web/i18n.ts +0 -72
  47. package/src/sessions/i18n.ts +17 -21
  48. package/src/tags/i18n.ts +2 -2
  49. package/src/tags/web/i18n.ts +1 -52
  50. package/src/template-resolver/web/__tests__/client-plugin.test.tsx +2 -2
  51. package/src/template-resolver/web/__tests__/editor-read-only.test.tsx +5 -5
  52. package/src/template-resolver/web/i18n.ts +0 -28
  53. package/src/tenant/__tests__/members-screens.boot.test.ts +0 -2
  54. package/src/tenant/i18n.ts +13 -27
  55. package/src/tenant/web/i18n.ts +0 -38
  56. package/src/tier-engine/i18n.ts +3 -39
  57. package/src/user/i18n.ts +14 -32
  58. package/src/user-data-rights/__tests__/default-mailers.test.ts +4 -0
  59. package/src/user-data-rights/__tests__/email-templates.test.ts +4 -0
  60. package/src/user-data-rights/__tests__/mail-default-bridge.integration.test.ts +2 -0
  61. package/src/user-data-rights/__tests__/run-export-jobs-cron-context.integration.test.ts +4 -0
  62. package/src/user-data-rights/email-templates.ts +55 -91
  63. package/src/user-data-rights/i18n.ts +18 -70
  64. package/src/user-data-rights/lib/default-mailers.ts +4 -1
  65. package/src/user-data-rights/web/__tests__/deletion-screens.test.tsx +11 -11
  66. package/src/user-data-rights/web/__tests__/public-deletion-gate.test.tsx +5 -5
  67. package/src/user-data-rights/web/i18n.ts +9 -157
  68. package/src/user-profile/i18n.ts +1 -71
@@ -1,145 +1,15 @@
1
1
  // @runtime client
2
- // Default-Bundles für die Feature-UI. Werden vom emailPasswordClient()
3
- // als Fallback-Bundle in den LocaleProvider gehängt — Apps können
4
- // einzelne Keys via `emailPasswordClient({ translations: { de: { ... } } })`
5
- // überschreiben, ohne das ganze Bundle kopieren zu müssen.
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 folgen dem Schema `auth.<area>.<slug>` — `auth.login.*` für die
8
- // Formular-UI, `auth.errors.*` für Reason-Codes aus dem Login-Handler
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(/enthält keinen Token/i)).toBeTruthy();
13
- expect(screen.getByRole("link", { name: "Zum Login" }).getAttribute("href")).toBe("/login");
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("Konto entsperrt")).toBeTruthy();
32
+ expect(screen.getByText("Account unlocked")).toBeTruthy();
33
33
  });
34
- expect(screen.getByRole("link", { name: "Zum Login" }).getAttribute("href")).toBe("/home");
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("Entsperren fehlgeschlagen")).toBeTruthy();
46
+ expect(screen.getByText("Unlock failed")).toBeTruthy();
47
47
  });
48
- expect(screen.getByRole("link", { name: "Zum Login" })).toBeTruthy();
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("Entsperren fehlgeschlagen")).toBeNull();
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("Passwort zurücksetzen")).toBeTruthy();
13
- expect(screen.getByLabelText(/^E-Mail/)).toBeTruthy();
14
- expect(screen.getByRole("button", { name: "Link anfordern" })).toBeTruthy();
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(/^E-Mail/), {
22
+ fireEvent.change(screen.getByLabelText(/^Email/), {
23
23
  target: { value: "user@example.com" },
24
24
  });
25
- fireEvent.click(screen.getByRole("button", { name: "Link anfordern" }));
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 + 'Zurück zum Login'-Link", async () => {
38
+ test("nach erfolgreichem Submit: success-Banner + 'Back to login'-Link", async () => {
39
39
  renderWithProviders(<ForgotPasswordScreen />);
40
- fireEvent.change(screen.getByLabelText(/^E-Mail/), {
40
+ fireEvent.change(screen.getByLabelText(/^Email/), {
41
41
  target: { value: "user@example.com" },
42
42
  });
43
- fireEvent.click(screen.getByRole("button", { name: "Link anfordern" }));
43
+ fireEvent.click(screen.getByRole("button", { name: "Request link" }));
44
44
 
45
45
  await waitFor(() => {
46
- expect(screen.getByText("Mail gesendet")).toBeTruthy();
46
+ expect(screen.getByText("Email sent")).toBeTruthy();
47
47
  });
48
- expect(screen.getByRole("link", { name: /Zurück zum Login/i })).toBeTruthy();
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(/^E-Mail/), {
57
+ fireEvent.change(screen.getByLabelText(/^Email/), {
58
58
  target: { value: "user@example.com" },
59
59
  });
60
- fireEvent.click(screen.getByRole("button", { name: "Link anfordern" }));
60
+ fireEvent.click(screen.getByRole("button", { name: "Request link" }));
61
61
 
62
62
  await waitFor(() => {
63
- expect(screen.getByRole("alert").textContent).toContain("schief");
63
+ expect(screen.getByRole("alert").textContent).toContain("wrong");
64
64
  });
65
- expect(screen.queryByText("Mail gesendet")).toBeNull();
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: "de" });
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("Einladung annehmen")).toBeTruthy();
55
- expect(screen.getByLabelText(/^Passwort/)).toBeTruthy();
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(/^E-Mail/)).toBeTruthy();
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
- screen.getByText("Der Einladungs-Link enthält keinen Token oder ist ungültig."),
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(/Du bist eingeloggt/)).toBeTruthy();
75
- expect(screen.getByRole("button", { name: "Annehmen" })).toBeTruthy();
76
- expect(screen.queryByLabelText(/^E-Mail/)).toBeNull();
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: "Annehmen" }));
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: "Annehmen" }));
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: "Mit anderem Account anmelden" }));
114
- expect(screen.getByLabelText(/^E-Mail/)).toBeTruthy();
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(/^E-Mail/), { target: { value: "a@example.com" } });
126
- fireEvent.change(screen.getByLabelText(/^Passwort/), { target: { value: "secret123" } });
127
- fireEvent.click(screen.getByRole("button", { name: "Annehmen + Anmelden" }));
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: "Ich habe noch keinen Account" }));
146
- expect(screen.queryByLabelText(/^E-Mail/)).toBeNull();
147
- fireEvent.change(screen.getByLabelText(/^Passwort/), { target: { value: "newpass123" } });
148
- fireEvent.click(screen.getByRole("button", { name: "Annehmen + Anmelden" }));
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(/^E-Mail/), { target: { value: "a@example.com" } });
165
- fireEvent.change(screen.getByLabelText(/^Passwort/), { target: { value: "wrong" } });
166
- fireEvent.click(screen.getByRole("button", { name: "Annehmen + Anmelden" }));
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
  });