From 69739c90d746892ac95964b4bfeafb0d75d2c72f Mon Sep 17 00:00:00 2001 From: fs Date: Fri, 24 Apr 2026 22:43:12 +0200 Subject: [PATCH] refactor(settings): split admin/settings into hub + per-section subpages Splits the 755-line monolithic settings page into a tile-based landing hub and six focused subpages (general, security, email, api, sso, branding), each with its own form, CSRF scope and POST handler. Each subpage offers Save / Save & close buttons plus a Cancel/back link to the hub. Backend (AdminSettingsService, gateways, policies, DB schema) unchanged. A new settingsSectionMergePost() helper overlays section POSTs onto the current DB values so partial saves don't wipe unrelated fields (the service defaults missing keys to 0/empty). Sub-action files (logo/favicon/tokens/lifecycle) redirect to the matching subpage, and architecture contracts now check the subpage files instead of the removed monolithic index. Co-Authored-By: Claude Opus 4.7 (1M context) --- core/Support/helpers.php | 1 + core/Support/helpers/admin_settings.php | 47 + i18n/default_de.json | 2586 +++++++++-------- i18n/default_en.json | 2586 +++++++++-------- pages/admin/settings/api().php | 86 + pages/admin/settings/api(default).phtml | 134 + pages/admin/settings/branding().php | 28 + pages/admin/settings/branding(default).phtml | 106 + pages/admin/settings/email().php | 89 + pages/admin/settings/email(default).phtml | 112 + .../settings/expire-remember-tokens().php | 8 +- pages/admin/settings/favicon().php | 15 +- pages/admin/settings/favicon-delete().php | 8 +- pages/admin/settings/general().php | 90 + pages/admin/settings/general(default).phtml | 183 ++ pages/admin/settings/index().php | 60 - pages/admin/settings/index(default).phtml | 809 +----- pages/admin/settings/logo().php | 15 +- pages/admin/settings/logo-delete().php | 8 +- pages/admin/settings/revoke-api-tokens().php | 8 +- pages/admin/settings/run-user-lifecycle().php | 12 +- pages/admin/settings/security().php | 95 + pages/admin/settings/security(default).phtml | 344 +++ pages/admin/settings/sso().php | 85 + pages/admin/settings/sso(default).phtml | 101 + .../AuthzAdminSettingsContractTest.php | 14 +- .../AuthzUiTemplateContractTest.php | 11 +- .../DetailActionPolicyContractFiles.php | 6 +- .../Architecture/DetailPageContractFiles.php | 6 +- .../FrontendRuntimeHostContractTest.php | 1 - 30 files changed, 4233 insertions(+), 3421 deletions(-) create mode 100644 core/Support/helpers/admin_settings.php create mode 100644 pages/admin/settings/api().php create mode 100644 pages/admin/settings/api(default).phtml create mode 100644 pages/admin/settings/branding().php create mode 100644 pages/admin/settings/branding(default).phtml create mode 100644 pages/admin/settings/email().php create mode 100644 pages/admin/settings/email(default).phtml create mode 100644 pages/admin/settings/general().php create mode 100644 pages/admin/settings/general(default).phtml create mode 100644 pages/admin/settings/security().php create mode 100644 pages/admin/settings/security(default).phtml create mode 100644 pages/admin/settings/sso().php create mode 100644 pages/admin/settings/sso(default).phtml diff --git a/core/Support/helpers.php b/core/Support/helpers.php index 84f36d5..6ca411c 100644 --- a/core/Support/helpers.php +++ b/core/Support/helpers.php @@ -1,6 +1,7 @@ $currentValues 'values' map from buildPageData() + * @param array $post user POST body (bodyAll()) + * @param list $sectionKeys keys owned by this section + * @return array + */ +function settingsSectionMergePost(array $currentValues, array $post, array $sectionKeys): array +{ + $seed = []; + foreach ($currentValues as $key => $value) { + if (is_bool($value)) { + if ($value) { + $seed[$key] = '1'; + } + continue; + } + if (is_array($value)) { + $seed[$key] = $value; + continue; + } + if ($value !== null) { + $seed[$key] = (string) $value; + } + } + + foreach ($sectionKeys as $key) { + unset($seed[$key]); + if (array_key_exists($key, $post)) { + $seed[$key] = $post[$key]; + } + } + + return $seed; +} diff --git a/i18n/default_de.json b/i18n/default_de.json index 5502f44..6415623 100644 --- a/i18n/default_de.json +++ b/i18n/default_de.json @@ -1,1343 +1,1357 @@ { - "Login": "Login", - "Login credentials": "Mit Zugangsdaten oder SSO anmelden", - "Login provider": "Login-Anbieter", - "Open full page": "Vollseite öffnen", - "Loading": "Lädt", - "Failed to load": "Laden fehlgeschlagen", - "Register": "Registrieren", - "Password": "Passwort", - "Or": "Oder", - "Forgot password": "Passwort vergessen", - "Remember me": "Angemeldet bleiben", - "Clear login tokens": "Login-Tokens löschen", - "Clear all login tokens for this user?": "Alle Login-Tokens für diesen Benutzer löschen?", - "Login tokens cleared": "Login-Tokens gelöscht", - "Send access": "Zugang versenden", - "Access PDF": "Zugangs-PDF", - "Download access PDFs": "Zugangs-PDFs herunterladen", - "Generate access PDFs for selected users?": "Zugangs-PDFs für ausgewählte Benutzer erstellen?", - "Too many users selected": "Zu viele Benutzer ausgewählt", - "No valid users selected": "Keine gültigen Benutzer ausgewählt", - "Failed to generate access PDF": "Zugangs-PDF konnte nicht erstellt werden", - "ZIP support missing (ext-zip)": "ZIP-Unterstützung fehlt (ext-zip)", - "Send access email to this user?": "Zugangsdaten an diesen Benutzer senden?", - "Access email sent": "Zugangsdaten gesendet", - "Access email failed": "Zugangsdaten konnten nicht gesendet werden", - "Your access details": "Deine Zugangsdaten", - "Reset password": "Passwort zurücksetzen", - "Verification code": "Bestätigungscode", - "Verify code": "Code prüfen", - "Verify": "Prüfen", - "Send code": "Code senden", - "Send code again": "Code erneut senden", - "Enter your email address and we will send you a verification code.": "Gib deine E-Mail-Adresse ein, wir senden dir einen Bestätigungscode.", - "Enter the verification code we sent to your email.": "Gib den Bestätigungscode ein, den wir dir per E-Mail gesendet haben.", - "Please enter a valid email address": "Bitte gib eine gültige E-Mail-Adresse ein", - "Please enter the 6-digit code": "Bitte gib den 6-stelligen Code ein", - "Invalid or expired code": "Code ist ungültig oder abgelaufen", - "Code verified": "Code bestätigt", - "Password reset code": "Code zum Zurücksetzen des Passworts", - "If the email exists, a verification code has been sent.": "Falls die E-Mail existiert, wurde ein Bestätigungscode gesendet.", - "Choose a new password for your account.": "Wähle ein neues Passwort für dein Konto.", - "Password updated": "Passwort aktualisiert", - "Password can not be updated": "Passwort kann nicht aktualisiert werden", - "Profile can not be updated": "Profil kann nicht aktualisiert werden", - "Reset request not found": "Zurücksetz-Anfrage nicht gefunden", - "Reset request already used": "Zurücksetz-Anfrage wurde bereits verwendet", - "Reset request expired": "Zurücksetz-Anfrage ist abgelaufen", - "Username": "Benutzername", - "Admin": "Admin", - "Logout": "Logout", - "Account": "Konto", - "Continue": "Weiter", - "Show password": "Passwort anzeigen", - "Hide password": "Passwort verbergen", - "Use different email": "Andere E-Mail verwenden", - "Back to login": "Zurück zum Login", - "Encrypted connection": "Verschlüsselt", - "HTTPS/TLS 1.2+ in transit": "HTTPS/TLS 1.2+ bei der Übertragung", - "Problems logging in": "Probleme beim Login", - "We could not continue with these login details": "Mit diesen Login-Daten konnte nicht fortgefahren werden", - "Cached": "Cache", - "App identity": "App-Identität", - "Configured": "Konfiguriert", - "Not configured": "Nicht konfiguriert", - "Theme policy": "Theme-Richtlinie", - "Brand color": "Markenfarbe", - "User override enabled": "Benutzer-Override aktiviert", - "User override disabled": "Benutzer-Override deaktiviert", - "Token lifetime policy": "Token-Laufzeit-Richtlinie", - "Token operations": "Token-Aktionen", - "CORS allowlist": "CORS-Allowlist", - "Shared Microsoft credentials": "Geteilte Microsoft-Zugangsdaten", - "Authority endpoint": "Authority-Endpunkt", + "%d active API tokens": "%d aktive API-Tokens", + "%d active login tokens": "%d aktive Login-Tokens", + "%d API audit entries purged": "%d API-Protokoll-Einträge bereinigt", + "%d API tokens revoked": "%d API-Tokens widerrufen", "%d defaults configured": "%d Standards konfiguriert", "%d events enabled": "%d Ereignisse aktiviert", + "%d import audit entries purged": "%d Import-Protokoll-Einträge bereinigt", + "%d login tokens expired": "%d Login-Tokens abgelaufen", "%d origins configured": "%d Origins konfiguriert", - "days": "Tage", - "Leave empty to use the runtime default title.": "Leer lassen, um den Laufzeit-Standardtitel zu verwenden.", - "Leave empty to keep the currently stored client secret.": "Leer lassen, um das aktuell gespeicherte Client-Secret beizubehalten.", - "This setting controls the application name shown across the UI.": "Diese Einstellung steuert den in der gesamten UI angezeigten Anwendungsnamen.", - "This setting controls the default language for users without a personal preference.": "Diese Einstellung steuert die Standardsprache für Benutzer ohne persönliche Präferenz.", - "These defaults prefill tenant, department and role when new users are created.": "Diese Standards füllen Mandant, Abteilung und Rolle bei neu erstellten Benutzern vor.", - "This setting controls the global default theme and whether users may choose their own theme.": "Diese Einstellung steuert das globale Standard-Theme und ob Benutzer ihr eigenes Theme wählen dürfen.", - "This setting controls the primary UI accent color for the default app theme.": "Diese Einstellung steuert die primäre UI-Akzentfarbe des Standard-App-Themes.", - "Telemetry helps detect recurring UI issues and failed requests in production.": "Telemetry hilft, wiederkehrende UI-Probleme und fehlgeschlagene Requests in Produktion zu erkennen.", - "Limit which event types are collected to match your privacy and operations requirements.": "Begrenze die erfassten Ereignistypen passend zu Datenschutz- und Betriebsanforderungen.", - "These limits define default and maximum lifetimes for newly issued API tokens.": "Diese Grenzwerte definieren Standard- und Maximallaufzeit für neu ausgestellte API-Tokens.", - "Define which origins may call your API from browsers. Use one origin per line.": "Definiere, welche Origins deine API aus Browsern aufrufen dürfen. Eine Origin pro Zeile.", - "This action revokes all active API tokens immediately across all users.": "Diese Aktion widerruft sofort alle aktiven API-Tokens über alle Benutzer hinweg.", - "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.": "Die Authority-URL definiert den Microsoft-Identity-Tenant-Endpunkt für die Anmeldung.", - "This will expire all remember-me tokens immediately and force users to sign in again.": "Dadurch werden alle Remember-me-Tokens sofort abgelaufen und Benutzer müssen sich erneut anmelden.", - "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.": "Globale Einstellungen werden in der Datenbank gespeichert. storage/runtime/settings.php ist nur ein Laufzeit-Cache für ausgewählte App-Einstellungen.", - "Too many login attempts. Please wait and try again.": "Zu viele Login-Versuche. Bitte warte kurz und versuche es erneut.", - "No login method is available for this tenant": "Für diesen Mandanten ist keine Login-Methode verfügbar", - "Create your account": "Erstelle dein Konto", - "First name": "Vorname", - "Name": "Name", - "Last name": "Nachname", - "Email": "E-Mail", - "Password (again)": "Passwort bestätigen", - "Password requirements": "Passwort-Anforderungen", - "At least %d characters": "Mindestens %d Zeichen", - "At least one uppercase letter": "Mindestens ein Großbuchstabe", - "At least one lowercase letter": "Mindestens ein Kleinbuchstabe", - "At least one number": "Mindestens eine Zahl", - "At least one symbol": "Mindestens ein Sonderzeichen", - "Must not contain your email": "Darf deine E-Mail nicht enthalten", - "Email/password not valid": "E-Mail oder Passwort ist ungültig", - "First name cannot be empty": "Vorname darf nicht leer sein", - "Last name cannot be empty": "Nachname darf nicht leer sein", - "Email cannot be empty": "E-Mail darf nicht leer sein", - "Email is not valid": "E-Mail ist ungültig", - "Password cannot be empty": "Passwort darf nicht leer sein", - "Passwords must match": "Passwörter müssen übereinstimmen", - "Password must be at least %d characters": "Passwort muss mindestens %d Zeichen haben", - "Password must include an uppercase letter": "Passwort muss einen Großbuchstaben enthalten", - "Password must include a lowercase letter": "Passwort muss einen Kleinbuchstaben enthalten", - "Password must include a number": "Passwort muss eine Zahl enthalten", - "Password must include a symbol": "Passwort muss ein Sonderzeichen enthalten", - "Password must not contain your email": "Passwort darf deine E-Mail nicht enthalten", - "Email is already taken": "E-Mail ist bereits vergeben", - "User can not be registered": "Benutzer kann nicht registriert werden", - "Language not supported": "Sprache wird nicht unterstützt", - "Language": "Sprache", - "Sales": "Vertrieb", - "Master data": "Stammdaten", - "Organization": "Organisation", - "Roles & permissions": "Rollen & Rechte", - "Permissions": "Berechtigungen", - "Permission key": "Berechtigungs-Schlüssel", - "Create permission": "Berechtigung erstellen", - "Edit permission": "Berechtigung bearbeiten", - "View permission": "Berechtigung anzeigen", - "Delete this permission?": "Diese Berechtigung löschen?", - "Permission created": "Berechtigung erstellt", - "Permission updated": "Berechtigung aktualisiert", - "Permission deleted": "Berechtigung gelöscht", - "Permission not found": "Berechtigung nicht gefunden", - "Permission can not be created": "Berechtigung kann nicht erstellt werden", - "Permission can not be updated": "Berechtigung kann nicht aktualisiert werden", - "Permission key cannot be empty": "Berechtigungs-Schlüssel darf nicht leer sein", - "Permission key is invalid": "Berechtigungs-Schlüssel ist ungültig", - "Permission key already exists": "Berechtigungs-Schlüssel existiert bereits", - "Assigned permissions": "Zugewiesene Berechtigungen", - "Select permissions": "Berechtigungen auswählen", - "No permissions available": "Keine Berechtigungen verfügbar", - "No permissions selected": "Keine Berechtigungen ausgewählt", - "Remove permission": "Berechtigung entfernen", - "Search permissions…": "Berechtigungen suchen…", - "No active permissions are configured yet.": "Es sind noch keine aktiven Berechtigungen konfiguriert.", - "No active roles are configured yet.": "Es sind noch keine aktiven Rollen konfiguriert.", - "Permission denied": "Keine Berechtigung", - "No active tenant assigned": "Kein aktiver Mandant zugewiesen", - "Please select at least one tenant": "Bitte mindestens einen Mandanten auswählen", - "perm.users.view": "Benutzer anzeigen", - "perm.users.create": "Benutzer erstellen", - "perm.users.update": "Benutzer bearbeiten", - "perm.users.access_pdf": "Onboarding-PDFs erstellen", - "perm.users.delete": "Benutzer löschen", - "perm.users.self_update": "Eigenen Benutzer bearbeiten", - "perm.users.update_assignments": "Benutzerzuweisungen bearbeiten", - "Permission origin": "Herkunft der Berechtigung", - "perm.tenants.view": "Mandanten anzeigen", - "perm.tenants.create": "Mandanten erstellen", - "perm.tenants.update": "Mandanten bearbeiten", - "perm.tenants.delete": "Mandanten löschen", - "perm.departments.view": "Abteilungen anzeigen", - "perm.departments.create": "Abteilungen erstellen", - "perm.departments.update": "Abteilungen bearbeiten", - "perm.departments.delete": "Abteilungen löschen", - "perm.roles.view": "Rollen anzeigen", - "perm.roles.create": "Rollen erstellen", - "perm.roles.update": "Rollen bearbeiten", - "perm.roles.delete": "Rollen löschen", - "perm.roles.assign_all": "Alle Rollen zuweisen", - "perm.permissions.view": "Berechtigungen anzeigen", - "perm.permissions.create": "Berechtigungen erstellen", - "perm.permissions.update": "Berechtigungen bearbeiten", - "perm.permissions.delete": "Berechtigungen löschen", - "perm.settings.view": "Einstellungen anzeigen", - "perm.settings.update": "Einstellungen bearbeiten", - "perm.mail_log.view": "E-Mail-Protokolle anzeigen", - "perm.jobs.view": "Geplante Aufgaben anzeigen", - "perm.jobs.manage": "Geplante Aufgaben verwalten", - "perm.jobs.run_now": "Geplante Aufgaben manuell ausführen", - "perm.audit.api.view": "API-Protokolle anzeigen", - "perm.audit.api.purge": "API-Protokolle bereinigen", - "perm.audit.system.view": "System-Protokolle anzeigen", - "perm.audit.system.purge": "System-Protokolle bereinigen", - "perm.audit.imports.view": "Import-Protokolle anzeigen", - "perm.audit.imports.purge": "Import-Protokolle bereinigen", - "perm.audit.user_lifecycle.view": "Benutzer-Lifecycle-Protokolle anzeigen", - "perm.audit.user_lifecycle.restore": "Benutzer aus Lifecycle-Protokoll wiederherstellen", - "perm.user_lifecycle_audit.view": "Benutzer-Lifecycle-Protokolle anzeigen", - "perm.users.lifecycle_restore": "Benutzer aus Lifecycle-Protokoll wiederherstellen", - "Select all": "Alle auswählen", - "Activate": "Aktivieren", - "Deactivate": "Deaktivieren", - "Delete": "Löschen", - "Activate users?": "Benutzer aktivieren?", - "Deactivate users?": "Benutzer deaktivieren?", - "Delete users?": "Benutzer löschen?", - "Send access emails to selected users?": "Zugangsdaten an ausgewählte Benutzer senden?", + "%d scheduler run logs purged": "%d Scheduler-Laufprotokolle bereinigt", + "%d selected": "%d ausgewählt", + "%d system audit entries purged": "%d System-Protokoll-Einträge bereinigt", + "%d user lifecycle audit entries purged": "%d Benutzer-Lifecycle-Protokoll-Einträge bereinigt", "%d users activated": "%d Benutzer aktiviert", "%d users deactivated": "%d Benutzer deaktiviert", "%d users deleted": "%d Benutzer gelöscht", - "Access emails sent to %d users": "Zugangsdaten an %d Benutzer gesendet", - "Access emails sent to %d users, %f failed": "Zugangsdaten an %d Benutzer gesendet, %f fehlgeschlagen", - "Failed to activate users": "Benutzer konnten nicht aktiviert werden", - "Failed to deactivate users": "Benutzer konnten nicht deaktiviert werden", - "Failed to delete users": "Benutzer konnten nicht gelöscht werden", - "Failed to send access emails": "Zugangsdaten konnten nicht gesendet werden", - "Home": "Home", - "Exception": "Ausnahme", - "An error occurred": "Ein Fehler ist aufgetreten", - "in %s on line %s": "in %s in Zeile %s", - "Copy request ID": "Request-ID kopieren", - "Error details": "Fehlerdetails", - "Request": "Anfrage", - "Queries": "Abfragen", - "An unexpected error occurred. If the problem persists, please contact support with the reference below.": "Ein unerwarteter Fehler ist aufgetreten. Wenn das Problem weiterhin besteht, kontaktiere bitte den Support mit der untenstehenden Referenz.", - "Stack Trace": "Stack-Trace", - "Caused by": "Verursacht durch", - "URL": "URL", - "User Agent": "User-Agent", - "Headers": "Header", - "GET Parameters": "GET-Parameter", - "POST Parameters": "POST-Parameter", - "Session (keys + types)": "Session (Schlüssel + Typen)", - "Context": "Kontext", - "PHP": "PHP", - "SAPI": "SAPI", - "Memory (current)": "Speicher (aktuell)", - "Memory (peak)": "Speicher (maximal)", - "Application": "Anwendung", - "Active Modules": "Aktive Module", - "Loaded Extensions (%d)": "Geladene Erweiterungen (%d)", - "Query tracking is not available (Debugger disabled or not initialized).": "Query-Tracking ist nicht verfügbar (Debugger deaktiviert oder nicht initialisiert).", - "No queries were executed before the error occurred.": "Vor dem Fehler wurden keine Abfragen ausgeführt.", - "Queries (%d)": "Abfragen (%d)", - "Bad Request": "Ungültige Anfrage", - "Unauthorized": "Nicht autorisiert", - "Forbidden": "Verboten", - "Not Found": "Nicht gefunden", - "Method Not Allowed": "Methode nicht erlaubt", - "Request Timeout": "Zeitüberschreitung der Anfrage", - "Unprocessable Entity": "Nicht verarbeitbare Anfrage", - "Too Many Requests": "Zu viele Anfragen", - "Internal Server Error": "Interner Serverfehler", - "Bad Gateway": "Fehlerhaftes Gateway", - "Service Unavailable": "Dienst nicht verfügbar", - "Users": "Benutzer", - "Avatar": "Avatar", - "Theme": "Theme", - "Light": "Hell", - "Dark": "Dunkel", - "Main menu": "Hauptmenü", - "Toggle Sidebar": "Sidebar umschalten", - "Toggle Detail Sidebar": "Detail-Seitenleiste umschalten", - "%d selected": "%d ausgewählt", - "Create user": "Benutzer anlegen", - "Edit user": "Benutzer bearbeiten", - "View user": "Benutzer anzeigen", - "Create": "Erstellen", - "Create & close": "Erstellen & schließen", - "Save": "Speichern", - "Save & close": "Speichern & schließen", - "Cancel": "Abbrechen", - "Close": "Schließen", - "Confirm": "Bestätigen", - "Please confirm": "Bitte bestätigen", - "This action cannot be undone.": "Diese Aktion kann nicht rückgängig gemacht werden.", - "Active": "Aktiv", - "Actions": "Aktionen", - "ID": "ID", - "Created": "Erstellt", - "Created by": "Erstellt von", - "Modified by": "Bearbeitet von", - "Modified": "Aktualisiert", - "Open": "Öffnen", - "Press Enter to open row": "Drücke Enter, um die Zeile zu öffnen", - "Retry": "Erneut versuchen", - "Yes": "Ja", - "No": "Nein", - "User created": "Benutzer erstellt", - "User updated": "Benutzer aktualisiert", - "User deleted": "Benutzer gelöscht", - "User not found": "Benutzer nicht gefunden", - "User can not be updated": "Benutzer kann nicht aktualisiert werden", - "Avatar updated": "Profilbild aktualisiert", - "Avatar removed": "Profilbild entfernt", - "Upload failed": "Upload fehlgeschlagen", - "File is too large": "Datei ist zu groß", - "Invalid image file": "Ungültige Bilddatei", - "No file uploaded": "Keine Datei hochgeladen", - "You cannot delete your own account": "Du kannst deinen eigenen Account nicht löschen", - "Login required": "Login erforderlich", - "You cannot deactivate your own account": "Du kannst dein eigenes Konto nicht deaktivieren", - "Welcome back": "Willkommen zurück", - "New password (optional)": "Neues Passwort (optional)", - "Account is inactive": "Konto ist deaktiviert", - "Inactive": "Inaktiv", - "Filter": "Filter", - "Apply filters": "Filter anwenden", - "Clear all filters": "Alle Filter zurücksetzen", - "Close filters": "Filter schließen", - "Remove filter": "Filter entfernen", - "Filters applied": "Filter angewendet", - "Filter removed": "Filter entfernt", - "All filters cleared": "Alle Filter entfernt", - "UUID": "UUID", - "Profile image": "Profilbild", - "Profile": "Profil", - "Profile description": "Profilbeschreibung", - "Search results": "Suchergebnisse", - "Result": "Ergebnis", - "Type": "Typ", - "Page": "Seite", - "Upload image": "Bild hochladen", - "App logo": "App-Logo", - "Upload logo": "Logo hochladen", - "Logo updated": "Logo aktualisiert", - "Logo removed": "Logo entfernt", - "Tenant logos": "Mandanten-Logos", - "Light logo": "Logo (hell)", - "Dark logo": "Logo (dunkel)", - "Upload light logo": "Helles Logo hochladen", - "Upload dark logo": "Dunkles Logo hochladen", - "Delete light logo": "Helles Logo löschen", - "Delete dark logo": "Dunkles Logo löschen", - "No logo for this theme yet": "Für dieses Theme wurde noch kein Logo hochgeladen", - "Delete this logo?": "Dieses Logo löschen?", - "Invalid theme": "Ungültiges Theme", - "Logo": "Logo", - "Remove": "Entfernen", - "Allowed file types: SVG, PNG, JPG, WEBP": "Erlaubte Dateitypen: SVG, PNG, JPG, WEBP", - "Favicon": "Favicon", - "Tenant favicon": "Mandanten-Favicon", - "Square PNG. Icons are center-cropped.": "Quadratisches PNG. Symbole werden mittig zugeschnitten.", - "Delete this favicon?": "Dieses Favicon löschen?", - "Upload favicon": "Favicon hochladen", - "Favicon updated": "Favicon aktualisiert", - "Favicon removed": "Favicon entfernt", - "Allowed file types: PNG": "Erlaubte Dateitypen: PNG", - "Square images are recommended (icons are center-cropped).": "Quadratische Bilder empfohlen (Icons werden zentriert zugeschnitten).", - "Primary color": "Primärfarbe", - "Primary color is invalid": "Primärfarbe ist ungültig", - "The primary color affects buttons and accent elements across the app.": "Die Primärfarbe beeinflusst Buttons und Akzent-Elemente in der gesamten App.", - "Export CSV": "CSV exportieren", - "Export": "Export", - "Export as CSV": "Als CSV exportieren", - "Export for Excel": "Für Excel exportieren", - "State": "Status", - "Edit": "Bearbeiten", - "Status": "Status", - "Visibility": "Sichtbarkeit", - "Inactive entries are hidden in lists and selections.": "Inaktive Einträge werden in Listen und Auswahlen ausgeblendet.", - "All": "Alle", - "Explorer": "Explorer", - "Search": "Suche", - "Search...": "Suchen...", - "Search users, tenants, pages...": "Benutzer, Mandanten, Seiten durchsuchen...", - "Users, tenants, departments, roles and more": "Benutzer, Mandanten, Abteilungen, Rollen und mehr", - "Searching...": "Suche läuft...", - "Search failed. Please try again.": "Suche fehlgeschlagen. Bitte erneut versuchen.", - "No results found": "Keine Ergebnisse gefunden", - "View all results": "Alle Ergebnisse anzeigen", - "navigate": "navigieren", - "open": "öffnen", - "close": "schließen", - "Created from": "Erstellt von", - "Created to": "Erstellt bis", - "Settings": "Einstellungen", - "Documentation": "Dokumentation", - "Documentation navigation": "Dokumentationsnavigation", - "On this page": "Auf dieser Seite", - "Getting started": "Erste Schritte", - "Architecture & rules": "Architektur & Regeln", - "Frontend": "Frontend", - "Features": "Features", - "API reference": "API-Referenz", - "Operations": "Betrieb", - "Automation & integrations": "Automatisierung & Integrationen", - "Logs": "Protokolle", - "System": "System", - "System permission": "Systemberechtigung", - "System permission can not be deleted": "Systemberechtigung kann nicht gelöscht werden", - "System permissions are core and should rarely be disabled.": "Systemberechtigungen sind kernrelevant und sollten nur selten deaktiviert werden.", - "Statistics": "Statistiken", - "Active users": "Aktive Benutzer", - "Inactive users": "Inaktive Benutzer", - "Sent emails": "Gesendete E-Mails", - "Primary navigation": "Hauptnavigation", - "Footer navigation": "Fußzeilen-Navigation", - "Language switcher": "Sprachauswahl", - "Sort column ascending": "Spalte aufsteigend sortieren", - "Sort column descending": "Spalte absteigend sortieren", - "Previous": "Zurück", - "Next": "Weiter", - "Navigation": "Navigation", - "Display": "Anzeige", - "Session": "Sitzung", - "Page %d of %d": "Seite %d von %d", - "Page %d": "Seite %d", - "Per page": "Pro Seite", - "Skip to main content": "Zum Hauptinhalt springen", - "Rows per page": "Einträge pro Seite", - "Showing": "Zeige", - "of": "von", - "to": "bis", - "results": "Ergebnisse", - "Loading...": "Lade...", - "No records found": "Keine Einträge gefunden", - "An error happened while fetching the data": "Fehler beim Laden der Daten", - "Delete this user?": "Diesen Benutzer wirklich löschen?", - "Delete user": "Benutzer löschen", - "This will permanently delete this user.": "Dieser Benutzer wird dauerhaft gelöscht.", - "Delete this tenant?": "Diesen Mandanten wirklich löschen?", - "Delete tenant": "Mandant löschen", - "This will permanently delete this tenant.": "Dieser Mandant wird dauerhaft gelöscht.", - "Tenant": "Mandant", - "Default tenant": "Standard-Mandant", - "Default role": "Standard-Rolle", - "Default department": "Standard-Abteilung", - "Default": "Standard", - "Access & password": "Zugang & Passwort", - "Security": "Sicherheit", - "Preferences": "Einstellungen", - "My account": "Meine Benutzereinstellungen", - "None": "Keine", - "Settings updated": "Einstellungen gespeichert", - "setting.default_tenant": "Standard-Mandant, wenn bei der Benutzeranlage keiner zugewiesen wird", - "setting.default_role": "Standard-Rolle, wenn bei der Benutzeranlage keine Rolle zugewiesen wird", - "setting.default_department": "Standard-Abteilung, wenn bei der Benutzeranlage keine Abteilung zugewiesen wird", - "setting.app_title": "App-Titel für den Browser-Tab", - "setting.app_locale": "Standard-Sprache, wenn keine Sprache gesetzt ist", - "Default language": "Standard-Sprache", - "setting.app_registration": "Öffentliche Selbstregistrierung erlauben", - "setting.api_token_default_ttl_days": "Standard-Laufzeit für neue API-Tokens in Tagen (Default: 90)", - "setting.api_token_max_ttl_days": "Maximale Laufzeit für API-Tokens in Tagen (Hard Cap)", - "setting.api_cors_allowed_origins": "Erlaubte Browser-Origins für API-CORS (eine Origin pro Zeile)", - "API token default lifetime (days)": "Standardlaufzeit für API-Tokens (Tage)", - "API token maximum lifetime (days)": "Maximale Laufzeit für API-Tokens (Tage)", - "Allowed CORS origins": "Erlaubte CORS-Origins", - "One origin per line, e.g. https://app.example.com": "Eine Origin pro Zeile, z. B. https://app.example.com", - "Default theme": "Standard-Theme", - "Allow user theme": "Benutzer-Theme erlauben", - "Allow registration": "Registrierung erlauben", - "Appearance": "Darstellung", - "API docs": "API-Doku", - "Can view API documentation": "Kann API-Dokumentation anzeigen", - "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.": "Die Darstellung wird pro Mandant gesteuert. Jeder Mandant hat eine eigene Primärfarbe und ein eigenes Standard-Theme.", - "The theme used for users in this tenant who have no personal preference.": "Das Theme für Nutzer dieses Mandanten, die keine persönliche Präferenz gesetzt haben.", - "Users may choose their own theme": "Benutzer dürfen ihr eigenes Theme wählen", - "Controls whether users in this tenant can override the tenant default with a personal theme preference.": "Steuert, ob Benutzer dieses Mandanten den Mandanten-Standard durch eine persönliche Theme-Präferenz überschreiben dürfen.", - "Inactive tenants are excluded from user access and tenant-scoped data.": "Inaktive Mandanten werden vom Benutzerzugriff und mandantenspezifischen Daten ausgeschlossen.", - "Status & meta": "Status & Meta", - "Audit": "Audit", - "Overview": "Übersicht", - "Choose color": "Farbe wählen", - "Code": "Code", - "Cost center": "Kostenstelle", - "Department code already exists": "Abteilungscode existiert bereits", - "Role code already exists": "Rollencode existiert bereits", - "Internationalization": "Internationalisierung", - "User creation rules": "Benutzeranlage-Regeln", - "App title": "App-Titel", - "Tenants": "Mandanten", - "Create tenant": "Mandant anlegen", - "Edit tenant": "Mandant bearbeiten", - "View tenant": "Mandant anzeigen", - "Tenant created": "Mandant erstellt", - "Tenant updated": "Mandant aktualisiert", - "Tenant deleted": "Mandant gelöscht", - "Tenant not found": "Mandant nicht gefunden", - "Tenant can not be deleted while departments are assigned": "Mandant kann nicht gelöscht werden, solange Abteilungen zugewiesen sind", - "Tenant can not be created": "Mandant kann nicht erstellt werden", - "Tenant can not be updated": "Mandant kann nicht aktualisiert werden", - "Assigned tenants": "Zugewiesene Mandanten", - "Assigned tenant": "Zugewiesener Mandant", - "Primary tenant": "Hauptmandant", - "Select primary tenant": "Hauptmandant auswählen", - "Please select a primary tenant": "Bitte einen Hauptmandanten auswählen", - "Primary tenant must be one of the assigned tenants": "Der Hauptmandant muss einem zugewiesenen Mandanten entsprechen", - "Department assignments cleaned: %d": "Abteilungszuweisungen bereinigt: %d", - "Select tenants": "Mandanten auswählen", - "Select tenant": "Mandant auswählen", - "Assigned roles": "Zugewiesene Rollen", - "Select roles": "Rollen auswählen", - "Department": "Abteilung", - "Departments": "Abteilungen", - "Create department": "Abteilung anlegen", - "Edit department": "Abteilung bearbeiten", - "View department": "Abteilung anzeigen", - "Department created": "Abteilung erstellt", - "Department updated": "Abteilung aktualisiert", - "Department deleted": "Abteilung gelöscht", - "Department not found": "Abteilung nicht gefunden", - "Department can not be created": "Abteilung kann nicht erstellt werden", - "Department can not be updated": "Abteilung kann nicht aktualisiert werden", - "Department can not be deleted while users are assigned": "Abteilung kann nicht gelöscht werden, solange Benutzer zugewiesen sind", - "Delete this department?": "Diese Abteilung wirklich löschen?", - "Delete department": "Abteilung löschen", - "This will permanently delete this department.": "Diese Abteilung wird dauerhaft gelöscht.", - "Assigned departments": "Zugewiesene Abteilungen", - "Select departments": "Abteilungen auswählen", - "Departments for tenant": "Abteilungen für Mandant", - "No departments available for this tenant": "Für diesen Mandanten sind keine Abteilungen verfügbar", - "Assign tenants first to select departments": "Bitte zuerst Mandanten zuweisen, um Abteilungen auszuwählen", - "No tenants available": "Keine Mandanten verfügbar", - "No tenant is available in your current scope.": "Im aktuellen Geltungsbereich sind keine Mandanten verfügbar.", - "Role": "Rolle", - "Roles": "Rollen", - "No roles available": "Keine Rollen verfügbar", - "No roles selected": "Keine Rollen ausgewählt", - "Remove role": "Rolle entfernen", - "Search roles…": "Rollen suchen…", - "Assignable roles": "Zuweisbare Rollen", - "Create role": "Rolle anlegen", - "Edit role": "Rolle bearbeiten", - "View role": "Rolle anzeigen", - "Role created": "Rolle erstellt", - "Role updated": "Rolle aktualisiert", - "Role deleted": "Rolle gelöscht", - "Role not found": "Rolle nicht gefunden", - "Role can not be created": "Rolle kann nicht erstellt werden", - "Role can not be updated": "Rolle kann nicht aktualisiert werden", - "Delete this role?": "Diese Rolle wirklich löschen?", - "Delete role": "Rolle löschen", - "Delete permission": "Berechtigung löschen", - "This will permanently delete this role.": "Diese Rolle wird dauerhaft gelöscht.", - "This will permanently delete this permission.": "Diese Berechtigung wird dauerhaft gelöscht.", - "Description": "Beschreibung", - "Description cannot be empty": "Beschreibung darf nicht leer sein", - "Status is invalid": "Status ist ungültig", - "Address": "Adresse", - "Postal code": "Postleitzahl", - "City": "Ort", - "Country": "Land", - "Mail logs": "E-Mail-Protokolle", - "Mail log": "E-Mail-Protokoll", - "View mail log": "E-Mail-Protokoll ansehen", - "Mail log not found": "E-Mail-Protokoll nicht gefunden", - "Email details": "E-Mail-Details", - "Recipient": "Empfänger", - "Subject": "Betreff", - "Template": "Vorlage", - "Sent": "Gesendet", - "Failed": "Fehlgeschlagen", - "Queued": "Warteschlange", - "Error message": "Fehlermeldung", - "Error information": "Fehlerinformationen", - "Provider message ID": "Provider-Nachrichten-ID", - "Sent at": "Gesendet am", - "Created at": "Erstellt am", - "Delivery information": "Versandinformationen", - "All statuses": "Alle Status", - "Contact": "Kontakt", - "Support": "Support", - "Support email": "Support-E-Mail", - "Support phone": "Support-Telefon", - "No contact details available": "Keine Kontaktdaten vorhanden", - "VAT ID": "USt-ID", - "Tax number": "Steuernummer", - "Billing email": "Rechnungs-E-Mail", - "Phone": "Telefon", - "Website": "Webseite", - "Legal": "Rechtliches", - "No legal links configured": "Keine rechtlichen Links konfiguriert", - "Privacy URL": "Datenschutz-URL", - "Imprint URL": "Impressum-URL", - "Region": "Region", - "Fax": "Fax", - "Back": "Zurück", - "Access denied": "Zugriff verweigert", - "You do not have permission to view this content.": "Du hast keine Berechtigung, diesen Inhalt zu sehen.", - "If you believe this is an error, please contact your system administrator.": "Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an den Systemadministrator.", - "Requested URL": "Angeforderte URL", - "Forward": "Vorwärts", - "Status changed": "Status geändert", - "Status changed by": "Status geändert von", - "Requested path": "Angeforderter Pfad", - "Page not found": "Seite nicht gefunden", - "The page you requested does not exist or has moved.": "Die angeforderte Seite existiert nicht oder wurde verschoben.", - "Back to start": "Zur Startseite", - "Page updated": "Seite aktualisiert", - "Page can not be updated": "Seite kann nicht aktualisiert werden", - "Content is invalid": "Inhalt ist ungültig", - "You are not allowed to edit this page": "Du darfst diese Seite nicht bearbeiten", - "Form expired, please try again": "Formular abgelaufen, bitte erneut versuchen", - "Start writing...": "Mit dem Schreiben beginnen...", - "View": "Ansicht", - "Heading": "Überschrift", - "Copy content to": "Inhalt kopieren nach", - "Existing content in the target language will be overwritten": "Bestehender Inhalt in der Zielsprache wird überschrieben", - "Content copied": "Inhalt kopiert", - "Target language required": "Zielsprache erforderlich", - "Source content not found": "Quellinhalt nicht gefunden", - "Employment": "Arbeitsverhältnis", - "Job title": "Position", - "Hire date": "Eintrittsdatum", - "German": "Deutsch", - "English": "Englisch", - "Switch tenant": "Mandant wechseln", - "Copy": "Kopieren", - "Copy to clipboard": "In Zwischenablage kopieren", - "Registration successful! Please check your email for the verification code.": "Registrierung erfolgreich! Bitte prüfe deine E-Mails für den Bestätigungscode.", - "Registration is currently disabled": "Registrierung ist derzeit deaktiviert.", - "A new verification code has been sent.": "Ein neuer Bestätigungscode wurde gesendet.", - "Email already verified. Please login.": "E-Mail bereits bestätigt. Bitte einloggen.", - "If the email exists, a new verification code has been sent.": "Falls die E-Mail existiert, wurde ein neuer Bestätigungscode gesendet.", - "Email verified successfully! Please login.": "E-Mail erfolgreich bestätigt! Bitte einloggen.", - "Too many failed attempts. Please request a new code.": "Zu viele Fehlversuche. Bitte fordere einen neuen Code an.", - "Verify email": "E-Mail bestätigen", - "Enter the verification code we sent to your email to complete your registration.": "Gib den Bestätigungscode ein, den wir dir per E-Mail gesendet haben, um deine Registrierung abzuschließen.", - "Email verified": "E-Mail bestätigt", - "Not verified": "Nicht bestätigt", - "Verified": "Bestätigt", - "SMTP host": "SMTP Host", - "SMTP port": "SMTP Port", - "SMTP user": "SMTP Benutzer", - "SMTP password": "SMTP Passwort", - "SMTP security": "SMTP Sicherheit", - "SMTP from address": "Absender-Adresse", - "SMTP from name": "Absendername", - "Mobile": "Mobil", - "Short dial": "Kurzwahl", - "setting.smtp_host": "SMTP-Serveradresse (z.B. smtp.example.com)", - "setting.smtp_port": "SMTP-Port (z.B. 587)", - "setting.smtp_user": "SMTP-Benutzername", - "setting.smtp_password": "Leer lassen, um das bestehende Passwort zu behalten", - "setting.smtp_secure": "Verschlüsselung für SMTP", - "setting.smtp_from": "Absender-E-Mail für ausgehende Nachrichten", - "setting.smtp_from_name": "Absendername für ausgehende Nachrichten", - "High contrast": "Hoher Kontrast", - "Toggle contrast": "Kontrast umschalten", - "Email security": "E-Mail Sicherheit", - "API": "API", - "API requests (24h)": "API Requests (24h)", - "Request trend vs previous 24h": "Request-Trend zur vorherigen 24h", + "0 disables this rule": "0 deaktiviert diese Regel", + "1. Upload CSV and click analyze": "1. CSV hochladen und analysieren klicken", + "2. Map your CSV columns to system fields": "2. CSV-Spalten auf Systemfelder mappen", + "3. Review preview counters and row errors": "3. Vorschau, Zähler und Zeilenfehler prüfen", + "4. Start import for valid rows": "4. Import für gültige Zeilen starten", "4xx errors (24h)": "4xx Fehler (24h)", "5xx errors (24h)": "5xx Fehler (24h)", - "P95 response time (ms)": "P95 Antwortzeit (ms)", - "Tokens expiring in 7 days": "Tokens mit Ablauf in 7 Tagen", - "Top API error codes (24h)": "Top API-Fehlercodes (24h)", - "Slowest API endpoints (avg, 24h)": "Langsamste API-Endpunkte (Durchschnitt, 24h)", - "Import runs (7d)": "Import-Läufe (7 Tage)", - "Created rows (7d)": "Erstellte Zeilen (7 Tage)", - "Failed rows (7d)": "Fehlgeschlagene Zeilen (7 Tage)", - "Success rate (7d)": "Erfolgsquote (7 Tage)", - "Recent import runs": "Letzte Import-Läufe", - "Imports by profile (7d)": "Importe nach Profil (7 Tage)", - "Top import error codes (7d)": "Häufigste Import-Fehlercodes (7 Tage)", - "Runs": "Läufe", - "Created rows": "Erstellte Zeilen", - "Failed rows": "Fehlgeschlagene Zeilen", - "Success rate": "Erfolgsquote", - "Requests": "Requests", - "Average duration (ms)": "Durchschnittliche Dauer (ms)", - "Maximum duration (ms)": "Maximale Dauer (ms)", - "Error": "Fehler", - "Active tenants": "Aktive Mandanten", - "Inactive tenants": "Inaktive Mandanten", - "Active departments": "Aktive Abteilungen", - "Inactive departments": "Inaktive Abteilungen", - "Active roles": "Aktive Rollen", - "Inactive roles": "Inaktive Rollen", - "Roles without permissions": "Rollen ohne Berechtigungen", - "Permissions without roles": "Berechtigungen ohne Rollen", - "Users without roles": "Benutzer ohne Rollen", - "Users without tenants": "Benutzer ohne Mandant", - "Mail failures": "E-Mail Fehler", - "Last email sent": "Letzte E-Mail gesendet", - "Never": "Nie", - "Recent logins": "Letzte Anmeldungen", - "Never logged in": "Nie angemeldet", - "Last login": "Letzte Anmeldung", - "Last login via": "Letzte Anmeldung über", - "Local": "Lokal", - "Microsoft": "Microsoft", - "Unknown": "Unbekannt", - "User": "Benutzer", - "No entries found": "Keine Einträge gefunden", - "Login status": "Anmeldestatus", - "Logged in": "Angemeldet", - "Email unverified": "E-Mail nicht verifiziert", - "Password resets": "Passwort-Resets", - "No password reset requests": "Keine Passwort-Reset-Anfragen", - "No reset has been requested for this account yet.": "Für dieses Konto wurde noch kein Reset angefordert.", - "Requested at": "Angefordert am", - "Expires at": "Gültig bis", - "Used at": "Verwendet am", - "Attempts": "Versuche", - "Used": "Verwendet", - "Expired": "Abgelaufen", - "Expired by admin": "Durch Admin abgelaufen", - "Login tokens": "Login-Tokens", - "No login tokens": "Keine Login-Tokens", - "This user is currently not signed in via remember-me.": "Dieser Benutzer ist aktuell nicht per Angemeldet-bleiben eingeloggt.", - "Expire all login tokens": "Alle Login-Tokens ablaufen", - "Expire all login tokens?": "Alle Login-Tokens ablaufen?", - "%d active login tokens": "%d aktive Login-Tokens", - "%d login tokens expired": "%d Login-Tokens abgelaufen", - "Danger zone": "Gefahrenzone", - "This will mark all remember-me tokens as expired. Users will need to sign in again.": "Alle Angemeldet-bleiben Tokens werden als abgelaufen markiert. Benutzer müssen sich erneut anmelden sobald die Browser-Session ausgelaufen ist.", - "Last used": "Zuletzt verwendet", - "Keyboard shortcuts": "Tastenkürzel", - "Open search": "Suche öffnen", - "Save in edit pages": "Auf Bearbeitungsseiten speichern", - "Unsaved changes": "Ungespeichert", - "Unsaved change (%d field)": "Ungespeichert (%d Feld)", - "Unsaved changes (%d fields)": "Ungespeichert (%d Felder)", - "Please review the following errors": "Bitte prüfen Sie die folgenden Fehler", - "You have unsaved changes. Leave without saving?": "Sie haben ungespeicherte Änderungen. Seite ohne Speichern verlassen?", - "Switch sidebar section": "Sidebar-Bereich wechseln", + "A new verification code has been sent.": "Ein neuer Bestätigungscode wurde gesendet.", + "About": "Über", + "Access & password": "Zugang & Passwort", + "Access and profile sync": "Zugriff und Profilabgleich", + "Access denied": "Zugriff verweigert", + "Access email failed": "Zugangsdaten konnten nicht gesendet werden", + "Access email sent": "Zugangsdaten gesendet", + "Access emails sent to %d users": "Zugangsdaten an %d Benutzer gesendet", + "Access emails sent to %d users, %f failed": "Zugangsdaten an %d Benutzer gesendet, %f fehlgeschlagen", + "Access PDF": "Zugangs-PDF", + "Account": "Konto", + "Account is inactive": "Konto ist deaktiviert", "Action": "Aktion", - "Mac": "Mac", - "Windows": "Windows", - "Email verification code": "E-Mail Verifizierungscode", - "Failed to switch tenant": "Mandantwechsel fehlgeschlagen", - "IDs": "IDs", - "Pages": "Seiten", - "Permission": "Berechtigung", - "No effective permissions": "Keine effektiven Berechtigungen", - "Assign at least one role to show effective permissions.": "Weisen Sie mindestens eine Rolle zu, um effektive Berechtigungen anzuzeigen.", - "Please verify your email first": "Bitte bestätige zuerst deine E-Mail", - "Toggle sidebar": "Sidebar umschalten", - "Unverified": "Nicht verifiziert", - "Imprint": "Impressum", - "Privacy": "Datenschutz", - "Terms of Service": "Nutzungsbedingungen", - "Custom fields": "Zusatzfelder", - "User custom fields": "Benutzerzusatzfelder", - "Affected tenants": "Betroffene Mandanten", - "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).": "Wenn ein Mandant hier erscheint, muss mindestens eine Zusatzfeld-Konfiguration geprüft werden (fehlende Optionen, inaktive Felder mit Werten oder ungenutzte aktive Felder).", - "Issue": "Problem", - "Count": "Anzahl", - "Selection fields without options": "Auswahlfelder ohne Optionen", - "Tenants with broken selection fields": "Mandanten mit fehlerhaften Auswahlfeldern", - "Inactive custom fields with values": "Inaktive Zusatzfelder mit Werten", - "Unused active custom fields": "Ungenutzte aktive Zusatzfelder", - "Save tenant first to manage custom fields": "Speichern Sie den Mandanten zuerst, um Zusatzfelder zu verwalten", - "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.": "Hier definieren Sie Zusatzfelder. Diese erscheinen pro Benutzer im Reiter \"Zusatzfelder\" und sind dort pflegbar.", + "Actions": "Aktionen", + "Activate": "Aktivieren", + "Activate users?": "Benutzer aktivieren?", + "Active": "Aktiv", + "Active departments": "Aktive Abteilungen", + "Active Modules": "Aktive Module", + "Active modules": "Aktive Module", + "Active permissions": "Aktive Berechtigungen", + "Active roles": "Aktive Rollen", + "Active tenants": "Aktive Mandanten", + "Active users": "Aktive Benutzer", + "Active value is invalid": "Active-Wert ist ungültig", + "Actor": "Akteur", + "Actor tenant": "Akteur-Mandant", + "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID": "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID", "Add custom field": "Zusatzfeld hinzufügen", - "The label is shown in user custom fields and in address book filters.": "Die Bezeichnung wird bei Benutzer-Zusatzfeldern und in den Adressbuch-Filtern angezeigt.", - "The field type controls input and filter behavior.": "Der Feldtyp steuert Eingabe- und Filterverhalten.", - "Field type": "Feldtyp", - "Text": "Text", - "Textarea": "Mehrzeiliger Text", - "Select": "Auswahl", - "Multiselect": "Mehrfachauswahl", - "Boolean": "Ja/Nein", - "Date": "Datum", - "Filterable": "Filterbar", - "Options (one per line)": "Optionen (eine pro Zeile)", - "Example: manager|Manager": "Beispiel: manager|Manager", - "One option per line. Optional format: key|Label.": "Eine Option pro Zeile. Optionales Format: key|Label.", - "No custom fields configured yet": "Noch keine Zusatzfelder konfiguriert", - "Delete custom field": "Zusatzfeld löschen", - "Custom field saved": "Zusatzfeld gespeichert", - "Custom field deleted": "Zusatzfeld gelöscht", - "Custom field can not be created": "Zusatzfeld kann nicht erstellt werden", - "Custom field can not be updated": "Zusatzfeld kann nicht aktualisiert werden", - "Custom field can not be deleted": "Zusatzfeld kann nicht gelöscht werden", - "Custom field values can not be saved": "Zusatzfeldwerte konnten nicht gespeichert werden", - "Custom field not found": "Zusatzfeld nicht gefunden", - "Label cannot be empty": "Bezeichnung darf nicht leer sein", - "Field key cannot be empty": "Feldschlüssel darf nicht leer sein", - "Field type is invalid": "Feldtyp ist ungültig", - "Field key already exists": "Feldschlüssel existiert bereits", - "Options are required for this field type": "Für diesen Feldtyp sind Optionen erforderlich", - "Assign tenants first to edit custom fields": "Bitte zuerst Mandanten zuweisen, um Zusatzfelder zu bearbeiten", - "Custom fields for tenant": "Zusatzfelder für Mandant", - "No custom fields configured for this tenant": "Für diesen Mandanten sind keine Zusatzfelder konfiguriert", - "No custom fields configured for selected tenants": "Für die ausgewählten Mandanten sind keine Zusatzfelder konfiguriert", - "Select options": "Optionen auswählen", - "Invalid value for %s": "Ungültiger Wert für %s", - "Please select": "Bitte auswählen", - "perm.custom_fields.manage": "Mandanten-Zusatzfelder verwalten", - "perm.custom_fields.edit_values": "Benutzer-Zusatzfelder bearbeiten", - "Label": "Bezeichnung", - "Required": "Pflichtfeld", - "Filterable fields are available in address book filters.": "Filterbare Felder sind im Adressbuch als Filter verfügbar.", - "Inactive fields are hidden in forms and filters.": "Inaktive Felder sind in Formularen und Filtern ausgeblendet.", - "Default theme is invalid": "Standard-Theme ist ungültig", - "Theme change is disabled for this tenant": "Theme-Wechsel ist für diesen Mandanten deaktiviert", - "Controls whether users in this tenant can choose their own theme.": "Steuert, ob Benutzer in diesem Mandanten ihr eigenes Theme wählen können.", - "Tenants can override color and theme behavior in their appearance settings.": "Mandanten können Farbe und Theme-Verhalten in ihren Darstellungs-Einstellungen überschreiben.", - "User theme policy": "Benutzer-Theme-Richtlinie", - "APP_CRYPTO_KEY is missing or invalid": "APP_CRYPTO_KEY fehlt oder ist ungültig", + "Address": "Adresse", + "Admin": "Admin", + "Administrator check could not be executed": "Administrator-Prüfung konnte nicht ausgeführt werden", + "Administrators": "Administratoren", + "Advanced telemetry options": "Erweiterte Telemetrie-Optionen", + "Affected tenants": "Betroffene Mandanten", + "AJAX errors": "AJAX-Fehler", + "All": "Alle", + "All channels": "Alle Kanäle", + "All filters cleared": "Alle Filter entfernt", + "All methods": "Alle Methoden", + "All outcomes": "Alle Ergebnisse", + "All profiles": "Alle Profile", + "All required core tables are present": "Alle erforderlichen Kerntabellen sind vorhanden", + "All statuses": "Alle Status", + "All systems operational": "Alle Systeme betriebsbereit", + "All triggers": "Alle Auslöser", + "Allow LDAP-only login (disable local password login)": "Nur LDAP-Anmeldung erlauben (lokale Passwortanmeldung deaktivieren)", + "Allow Microsoft-only login (disable local password login)": "Nur Microsoft-Anmeldung erlauben (lokale Passwort-Anmeldung deaktivieren)", + "Allow registration": "Registrierung erlauben", + "Allow user theme": "Benutzer-Theme erlauben", + "Allowed CORS origins": "Erlaubte CORS-Origins", "Allowed email domains": "Erlaubte E-Mail-Domains", + "Allowed file types: PNG": "Erlaubte Dateitypen: PNG", + "Allowed file types: SVG, PNG, JPG, WEBP": "Erlaubte Dateitypen: SVG, PNG, JPG, WEBP", + "Allowed range: 1-365 days (default: 30)": "Erlaubter Bereich: 1–365 Tage (Standard: 30)", + "Allowed range: 1-72 hours (default: 8)": "Erlaubter Bereich: 1-72 Stunden (Standard: 8)", + "Allowed range: 5-1440 minutes (default: 30)": "Erlaubter Bereich: 5-1440 Minuten (Standard: 30)", + "Allowed telemetry events": "Erlaubte Telemetrie-Ereignisse", + "An error happened while fetching the data": "Fehler beim Laden der Daten", + "An error occurred": "Ein Fehler ist aufgetreten", + "An unexpected error occurred. If the problem persists, please contact support with the reference below.": "Ein unerwarteter Fehler ist aufgetreten. Wenn das Problem weiterhin besteht, kontaktiere bitte den Support mit der untenstehenden Referenz.", + "Analyze file": "Datei analysieren", + "API": "API", + "API audit": "API-Protokolle", + "API audit entry not found": "API-Protokoll-Eintrag nicht gefunden", + "API audit logs": "API-Protokolle", + "API docs": "API-Doku", + "API reference": "API-Referenz", + "API requests (24h)": "API Requests (24h)", + "API settings": "API-Einstellungen", + "API token created. Copy it now — it will not be shown again.": "API-Token erstellt. Jetzt kopieren — es wird nicht erneut angezeigt.", + "API token default lifetime (days)": "Standardlaufzeit für API-Tokens (Tage)", + "API token default lifetime is invalid": "Standardlaufzeit für API-Tokens ist ungültig", + "API token max lifetime is invalid": "Maximale Laufzeit für API-Tokens ist ungültig", + "API token maximum lifetime (days)": "Maximale Laufzeit für API-Tokens (Tage)", + "API token policy and CORS allowlist": "API-Token-Richtlinien und CORS-Allowlist", + "API token revoked": "API-Token widerrufen", + "API tokens": "API-Tokens", + "App credentials (advanced)": "App-Anmeldedaten (Erweitert)", + "App identity": "App-Identität", + "App logo": "App-Logo", + "App logo and favicon": "App-Logo und Favicon", + "App title": "App-Titel", + "App title, language, user creation defaults": "App-Titel, Sprache, Standardwerte für neue Benutzer", + "APP_CRYPTO_KEY is missing or invalid": "APP_CRYPTO_KEY fehlt oder ist ungültig", + "Appearance": "Darstellung", + "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.": "Die Darstellung wird pro Mandant gesteuert. Jeder Mandant hat eine eigene Primärfarbe und ein eigenes Standard-Theme.", + "Application": "Anwendung", + "Apply filters": "Filter anwenden", + "Architecture & rules": "Architektur & Regeln", + "Assign at least one role to show effective permissions.": "Weisen Sie mindestens eine Rolle zu, um effektive Berechtigungen anzuzeigen.", + "Assign tenants first to edit custom fields": "Bitte zuerst Mandanten zuweisen, um Zusatzfelder zu bearbeiten", + "Assign tenants first to select departments": "Bitte zuerst Mandanten zuweisen, um Abteilungen auszuwählen", + "Assignable roles": "Zuweisbare Rollen", + "Assigned departments": "Zugewiesene Abteilungen", + "Assigned permissions": "Zugewiesene Berechtigungen", + "Assigned roles": "Zugewiesene Rollen", + "Assigned tenant": "Zugewiesener Mandant", + "Assigned tenants": "Zugewiesene Mandanten", + "Assignment columns require additional permission.": "Zuweisungsspalten benötigen eine zusätzliche Berechtigung.", + "Assignment import permission is required": "Berechtigung für Assignment-Import ist erforderlich", + "At least %d characters": "Mindestens %d Zeichen", + "At least one administrator is active": "Mindestens ein Administrator ist aktiv", + "At least one lowercase letter": "Mindestens ein Kleinbuchstabe", + "At least one number": "Mindestens eine Zahl", + "At least one symbol": "Mindestens ein Sonderzeichen", + "At least one uppercase letter": "Mindestens ein Großbuchstabe", + "At least one weekday is required for weekly schedule": "Für einen wöchentlichen Zeitplan ist mindestens ein Wochentag erforderlich", + "Attempts": "Versuche", + "Attribute mapping and sync": "Attributzuordnung und Synchronisierung", + "Audit": "Audit", + "Authority endpoint": "Authority-Endpunkt", "Authority URL": "Authority-URL", + "Auto-delete is ignored while auto-deactivate is disabled": "Auto-Löschung wird ignoriert, solange Auto-Deaktivierung deaktiviert ist", + "Automation & integrations": "Automatisierung & Integrationen", + "Avatar": "Avatar", + "Avatar removed": "Profilbild entfernt", + "Avatar updated": "Profilbild aktualisiert", + "Average duration (ms)": "Durchschnittliche Dauer (ms)", + "Back": "Zurück", + "Back to login": "Zurück zum Login", + "Back to start": "Zur Startseite", + "Bad Gateway": "Fehlerhaftes Gateway", + "Bad Request": "Ungültige Anfrage", + "Base DN": "Base-DN", + "Baseline permissions are missing": "Basisberechtigungen fehlen", + "Baseline permissions are present": "Basisberechtigungen sind vorhanden", + "Billing email": "Rechnungs-E-Mail", + "Bind DN (service account)": "Bind-DN (Dienstkonto)", + "Bind DN could not be decrypted": "Bind-DN konnte nicht entschlüsselt werden", + "Bind DN could not be encrypted": "Bind-DN konnte nicht verschlüsselt werden", + "Bind method": "Bindungsmethode", + "Bind password": "Bind-Passwort", + "Bind password could not be decrypted": "Bind-Passwort konnte nicht entschlüsselt werden", + "Bind password could not be encrypted": "Bind-Passwort konnte nicht verschlüsselt werden", + "Boolean": "Ja/Nein", + "Brand color": "Markenfarbe", + "Branding": "Branding", + "Branding settings": "Branding-Einstellungen", + "Breadcrumb": "Breadcrumb", + "Cached": "Cache", + "Call": "Anrufen", + "Can view API documentation": "Kann API-Dokumentation anzeigen", + "Cancel": "Abbrechen", + "Catch up once": "Verpassten Lauf einmal nachholen", + "Caused by": "Verursacht durch", + "Channel": "Kanal", + "Check": "Prüfung", + "Choose a new password for your account.": "Wähle ein neues Passwort für dein Konto.", + "Choose color": "Farbe wählen", + "City": "Ort", + "Clear all filters": "Alle Filter zurücksetzen", + "Clear all login tokens for this user?": "Alle Login-Tokens für diesen Benutzer löschen?", + "Clear bind password": "Bind-Passwort löschen", + "Clear login tokens": "Login-Tokens löschen", "Clear override secret": "Override-Secret entfernen", + "Client credentials are missing": "Client-Zugangsdaten fehlen", "Client ID override": "Client-ID-Override", "Client ID override is required": "Client-ID-Override ist erforderlich", "Client secret could not be encrypted": "Client-Secret konnte nicht verschlüsselt werden", "Client secret override": "Client-Secret-Override", + "Client secret override is invalid": "Client-Secret-Override ist ungültig", "Client secret override is required": "Client-Secret-Override ist erforderlich", + "Close": "Schließen", + "close": "schließen", + "Close filters": "Filter schließen", + "Close navigation": "Navigation schließen", + "Code": "Code", + "Code already exists": "Code existiert bereits", + "Code verified": "Code bestätigt", + "Complete": "Vollständig", + "Complete the required Microsoft configuration before enforcing Microsoft-only login.": "Vervollständigen Sie die erforderliche Microsoft-Konfiguration, bevor Sie Microsoft-only-Anmeldung erzwingen.", + "Components": "Komponenten", + "Concepts": "Konzepte", + "Configuration complete": "Konfiguration vollständig", + "Configuration status": "Konfigurationsstatus", + "Configured": "Konfiguriert", + "Confirm": "Bestätigen", + "Connection established": "Verbindung hergestellt", + "Contact": "Kontakt", + "Content copied": "Inhalt kopiert", + "Content is invalid": "Inhalt ist ungültig", + "Context": "Kontext", + "Continue": "Weiter", + "Contributor guide": "Mitwirken", + "Controls remember-me token lifetime and Microsoft auto-remember behavior.": "Steuert die Lebensdauer von Angemeldet-bleiben-Tokens und das automatische Anmeldeverhalten bei Microsoft-Login.", + "Controls whether Microsoft logins automatically persist a remember-me token.": "Steuert, ob Microsoft-Anmeldungen automatisch ein Angemeldet-bleiben-Token setzen.", + "Controls whether users in this tenant can choose their own theme.": "Steuert, ob Benutzer in diesem Mandanten ihr eigenes Theme wählen können.", + "Controls whether users in this tenant can override the tenant default with a personal theme preference.": "Steuert, ob Benutzer dieses Mandanten den Mandanten-Standard durch eine persönliche Theme-Präferenz überschreiben dürfen.", + "Copy": "Kopieren", + "Copy content to": "Inhalt kopieren nach", + "Copy email address": "E-Mail-Adresse kopieren", + "Copy mobile number": "Mobilnummer kopieren", + "Copy phone number": "Telefonnummer kopieren", + "Copy request ID": "Request-ID kopieren", + "Copy to clipboard": "In Zwischenablage kopieren", + "CORS allowed origins are invalid": "Erlaubte CORS-Origins sind ungültig", + "CORS allowlist": "CORS-Allowlist", + "Cost center": "Kostenstelle", + "Could not create API token: %s": "API-Token konnte nicht erstellt werden: %s", + "Count": "Anzahl", + "Counters": "Zähler", + "Country": "Land", + "Create": "Erstellen", + "Create & close": "Erstellen & schließen", + "Create a token to enable API access for this user.": "Erstellen Sie ein Token, um den API-Zugriff für diesen Benutzer zu aktivieren.", + "Create API token": "API-Token erstellen", + "Create department": "Abteilung anlegen", + "Create permission": "Berechtigung erstellen", + "Create role": "Rolle anlegen", + "Create tenant": "Mandant anlegen", + "Create user": "Benutzer anlegen", + "Create your account": "Erstelle dein Konto", + "Create-only: existing entries are skipped": "Nur erstellen: bestehende Einträge werden übersprungen", + "Created": "Erstellt", + "Created at": "Erstellt am", + "Created by": "Erstellt von", + "Created count": "Erstellt", + "Created from": "Erstellt von", + "Created rows": "Erstellte Zeilen", + "Created rows (7d)": "Erstellte Zeilen (7 Tage)", + "Created to": "Erstellt bis", + "Credentials source": "Quelle der Zugangsdaten", + "Cron": "Cron", + "Cron runner active": "Cron-Runner aktiv", + "CSV file": "CSV-Datei", + "CSV file has no data rows": "CSV-Datei enthält keine Datenzeilen", + "CSV header": "CSV-Header", + "CSV header is invalid": "CSV-Header ist ungültig", + "CSV row limit exceeded": "CSV-Zeilenlimit überschritten", + "Current image": "Aktuelles Bild", + "Current tenant": "Aktueller Mandant", + "Custom field can not be created": "Zusatzfeld kann nicht erstellt werden", + "Custom field can not be deleted": "Zusatzfeld kann nicht gelöscht werden", + "Custom field can not be updated": "Zusatzfeld kann nicht aktualisiert werden", + "Custom field deleted": "Zusatzfeld gelöscht", + "Custom field not found": "Zusatzfeld nicht gefunden", + "Custom field saved": "Zusatzfeld gespeichert", + "Custom field values can not be saved": "Zusatzfeldwerte konnten nicht gespeichert werden", + "Custom fields": "Zusatzfelder", + "Custom fields for tenant": "Zusatzfelder für Mandant", + "Daily": "Täglich", + "Daily interval must be between 1 and 365": "Tägliches Intervall muss zwischen 1 und 365 liegen", + "Danger zone": "Gefahrenzone", + "Dark": "Dunkel", + "Dark logo": "Logo (dunkel)", + "Database": "Datenbank", + "Database check could not be executed": "Datenbank-Prüfung konnte nicht ausgeführt werden", + "Database did not return the expected response": "Datenbank hat keine erwartete Antwort geliefert", + "Database schema": "Datenbankschema", + "Date": "Datum", + "days": "Tage", + "Deactivate": "Deaktivieren", + "Deactivate users after inactivity (days)": "Nach Inaktivität deaktivieren (Tage)", + "Deactivate users?": "Benutzer deaktivieren?", + "Default": "Standard", + "Default department": "Standard-Abteilung", + "Default language": "Standard-Sprache", + "Default role": "Standard-Rolle", + "Default tenant": "Standard-Mandant", + "Default theme": "Standard-Theme", + "Default theme is invalid": "Standard-Theme ist ungültig", + "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.": "Hier definieren Sie Zusatzfelder. Diese erscheinen pro Benutzer im Reiter \"Zusatzfelder\" und sind dort pflegbar.", + "Define which origins may call your API from browsers. Use one origin per line.": "Definiere, welche Origins deine API aus Browsern aufrufen dürfen. Eine Origin pro Zeile.", + "Degraded service": "Eingeschränkter Betrieb", + "Delete": "Löschen", + "Delete custom field": "Zusatzfeld löschen", + "Delete dark logo": "Dunkles Logo löschen", + "Delete department": "Abteilung löschen", + "Delete inactive users after (days)": "Inaktive löschen nach (Tagen)", + "Delete light logo": "Helles Logo löschen", + "Delete permission": "Berechtigung löschen", + "Delete role": "Rolle löschen", + "Delete tenant": "Mandant löschen", + "Delete this department?": "Diese Abteilung wirklich löschen?", + "Delete this favicon?": "Dieses Favicon löschen?", + "Delete this image?": "Dieses Bild löschen?", + "Delete this logo?": "Dieses Logo löschen?", + "Delete this permission?": "Diese Berechtigung löschen?", + "Delete this role?": "Diese Rolle wirklich löschen?", + "Delete this tenant?": "Diesen Mandanten wirklich löschen?", + "Delete this user?": "Diesen Benutzer wirklich löschen?", + "Delete user": "Benutzer löschen", + "Delete users?": "Benutzer löschen?", + "Delivery information": "Versandinformationen", + "Denied": "Verweigert", + "Department": "Abteilung", + "Department already exists for this tenant": "Abteilung für diesen Mandanten existiert bereits", + "Department assignments cleaned: %d": "Abteilungszuweisungen bereinigt: %d", + "Department can not be created": "Abteilung kann nicht erstellt werden", + "Department can not be deleted while users are assigned": "Abteilung kann nicht gelöscht werden, solange Benutzer zugewiesen sind", + "Department can not be updated": "Abteilung kann nicht aktualisiert werden", + "Department code already exists": "Abteilungscode existiert bereits", + "Department created": "Abteilung erstellt", + "Department deleted": "Abteilung gelöscht", + "Department does not belong to tenant": "Abteilung gehört nicht zum Mandanten", + "Department is missing, inactive or invalid": "Abteilung fehlt, ist inaktiv oder ungültig", + "Department not found": "Abteilung nicht gefunden", + "Department updated": "Abteilung aktualisiert", + "Departments": "Abteilungen", + "Departments for tenant": "Abteilungen für Mandant", + "Dependencies": "Abhängigkeiten", + "Description": "Beschreibung", + "Description cannot be empty": "Beschreibung darf nicht leer sein", + "Details": "Details", + "Direct bind": "Direkte Bindung", + "Direct bind method requires a username format": "Direkte Bindung erfordert ein Benutzernamenformat", + "Direct bind username format": "Format für direkte Bindung", + "Disabled": "Inaktiv", + "Display": "Anzeige", + "Documentation": "Dokumentation", + "Documentation navigation": "Dokumentationsnavigation", + "Download access PDFs": "Zugangs-PDFs herunterladen", + "Download sample CSV": "Beispiel-CSV herunterladen", + "Drop file here or click to select": "Datei hierher ziehen oder klicken", + "Duplicate entry in CSV file": "Doppelter Eintrag in der CSV-Datei", + "Duration (ms)": "Dauer (ms)", + "e.g. CI Pipeline": "z.B. CI-Pipeline", + "Edit": "Bearbeiten", + "Edit department": "Abteilung bearbeiten", + "Edit permission": "Berechtigung bearbeiten", + "Edit role": "Rolle bearbeiten", + "Edit scheduled job": "Geplante Aufgabe bearbeiten", + "Edit tenant": "Mandant bearbeiten", + "Edit user": "Benutzer bearbeiten", + "Email": "E-Mail", + "Email already exists": "E-Mail existiert bereits", + "Email already verified. Please login.": "E-Mail bereits bestätigt. Bitte einloggen.", + "Email cannot be empty": "E-Mail darf nicht leer sein", + "Email details": "E-Mail-Details", + "Email is already taken": "E-Mail ist bereits vergeben", + "Email is invalid": "E-Mail ist ungültig", + "Email is not valid": "E-Mail ist ungültig", + "Email security": "E-Mail Sicherheit", + "Email settings": "E-Mail-Einstellungen", + "Email unverified": "E-Mail nicht verifiziert", + "Email verification code": "E-Mail Verifizierungscode", + "Email verified": "E-Mail bestätigt", + "Email verified successfully! Please login.": "E-Mail erfolgreich bestätigt! Bitte einloggen.", + "Email/password not valid": "E-Mail oder Passwort ist ungültig", + "Employment": "Arbeitsverhältnis", + "Enable frontend telemetry": "Frontend-Telemetrie aktivieren", + "Enable LDAP login for this tenant": "LDAP-Anmeldung für diesen Mandanten aktivieren", "Enable Microsoft login for this tenant": "Microsoft-Login für diesen Mandanten aktivieren", + "Enable system audit log": "System-Protokolle aktivieren", + "Enabled": "Aktiv", + "Enabled jobs": "Aktive Aufgaben", + "Encrypted connection": "Verschlüsselt", + "Encryption": "Verschlüsselung", + "English": "Englisch", + "Enter the verification code we sent to your email to complete your registration.": "Gib den Bestätigungscode ein, den wir dir per E-Mail gesendet haben, um deine Registrierung abzuschließen.", + "Enter the verification code we sent to your email.": "Gib den Bestätigungscode ein, den wir dir per E-Mail gesendet haben.", + "Enter your email address and we will send you a verification code.": "Gib deine E-Mail-Adresse ein, wir senden dir einen Bestätigungscode.", "Entra tenant ID (tid)": "Entra-Tenant-ID (tid)", "Entra tenant ID is invalid": "Entra-Tenant-ID ist ungültig", - "Microsoft SSO": "Microsoft SSO", + "Entry could not be created": "Eintrag konnte nicht erstellt werden", + "Environment": "Umgebung", + "Error": "Fehler", + "Error code": "Fehlercode", + "Error code distribution": "Fehlercode-Verteilung", + "Error details": "Fehlerdetails", + "Error information": "Fehlerinformationen", + "Error message": "Fehlermeldung", + "Event": "Ereignis", + "Event details": "Ereignisdetails", + "Event type": "Ereignistyp", + "Every %d day(s) at %s": "Alle %d Tag(e) um %s", + "Every %d hour(s)": "Alle %d Stunde(n)", + "Every %d week(s) on %s at %s": "Alle %d Woche(n) an %s um %s", + "Example: manager|Manager": "Beispiel: manager|Manager", + "Exception": "Ausnahme", + "Existing content in the target language will be overwritten": "Bestehender Inhalt in der Zielsprache wird überschrieben", + "Expire all login tokens": "Alle Login-Tokens ablaufen", + "Expire all login tokens?": "Alle Login-Tokens ablaufen?", + "Expired": "Abgelaufen", + "Expired by admin": "Durch Admin abgelaufen", + "Expires at": "Gültig bis", + "Explorer": "Explorer", + "Export": "Export", + "Export as CSV": "Als CSV exportieren", + "Export CSV": "CSV exportieren", + "Export for Excel": "Für Excel exportieren", + "Extend session": "Sitzung verlängern", + "Fail": "Fehler", + "Failed": "Fehlgeschlagen", + "Failed count": "Fehlgeschlagen", + "Failed or denied": "Fehlgeschlagen oder verweigert", + "Failed rows": "Fehlgeschlagene Zeilen", + "Failed rows (7d)": "Fehlgeschlagene Zeilen (7 Tage)", + "Failed scheduler runs (24h)": "Fehlgeschlagene Scheduler-Läufe (24h)", + "Failed to activate users": "Benutzer konnten nicht aktiviert werden", + "Failed to deactivate users": "Benutzer konnten nicht deaktiviert werden", + "Failed to delete users": "Benutzer konnten nicht gelöscht werden", + "Failed to generate access PDF": "Zugangs-PDF konnte nicht erstellt werden", + "Failed to load": "Laden fehlgeschlagen", + "Failed to send access emails": "Zugangsdaten konnten nicht gesendet werden", + "Failed to switch tenant": "Mandantwechsel fehlgeschlagen", + "Failed to update permission roles": "Berechtigungsrollen konnten nicht aktualisiert werden", + "Failed to update role permissions": "Rollenberechtigungen konnten nicht aktualisiert werden", + "Favicon": "Favicon", + "Favicon removed": "Favicon entfernt", + "Favicon updated": "Favicon aktualisiert", + "Fax": "Fax", + "Features": "Features", + "Field key already exists": "Feldschlüssel existiert bereits", + "Field key cannot be empty": "Feldschlüssel darf nicht leer sein", + "Field type": "Feldtyp", + "Field type is invalid": "Feldtyp ist ungültig", + "File": "Datei", + "File is too large": "Datei ist zu groß", + "Filter": "Filter", + "Filter removed": "Filter entfernt", + "Filterable": "Filterbar", + "Filterable fields are available in address book filters.": "Filterbare Felder sind im Adressbuch als Filter verfügbar.", + "Filters applied": "Filter angewendet", + "Finished": "Beendet", + "First name": "Vorname", + "First name cannot be empty": "Vorname darf nicht leer sein", + "Footer navigation": "Fußzeilen-Navigation", + "Forbidden": "Verboten", + "Force off": "Erzwingen (aus)", + "Force on": "Erzwingen (an)", + "Forgot password": "Passwort vergessen", + "Form expired, please try again": "Formular abgelaufen, bitte erneut versuchen", + "Forward": "Vorwärts", + "Fri": "Fr", + "Frontend": "Frontend", + "Frontend telemetry": "Frontend-Telemetrie", + "General": "Allgemein", + "General settings": "Allgemeine Einstellungen", + "Generate access PDFs for selected users?": "Zugangs-PDFs für ausgewählte Benutzer erstellen?", + "German": "Deutsch", + "GET Parameters": "GET-Parameter", + "Getting started": "Erste Schritte", + "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.": "Globale Einstellungen werden in der Datenbank gespeichert. storage/runtime/settings.php ist nur ein Laufzeit-Cache für ausgewählte App-Einstellungen.", + "Headers": "Header", + "Heading": "Überschrift", + "Health Status": "Systemstatus", + "Here is a CSV template for this import profile.": "Hier ist eine CSV-Vorlage für dieses Importprofil.", + "Hide password": "Passwort verbergen", + "High contrast": "Hoher Kontrast", + "Hire date": "Eintrittsdatum", + "Hire date must be YYYY-MM-DD": "Eintrittsdatum muss YYYY-MM-DD sein", + "Hired": "Eingestellt", + "Home": "Home", + "Hourly": "Stündlich", + "Hourly interval must be between 1 and 24": "Stündliches Intervall muss zwischen 1 und 24 liegen", + "How the import works": "So funktioniert der Import", + "How-to guides": "Aufgabenanleitungen", + "HTTPS/TLS 1.2+ in transit": "HTTPS/TLS 1.2+ bei der Übertragung", + "ID": "ID", + "IDs": "IDs", + "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).": "Wenn ein Mandant hier erscheint, muss mindestens eine Zusatzfeld-Konfiguration geprüft werden (fehlende Optionen, inaktive Felder mit Werten oder ungenutzte aktive Felder).", + "If the email exists, a new verification code has been sent.": "Falls die E-Mail existiert, wurde ein neuer Bestätigungscode gesendet.", + "If the email exists, a verification code has been sent.": "Falls die E-Mail existiert, wurde ein Bestätigungscode gesendet.", + "If you believe this is an error, please contact your system administrator.": "Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an den Systemadministrator.", + "Ignore column": "Spalte ignorieren", + "Import": "Import", + "Import another file": "Weitere Datei importieren", + "Import audit entry not found": "Import-Protokoll-Eintrag nicht gefunden", + "Import audit logs": "Import-Protokolle", + "Import details": "Import-Details", + "Import finished": "Import abgeschlossen", + "Import logs": "Import-Protokolle", + "Import runs (7d)": "Import-Läufe (7 Tage)", + "Imports": "Importe", + "Imports by profile (7d)": "Importe nach Profil (7 Tage)", + "Imprint": "Impressum", + "Imprint URL": "Impressum-URL", + "in %s on line %s": "in %s in Zeile %s", + "Inactive": "Inaktiv", + "Inactive (orphaned) permissions": "Inaktive (verwaiste) Berechtigungen", + "Inactive custom fields with values": "Inaktive Zusatzfelder mit Werten", + "Inactive departments": "Inaktive Abteilungen", + "Inactive entries are hidden in lists and selections.": "Inaktive Einträge werden in Listen und Auswahlen ausgeblendet.", + "Inactive fields are hidden in forms and filters.": "Inaktive Felder sind in Formularen und Filtern ausgeblendet.", + "Inactive roles": "Inaktive Rollen", + "Inactive tenants": "Inaktive Mandanten", + "Inactive tenants are excluded from user access and tenant-scoped data.": "Inaktive Mandanten werden vom Benutzerzugriff und mandantenspezifischen Daten ausgeschlossen.", + "Inactive users": "Inaktive Benutzer", + "Incomplete": "Unvollständig", + "Inherit global default": "Globalen Standard verwenden", + "Internal Server Error": "Interner Serverfehler", + "Internationalization": "Internationalisierung", + "Invalid file type": "Ungültiger Dateityp", + "Invalid image file": "Ungültige Bilddatei", + "Invalid or expired code": "Code ist ungültig oder abgelaufen", + "Invalid theme": "Ungültiges Theme", + "Invalid value for %s": "Ungültiger Wert für %s", + "IP": "IP", + "IP hash": "IP-Hash", + "Issue": "Problem", + "Job": "Aufgabe", + "Job key": "Aufgaben-Key", + "Job title": "Position", + "Keyboard shortcuts": "Tastenkürzel", + "Label": "Bezeichnung", + "Label cannot be empty": "Bezeichnung darf nicht leer sein", + "Language": "Sprache", + "Language not supported": "Sprache wird nicht unterstützt", + "Language switcher": "Sprachauswahl", + "Last checked": "Zuletzt geprüft", + "Last email sent": "Letzte E-Mail gesendet", + "Last error": "Letzter Fehler", + "Last heartbeat": "Letzter Heartbeat", + "Last login": "Letzte Anmeldung", + "Last login via": "Letzte Anmeldung über", + "Last name": "Nachname", + "Last name cannot be empty": "Nachname darf nicht leer sein", + "Last run": "Letzter Lauf", + "Last runner result": "Letztes Runner-Ergebnis", + "Last used": "Zuletzt verwendet", + "LDAP": "LDAP", + "LDAP attribute map could not be encoded": "LDAP-Attributzuordnung konnte nicht kodiert werden", + "LDAP base DN is required": "LDAP-Base-DN ist erforderlich", + "LDAP connection settings": "LDAP-Verbindungseinstellungen", + "LDAP Host": "LDAP-Host", + "LDAP host is required": "LDAP-Host ist erforderlich", + "LDAP login": "LDAP-Anmeldung", + "LDAP login is not available for this tenant.": "LDAP-Anmeldung ist für diesen Mandanten nicht verfügbar.", + "LDAP port must be between 1 and 65535": "LDAP-Port muss zwischen 1 und 65535 liegen", + "LDAP server is not reachable. Please try again later.": "LDAP-Server ist nicht erreichbar. Bitte versuchen Sie es später erneut.", + "LDAP setup is incomplete": "LDAP-Konfiguration ist unvollständig", + "LDAP Username": "LDAP-Benutzername", + "LDAP-only login requires a complete configuration": "Nur-LDAP-Anmeldung erfordert eine vollständige Konfiguration", + "Learning path": "Lernpfad", + "Leave empty to keep the currently stored client secret.": "Leer lassen, um das aktuell gespeicherte Client-Secret beizubehalten.", + "Leave empty to use the runtime default title.": "Leer lassen, um den Laufzeit-Standardtitel zu verwenden.", + "Legal": "Rechtliches", + "Lifecycle audit entry not found": "Benutzer-Lifecycle-Eintrag nicht gefunden", + "Lifecycle event": "Lifecycle-Ereignis", + "Lifecycle event was already restored": "Lifecycle-Ereignis wurde bereits wiederhergestellt", + "Lifecycle risks (7d)": "Lifecycle-Risiken (7d)", + "Lifecycle runs (7d)": "Lifecycle-Läufe (7d)", + "Lifecycle snapshot unavailable": "Lifecycle-Snapshot nicht verfügbar", + "Light": "Hell", + "Light logo": "Logo (hell)", + "Limit which event types are collected to match your privacy and operations requirements.": "Begrenze die erfassten Ereignistypen passend zu Datenschutz- und Betriebsanforderungen.", + "Loaded Extensions (%d)": "Geladene Erweiterungen (%d)", + "Loading": "Lädt", + "Loading...": "Lade...", + "Local": "Lokal", + "Local password + Microsoft": "Lokales Passwort + Microsoft", + "Local password only": "Nur lokales Passwort", + "Locale": "Sprache", + "Locale is invalid": "Locale ist ungültig", + "Log out": "Abmelden", + "Logged in": "Angemeldet", + "Login": "Login", + "Login could not be completed. Please contact your administrator.": "Anmeldung konnte nicht abgeschlossen werden. Bitte kontaktieren Sie Ihren Administrator.", + "Login credentials": "Mit Zugangsdaten oder SSO anmelden", + "Login persistence": "Anmeldespeicherung", + "Login policy": "Anmelderichtlinie", + "Login provider": "Login-Anbieter", + "Login required": "Login erforderlich", + "Login status": "Anmeldestatus", + "Login tokens": "Login-Tokens", + "Login tokens cleared": "Login-Tokens gelöscht", + "Logo": "Logo", + "Logo removed": "Logo entfernt", + "Logo updated": "Logo aktualisiert", + "Logout": "Logout", + "Logs": "Protokolle", + "Mac": "Mac", + "Mail failures": "E-Mail Fehler", + "Mail log": "E-Mail-Protokoll", + "Mail log not found": "E-Mail-Protokoll nicht gefunden", + "Mail logs": "E-Mail-Protokolle", + "Main menu": "Hauptmenü", + "Manual": "Manuell", + "Map application fields to LDAP directory attributes.": "Anwendungsfelder den LDAP-Verzeichnisattributen zuordnen.", + "Mapped fields": "Gemappte Felder", + "Master data": "Stammdaten", + "Max size 10MB, max 20000 rows": "Maximal 10MB, maximal 20000 Zeilen", + "Maximum duration (ms)": "Maximale Dauer (ms)", + "Memory (current)": "Speicher (aktuell)", + "Memory (peak)": "Speicher (maximal)", + "Message": "Nachricht", + "Metadata": "Metadaten", + "Method": "Methode", + "Method Not Allowed": "Methode nicht erlaubt", + "Microsoft": "Microsoft", + "Microsoft Auto-Remember default": "Microsoft Auto-Anmeldung Standard", "Microsoft login": "Microsoft-Login", "Microsoft login could not be started": "Microsoft-Login konnte nicht gestartet werden", "Microsoft login failed": "Microsoft-Login fehlgeschlagen", "Microsoft login is not allowed for this account": "Microsoft-Login ist für dieses Konto nicht erlaubt", "Microsoft login is not available for this tenant": "Microsoft-Login ist für diesen Mandanten nicht verfügbar", "Microsoft login was cancelled or failed": "Microsoft-Login wurde abgebrochen oder ist fehlgeschlagen", - "Microsoft-only login requires a complete configuration": "Nur-Microsoft-Login erfordert eine vollständige Konfiguration", - "No access to this tenant": "Kein Zugriff auf diesen Mandanten", - "Shared credentials missing": "Geteilte Zugangsdaten fehlen", - "Optional allow-list, comma or newline separated (example.com).": "Optionale Allow-List, per Komma oder Zeilenumbruch getrennt (example.com).", - "Password login is disabled for this tenant. Please use Microsoft login.": "Passwort-Login ist für diesen Mandanten deaktiviert. Bitte nutze Microsoft-Login.", - "Password login is disabled for all assigned tenants": "Passwort-Login ist für alle zugewiesenen Mandanten deaktiviert.", - "Password login mode": "Passwort-Login-Modus", - "Local password only": "Nur lokales Passwort", - "Local password + Microsoft": "Lokales Passwort + Microsoft", - "Credentials source": "Quelle der Zugangsdaten", - "Shared app": "Geteilte App", - "Tenant override": "Mandanten-Override", - "SSO configuration status": "SSO-Konfigurationsstatus", - "Configuration complete": "Konfiguration vollständig", - "Required Microsoft configuration": "Pflichtkonfiguration Microsoft", - "Required for Microsoft login.": "Für Microsoft-Login erforderlich.", - "SSO": "SSO", - "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".": "Geteilte Microsoft-App-Zugangsdaten werden von Mandanten verwendet, die \"Geteilte App-Zugangsdaten verwenden\" aktivieren.", - "Shared client ID": "Geteilte Client-ID", - "Shared client secret": "Geteiltes Client-Secret", - "Sign in with Microsoft": "Mit Microsoft anmelden", - "Tenant SSO settings could not be saved": "Mandanten-SSO-Einstellungen konnten nicht gespeichert werden", - "Tenant login link is invalid": "Mandanten-Login-Link ist ungültig", - "Profile sync on Microsoft login": "Profil-Sync bei Microsoft-Login", - "Sync fields": "Sync-Felder", - "Sync first name": "Vorname synchronisieren", - "Sync last name": "Nachname synchronisieren", - "Sync display name": "Anzeigename synchronisieren", - "Sync job title": "Berufsbezeichnung synchronisieren", - "Sync phone": "Telefon synchronisieren", - "Sync mobile": "Mobil synchronisieren", - "Sync avatar image": "Avatarbild synchronisieren", - "User profile fields are global and affect all tenants of this user": "Benutzer-Profildaten sind global und wirken auf alle Mandanten dieses Benutzers.", - "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)": "Telefon/Mobil/Avatar-Sync benötigt Microsoft Graph (User.Read).", - "SSO-enabled tenants": "Mandanten mit aktivem SSO", - "SSO-enforced tenants": "Mandanten mit erzwungenem SSO", - "SSO rollout": "SSO-Rollout", - "Users with Microsoft-only login": "Benutzer mit nur Microsoft-Login", - "Microsoft profile sync gaps": "Microsoft-Profil-Sync-Lücken", "Microsoft only": "Nur Microsoft", - "Use shared app credentials from settings": "Geteilte App-Zugangsdaten aus Einstellungen verwenden", - "Override only if this tenant needs a separate Entra app.": "Override nur nutzen, wenn dieser Mandant eine eigene Entra-App benötigt.", - "Write-only. Leave empty to keep current secret.": "Nur schreiben. Leer lassen, um das aktuelle Secret beizubehalten.", - "Client secret override is invalid": "Client-Secret-Override ist ungültig", - "Client credentials are missing": "Client-Zugangsdaten fehlen", - "setting.microsoft_shared_client_id": "Einstellungsschlüssel für geteilte Microsoft-Client-ID", - "setting.microsoft_shared_client_secret_enc": "Einstellungsschlüssel für geteiltes Microsoft-Client-Secret (verschlüsselt)", - "setting.microsoft_authority": "Basis-OpenID-Authority-URL für Microsoft-Login", - "API tokens": "API-Tokens", - "Token name": "Token-Name", - "Create API token": "API-Token erstellen", - "Revoke": "Widerrufen", - "Revoke this API token?": "Dieses API-Token widerrufen?", - "Revoked": "Widerrufen", - "Prefix": "Präfix", - "No API tokens": "Keine API-Tokens", - "Create a token to enable API access for this user.": "Erstellen Sie ein Token, um den API-Zugriff für diesen Benutzer zu aktivieren.", - "No API token has been created for this user yet.": "Für diesen Benutzer wurde noch kein API-Token erstellt.", - "New API token (copy now — shown only once):": "Neues API-Token (jetzt kopieren — wird nur einmal angezeigt):", - "API token created. Copy it now — it will not be shown again.": "API-Token erstellt. Jetzt kopieren — es wird nicht erneut angezeigt.", - "Could not create API token: %s": "API-Token konnte nicht erstellt werden: %s", - "API token revoked": "API-Token widerrufen", - "%d API tokens revoked": "%d API-Tokens widerrufen", - "%d active API tokens": "%d aktive API-Tokens", - "Revoke all API tokens": "Alle API-Tokens widerrufen", - "Revoke all API tokens?": "Alle API-Tokens widerrufen?", - "API token default lifetime is invalid": "Standardlaufzeit für API-Tokens ist ungültig", - "API token max lifetime is invalid": "Maximale Laufzeit für API-Tokens ist ungültig", - "nav.logs.mail": "E-Mail", + "Microsoft profile sync gaps": "Microsoft-Profil-Sync-Lücken", + "Microsoft SSO": "Microsoft SSO", + "Microsoft SSO settings": "Microsoft-SSO-Einstellungen", + "Microsoft-only login requires a complete configuration": "Nur-Microsoft-Login erfordert eine vollständige Konfiguration", + "Mobile": "Mobil", + "Modified": "Aktualisiert", + "Modified by": "Bearbeitet von", + "Module": "Modul", + "Modules": "Module", + "Mon": "Mo", + "Multiselect": "Mehrfachauswahl", + "Must not contain your email": "Darf deine E-Mail nicht enthalten", + "My account": "Meine Benutzereinstellungen", + "Name": "Name", "nav.audit.api": "API", - "nav.audit.system": "System", "nav.audit.imports": "Importe", + "nav.audit.system": "System", "nav.audit.user_lifecycle": "Benutzer-Lifecycle", - "API audit": "API-Protokolle", - "API audit logs": "API-Protokolle", - "Request ID": "Request-ID", - "Method": "Methode", - "Path": "Pfad", - "Status code": "Statuscode", - "Duration (ms)": "Dauer (ms)", - "Error code": "Fehlercode", - "Token ID": "Token-ID", - "Token tenant": "Token-Mandant", - "Purge API audit logs": "API-Protokolle bereinigen", - "Purge entries older than 90 days?": "Einträge älter als 90 Tage bereinigen?", - "%d API audit entries purged": "%d API-Protokoll-Einträge bereinigt", - "API audit entry not found": "API-Protokoll-Eintrag nicht gefunden", - "View API audit entry": "API-Protokoll-Eintrag anzeigen", - "Request details": "Request-Details", - "Scope": "Geltungsbereich", - "Query metadata (keys)": "Query-Metadaten (Schlüssel)", - "All methods": "Alle Methoden", - "Tenant ID": "Mandanten-ID", - "User ID": "Benutzer-ID", - "IP": "IP", - "CORS allowed origins are invalid": "Erlaubte CORS-Origins sind ungültig", - "Token name is required": "Token-Name ist erforderlich", - "e.g. CI Pipeline": "z.B. CI-Pipeline", - "Imports": "Importe", - "You do not have permission to run imports.": "Du hast keine Berechtigung für Importe.", - "CSV file": "CSV-Datei", - "Max size 10MB, max 20000 rows": "Maximal 10MB, maximal 20000 Zeilen", - "Download sample CSV": "Beispiel-CSV herunterladen", - "Analyze file": "Datei analysieren", - "CSV header": "CSV-Header", - "Target field": "Zielfeld", - "Ignore column": "Spalte ignorieren", - "Assignment columns require additional permission.": "Zuweisungsspalten benötigen eine zusätzliche Berechtigung.", - "Run preview": "Vorschau ausführen", - "Preview": "Vorschau", - "Rows total": "Zeilen gesamt", - "Valid rows": "Gültige Zeilen", - "Would create": "Würde erstellen", - "Would skip": "Würde überspringen", - "Would fail": "Würde fehlschlagen", - "Row issues": "Zeilenprobleme", - "Start import": "Import starten", - "Import finished": "Import abgeschlossen", - "Processed": "Verarbeitet", - "Skipped": "Übersprungen", - "Import another file": "Weitere Datei importieren", + "nav.logs.mail": "E-Mail", + "navigate": "navigieren", + "Navigation": "Navigation", + "Network timeout (seconds)": "Netzwerk-Timeout (Sekunden)", + "Never": "Nie", + "Never logged in": "Nie angemeldet", + "New API token (copy now — shown only once):": "Neues API-Token (jetzt kopieren — wird nur einmal angezeigt):", + "New password (optional)": "Neues Passwort (optional)", + "Next": "Weiter", + "Next run": "Nächster Lauf", + "No": "Nein", + "No access to this tenant": "Kein Zugriff auf diesen Mandanten", + "No active permissions are configured yet.": "Es sind noch keine aktiven Berechtigungen konfiguriert.", + "No active roles are configured yet.": "Es sind noch keine aktiven Rollen konfiguriert.", + "No active tenant assigned": "Kein aktiver Mandant zugewiesen", + "No active user has the administrator role": "Kein aktiver Nutzer hat die Administrator-Rolle", + "No API token has been created for this user yet.": "Für diesen Benutzer wurde noch kein API-Token erstellt.", + "No API tokens": "Keine API-Tokens", + "No contact details available": "Keine Kontaktdaten vorhanden", + "No custom fields configured for selected tenants": "Für die ausgewählten Mandanten sind keine Zusatzfelder konfiguriert", + "No custom fields configured for this tenant": "Für diesen Mandanten sind keine Zusatzfelder konfiguriert", + "No custom fields configured yet": "Noch keine Zusatzfelder konfiguriert", + "No departments available for this tenant": "Für diesen Mandanten sind keine Abteilungen verfügbar", + "No domain restrictions": "Keine Domain-Einschränkungen", + "No effective permissions": "Keine effektiven Berechtigungen", + "No entries found": "Keine Einträge gefunden", + "No file uploaded": "Keine Datei hochgeladen", + "No health checks available.": "Keine Systemprüfungen verfügbar.", + "No legal links configured": "Keine rechtlichen Links konfiguriert", + "No login method is available for this tenant": "Für diesen Mandanten ist keine Login-Methode verfügbar", + "No login tokens": "Keine Login-Tokens", + "No logo for this theme yet": "Für dieses Theme wurde noch kein Logo hochgeladen", + "No modules active.": "Keine Module aktiv.", + "No password reset requests": "Keine Passwort-Reset-Anfragen", + "No permissions available": "Keine Berechtigungen verfügbar", + "No permissions selected": "Keine Berechtigungen ausgewählt", + "No queries were executed before the error occurred.": "Vor dem Fehler wurden keine Abfragen ausgeführt.", + "No records found": "Keine Einträge gefunden", + "No reset has been requested for this account yet.": "Für dieses Konto wurde noch kein Reset angefordert.", + "No results found": "Keine Ergebnisse gefunden", + "No roles available": "Keine Rollen verfügbar", + "No roles selected": "Keine Rollen ausgewählt", "No row errors found": "Keine Zeilenfehler gefunden", - "Row": "Zeile", - "Message": "Nachricht", + "No tenant is available in your current scope.": "Im aktuellen Geltungsbereich sind keine Mandanten verfügbar.", + "No tenants available": "Keine Mandanten verfügbar", "No upload file provided": "Keine Upload-Datei übergeben", - "Upload exceeds the maximum size": "Upload überschreitet die maximale Dateigröße", - "Invalid file type": "Ungültiger Dateityp", - "CSV header is invalid": "CSV-Header ist ungültig", - "CSV file has no data rows": "CSV-Datei enthält keine Datenzeilen", - "CSV row limit exceeded": "CSV-Zeilenlimit überschritten", - "Required mapping is missing": "Erforderliches Mapping fehlt", - "Assignment import permission is required": "Berechtigung für Assignment-Import ist erforderlich", - "Email is invalid": "E-Mail ist ungültig", - "Email already exists": "E-Mail existiert bereits", - "Locale is invalid": "Locale ist ungültig", - "Active value is invalid": "Active-Wert ist ungültig", - "Hire date must be YYYY-MM-DD": "Eintrittsdatum muss YYYY-MM-DD sein", - "Tenant is missing, inactive or invalid": "Mandant fehlt, ist inaktiv oder ungültig", - "Role is missing, inactive or invalid": "Rolle fehlt, ist inaktiv oder ungültig", - "Department is missing, inactive or invalid": "Abteilung fehlt, ist inaktiv oder ungültig", - "Department does not belong to tenant": "Abteilung gehört nicht zum Mandanten", - "Tenant assignment is out of your scope": "Mandantenzuweisung liegt außerhalb deines Scopes", - "Unexpected error during import": "Unerwarteter Fehler beim Import", + "No valid users selected": "Keine gültigen Benutzer ausgewählt", + "No weekdays": "Keine Wochentage", + "None": "Keine", + "None (not recommended)": "Keine (nicht empfohlen)", + "Not configured": "Nicht konfiguriert", + "Not Found": "Nicht gefunden", + "Not verified": "Nicht bestätigt", + "Note": "Notiz", + "of": "von", + "OK": "OK", + "On this page": "Auf dieser Seite", + "One level": "Eine Ebene", + "One option per line. Optional format: key|Label.": "Eine Option pro Zeile. Optionales Format: key|Label.", + "One origin per line, e.g. https://app.example.com": "Eine Origin pro Zeile, z. B. https://app.example.com", + "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com": "Nur für direkte Bindung. Verwenden Sie %s als Platzhalter. Beispiel: %s@corp.example.com oder uid=%s,ou=People,dc=example,dc=com", + "Open": "Öffnen", + "open": "öffnen", + "Open full page": "Vollseite öffnen", + "Open navigation": "Navigation öffnen", + "Open search": "Suche öffnen", + "Operations": "Betrieb", + "Optional allow-list, comma or newline separated (example.com).": "Optionale Allow-List, per Komma oder Zeilenumbruch getrennt (example.com).", + "Optional allow-list, comma or newline separated.": "Optionale Zulassungsliste, durch Komma oder Zeilenumbruch getrennt.", + "Optional note...": "Optionale Notiz...", + "Options (one per line)": "Optionen (eine pro Zeile)", + "Options are required for this field type": "Für diesen Feldtyp sind Optionen erforderlich", + "Or": "Oder", + "Organization": "Organisation", + "Outcome": "Ergebnis", + "Overdue jobs": "Überfällige Aufgaben", + "Override only if this tenant needs a separate Entra app.": "Override nur nutzen, wenn dieser Mandant eine eigene Entra-App benötigt.", + "Overview": "Übersicht", + "P95 response time (ms)": "P95 Antwortzeit (ms)", + "Page": "Seite", + "Page %d": "Seite %d", + "Page %d of %d": "Seite %d von %d", + "Page can not be updated": "Seite kann nicht aktualisiert werden", + "Page not found": "Seite nicht gefunden", + "Page updated": "Seite aktualisiert", + "Pages": "Seiten", + "Partial": "Teilweise", + "Password": "Passwort", + "Password (again)": "Passwort bestätigen", + "Password can not be updated": "Passwort kann nicht aktualisiert werden", + "Password cannot be empty": "Passwort darf nicht leer sein", + "Password login is disabled for all assigned tenants": "Passwort-Login ist für alle zugewiesenen Mandanten deaktiviert.", + "Password login is disabled for this tenant. Please use Microsoft login.": "Passwort-Login ist für diesen Mandanten deaktiviert. Bitte nutze Microsoft-Login.", + "Password login mode": "Passwort-Login-Modus", + "Password must be at least %d characters": "Passwort muss mindestens %d Zeichen haben", + "Password must include a lowercase letter": "Passwort muss einen Kleinbuchstaben enthalten", + "Password must include a number": "Passwort muss eine Zahl enthalten", + "Password must include a symbol": "Passwort muss ein Sonderzeichen enthalten", + "Password must include an uppercase letter": "Passwort muss einen Großbuchstaben enthalten", + "Password must not contain your email": "Passwort darf deine E-Mail nicht enthalten", + "Password requirements": "Passwort-Anforderungen", + "Password reset code": "Code zum Zurücksetzen des Passworts", + "Password resets": "Passwort-Resets", + "Password updated": "Passwort aktualisiert", + "Passwords must match": "Passwörter müssen übereinstimmen", + "Path": "Pfad", + "Per page": "Pro Seite", + "perm.audit.api.purge": "API-Protokolle bereinigen", + "perm.audit.api.view": "API-Protokolle anzeigen", + "perm.audit.imports.purge": "Import-Protokolle bereinigen", + "perm.audit.imports.view": "Import-Protokolle anzeigen", + "perm.audit.system.purge": "System-Protokolle bereinigen", + "perm.audit.system.view": "System-Protokolle anzeigen", + "perm.audit.user_lifecycle.restore": "Benutzer aus Lifecycle-Protokoll wiederherstellen", + "perm.audit.user_lifecycle.view": "Benutzer-Lifecycle-Protokolle anzeigen", + "perm.custom_fields.edit_values": "Benutzer-Zusatzfelder bearbeiten", + "perm.custom_fields.manage": "Mandanten-Zusatzfelder verwalten", + "perm.departments.create": "Abteilungen erstellen", + "perm.departments.delete": "Abteilungen löschen", + "perm.departments.update": "Abteilungen bearbeiten", + "perm.departments.view": "Abteilungen anzeigen", + "perm.jobs.manage": "Geplante Aufgaben verwalten", + "perm.jobs.run_now": "Geplante Aufgaben manuell ausführen", + "perm.jobs.view": "Geplante Aufgaben anzeigen", + "perm.mail_log.view": "E-Mail-Protokolle anzeigen", + "perm.permissions.create": "Berechtigungen erstellen", + "perm.permissions.delete": "Berechtigungen löschen", + "perm.permissions.update": "Berechtigungen bearbeiten", + "perm.permissions.view": "Berechtigungen anzeigen", + "perm.roles.assign_all": "Alle Rollen zuweisen", + "perm.roles.create": "Rollen erstellen", + "perm.roles.delete": "Rollen löschen", + "perm.roles.update": "Rollen bearbeiten", + "perm.roles.view": "Rollen anzeigen", + "perm.settings.update": "Einstellungen bearbeiten", + "perm.settings.view": "Einstellungen anzeigen", + "perm.tenants.create": "Mandanten erstellen", + "perm.tenants.delete": "Mandanten löschen", + "perm.tenants.update": "Mandanten bearbeiten", + "perm.tenants.view": "Mandanten anzeigen", + "perm.user_lifecycle_audit.view": "Benutzer-Lifecycle-Protokolle anzeigen", + "perm.users.access_pdf": "Onboarding-PDFs erstellen", + "perm.users.create": "Benutzer erstellen", + "perm.users.delete": "Benutzer löschen", + "perm.users.lifecycle_restore": "Benutzer aus Lifecycle-Protokoll wiederherstellen", + "perm.users.self_update": "Eigenen Benutzer bearbeiten", + "perm.users.update": "Benutzer bearbeiten", + "perm.users.update_assignments": "Benutzerzuweisungen bearbeiten", + "perm.users.view": "Benutzer anzeigen", + "Permission": "Berechtigung", + "Permission can not be created": "Berechtigung kann nicht erstellt werden", + "Permission can not be updated": "Berechtigung kann nicht aktualisiert werden", + "Permission check could not be executed": "Berechtigungs-Prüfung konnte nicht ausgeführt werden", + "Permission created": "Berechtigung erstellt", + "Permission deleted": "Berechtigung gelöscht", + "Permission denied": "Keine Berechtigung", + "Permission key": "Berechtigungs-Schlüssel", + "Permission key already exists": "Berechtigungs-Schlüssel existiert bereits", + "Permission key cannot be empty": "Berechtigungs-Schlüssel darf nicht leer sein", + "Permission key is invalid": "Berechtigungs-Schlüssel ist ungültig", + "Permission not found": "Berechtigung nicht gefunden", + "Permission origin": "Herkunft der Berechtigung", + "Permission summary": "Berechtigungsübersicht", + "Permission updated": "Berechtigung aktualisiert", + "Permissions": "Berechtigungen", + "Permissions by source": "Berechtigungen nach Quelle", + "Permissions without roles": "Berechtigungen ohne Rollen", + "Phone": "Telefon", + "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)": "Telefon/Mobil/Avatar-Sync benötigt Microsoft Graph (User.Read).", + "PHP": "PHP", + "PHP SAPI": "PHP SAPI", + "PHP version": "PHP-Version", + "Please confirm": "Bitte bestätigen", + "Please enter a valid email address": "Bitte gib eine gültige E-Mail-Adresse ein", + "Please enter the 6-digit code": "Bitte gib den 6-stelligen Code ein", + "Please enter your username and password.": "Bitte geben Sie Ihren Benutzernamen und Ihr Passwort ein.", + "Please review the following errors": "Bitte prüfen Sie die folgenden Fehler", + "Please select": "Bitte auswählen", + "Please select a primary tenant": "Bitte einen Hauptmandanten auswählen", + "Please select at least one tenant": "Bitte mindestens einen Mandanten auswählen", + "Please verify your email first": "Bitte bestätige zuerst deine E-Mail", + "Policy": "Regel", + "Port": "Port", + "POST Parameters": "POST-Parameter", + "Postal code": "Postleitzahl", + "Preferences": "Einstellungen", + "Prefix": "Präfix", + "Press Enter to open row": "Drücke Enter, um die Zeile zu öffnen", + "Preview": "Vorschau", + "Previous": "Zurück", + "Primary": "Primär", + "Primary color": "Primärfarbe", + "Primary color is invalid": "Primärfarbe ist ungültig", + "Primary navigation": "Hauptnavigation", + "Primary tenant": "Hauptmandant", + "Primary tenant must be one of the assigned tenants": "Der Hauptmandant muss einem zugewiesenen Mandanten entsprechen", + "Priority": "Priorität", + "Privacy": "Datenschutz", + "Privacy URL": "Datenschutz-URL", + "Problems logging in": "Probleme beim Login", + "Processed": "Verarbeitet", + "Profile": "Profil", + "Profile can not be updated": "Profil kann nicht aktualisiert werden", + "Profile description": "Profilbeschreibung", + "Profile image": "Profilbild", + "Profile sync": "Profilabgleich", + "Profile sync on LDAP login": "Profilsynchronisierung bei LDAP-Anmeldung", + "Profile sync on Microsoft login": "Profil-Sync bei Microsoft-Login", + "Provider message ID": "Provider-Nachrichten-ID", + "Purge API audit logs": "API-Protokolle bereinigen", + "Purge entries older than 365 days?": "Einträge älter als 365 Tage bereinigen?", + "Purge entries older than 90 days?": "Einträge älter als 90 Tage bereinigen?", + "Purge expired system audit entries?": "Abgelaufene System-Protokoll-Einträge bereinigen?", + "Purge import logs": "Import-Protokolle bereinigen", + "Purge run logs older than 90 days?": "Laufprotokolle älter als 90 Tage bereinigen?", + "Purge scheduler logs": "Scheduler-Protokolle bereinigen", + "Purge system audit logs": "System-Protokolle bereinigen", + "Purge user lifecycle logs": "Benutzer-Lifecycle-Protokolle bereinigen", + "Queries": "Abfragen", + "Queries (%d)": "Abfragen (%d)", + "Query metadata (keys)": "Query-Metadaten (Schlüssel)", + "Query tracking is not available (Debugger disabled or not initialized).": "Query-Tracking ist nicht verfügbar (Debugger deaktiviert oder nicht initialisiert).", + "Queued": "Warteschlange", + "Reason code": "Fehlercode", + "Recent import runs": "Letzte Import-Läufe", + "Recent lifecycle risks (7d)": "Aktuelle Lifecycle-Risiken (7d)", + "Recent logins": "Letzte Anmeldungen", + "Recent system audit risks (24h)": "Aktuelle System-Protokoll-Risiken (24h)", + "Recipient": "Empfänger", + "Reference": "Referenz", + "Region": "Region", + "Register": "Registrieren", + "Registration controls whether new users can create an account.": "Hier wird gesteuert, ob neue Benutzer ein Konto erstellen dürfen.", + "Registration is currently disabled": "Registrierung ist derzeit deaktiviert.", + "Registration successful! Please check your email for the verification code.": "Registrierung erfolgreich! Bitte prüfe deine E-Mails für den Bestätigungscode.", + "Remember login after Microsoft sign-in": "Angemeldet bleiben nach Microsoft-Login", + "Remember me": "Angemeldet bleiben", + "Remember token lifetime (days)": "Token-Lebensdauer Angemeldet-bleiben (Tage)", + "Remember token lifetime is invalid": "Token-Lebensdauer ist ungültig", + "Remove": "Entfernen", + "Remove filter": "Filter entfernen", + "Remove permission": "Berechtigung entfernen", + "Remove role": "Rolle entfernen", + "Remove selected file": "Ausgewaehlte Datei entfernen", + "Replace": "Ersetzen", + "Request": "Anfrage", + "Request details": "Request-Details", + "Request ID": "Request-ID", + "Request Timeout": "Zeitüberschreitung der Anfrage", + "Request trend vs previous 24h": "Request-Trend zur vorherigen 24h", + "Requested at": "Angefordert am", + "Requested path": "Angeforderter Pfad", + "Requested URL": "Angeforderte URL", + "Requests": "Requests", + "Required": "Pflichtfeld", + "Required core tables are missing": "Erforderliche Kerntabellen fehlen", + "Required field is empty: description": "Pflichtfeld ist leer: description", "Required field is empty: first_name": "Pflichtfeld ist leer: first_name", "Required field is empty: last_name": "Pflichtfeld ist leer: last_name", - "User assignments can not be updated": "Benutzerzuweisungen können nicht aktualisiert werden", - "How the import works": "So funktioniert der Import", - "1. Upload CSV and click analyze": "1. CSV hochladen und analysieren klicken", - "2. Map your CSV columns to system fields": "2. CSV-Spalten auf Systemfelder mappen", - "3. Review preview counters and row errors": "3. Vorschau, Zähler und Zeilenfehler prüfen", - "4. Start import for valid rows": "4. Import für gültige Zeilen starten", - "Rules": "Regeln", - "Create-only: existing entries are skipped": "Nur erstellen: bestehende Einträge werden übersprungen", - "Here is a CSV template for this import profile.": "Hier ist eine CSV-Vorlage für dieses Importprofil.", - "Reference": "Referenz", "Required fields": "Pflichtfelder", - "Required field is empty: description": "Pflichtfeld ist leer: description", - "Tenant must be a valid UUID": "Mandant muss eine gültige UUID sein", - "Code already exists": "Code existiert bereits", - "Department already exists for this tenant": "Abteilung für diesen Mandanten existiert bereits", - "Duplicate entry in CSV file": "Doppelter Eintrag in der CSV-Datei", - "Entry could not be created": "Eintrag konnte nicht erstellt werden", - "Import logs": "Import-Protokolle", - "Import audit logs": "Import-Protokolle", - "Run UUID": "Run-UUID", - "Mapped fields": "Gemappte Felder", - "Created count": "Erstellt", - "Skipped count": "Übersprungen", - "Failed count": "Fehlgeschlagen", - "Purge import logs": "Import-Protokolle bereinigen", - "%d import audit entries purged": "%d Import-Protokoll-Einträge bereinigt", - "Import audit entry not found": "Import-Protokoll-Eintrag nicht gefunden", - "View import audit entry": "Import-Protokoll-Eintrag anzeigen", - "Import details": "Import-Details", - "Started": "Gestartet", - "Finished": "Beendet", - "File": "Datei", - "Current tenant": "Aktueller Mandant", - "Error code distribution": "Fehlercode-Verteilung", - "All profiles": "Alle Profile", - "Running": "Laufend", - "Success": "Erfolgreich", - "Partial": "Teilweise", - "Import": "Import", - "Counters": "Zähler", - "User lifecycle policy": "Benutzer-Lifecycle-Regel", - "Session policy": "Sitzungsrichtlinie", - "Registration controls whether new users can create an account.": "Hier wird gesteuert, ob neue Benutzer ein Konto erstellen dürfen.", - "Session limits define how long logged-in users stay signed in.": "Hier werden Inaktivitäts- und Absolute-Timeout für aktive Sitzungen festgelegt.", - "User lifecycle defines when inactive users are deactivated or deleted.": "Hier wird festgelegt, wann inaktive Benutzer deaktiviert oder gelöscht werden.", - "System audit controls whether security events are logged and how long they are kept.": "Hier wird gesteuert, ob Sicherheitsereignisse protokolliert werden und wie lange sie aufbewahrt werden.", - "Session idle timeout (minutes)": "Sitzungs-Inaktivitäts-Timeout (Minuten)", - "Session absolute timeout (hours)": "Absolutes Sitzungs-Timeout (Stunden)", - "Allowed range: 5-1440 minutes (default: 30)": "Erlaubter Bereich: 5-1440 Minuten (Standard: 30)", - "Allowed range: 1-72 hours (default: 8)": "Erlaubter Bereich: 1-72 Stunden (Standard: 8)", - "Deactivate users after inactivity (days)": "Nach Inaktivität deaktivieren (Tage)", - "Delete inactive users after (days)": "Inaktive löschen nach (Tagen)", - "0 disables this rule": "0 deaktiviert diese Regel", - "Run user lifecycle now?": "Benutzer-Lifecycle jetzt ausführen?", - "Run user lifecycle now": "Benutzer-Lifecycle jetzt ausführen", - "setting.user_inactivity_deactivate_days": "Setzt Benutzer nach dieser Anzahl Tagen ohne Login automatisch auf inaktiv", - "setting.user_inactivity_delete_days": "Löscht inaktive Benutzer nach dieser zusätzlichen Anzahl Tagen automatisch", - "setting.session_idle_timeout_minutes": "Maximale Inaktivitätsdauer in Minuten vor automatischer Abmeldung (Standard: 30)", - "setting.session_absolute_timeout_hours": "Maximale Gesamtdauer einer Sitzung in Stunden vor automatischer Abmeldung (Standard: 8)", - "User lifecycle already running": "Benutzer-Lifecycle läuft bereits", - "User lifecycle failed": "Benutzer-Lifecycle fehlgeschlagen", - "User lifecycle completed: %d deactivated, %d deleted": "Benutzer-Lifecycle abgeschlossen: %d deaktiviert, %d gelöscht", - "User inactivity deactivation period is invalid": "Zeitraum für automatische Deaktivierung ist ungültig", - "User inactivity deletion period is invalid": "Zeitraum für automatische Löschung ist ungültig", - "Session idle timeout is invalid": "Sitzungs-Inaktivitäts-Timeout ist ungültig", - "Session absolute timeout is invalid": "Absolutes Sitzungs-Timeout ist ungültig", - "Auto-delete is ignored while auto-deactivate is disabled": "Auto-Löschung wird ignoriert, solange Auto-Deaktivierung deaktiviert ist", - "Scheduled jobs": "Geplante Aufgaben", - "Scheduled job not found": "Geplante Aufgabe nicht gefunden", - "Scheduled job is not registered": "Geplante Aufgabe ist nicht registriert", - "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.": "Diese geplante Aufgabe ist nicht mehr registriert und kann nicht bearbeitet werden. Sie wurde durch eine neuere Version ersetzt.", - "Scheduled job could not be saved": "Geplante Aufgabe konnte nicht gespeichert werden", - "Scheduled job saved": "Geplante Aufgabe gespeichert", - "Edit scheduled job": "Geplante Aufgabe bearbeiten", - "View scheduled job": "Geplante Aufgabe anzeigen", - "Job": "Aufgabe", - "Job key": "Aufgaben-Key", - "Run history": "Laufhistorie", - "Run now": "Jetzt ausführen", - "Next run": "Nächster Lauf", - "Last run": "Letzter Lauf", - "Last error": "Letzter Fehler", - "Schedule": "Zeitplan", - "Schedule type": "Zeitplan-Typ", - "Schedule interval": "Zeitplan-Intervall", - "Schedule time": "Zeitplan-Uhrzeit", - "Weekdays": "Wochentage", - "Hourly": "Stündlich", - "Daily": "Täglich", - "Weekly": "Wöchentlich", - "Enabled": "Aktiv", - "Disabled": "Inaktiv", - "Timezone": "Zeitzone", - "Catch up once": "Verpassten Lauf einmal nachholen", - "Scheduler": "Scheduler", - "Every %d hour(s)": "Alle %d Stunde(n)", - "Every %d day(s) at %s": "Alle %d Tag(e) um %s", - "Every %d week(s) on %s at %s": "Alle %d Woche(n) an %s um %s", - "No weekdays": "Keine Wochentage", - "Mon": "Mo", - "Tue": "Di", - "Wed": "Mi", - "Thu": "Do", - "Fri": "Fr", - "Sat": "Sa", - "Sun": "So", - "Schedule type is invalid": "Zeitplan-Typ ist ungültig", - "Schedule time is required": "Zeitplan-Uhrzeit ist erforderlich", - "Timezone is invalid": "Zeitzone ist ungültig", - "Hourly interval must be between 1 and 24": "Stündliches Intervall muss zwischen 1 und 24 liegen", - "Daily interval must be between 1 and 365": "Tägliches Intervall muss zwischen 1 und 365 liegen", - "Weekly interval must be between 1 and 52": "Wöchentliches Intervall muss zwischen 1 und 52 liegen", - "At least one weekday is required for weekly schedule": "Für einen wöchentlichen Zeitplan ist mindestens ein Wochentag erforderlich", - "Scheduled job run completed": "Geplante Aufgabe wurde ausgeführt", - "Scheduled job run skipped": "Geplante Aufgabe wurde übersprungen", - "Scheduled job run failed": "Ausführung der geplanten Aufgabe fehlgeschlagen", - "Scheduler is already running": "Scheduler läuft bereits", - "Purge scheduler logs": "Scheduler-Protokolle bereinigen", - "Purge run logs older than 90 days?": "Laufprotokolle älter als 90 Tage bereinigen?", - "%d scheduler run logs purged": "%d Scheduler-Laufprotokolle bereinigt", - "User lifecycle logs": "Benutzer-Lifecycle-Protokolle", - "View user lifecycle audit entry": "Benutzer-Lifecycle-Eintrag anzeigen", - "Lifecycle audit entry not found": "Benutzer-Lifecycle-Eintrag nicht gefunden", - "Purge user lifecycle logs": "Benutzer-Lifecycle-Protokolle bereinigen", - "Purge entries older than 365 days?": "Einträge älter als 365 Tage bereinigen?", - "%d user lifecycle audit entries purged": "%d Benutzer-Lifecycle-Protokoll-Einträge bereinigt", - "Lifecycle event": "Lifecycle-Ereignis", - "Trigger": "Auslöser", - "Reason code": "Fehlercode", - "Target": "Ziel", - "Target UUID": "Ziel-UUID", - "Target email": "Ziel-E-Mail", - "Policy": "Regel", - "Snapshot summary": "Snapshot-Zusammenfassung", - "Snapshot version": "Snapshot-Version", + "Required for Microsoft login.": "Für Microsoft-Login erforderlich.", + "Required mapping is missing": "Erforderliches Mapping fehlt", + "Required Microsoft configuration": "Pflichtkonfiguration Microsoft", + "Reset password": "Passwort zurücksetzen", + "Reset request already used": "Zurücksetz-Anfrage wurde bereits verwendet", + "Reset request expired": "Zurücksetz-Anfrage ist abgelaufen", + "Reset request not found": "Zurücksetz-Anfrage nicht gefunden", + "Restore": "Wiederherstellen", + "Restore actions (7d)": "Wiederherstellungsaktionen (7d)", + "Restore not possible: email already exists": "Wiederherstellung nicht möglich: E-Mail existiert bereits", + "Restore not possible: uuid already exists": "Wiederherstellung nicht möglich: UUID existiert bereits", "Restore status": "Wiederherstellungsstatus", + "Restore this user from lifecycle snapshot?": "Diesen Benutzer aus dem Lifecycle-Snapshot wiederherstellen?", + "Restore user": "Benutzer wiederherstellen", "Restored at": "Wiederhergestellt am", "Restored by": "Wiederhergestellt von", "Restored user": "Wiederhergestellter Benutzer", - "Restore user": "Benutzer wiederherstellen", - "Restore": "Wiederherstellen", - "Restore this user from lifecycle snapshot?": "Diesen Benutzer aus dem Lifecycle-Snapshot wiederherstellen?", - "User restored": "Benutzer wiederhergestellt", - "User restore failed": "Benutzer-Wiederherstellung fehlgeschlagen", - "Lifecycle event was already restored": "Lifecycle-Ereignis wurde bereits wiederhergestellt", - "Lifecycle snapshot unavailable": "Lifecycle-Snapshot nicht verfügbar", - "Restore not possible: email already exists": "Wiederherstellung nicht möglich: E-Mail existiert bereits", - "Restore not possible: uuid already exists": "Wiederherstellung nicht möglich: UUID existiert bereits", - "All triggers": "Alle Auslöser", - "Manual": "Manuell", - "Cron": "Cron", - "Enabled jobs": "Aktive Aufgaben", - "Overdue jobs": "Überfällige Aufgaben", - "Scheduler runs (24h)": "Scheduler-Läufe (24h)", - "Failed scheduler runs (24h)": "Fehlgeschlagene Scheduler-Läufe (24h)", - "Cron runner active": "Cron-Runner aktiv", - "Last heartbeat": "Letzter Heartbeat", - "Last runner result": "Letztes Runner-Ergebnis", - "Runner lock not acquired": "Runner-Lock nicht erhalten", - "Locale": "Sprache", - "Learning path": "Lernpfad", - "Concepts": "Konzepte", - "How-to guides": "Aufgabenanleitungen", - "Contributor guide": "Mitwirken", - "System audit": "System-Protokolle", - "System audit logs": "System-Protokolle", - "View system audit entry": "System-Protokoll-Eintrag anzeigen", - "System audit entry not found": "System-Protokoll-Eintrag nicht gefunden", - "Enable system audit log": "System-Protokolle aktivieren", - "Purge system audit logs": "System-Protokolle bereinigen", - "Purge expired system audit entries?": "Abgelaufene System-Protokoll-Einträge bereinigen?", - "%d system audit entries purged": "%d System-Protokoll-Einträge bereinigt", - "All outcomes": "Alle Ergebnisse", - "All channels": "Alle Kanäle", - "Event type": "Ereignistyp", - "Outcome": "Ergebnis", - "Actor": "Akteur", - "Actor tenant": "Akteur-Mandant", - "Event details": "Ereignisdetails", - "Target type": "Zieltyp", - "IP hash": "IP-Hash", - "User agent hash": "User-Agent-Hash", - "Channel": "Kanal", - "Denied": "Verweigert", - "Event": "Ereignis", - "Metadata": "Metadaten", - "Select users": "Benutzer auswählen", - "Select actions": "Aktionen auswählen", - "Select statuses": "Status auswählen", - "Select triggers": "Auslöser auswählen", - "Tenant #%d": "Mandant #%d", - "Tenant #%d (deleted)": "Mandant #%d (gelöscht)", - "Select event types": "Ereignistypen auswählen", - "Select actor users": "Akteure auswählen", - "User #%d": "Benutzer #%d", - "User #%d (deleted)": "Benutzer #%d (gelöscht)", + "Result": "Ergebnis", + "results": "Ergebnisse", "Retention (days)": "Aufbewahrung (Tage)", - "Frontend telemetry": "Frontend-Telemetrie", - "Enable frontend telemetry": "Frontend-Telemetrie aktivieren", + "Retry": "Erneut versuchen", + "Revoke": "Widerrufen", + "Revoke all API tokens": "Alle API-Tokens widerrufen", + "Revoke all API tokens?": "Alle API-Tokens widerrufen?", + "Revoke this API token?": "Dieses API-Token widerrufen?", + "Revoked": "Widerrufen", + "Role": "Rolle", + "Role can not be created": "Rolle kann nicht erstellt werden", + "Role can not be updated": "Rolle kann nicht aktualisiert werden", + "Role code already exists": "Rollencode existiert bereits", + "Role created": "Rolle erstellt", + "Role deleted": "Rolle gelöscht", + "Role is missing, inactive or invalid": "Rolle fehlt, ist inaktiv oder ungültig", + "Role not found": "Rolle nicht gefunden", + "Role updated": "Rolle aktualisiert", + "Roles": "Rollen", + "Roles & permissions": "Rollen & Rechte", + "Roles without permissions": "Rollen ohne Berechtigungen", + "Row": "Zeile", + "Row issues": "Zeilenprobleme", + "Rows per page": "Einträge pro Seite", + "Rows total": "Zeilen gesamt", + "Rules": "Regeln", + "Run history": "Laufhistorie", + "Run now": "Jetzt ausführen", + "Run preview": "Vorschau ausführen", + "Run user lifecycle now": "Benutzer-Lifecycle jetzt ausführen", + "Run user lifecycle now?": "Benutzer-Lifecycle jetzt ausführen?", + "Run UUID": "Run-UUID", + "Runner lock not acquired": "Runner-Lock nicht erhalten", + "Running": "Laufend", + "Runs": "Läufe", + "Sales": "Vertrieb", "Sampling rate": "Sampling-Rate", - "Allowed telemetry events": "Erlaubte Telemetrie-Ereignisse", - "warnOnce warnings": "warnOnce-Warnungen", - "AJAX errors": "AJAX-Fehler", - "The percentage of users who will have telemetry enabled.": "Der Anteil der Nutzer, für die Telemetrie aktiv ist.", - "Advanced telemetry options": "Erweiterte Telemetrie-Optionen", - "setting.system_audit_enabled": "System-Protokolle aktivieren/deaktivieren", - "setting.system_audit_retention_days": "Aufbewahrungsdauer in Tagen für System-Protokoll-Einträge", - "setting.frontend_telemetry_enabled": "Sichere Frontend-UX- und Fehler-Telemetrie aktivieren/deaktivieren", - "setting.frontend_telemetry_sample_rate": "Sampling-Rate zwischen 0 und 1 für akzeptierte Frontend-Telemetrie-Ereignisse", - "setting.frontend_telemetry_allowed_events": "Erlaubte Frontend-Telemetrie-Ereignisgruppen (warn_once, ajax_error)", - "System audit events (24h)": "System-Protokoll-Ereignisse (24h)", - "System audit risks (24h)": "System-Protokoll-Risiken (24h)", - "Failed or denied": "Fehlgeschlagen oder verweigert", - "Recent system audit risks (24h)": "Aktuelle System-Protokoll-Risiken (24h)", - "Lifecycle runs (7d)": "Lifecycle-Läufe (7d)", - "Lifecycle risks (7d)": "Lifecycle-Risiken (7d)", - "Restore actions (7d)": "Wiederherstellungsaktionen (7d)", - "Recent lifecycle risks (7d)": "Aktuelle Lifecycle-Risiken (7d)", - "Your session has expired. Please log in again.": "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an. Mit „Angemeldet bleiben“ erfolgt die Anmeldung ggf. automatisch.", - "Failed to update role permissions": "Rollenberechtigungen konnten nicht aktualisiert werden", - "Failed to update permission roles": "Berechtigungsrollen konnten nicht aktualisiert werden", - "Login persistence": "Anmeldespeicherung", - "Controls remember-me token lifetime and Microsoft auto-remember behavior.": "Steuert die Lebensdauer von Angemeldet-bleiben-Tokens und das automatische Anmeldeverhalten bei Microsoft-Login.", - "Remember token lifetime (days)": "Token-Lebensdauer Angemeldet-bleiben (Tage)", - "Allowed range: 1-365 days (default: 30)": "Erlaubter Bereich: 1–365 Tage (Standard: 30)", - "Microsoft Auto-Remember default": "Microsoft Auto-Anmeldung Standard", - "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).": "Wenn aktiviert, setzen erfolgreiche Microsoft-Anmeldungen automatisch ein Angemeldet-bleiben-Token (sofern nicht pro Mandant überschrieben).", - "Inherit global default": "Globalen Standard verwenden", - "Force on": "Erzwingen (an)", - "Force off": "Erzwingen (aus)", - "Controls whether Microsoft logins automatically persist a remember-me token.": "Steuert, ob Microsoft-Anmeldungen automatisch ein Angemeldet-bleiben-Token setzen.", - "Complete": "Vollständig", - "Incomplete": "Unvollständig", - "No domain restrictions": "Keine Domain-Einschränkungen", - "Configuration status": "Konfigurationsstatus", - "SSO setup is incomplete": "SSO-Konfiguration ist unvollständig", - "Complete the required Microsoft configuration before enforcing Microsoft-only login.": "Vervollständigen Sie die erforderliche Microsoft-Konfiguration, bevor Sie Microsoft-only-Anmeldung erzwingen.", - "Login policy": "Anmelderichtlinie", - "Allow Microsoft-only login (disable local password login)": "Nur Microsoft-Anmeldung erlauben (lokale Passwort-Anmeldung deaktivieren)", - "Remember login after Microsoft sign-in": "Angemeldet bleiben nach Microsoft-Login", - "Access and profile sync": "Zugriff und Profilabgleich", - "Profile sync": "Profilabgleich", - "App credentials (advanced)": "App-Anmeldedaten (Erweitert)", - "Remember token lifetime is invalid": "Token-Lebensdauer ist ungültig", - "Session expiring": "Sitzung läuft ab", - "Your session will expire in {countdown}. Would you like to continue?": "Ihre Sitzung läuft in {countdown} ab. Möchten Sie fortfahren?", - "Extend session": "Sitzung verlängern", - "Log out": "Abmelden", - "System Info": "Systeminfo", - "OK": "OK", - "System status": "Systemstatus", - "All systems operational": "Alle Systeme betriebsbereit", - "Degraded service": "Eingeschränkter Betrieb", - "System outage detected": "Systemstörung erkannt", - "Last checked": "Zuletzt geprüft", - "Components": "Komponenten", - "Database": "Datenbank", - "Database schema": "Datenbankschema", - "Storage": "Speicher", - "Administrators": "Administratoren", - "Connection established": "Verbindung hergestellt", - "Database did not return the expected response": "Datenbank hat keine erwartete Antwort geliefert", - "Database check could not be executed": "Datenbank-Prüfung konnte nicht ausgeführt werden", - "All required core tables are present": "Alle erforderlichen Kerntabellen sind vorhanden", - "Required core tables are missing": "Erforderliche Kerntabellen fehlen", - "Schema check could not be executed": "Schema-Prüfung konnte nicht ausgeführt werden", - "Storage path is writable": "Speicherpfad ist beschreibbar", - "Storage directory is missing": "Speicherverzeichnis fehlt", - "Storage directory is not writable": "Speicherverzeichnis ist nicht beschreibbar", - "Storage write probe failed": "Schreibprobe im Speicher fehlgeschlagen", - "Storage check could not be executed": "Speicher-Prüfung konnte nicht ausgeführt werden", - "Baseline permissions are present": "Basisberechtigungen sind vorhanden", - "Baseline permissions are missing": "Basisberechtigungen fehlen", - "Permission check could not be executed": "Berechtigungs-Prüfung konnte nicht ausgeführt werden", - "At least one administrator is active": "Mindestens ein Administrator ist aktiv", - "No active user has the administrator role": "Kein aktiver Nutzer hat die Administrator-Rolle", - "Administrator check could not be executed": "Administrator-Prüfung konnte nicht ausgeführt werden", - "Scheduler is running on schedule": "Scheduler läuft planmäßig", - "Scheduler heartbeat is outdated": "Scheduler-Heartbeat ist veraltet", + "SAPI": "SAPI", + "Sat": "Sa", + "Save": "Speichern", + "Save & close": "Speichern & schließen", + "Save in edit pages": "Auf Bearbeitungsseiten speichern", + "Save tenant first to manage custom fields": "Speichern Sie den Mandanten zuerst, um Zusatzfelder zu verwalten", + "Schedule": "Zeitplan", + "Schedule interval": "Zeitplan-Intervall", + "Schedule time": "Zeitplan-Uhrzeit", + "Schedule time is required": "Zeitplan-Uhrzeit ist erforderlich", + "Schedule type": "Zeitplan-Typ", + "Schedule type is invalid": "Zeitplan-Typ ist ungültig", + "Scheduled job could not be saved": "Geplante Aufgabe konnte nicht gespeichert werden", + "Scheduled job is not registered": "Geplante Aufgabe ist nicht registriert", + "Scheduled job not found": "Geplante Aufgabe nicht gefunden", + "Scheduled job run completed": "Geplante Aufgabe wurde ausgeführt", + "Scheduled job run failed": "Ausführung der geplanten Aufgabe fehlgeschlagen", + "Scheduled job run skipped": "Geplante Aufgabe wurde übersprungen", + "Scheduled job saved": "Geplante Aufgabe gespeichert", + "Scheduled jobs": "Geplante Aufgaben", + "Scheduler": "Scheduler", + "Scheduler check could not be executed": "Scheduler-Prüfung konnte nicht ausgeführt werden", "Scheduler has not reported yet": "Scheduler hat sich noch nicht gemeldet", "Scheduler heartbeat is empty": "Scheduler-Heartbeat ist leer", - "Scheduler check could not be executed": "Scheduler-Prüfung konnte nicht ausgeführt werden", - "Health Status": "Systemstatus", - "Check": "Prüfung", - "Details": "Details", - "PHP version": "PHP-Version", - "PHP SAPI": "PHP SAPI", - "Active modules": "Aktive Module", - "No modules active.": "Keine Module aktiv.", - "Module": "Modul", - "Dependencies": "Abhängigkeiten", - "Permission summary": "Berechtigungsübersicht", - "Active permissions": "Aktive Berechtigungen", - "Inactive (orphaned) permissions": "Inaktive (verwaiste) Berechtigungen", - "Permissions by source": "Berechtigungen nach Quelle", - "Source": "Quelle", - "No health checks available.": "Keine Systemprüfungen verfügbar.", - "Warning": "Warnung", - "Fail": "Fehler", - "Environment": "Umgebung", - "Modules": "Module", - "Version": "Version", - "Breadcrumb": "Breadcrumb", - "LDAP Username": "LDAP-Benutzername", - "Sign in with LDAP": "Mit LDAP anmelden", - "LDAP login is not available for this tenant.": "LDAP-Anmeldung ist für diesen Mandanten nicht verfügbar.", - "Your email domain is not allowed for LDAP login on this tenant.": "Ihre E-Mail-Domain ist für die LDAP-Anmeldung bei diesem Mandanten nicht zugelassen.", - "LDAP server is not reachable. Please try again later.": "LDAP-Server ist nicht erreichbar. Bitte versuchen Sie es später erneut.", - "Your LDAP account does not have an email address configured.": "Ihr LDAP-Konto hat keine E-Mail-Adresse konfiguriert.", - "LDAP host is required": "LDAP-Host ist erforderlich", - "LDAP base DN is required": "LDAP-Base-DN ist erforderlich", - "LDAP port must be between 1 and 65535": "LDAP-Port muss zwischen 1 und 65535 liegen", - "Search filter must contain %s placeholder": "Suchfilter muss den Platzhalter %s enthalten", - "LDAP-only login requires a complete configuration": "Nur-LDAP-Anmeldung erfordert eine vollständige Konfiguration", - "Direct bind method requires a username format": "Direkte Bindung erfordert ein Benutzernamenformat", - "Bind DN could not be encrypted": "Bind-DN konnte nicht verschlüsselt werden", - "Bind password could not be encrypted": "Bind-Passwort konnte nicht verschlüsselt werden", - "Tenant LDAP settings could not be saved": "LDAP-Einstellungen des Mandanten konnten nicht gespeichert werden", - "Bind DN could not be decrypted": "Bind-DN konnte nicht entschlüsselt werden", - "Bind password could not be decrypted": "Bind-Passwort konnte nicht entschlüsselt werden", - "LDAP login": "LDAP-Anmeldung", - "LDAP setup is incomplete": "LDAP-Konfiguration ist unvollständig", - "LDAP connection settings": "LDAP-Verbindungseinstellungen", - "Enable LDAP login for this tenant": "LDAP-Anmeldung für diesen Mandanten aktivieren", - "LDAP Host": "LDAP-Host", - "Encryption": "Verschlüsselung", - "None (not recommended)": "Keine (nicht empfohlen)", - "Verify TLS certificate": "TLS-Zertifikat überprüfen", - "Base DN": "Base-DN", - "Bind DN (service account)": "Bind-DN (Dienstkonto)", - "Bind password": "Bind-Passwort", - "Clear bind password": "Bind-Passwort löschen", - "Test connection": "Verbindung testen", + "Scheduler heartbeat is outdated": "Scheduler-Heartbeat ist veraltet", + "Scheduler is already running": "Scheduler läuft bereits", + "Scheduler is running on schedule": "Scheduler läuft planmäßig", + "Scheduler runs (24h)": "Scheduler-Läufe (24h)", + "Schema check could not be executed": "Schema-Prüfung konnte nicht ausgeführt werden", + "Scope": "Geltungsbereich", + "Search": "Suche", "Search and bind settings": "Such- und Bindungseinstellungen", - "Bind method": "Bindungsmethode", - "Search then bind (recommended)": "Suchen dann binden (empfohlen)", - "Direct bind": "Direkte Bindung", - "User search filter": "Benutzer-Suchfilter", + "Search failed. Please try again.": "Suche fehlgeschlagen. Bitte erneut versuchen.", + "Search filter must contain %s placeholder": "Suchfilter muss den Platzhalter %s enthalten", + "Search permissions…": "Berechtigungen suchen…", + "Search results": "Suchergebnisse", + "Search roles…": "Rollen suchen…", "Search scope": "Suchbereich", - "Subtree (recursive)": "Unterbaum (rekursiv)", - "One level": "Eine Ebene", - "Network timeout (seconds)": "Netzwerk-Timeout (Sekunden)", - "Direct bind username format": "Format für direkte Bindung", - "Unique ID attribute": "Eindeutiges ID-Attribut", - "Attribute mapping and sync": "Attributzuordnung und Synchronisierung", - "Map application fields to LDAP directory attributes.": "Anwendungsfelder den LDAP-Verzeichnisattributen zuordnen.", - "Profile sync on LDAP login": "Profilsynchronisierung bei LDAP-Anmeldung", - "Allow LDAP-only login (disable local password login)": "Nur LDAP-Anmeldung erlauben (lokale Passwortanmeldung deaktivieren)", - "Sync email": "E-Mail synchronisieren", - "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID": "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID", - "Login could not be completed. Please contact your administrator.": "Anmeldung konnte nicht abgeschlossen werden. Bitte kontaktieren Sie Ihren Administrator.", - "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com": "Nur für direkte Bindung. Verwenden Sie %s als Platzhalter. Beispiel: %s@corp.example.com oder uid=%s,ou=People,dc=example,dc=com", - "Optional allow-list, comma or newline separated.": "Optionale Zulassungsliste, durch Komma oder Zeilenumbruch getrennt.", - "Please enter your username and password.": "Bitte geben Sie Ihren Benutzernamen und Ihr Passwort ein.", - "Port": "Port", + "Search then bind (recommended)": "Suchen dann binden (empfohlen)", + "Search users, tenants, pages...": "Benutzer, Mandanten, Seiten durchsuchen...", "Search-then-bind uses a service account to find the user DN first, then binds with the user credentials.": "Suchen-dann-binden verwendet ein Dienstkonto, um zuerst den Benutzer-DN zu finden, und bindet dann mit den Benutzeranmeldedaten.", - "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP": "Verwenden Sie %s als Platzhalter für den Benutzernamen. Beispiele: (&(objectClass=user)(sAMAccountName=%s)) für AD, (&(objectClass=inetOrgPerson)(uid=%s)) für OpenLDAP", - "Username or password not valid": "Benutzername oder Passwort ungültig", - "Write-only. Leave empty to keep current value.": "Nur Schreibzugriff. Leer lassen, um den aktuellen Wert beizubehalten.", - "Your account is deactivated.": "Ihr Konto ist deaktiviert.", - "LDAP": "LDAP", - "LDAP attribute map could not be encoded": "LDAP-Attributzuordnung konnte nicht kodiert werden", - "Drop file here or click to select": "Datei hierher ziehen oder klicken", - "Remove selected file": "Ausgewaehlte Datei entfernen", - "Replace": "Ersetzen", - "Delete this image?": "Dieses Bild löschen?", - "Current image": "Aktuelles Bild", - "Open navigation": "Navigation öffnen", - "Close navigation": "Navigation schließen", - "Priority": "Priorität", - "Note": "Notiz", - "Optional note...": "Optionale Notiz...", + "Search...": "Suchen...", + "Searching...": "Suche läuft...", + "Security": "Sicherheit", "Security level updated": "Sicherheitsstufe aktualisiert", - "About": "Über", - "Call": "Anrufen", - "Copy email address": "E-Mail-Adresse kopieren", - "Copy phone number": "Telefonnummer kopieren", - "Copy mobile number": "Mobilnummer kopieren", - "Hired": "Eingestellt", - "Primary": "Primär", + "Security settings": "Sicherheitseinstellungen", + "Select": "Auswahl", + "Select actions": "Aktionen auswählen", + "Select actor users": "Akteure auswählen", + "Select all": "Alle auswählen", + "Select departments": "Abteilungen auswählen", + "Select event types": "Ereignistypen auswählen", + "Select options": "Optionen auswählen", + "Select permissions": "Berechtigungen auswählen", + "Select primary tenant": "Hauptmandant auswählen", + "Select roles": "Rollen auswählen", + "Select statuses": "Status auswählen", + "Select tenant": "Mandant auswählen", + "Select tenants": "Mandanten auswählen", + "Select triggers": "Auslöser auswählen", + "Select users": "Benutzer auswählen", + "Selection fields without options": "Auswahlfelder ohne Optionen", + "Send access": "Zugang versenden", + "Send access email to this user?": "Zugangsdaten an diesen Benutzer senden?", + "Send access emails to selected users?": "Zugangsdaten an ausgewählte Benutzer senden?", + "Send code": "Code senden", + "Send code again": "Code erneut senden", "Send email": "E-Mail senden", + "Sent": "Gesendet", + "Sent at": "Gesendet am", + "Sent emails": "Gesendete E-Mails", + "Service Unavailable": "Dienst nicht verfügbar", + "Session": "Sitzung", + "Session (keys + types)": "Session (Schlüssel + Typen)", + "Session absolute timeout (hours)": "Absolutes Sitzungs-Timeout (Stunden)", + "Session absolute timeout is invalid": "Absolutes Sitzungs-Timeout ist ungültig", + "Session expiring": "Sitzung läuft ab", + "Session idle timeout (minutes)": "Sitzungs-Inaktivitäts-Timeout (Minuten)", + "Session idle timeout is invalid": "Sitzungs-Inaktivitäts-Timeout ist ungültig", + "Session limits define how long logged-in users stay signed in.": "Hier werden Inaktivitäts- und Absolute-Timeout für aktive Sitzungen festgelegt.", + "Session policy": "Sitzungsrichtlinie", + "Sessions, registration, lifecycle, audit, telemetry": "Sitzungen, Registrierung, Lebenszyklus, Audit, Telemetrie", + "setting.api_cors_allowed_origins": "Erlaubte Browser-Origins für API-CORS (eine Origin pro Zeile)", + "setting.api_token_default_ttl_days": "Standard-Laufzeit für neue API-Tokens in Tagen (Default: 90)", + "setting.api_token_max_ttl_days": "Maximale Laufzeit für API-Tokens in Tagen (Hard Cap)", + "setting.app_locale": "Standard-Sprache, wenn keine Sprache gesetzt ist", + "setting.app_registration": "Öffentliche Selbstregistrierung erlauben", + "setting.app_title": "App-Titel für den Browser-Tab", + "setting.default_department": "Standard-Abteilung, wenn bei der Benutzeranlage keine Abteilung zugewiesen wird", + "setting.default_role": "Standard-Rolle, wenn bei der Benutzeranlage keine Rolle zugewiesen wird", + "setting.default_tenant": "Standard-Mandant, wenn bei der Benutzeranlage keiner zugewiesen wird", + "setting.frontend_telemetry_allowed_events": "Erlaubte Frontend-Telemetrie-Ereignisgruppen (warn_once, ajax_error)", + "setting.frontend_telemetry_enabled": "Sichere Frontend-UX- und Fehler-Telemetrie aktivieren/deaktivieren", + "setting.frontend_telemetry_sample_rate": "Sampling-Rate zwischen 0 und 1 für akzeptierte Frontend-Telemetrie-Ereignisse", + "setting.microsoft_authority": "Basis-OpenID-Authority-URL für Microsoft-Login", + "setting.microsoft_shared_client_id": "Einstellungsschlüssel für geteilte Microsoft-Client-ID", + "setting.microsoft_shared_client_secret_enc": "Einstellungsschlüssel für geteiltes Microsoft-Client-Secret (verschlüsselt)", + "setting.session_absolute_timeout_hours": "Maximale Gesamtdauer einer Sitzung in Stunden vor automatischer Abmeldung (Standard: 8)", + "setting.session_idle_timeout_minutes": "Maximale Inaktivitätsdauer in Minuten vor automatischer Abmeldung (Standard: 30)", + "setting.smtp_from": "Absender-E-Mail für ausgehende Nachrichten", + "setting.smtp_from_name": "Absendername für ausgehende Nachrichten", + "setting.smtp_host": "SMTP-Serveradresse (z.B. smtp.example.com)", + "setting.smtp_password": "Leer lassen, um das bestehende Passwort zu behalten", + "setting.smtp_port": "SMTP-Port (z.B. 587)", + "setting.smtp_secure": "Verschlüsselung für SMTP", + "setting.smtp_user": "SMTP-Benutzername", + "setting.system_audit_enabled": "System-Protokolle aktivieren/deaktivieren", + "setting.system_audit_retention_days": "Aufbewahrungsdauer in Tagen für System-Protokoll-Einträge", + "setting.user_inactivity_deactivate_days": "Setzt Benutzer nach dieser Anzahl Tagen ohne Login automatisch auf inaktiv", + "setting.user_inactivity_delete_days": "Löscht inaktive Benutzer nach dieser zusätzlichen Anzahl Tagen automatisch", + "Settings": "Einstellungen", + "Settings updated": "Einstellungen gespeichert", + "Shared app": "Geteilte App", + "Shared client ID": "Geteilte Client-ID", + "Shared client secret": "Geteiltes Client-Secret", + "Shared credentials missing": "Geteilte Zugangsdaten fehlen", + "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".": "Geteilte Microsoft-App-Zugangsdaten werden von Mandanten verwendet, die \"Geteilte App-Zugangsdaten verwenden\" aktivieren.", + "Shared Microsoft credentials": "Geteilte Microsoft-Zugangsdaten", + "Shared Microsoft Entra ID credentials": "Gemeinsame Microsoft-Entra-ID-Zugangsdaten", + "Short dial": "Kurzwahl", + "Show password": "Passwort anzeigen", + "Showing": "Zeige", + "Sign in with LDAP": "Mit LDAP anmelden", + "Sign in with Microsoft": "Mit Microsoft anmelden", + "Skip to main content": "Zum Hauptinhalt springen", + "Skipped": "Übersprungen", + "Skipped count": "Übersprungen", + "Slowest API endpoints (avg, 24h)": "Langsamste API-Endpunkte (Durchschnitt, 24h)", + "SMTP connection and sender details": "SMTP-Verbindung und Absenderangaben", + "SMTP from address": "Absender-Adresse", + "SMTP from name": "Absendername", + "SMTP host": "SMTP Host", + "SMTP password": "SMTP Passwort", + "SMTP port": "SMTP Port", + "SMTP security": "SMTP Sicherheit", + "SMTP user": "SMTP Benutzer", + "Snapshot summary": "Snapshot-Zusammenfassung", + "Snapshot version": "Snapshot-Version", + "Sort column ascending": "Spalte aufsteigend sortieren", + "Sort column descending": "Spalte absteigend sortieren", + "Source": "Quelle", + "Source content not found": "Quellinhalt nicht gefunden", + "Square images are recommended (icons are center-cropped).": "Quadratische Bilder empfohlen (Icons werden zentriert zugeschnitten).", + "Square PNG. Icons are center-cropped.": "Quadratisches PNG. Symbole werden mittig zugeschnitten.", + "SSO": "SSO", + "SSO configuration status": "SSO-Konfigurationsstatus", + "SSO rollout": "SSO-Rollout", + "SSO setup is incomplete": "SSO-Konfiguration ist unvollständig", + "SSO-enabled tenants": "Mandanten mit aktivem SSO", + "SSO-enforced tenants": "Mandanten mit erzwungenem SSO", + "Stack Trace": "Stack-Trace", + "Start import": "Import starten", + "Start writing...": "Mit dem Schreiben beginnen...", + "Started": "Gestartet", + "State": "Status", + "Statistics": "Statistiken", + "Status": "Status", + "Status & meta": "Status & Meta", + "Status changed": "Status geändert", + "Status changed by": "Status geändert von", + "Status code": "Statuscode", + "Status is invalid": "Status ist ungültig", + "Storage": "Speicher", + "Storage check could not be executed": "Speicher-Prüfung konnte nicht ausgeführt werden", + "Storage directory is missing": "Speicherverzeichnis fehlt", + "Storage directory is not writable": "Speicherverzeichnis ist nicht beschreibbar", + "Storage path is writable": "Speicherpfad ist beschreibbar", + "Storage write probe failed": "Schreibprobe im Speicher fehlgeschlagen", + "Subject": "Betreff", + "Subtree (recursive)": "Unterbaum (rekursiv)", + "Success": "Erfolgreich", + "Success rate": "Erfolgsquote", + "Success rate (7d)": "Erfolgsquote (7 Tage)", "Summary": "Zusammenfassung", + "Sun": "So", + "Support": "Support", + "Support email": "Support-E-Mail", + "Support phone": "Support-Telefon", + "Switch sidebar section": "Sidebar-Bereich wechseln", + "Switch tenant": "Mandant wechseln", + "Sync avatar image": "Avatarbild synchronisieren", + "Sync display name": "Anzeigename synchronisieren", + "Sync email": "E-Mail synchronisieren", + "Sync fields": "Sync-Felder", + "Sync first name": "Vorname synchronisieren", + "Sync job title": "Berufsbezeichnung synchronisieren", + "Sync last name": "Nachname synchronisieren", + "Sync mobile": "Mobil synchronisieren", + "Sync phone": "Telefon synchronisieren", + "System": "System", + "System audit": "System-Protokolle", + "System audit controls whether security events are logged and how long they are kept.": "Hier wird gesteuert, ob Sicherheitsereignisse protokolliert werden und wie lange sie aufbewahrt werden.", + "System audit entry not found": "System-Protokoll-Eintrag nicht gefunden", + "System audit events (24h)": "System-Protokoll-Ereignisse (24h)", + "System audit logs": "System-Protokolle", + "System audit risks (24h)": "System-Protokoll-Risiken (24h)", + "System Info": "Systeminfo", + "System outage detected": "Systemstörung erkannt", + "System permission": "Systemberechtigung", + "System permission can not be deleted": "Systemberechtigung kann nicht gelöscht werden", + "System permissions are core and should rarely be disabled.": "Systemberechtigungen sind kernrelevant und sollten nur selten deaktiviert werden.", + "System status": "Systemstatus", + "Target": "Ziel", + "Target email": "Ziel-E-Mail", + "Target field": "Zielfeld", + "Target language required": "Zielsprache erforderlich", + "Target type": "Zieltyp", + "Target UUID": "Ziel-UUID", + "Tax number": "Steuernummer", + "Telemetry helps detect recurring UI issues and failed requests in production.": "Telemetry hilft, wiederkehrende UI-Probleme und fehlgeschlagene Requests in Produktion zu erkennen.", + "Template": "Vorlage", + "Tenant": "Mandant", + "Tenant #%d": "Mandant #%d", + "Tenant #%d (deleted)": "Mandant #%d (gelöscht)", + "Tenant assignment is out of your scope": "Mandantenzuweisung liegt außerhalb deines Scopes", + "Tenant can not be created": "Mandant kann nicht erstellt werden", + "Tenant can not be deleted while departments are assigned": "Mandant kann nicht gelöscht werden, solange Abteilungen zugewiesen sind", + "Tenant can not be updated": "Mandant kann nicht aktualisiert werden", + "Tenant created": "Mandant erstellt", + "Tenant deleted": "Mandant gelöscht", + "Tenant favicon": "Mandanten-Favicon", + "Tenant ID": "Mandanten-ID", + "Tenant is missing, inactive or invalid": "Mandant fehlt, ist inaktiv oder ungültig", + "Tenant LDAP settings could not be saved": "LDAP-Einstellungen des Mandanten konnten nicht gespeichert werden", + "Tenant login link is invalid": "Mandanten-Login-Link ist ungültig", + "Tenant logos": "Mandanten-Logos", + "Tenant must be a valid UUID": "Mandant muss eine gültige UUID sein", + "Tenant not found": "Mandant nicht gefunden", + "Tenant override": "Mandanten-Override", + "Tenant SSO settings could not be saved": "Mandanten-SSO-Einstellungen konnten nicht gespeichert werden", + "Tenant updated": "Mandant aktualisiert", + "Tenants": "Mandanten", + "Tenants can override color and theme behavior in their appearance settings.": "Mandanten können Farbe und Theme-Verhalten in ihren Darstellungs-Einstellungen überschreiben.", + "Tenants with broken selection fields": "Mandanten mit fehlerhaften Auswahlfeldern", + "Terms of Service": "Nutzungsbedingungen", + "Test connection": "Verbindung testen", + "Text": "Text", + "Textarea": "Mehrzeiliger Text", + "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.": "Die Authority-URL definiert den Microsoft-Identity-Tenant-Endpunkt für die Anmeldung.", + "The field type controls input and filter behavior.": "Der Feldtyp steuert Eingabe- und Filterverhalten.", + "The label is shown in user custom fields and in address book filters.": "Die Bezeichnung wird bei Benutzer-Zusatzfeldern und in den Adressbuch-Filtern angezeigt.", + "The page you requested does not exist or has moved.": "Die angeforderte Seite existiert nicht oder wurde verschoben.", + "The percentage of users who will have telemetry enabled.": "Der Anteil der Nutzer, für die Telemetrie aktiv ist.", + "The primary color affects buttons and accent elements across the app.": "Die Primärfarbe beeinflusst Buttons und Akzent-Elemente in der gesamten App.", + "The theme used for users in this tenant who have no personal preference.": "Das Theme für Nutzer dieses Mandanten, die keine persönliche Präferenz gesetzt haben.", + "Theme": "Theme", + "Theme change is disabled for this tenant": "Theme-Wechsel ist für diesen Mandanten deaktiviert", + "Theme policy": "Theme-Richtlinie", + "These defaults prefill tenant, department and role when new users are created.": "Diese Standards füllen Mandant, Abteilung und Rolle bei neu erstellten Benutzern vor.", + "These limits define default and maximum lifetimes for newly issued API tokens.": "Diese Grenzwerte definieren Standard- und Maximallaufzeit für neu ausgestellte API-Tokens.", + "This action cannot be undone.": "Diese Aktion kann nicht rückgängig gemacht werden.", + "This action revokes all active API tokens immediately across all users.": "Diese Aktion widerruft sofort alle aktiven API-Tokens über alle Benutzer hinweg.", + "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.": "Diese geplante Aufgabe ist nicht mehr registriert und kann nicht bearbeitet werden. Sie wurde durch eine neuere Version ersetzt.", + "This setting controls the application name shown across the UI.": "Diese Einstellung steuert den in der gesamten UI angezeigten Anwendungsnamen.", + "This setting controls the default language for users without a personal preference.": "Diese Einstellung steuert die Standardsprache für Benutzer ohne persönliche Präferenz.", + "This setting controls the global default theme and whether users may choose their own theme.": "Diese Einstellung steuert das globale Standard-Theme und ob Benutzer ihr eigenes Theme wählen dürfen.", + "This setting controls the primary UI accent color for the default app theme.": "Diese Einstellung steuert die primäre UI-Akzentfarbe des Standard-App-Themes.", + "This user is currently not signed in via remember-me.": "Dieser Benutzer ist aktuell nicht per Angemeldet-bleiben eingeloggt.", + "This will expire all remember-me tokens immediately and force users to sign in again.": "Dadurch werden alle Remember-me-Tokens sofort abgelaufen und Benutzer müssen sich erneut anmelden.", + "This will mark all remember-me tokens as expired. Users will need to sign in again.": "Alle Angemeldet-bleiben Tokens werden als abgelaufen markiert. Benutzer müssen sich erneut anmelden sobald die Browser-Session ausgelaufen ist.", + "This will permanently delete this department.": "Diese Abteilung wird dauerhaft gelöscht.", + "This will permanently delete this permission.": "Diese Berechtigung wird dauerhaft gelöscht.", + "This will permanently delete this role.": "Diese Rolle wird dauerhaft gelöscht.", + "This will permanently delete this tenant.": "Dieser Mandant wird dauerhaft gelöscht.", + "This will permanently delete this user.": "Dieser Benutzer wird dauerhaft gelöscht.", + "Thu": "Do", + "Timezone": "Zeitzone", + "Timezone is invalid": "Zeitzone ist ungültig", + "to": "bis", + "Toggle contrast": "Kontrast umschalten", + "Toggle Detail Sidebar": "Detail-Seitenleiste umschalten", + "Toggle Sidebar": "Sidebar umschalten", + "Toggle sidebar": "Sidebar umschalten", + "Token ID": "Token-ID", + "Token lifetime policy": "Token-Laufzeit-Richtlinie", + "Token name": "Token-Name", + "Token name is required": "Token-Name ist erforderlich", + "Token operations": "Token-Aktionen", + "Token tenant": "Token-Mandant", "token_select.clear_all": "Alle entfernen", "token_select.empty_state_title": "Keine Elemente ausgewählt", "token_select.error_invalid_items": "Elemente konnten nicht geladen werden.", "token_select.no_matches": "Keine Treffer", "token_select.remove": "Entfernen", - "token_select.selected_count_suffix": "ausgewählt" + "token_select.selected_count_suffix": "ausgewählt", + "Tokens expiring in 7 days": "Tokens mit Ablauf in 7 Tagen", + "Too many failed attempts. Please request a new code.": "Zu viele Fehlversuche. Bitte fordere einen neuen Code an.", + "Too many login attempts. Please wait and try again.": "Zu viele Login-Versuche. Bitte warte kurz und versuche es erneut.", + "Too Many Requests": "Zu viele Anfragen", + "Too many users selected": "Zu viele Benutzer ausgewählt", + "Top API error codes (24h)": "Top API-Fehlercodes (24h)", + "Top import error codes (7d)": "Häufigste Import-Fehlercodes (7 Tage)", + "Trigger": "Auslöser", + "Tue": "Di", + "Type": "Typ", + "Unauthorized": "Nicht autorisiert", + "Unexpected error during import": "Unerwarteter Fehler beim Import", + "Unique ID attribute": "Eindeutiges ID-Attribut", + "Unknown": "Unbekannt", + "Unprocessable Entity": "Nicht verarbeitbare Anfrage", + "Unsaved change (%d field)": "Ungespeichert (%d Feld)", + "Unsaved changes": "Ungespeichert", + "Unsaved changes (%d fields)": "Ungespeichert (%d Felder)", + "Unused active custom fields": "Ungenutzte aktive Zusatzfelder", + "Unverified": "Nicht verifiziert", + "Upload dark logo": "Dunkles Logo hochladen", + "Upload exceeds the maximum size": "Upload überschreitet die maximale Dateigröße", + "Upload failed": "Upload fehlgeschlagen", + "Upload favicon": "Favicon hochladen", + "Upload image": "Bild hochladen", + "Upload light logo": "Helles Logo hochladen", + "Upload logo": "Logo hochladen", + "URL": "URL", + "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP": "Verwenden Sie %s als Platzhalter für den Benutzernamen. Beispiele: (&(objectClass=user)(sAMAccountName=%s)) für AD, (&(objectClass=inetOrgPerson)(uid=%s)) für OpenLDAP", + "Use different email": "Andere E-Mail verwenden", + "Use shared app credentials from settings": "Geteilte App-Zugangsdaten aus Einstellungen verwenden", + "Used": "Verwendet", + "Used at": "Verwendet am", + "User": "Benutzer", + "User #%d": "Benutzer #%d", + "User #%d (deleted)": "Benutzer #%d (gelöscht)", + "User Agent": "User-Agent", + "User agent hash": "User-Agent-Hash", + "User assignments can not be updated": "Benutzerzuweisungen können nicht aktualisiert werden", + "User can not be registered": "Benutzer kann nicht registriert werden", + "User can not be updated": "Benutzer kann nicht aktualisiert werden", + "User created": "Benutzer erstellt", + "User creation rules": "Benutzeranlage-Regeln", + "User custom fields": "Benutzerzusatzfelder", + "User deleted": "Benutzer gelöscht", + "User ID": "Benutzer-ID", + "User inactivity deactivation period is invalid": "Zeitraum für automatische Deaktivierung ist ungültig", + "User inactivity deletion period is invalid": "Zeitraum für automatische Löschung ist ungültig", + "User lifecycle already running": "Benutzer-Lifecycle läuft bereits", + "User lifecycle completed: %d deactivated, %d deleted": "Benutzer-Lifecycle abgeschlossen: %d deaktiviert, %d gelöscht", + "User lifecycle defines when inactive users are deactivated or deleted.": "Hier wird festgelegt, wann inaktive Benutzer deaktiviert oder gelöscht werden.", + "User lifecycle failed": "Benutzer-Lifecycle fehlgeschlagen", + "User lifecycle logs": "Benutzer-Lifecycle-Protokolle", + "User lifecycle policy": "Benutzer-Lifecycle-Regel", + "User not found": "Benutzer nicht gefunden", + "User override disabled": "Benutzer-Override deaktiviert", + "User override enabled": "Benutzer-Override aktiviert", + "User profile fields are global and affect all tenants of this user": "Benutzer-Profildaten sind global und wirken auf alle Mandanten dieses Benutzers.", + "User restore failed": "Benutzer-Wiederherstellung fehlgeschlagen", + "User restored": "Benutzer wiederhergestellt", + "User search filter": "Benutzer-Suchfilter", + "User theme policy": "Benutzer-Theme-Richtlinie", + "User updated": "Benutzer aktualisiert", + "Username": "Benutzername", + "Username or password not valid": "Benutzername oder Passwort ungültig", + "Users": "Benutzer", + "Users may choose their own theme": "Benutzer dürfen ihr eigenes Theme wählen", + "Users with Microsoft-only login": "Benutzer mit nur Microsoft-Login", + "Users without roles": "Benutzer ohne Rollen", + "Users without tenants": "Benutzer ohne Mandant", + "Users, tenants, departments, roles and more": "Benutzer, Mandanten, Abteilungen, Rollen und mehr", + "UUID": "UUID", + "Valid rows": "Gültige Zeilen", + "VAT ID": "USt-ID", + "Verification code": "Bestätigungscode", + "Verified": "Bestätigt", + "Verify": "Prüfen", + "Verify code": "Code prüfen", + "Verify email": "E-Mail bestätigen", + "Verify TLS certificate": "TLS-Zertifikat überprüfen", + "Version": "Version", + "View": "Ansicht", + "View all results": "Alle Ergebnisse anzeigen", + "View API audit entry": "API-Protokoll-Eintrag anzeigen", + "View department": "Abteilung anzeigen", + "View import audit entry": "Import-Protokoll-Eintrag anzeigen", + "View mail log": "E-Mail-Protokoll ansehen", + "View permission": "Berechtigung anzeigen", + "View role": "Rolle anzeigen", + "View scheduled job": "Geplante Aufgabe anzeigen", + "View system audit entry": "System-Protokoll-Eintrag anzeigen", + "View tenant": "Mandant anzeigen", + "View user": "Benutzer anzeigen", + "View user lifecycle audit entry": "Benutzer-Lifecycle-Eintrag anzeigen", + "Visibility": "Sichtbarkeit", + "Warning": "Warnung", + "warnOnce warnings": "warnOnce-Warnungen", + "We could not continue with these login details": "Mit diesen Login-Daten konnte nicht fortgefahren werden", + "Website": "Webseite", + "Wed": "Mi", + "Weekdays": "Wochentage", + "Weekly": "Wöchentlich", + "Weekly interval must be between 1 and 52": "Wöchentliches Intervall muss zwischen 1 und 52 liegen", + "Welcome back": "Willkommen zurück", + "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).": "Wenn aktiviert, setzen erfolgreiche Microsoft-Anmeldungen automatisch ein Angemeldet-bleiben-Token (sofern nicht pro Mandant überschrieben).", + "Windows": "Windows", + "Would create": "Würde erstellen", + "Would fail": "Würde fehlschlagen", + "Would skip": "Würde überspringen", + "Write-only. Leave empty to keep current secret.": "Nur schreiben. Leer lassen, um das aktuelle Secret beizubehalten.", + "Write-only. Leave empty to keep current value.": "Nur Schreibzugriff. Leer lassen, um den aktuellen Wert beizubehalten.", + "Yes": "Ja", + "You are not allowed to edit this page": "Du darfst diese Seite nicht bearbeiten", + "You cannot deactivate your own account": "Du kannst dein eigenes Konto nicht deaktivieren", + "You cannot delete your own account": "Du kannst deinen eigenen Account nicht löschen", + "You do not have permission to run imports.": "Du hast keine Berechtigung für Importe.", + "You do not have permission to view this content.": "Du hast keine Berechtigung, diesen Inhalt zu sehen.", + "You have unsaved changes. Leave without saving?": "Sie haben ungespeicherte Änderungen. Seite ohne Speichern verlassen?", + "Your access details": "Deine Zugangsdaten", + "Your account is deactivated.": "Ihr Konto ist deaktiviert.", + "Your email domain is not allowed for LDAP login on this tenant.": "Ihre E-Mail-Domain ist für die LDAP-Anmeldung bei diesem Mandanten nicht zugelassen.", + "Your LDAP account does not have an email address configured.": "Ihr LDAP-Konto hat keine E-Mail-Adresse konfiguriert.", + "Your session has expired. Please log in again.": "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an. Mit „Angemeldet bleiben“ erfolgt die Anmeldung ggf. automatisch.", + "Your session will expire in {countdown}. Would you like to continue?": "Ihre Sitzung läuft in {countdown} ab. Möchten Sie fortfahren?", + "ZIP support missing (ext-zip)": "ZIP-Unterstützung fehlt (ext-zip)" } diff --git a/i18n/default_en.json b/i18n/default_en.json index 1b0ece0..733ae73 100644 --- a/i18n/default_en.json +++ b/i18n/default_en.json @@ -1,1343 +1,1357 @@ { - "Login": "Login", - "Login credentials": "Login credentials", - "Login provider": "Login provider", - "Open full page": "Open full page", - "Loading": "Loading", - "Failed to load": "Failed to load", - "Register": "Register", - "Password": "Password", - "Or": "Or", - "Forgot password": "Forgot password", - "Remember me": "Remember me", - "Clear login tokens": "Clear login tokens", - "Clear all login tokens for this user?": "Clear all login tokens for this user?", - "Login tokens cleared": "Login tokens cleared", - "Send access": "Send access", - "Access PDF": "Access PDF", - "Download access PDFs": "Download access PDFs", - "Generate access PDFs for selected users?": "Generate access PDFs for selected users?", - "Too many users selected": "Too many users selected", - "No valid users selected": "No valid users selected", - "Failed to generate access PDF": "Failed to generate access PDF", - "ZIP support missing (ext-zip)": "ZIP support missing (ext-zip)", - "Send access email to this user?": "Send access email to this user?", - "Access email sent": "Access email sent", - "Access email failed": "Access email failed", - "Your access details": "Your access details", - "Reset password": "Reset password", - "Verification code": "Verification code", - "Verify code": "Verify code", - "Verify": "Verify", - "Send code": "Send code", - "Send code again": "Send code again", - "Enter your email address and we will send you a verification code.": "Enter your email address and we will send you a verification code.", - "Enter the verification code we sent to your email.": "Enter the verification code we sent to your email.", - "Please enter a valid email address": "Please enter a valid email address", - "Please enter the 6-digit code": "Please enter the 6-digit code", - "Invalid or expired code": "Invalid or expired code", - "Code verified": "Code verified", - "Password reset code": "Password reset code", - "If the email exists, a verification code has been sent.": "If the email exists, a verification code has been sent.", - "Choose a new password for your account.": "Choose a new password for your account.", - "Password updated": "Password updated", - "Password can not be updated": "Password can not be updated", - "Profile can not be updated": "Profile can not be updated", - "Reset request not found": "Reset request not found", - "Reset request already used": "Reset request already used", - "Reset request expired": "Reset request expired", - "Username": "Username", - "Admin": "Admin", - "Logout": "Logout", - "Account": "Account", - "Continue": "Continue", - "Show password": "Show password", - "Hide password": "Hide password", - "Use different email": "Use different email", - "Back to login": "Back to login", - "Encrypted connection": "Encrypted", - "HTTPS/TLS 1.2+ in transit": "HTTPS/TLS 1.2+ in transit", - "Problems logging in": "Problems logging in", - "We could not continue with these login details": "We could not continue with these login details", - "Too many login attempts. Please wait and try again.": "Too many login attempts. Please wait and try again.", - "No login method is available for this tenant": "No login method is available for this tenant", - "Cached": "Cached", - "App identity": "App identity", - "Configured": "Configured", - "Not configured": "Not configured", - "Theme policy": "Theme policy", - "Brand color": "Brand color", - "User override enabled": "User override enabled", - "User override disabled": "User override disabled", - "Token lifetime policy": "Token lifetime policy", - "Token operations": "Token operations", - "CORS allowlist": "CORS allowlist", - "Shared Microsoft credentials": "Shared Microsoft credentials", - "Authority endpoint": "Authority endpoint", + "%d active API tokens": "%d active API tokens", + "%d active login tokens": "%d active login tokens", + "%d API audit entries purged": "%d API log entries purged", + "%d API tokens revoked": "%d API tokens revoked", "%d defaults configured": "%d defaults configured", "%d events enabled": "%d events enabled", + "%d import audit entries purged": "%d import audit entries purged", + "%d login tokens expired": "%d login tokens expired", "%d origins configured": "%d origins configured", - "days": "days", - "Leave empty to use the runtime default title.": "Leave empty to use the runtime default title.", - "Leave empty to keep the currently stored client secret.": "Leave empty to keep the currently stored client secret.", - "This setting controls the application name shown across the UI.": "This setting controls the application name shown across the UI.", - "This setting controls the default language for users without a personal preference.": "This setting controls the default language for users without a personal preference.", - "These defaults prefill tenant, department and role when new users are created.": "These defaults prefill tenant, department and role when new users are created.", - "This setting controls the global default theme and whether users may choose their own theme.": "This setting controls the global default theme and whether users may choose their own theme.", - "This setting controls the primary UI accent color for the default app theme.": "This setting controls the primary UI accent color for the default app theme.", - "Telemetry helps detect recurring UI issues and failed requests in production.": "Telemetry helps detect recurring UI issues and failed requests in production.", - "Limit which event types are collected to match your privacy and operations requirements.": "Limit which event types are collected to match your privacy and operations requirements.", - "These limits define default and maximum lifetimes for newly issued API tokens.": "These limits define default and maximum lifetimes for newly issued API tokens.", - "Define which origins may call your API from browsers. Use one origin per line.": "Define which origins may call your API from browsers. Use one origin per line.", - "This action revokes all active API tokens immediately across all users.": "This action revokes all active API tokens immediately across all users.", - "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.": "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.", - "This will expire all remember-me tokens immediately and force users to sign in again.": "This will expire all remember-me tokens immediately and force users to sign in again.", - "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.": "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.", - "Create your account": "Create your account", - "First name": "First name", - "Name": "Name", - "Last name": "Last name", - "Email": "Email", - "Password (again)": "Password confirm", - "Password requirements": "Password requirements", - "At least %d characters": "At least %d characters", - "At least one uppercase letter": "At least one uppercase letter", - "At least one lowercase letter": "At least one lowercase letter", - "At least one number": "At least one number", - "At least one symbol": "At least one symbol", - "Must not contain your email": "Must not contain your email", - "Email/password not valid": "Email or password is invalid", - "First name cannot be empty": "First name cannot be empty", - "Last name cannot be empty": "Last name cannot be empty", - "Email cannot be empty": "Email cannot be empty", - "Email is not valid": "Email is not valid", - "Password cannot be empty": "Password cannot be empty", - "Passwords must match": "Passwords must match", - "Password must be at least %d characters": "Password must be at least %d characters", - "Password must include an uppercase letter": "Password must include an uppercase letter", - "Password must include a lowercase letter": "Password must include a lowercase letter", - "Password must include a number": "Password must include a number", - "Password must include a symbol": "Password must include a symbol", - "Password must not contain your email": "Password must not contain your email", - "Email is already taken": "Email is already taken", - "User can not be registered": "User can not be registered", - "Language not supported": "Language not supported", - "Language": "Language", - "Sales": "Sales", - "Master data": "Master data", - "Organization": "Organization", - "Roles & permissions": "Roles & permissions", - "Permissions": "Permissions", - "Permission key": "Permission key", - "Create permission": "Create permission", - "Edit permission": "Edit permission", - "View permission": "View permission", - "Delete this permission?": "Delete this permission?", - "Permission created": "Permission created", - "Permission updated": "Permission updated", - "Permission deleted": "Permission deleted", - "Permission not found": "Permission not found", - "Permission can not be created": "Permission can not be created", - "Permission can not be updated": "Permission can not be updated", - "Permission key cannot be empty": "Permission key cannot be empty", - "Permission key is invalid": "Permission key is invalid", - "Permission key already exists": "Permission key already exists", - "Assigned permissions": "Assigned permissions", - "Select permissions": "Select permissions", - "No permissions available": "No permissions available", - "No permissions selected": "No permissions selected", - "Remove permission": "Remove permission", - "Search permissions…": "Search permissions…", - "No active permissions are configured yet.": "No active permissions are configured yet.", - "No active roles are configured yet.": "No active roles are configured yet.", - "Permission denied": "Permission denied", - "No active tenant assigned": "No active tenant assigned", - "Please select at least one tenant": "Please select at least one tenant", - "perm.users.view": "View users", - "perm.users.create": "Create users", - "perm.users.update": "Update users", - "perm.users.access_pdf": "Generate onboarding PDFs", - "perm.users.delete": "Delete users", - "perm.users.self_update": "Update own user", - "perm.users.update_assignments": "Update user assignments", - "Permission origin": "Permission origin", - "perm.tenants.view": "View tenants", - "perm.tenants.create": "Create tenants", - "perm.tenants.update": "Update tenants", - "perm.tenants.delete": "Delete tenants", - "perm.departments.view": "View departments", - "perm.departments.create": "Create departments", - "perm.departments.update": "Update departments", - "perm.departments.delete": "Delete departments", - "perm.roles.view": "View roles", - "perm.roles.create": "Create roles", - "perm.roles.update": "Update roles", - "perm.roles.delete": "Delete roles", - "perm.roles.assign_all": "Assign all roles", - "perm.permissions.view": "View permissions", - "perm.permissions.create": "Create permissions", - "perm.permissions.update": "Update permissions", - "perm.permissions.delete": "Delete permissions", - "perm.settings.view": "View settings", - "perm.settings.update": "Update settings", - "perm.mail_log.view": "View mail logs", - "perm.jobs.view": "View scheduled jobs", - "perm.jobs.manage": "Manage scheduled jobs", - "perm.jobs.run_now": "Run scheduled jobs manually", - "perm.audit.api.view": "View API logs", - "perm.audit.api.purge": "Purge API logs", - "perm.audit.system.view": "View system logs", - "perm.audit.system.purge": "Purge system logs", - "perm.audit.imports.view": "View import audit logs", - "perm.audit.imports.purge": "Purge import audit logs", - "perm.audit.user_lifecycle.view": "View user lifecycle logs", - "perm.audit.user_lifecycle.restore": "Restore users from lifecycle audit", - "perm.user_lifecycle_audit.view": "View user lifecycle logs", - "perm.users.lifecycle_restore": "Restore users from lifecycle audit", - "Select all": "Select all", - "Activate": "Activate", - "Deactivate": "Deactivate", - "Delete": "Delete", - "Activate users?": "Activate users?", - "Deactivate users?": "Deactivate users?", - "Delete users?": "Delete users?", - "Send access emails to selected users?": "Send access emails to selected users?", + "%d scheduler run logs purged": "%d scheduler run logs purged", + "%d selected": "%d selected", + "%d system audit entries purged": "%d system audit entries purged", + "%d user lifecycle audit entries purged": "%d user lifecycle audit entries purged", "%d users activated": "%d users activated", "%d users deactivated": "%d users deactivated", "%d users deleted": "%d users deleted", - "Access emails sent to %d users": "Access emails sent to %d users", - "Access emails sent to %d users, %f failed": "Access emails sent to %d users, %f failed", - "Failed to activate users": "Failed to activate users", - "Failed to deactivate users": "Failed to deactivate users", - "Failed to delete users": "Failed to delete users", - "Failed to send access emails": "Failed to send access emails", - "Home": "Home", - "Exception": "Exception", - "An error occurred": "An error occurred", - "in %s on line %s": "in %s on line %s", - "Copy request ID": "Copy request ID", - "Error details": "Error details", - "Request": "Request", - "Queries": "Queries", - "An unexpected error occurred. If the problem persists, please contact support with the reference below.": "An unexpected error occurred. If the problem persists, please contact support with the reference below.", - "Stack Trace": "Stack Trace", - "Caused by": "Caused by", - "URL": "URL", - "User Agent": "User Agent", - "Headers": "Headers", - "GET Parameters": "GET Parameters", - "POST Parameters": "POST Parameters", - "Session (keys + types)": "Session (keys + types)", - "Context": "Context", - "PHP": "PHP", - "SAPI": "SAPI", - "Memory (current)": "Memory (current)", - "Memory (peak)": "Memory (peak)", - "Application": "Application", - "Active Modules": "Active Modules", - "Loaded Extensions (%d)": "Loaded Extensions (%d)", - "Query tracking is not available (Debugger disabled or not initialized).": "Query tracking is not available (Debugger disabled or not initialized).", - "No queries were executed before the error occurred.": "No queries were executed before the error occurred.", - "Queries (%d)": "Queries (%d)", - "Bad Request": "Bad Request", - "Unauthorized": "Unauthorized", - "Forbidden": "Forbidden", - "Not Found": "Not Found", - "Method Not Allowed": "Method Not Allowed", - "Request Timeout": "Request Timeout", - "Unprocessable Entity": "Unprocessable Entity", - "Too Many Requests": "Too Many Requests", - "Internal Server Error": "Internal Server Error", - "Bad Gateway": "Bad Gateway", - "Service Unavailable": "Service Unavailable", - "Users": "Users", - "Avatar": "Avatar", - "Theme": "Theme", - "Light": "Light", - "Dark": "Dark", - "Main menu": "Main menu", - "Toggle Sidebar": "Toggle Sidebar", - "Toggle Detail Sidebar": "Toggle Detail Sidebar", - "%d selected": "%d selected", - "Create user": "Create user", - "Edit user": "Edit user", - "View user": "View user", - "Create": "Create", - "Create & close": "Create & close", - "Save": "Save", - "Save & close": "Save & close", - "Cancel": "Cancel", - "Close": "Close", - "Confirm": "Confirm", - "Please confirm": "Please confirm", - "This action cannot be undone.": "This action cannot be undone.", - "Active": "Active", - "Actions": "Actions", - "ID": "ID", - "Created": "Created", - "Created by": "Created by", - "Modified by": "Modified by", - "Modified": "Modified", - "Open": "Open", - "Press Enter to open row": "Press Enter to open row", - "Retry": "Retry", - "Yes": "Yes", - "No": "No", - "User created": "User created", - "User updated": "User updated", - "User deleted": "User deleted", - "User not found": "User not found", - "User can not be updated": "User can not be updated", - "Avatar updated": "Profile image updated", - "Avatar removed": "Profile image removed", - "Upload failed": "Upload failed", - "File is too large": "File is too large", - "Invalid image file": "Invalid image file", - "No file uploaded": "No file uploaded", - "You cannot delete your own account": "You cannot delete your own account", - "Login required": "Login required", - "You cannot deactivate your own account": "You cannot deactivate your own account", - "Welcome back": "Welcome back", - "New password (optional)": "New password (optional)", - "Account is inactive": "Account is inactive", - "Inactive": "Inactive", - "Filter": "Filter", - "Apply filters": "Apply filters", - "Clear all filters": "Clear all filters", - "Close filters": "Close filters", - "Remove filter": "Remove filter", - "Filters applied": "Filters applied", - "Filter removed": "Filter removed", - "All filters cleared": "All filters cleared", - "UUID": "UUID", - "Profile image": "Profile image", - "Profile": "Profile", - "Profile description": "Profile description", - "Search results": "Search results", - "Result": "Result", - "Type": "Type", - "Page": "Page", - "Upload image": "Upload image", - "App logo": "App logo", - "Upload logo": "Upload logo", - "Logo updated": "Logo updated", - "Logo removed": "Logo removed", - "Tenant logos": "Tenant logos", - "Light logo": "Light logo", - "Dark logo": "Dark logo", - "Upload light logo": "Upload light logo", - "Upload dark logo": "Upload dark logo", - "Delete light logo": "Delete light logo", - "Delete dark logo": "Delete dark logo", - "No logo for this theme yet": "No logo for this theme yet", - "Delete this logo?": "Delete this logo?", - "Invalid theme": "Invalid theme", - "Logo": "Logo", - "Remove": "Remove", - "Allowed file types: SVG, PNG, JPG, WEBP": "Allowed file types: SVG, PNG, JPG, WEBP", - "Favicon": "Favicon", - "Tenant favicon": "Tenant favicon", - "Square PNG. Icons are center-cropped.": "Square PNG. Icons are center-cropped.", - "Delete this favicon?": "Delete this favicon?", - "Upload favicon": "Upload favicon", - "Favicon updated": "Favicon updated", - "Favicon removed": "Favicon removed", - "Allowed file types: PNG": "Allowed file types: PNG", - "Square images are recommended (icons are center-cropped).": "Square images are recommended (icons are center-cropped).", - "Primary color": "Primary color", - "Primary color is invalid": "Primary color is invalid", - "The primary color affects buttons and accent elements across the app.": "The primary color affects buttons and accent elements across the app.", - "Export CSV": "Export CSV", - "Export": "Export", - "Export as CSV": "Export as CSV", - "Export for Excel": "Export for Excel", - "State": "State", - "Edit": "Edit", - "Status": "Status", - "Visibility": "Visibility", - "Inactive entries are hidden in lists and selections.": "Inactive entries are hidden in lists and selections.", - "All": "All", - "Explorer": "Explorer", - "Search": "Search", - "Search...": "Search...", - "Search users, tenants, pages...": "Search users, tenants, pages...", - "Users, tenants, departments, roles and more": "Users, tenants, departments, roles and more", - "Searching...": "Searching...", - "Search failed. Please try again.": "Search failed. Please try again.", - "No results found": "No results found", - "View all results": "View all results", - "navigate": "navigate", - "open": "open", - "close": "close", - "Created from": "Created from", - "Created to": "Created to", - "Settings": "Settings", - "Documentation": "Documentation", - "Documentation navigation": "Documentation navigation", - "On this page": "On this page", - "Getting started": "Getting started", - "Architecture & rules": "Architecture & rules", - "Frontend": "Frontend", - "Features": "Features", - "API reference": "API reference", - "Operations": "Operations", - "Automation & integrations": "Automation & integrations", - "Logs": "Logs", - "System": "System", - "System permission": "System permission", - "System permission can not be deleted": "System permission can not be deleted", - "System permissions are core and should rarely be disabled.": "System permissions are core and should rarely be disabled.", - "Statistics": "Statistics", - "Active users": "Active users", - "Inactive users": "Inactive users", - "Sent emails": "Sent emails", - "Primary navigation": "Primary navigation", - "Footer navigation": "Footer navigation", - "Language switcher": "Language switcher", - "Sort column ascending": "Sort column ascending", - "Sort column descending": "Sort column descending", - "Previous": "Previous", - "Next": "Next", - "Navigation": "Navigation", - "Display": "Display", - "Session": "Session", - "Page %d of %d": "Page %d of %d", - "Page %d": "Page %d", - "Per page": "Per page", - "Skip to main content": "Skip to main content", - "Rows per page": "Rows per page", - "Showing": "Showing", - "of": "of", - "to": "to", - "results": "results", - "Loading...": "Loading...", - "No records found": "No records found", - "An error happened while fetching the data": "An error happened while fetching the data", - "Delete this user?": "Delete this user?", - "Delete user": "Delete user", - "This will permanently delete this user.": "This will permanently delete this user.", - "Delete this tenant?": "Delete this tenant?", - "Delete tenant": "Delete tenant", - "This will permanently delete this tenant.": "This will permanently delete this tenant.", - "Tenant": "Tenant", - "Default tenant": "Default tenant", - "Default role": "Default role", - "Default department": "Default department", - "Default": "Default", - "Access & password": "Access & password", - "Security": "Security", - "Preferences": "Preferences", - "My account": "My account", - "None": "None", - "Settings updated": "Settings updated", - "setting.default_tenant": "Default tenant used when no tenant is assigned on user creation", - "setting.default_role": "Default role used when no role is assigned on user creation", - "setting.default_department": "Default department used when no department is assigned on user creation", - "setting.app_title": "App title shown in the browser title bar", - "setting.app_locale": "Default language used when no user or URL locale is set", - "Default language": "Default language", - "setting.app_registration": "Allow public self-registration", - "setting.api_token_default_ttl_days": "Default lifetime for newly created API tokens in days (default: 90)", - "setting.api_token_max_ttl_days": "Maximum lifetime for API tokens in days (hard cap)", - "setting.api_cors_allowed_origins": "Allowed browser origins for API CORS (one origin per line)", - "API token default lifetime (days)": "API token default lifetime (days)", - "API token maximum lifetime (days)": "API token maximum lifetime (days)", - "Allowed CORS origins": "Allowed CORS origins", - "One origin per line, e.g. https://app.example.com": "One origin per line, e.g. https://app.example.com", - "Default theme": "Default theme", - "Allow user theme": "Allow user theme", - "Allow registration": "Allow registration", - "Appearance": "Appearance", - "API docs": "API docs", - "Can view API documentation": "Can view API documentation", - "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.": "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.", - "Users may choose their own theme": "Users may choose their own theme", - "Controls whether users in this tenant can override the tenant default with a personal theme preference.": "Controls whether users in this tenant can override the tenant default with a personal theme preference.", - "The theme used for users in this tenant who have no personal preference.": "The theme used for users in this tenant who have no personal preference.", - "Inactive tenants are excluded from user access and tenant-scoped data.": "Inactive tenants are excluded from user access and tenant-scoped data.", - "Status & meta": "Status & meta", - "Audit": "Audit", - "Overview": "Overview", - "Choose color": "Choose color", - "Code": "Code", - "Cost center": "Cost center", - "Department code already exists": "Department code already exists", - "Role code already exists": "Role code already exists", - "Internationalization": "Internationalization", - "User creation rules": "User creation rules", - "App title": "App title", - "Tenants": "Tenants", - "Create tenant": "Create tenant", - "Edit tenant": "Edit tenant", - "View tenant": "View tenant", - "Tenant created": "Tenant created", - "Tenant updated": "Tenant updated", - "Tenant deleted": "Tenant deleted", - "Tenant not found": "Tenant not found", - "Tenant can not be deleted while departments are assigned": "Tenant can not be deleted while departments are assigned", - "Tenant can not be created": "Tenant can not be created", - "Tenant can not be updated": "Tenant can not be updated", - "Assigned tenants": "Assigned tenants", - "Assigned tenant": "Assigned tenant", - "Primary tenant": "Primary tenant", - "Select primary tenant": "Select primary tenant", - "Please select a primary tenant": "Please select a primary tenant", - "Primary tenant must be one of the assigned tenants": "Primary tenant must be one of the assigned tenants", - "Department assignments cleaned: %d": "Department assignments cleaned: %d", - "Select tenants": "Select tenants", - "Select tenant": "Select tenant", - "Assigned roles": "Assigned roles", - "Select roles": "Select roles", - "Department": "Department", - "Departments": "Departments", - "Create department": "Create department", - "Edit department": "Edit department", - "View department": "View department", - "Department created": "Department created", - "Department updated": "Department updated", - "Department deleted": "Department deleted", - "Department not found": "Department not found", - "Department can not be created": "Department can not be created", - "Department can not be updated": "Department can not be updated", - "Department can not be deleted while users are assigned": "Department can not be deleted while users are assigned", - "Delete this department?": "Delete this department?", - "Delete department": "Delete department", - "This will permanently delete this department.": "This will permanently delete this department.", - "Assigned departments": "Assigned departments", - "Select departments": "Select departments", - "Departments for tenant": "Departments for tenant", - "No departments available for this tenant": "No departments available for this tenant", - "Assign tenants first to select departments": "Assign tenants first to select departments", - "No tenants available": "No tenants available", - "No tenant is available in your current scope.": "No tenant is available in your current scope.", - "Role": "Role", - "Roles": "Roles", - "No roles available": "No roles available", - "No roles selected": "No roles selected", - "Remove role": "Remove role", - "Search roles…": "Search roles…", - "Assignable roles": "Assignable roles", - "Create role": "Create role", - "Edit role": "Edit role", - "View role": "View role", - "Role created": "Role created", - "Role updated": "Role updated", - "Role deleted": "Role deleted", - "Role not found": "Role not found", - "Role can not be created": "Role can not be created", - "Role can not be updated": "Role can not be updated", - "Delete this role?": "Delete this role?", - "Delete role": "Delete role", - "Delete permission": "Delete permission", - "This will permanently delete this role.": "This will permanently delete this role.", - "This will permanently delete this permission.": "This will permanently delete this permission.", - "Description": "Description", - "Description cannot be empty": "Description cannot be empty", - "Status is invalid": "Status is invalid", - "Address": "Address", - "Postal code": "Postal code", - "City": "City", - "Country": "Country", - "Mail logs": "Mail logs", - "Mail log": "Mail log", - "View mail log": "View mail log", - "Mail log not found": "Mail log not found", - "Email details": "Email details", - "Recipient": "Recipient", - "Subject": "Subject", - "Template": "Template", - "Sent": "Sent", - "Failed": "Failed", - "Queued": "Queued", - "Error message": "Error message", - "Error information": "Error information", - "Provider message ID": "Provider message ID", - "Sent at": "Sent at", - "Created at": "Created at", - "Delivery information": "Delivery information", - "All statuses": "All statuses", - "Contact": "Contact", - "Support": "Support", - "Support email": "Support email", - "Support phone": "Support phone", - "No contact details available": "No contact details available", - "VAT ID": "VAT ID", - "Tax number": "Tax number", - "Billing email": "Billing email", - "Phone": "Phone", - "Website": "Website", - "Legal": "Legal", - "No legal links configured": "No legal links configured", - "Privacy URL": "Privacy URL", - "Imprint URL": "Imprint URL", - "Region": "Region", - "Fax": "Fax", - "Back": "Back", - "Access denied": "Access denied", - "You do not have permission to view this content.": "You do not have permission to view this content.", - "If you believe this is an error, please contact your system administrator.": "If you believe this is an error, please contact your system administrator.", - "Requested URL": "Requested URL", - "Forward": "Forward", - "Status changed": "Status changed", - "Status changed by": "Status changed by", - "Requested path": "Requested path", - "Page not found": "Page not found", - "The page you requested does not exist or has moved.": "The page you requested does not exist or has moved.", - "Back to start": "Back to start", - "Page updated": "Page updated", - "Page can not be updated": "Page can not be updated", - "Content is invalid": "Content is invalid", - "You are not allowed to edit this page": "You are not allowed to edit this page", - "Form expired, please try again": "Form expired, please try again", - "Start writing...": "Start writing...", - "View": "View", - "Heading": "Heading", - "Copy content to": "Copy content to", - "Existing content in the target language will be overwritten": "Existing content in the target language will be overwritten", - "Content copied": "Content copied", - "Target language required": "Target language required", - "Source content not found": "Source content not found", - "Employment": "Employment", - "Job title": "Job title", - "Hire date": "Hire date", - "German": "German", - "English": "English", - "Switch tenant": "Switch tenant", - "Copy": "Copy", - "Copy to clipboard": "Copy to clipboard", - "Registration successful! Please check your email for the verification code.": "Registration successful! Please check your email for the verification code.", - "Registration is currently disabled": "Registration is currently disabled.", - "A new verification code has been sent.": "A new verification code has been sent.", - "Email already verified. Please login.": "Email already verified. Please login.", - "If the email exists, a new verification code has been sent.": "If the email exists, a new verification code has been sent.", - "Email verified successfully! Please login.": "Email verified successfully! Please login.", - "Too many failed attempts. Please request a new code.": "Too many failed attempts. Please request a new code.", - "Verify email": "Verify email", - "Enter the verification code we sent to your email to complete your registration.": "Enter the verification code we sent to your email to complete your registration.", - "Email verified": "Email verified", - "Not verified": "Not verified", - "Verified": "Verified", - "SMTP host": "SMTP host", - "SMTP port": "SMTP port", - "SMTP user": "SMTP user", - "SMTP password": "SMTP password", - "SMTP security": "SMTP security", - "SMTP from address": "SMTP from address", - "SMTP from name": "SMTP from name", - "Mobile": "Mobile", - "Short dial": "Short dial", - "setting.smtp_host": "SMTP server host (e.g. smtp.example.com)", - "setting.smtp_port": "SMTP port (e.g. 587)", - "setting.smtp_user": "SMTP username", - "setting.smtp_password": "Leave empty to keep the existing password", - "setting.smtp_secure": "SMTP encryption method", - "setting.smtp_from": "From address for outgoing emails", - "setting.smtp_from_name": "From name for outgoing emails", - "High contrast": "High contrast", - "Toggle contrast": "Toggle contrast", - "Email security": "Email security", - "API": "API", - "API requests (24h)": "API requests (24h)", - "Request trend vs previous 24h": "Request trend vs previous 24h", + "0 disables this rule": "0 disables this rule", + "1. Upload CSV and click analyze": "1. Upload CSV and click analyze", + "2. Map your CSV columns to system fields": "2. Map your CSV columns to system fields", + "3. Review preview counters and row errors": "3. Review preview counters and row errors", + "4. Start import for valid rows": "4. Start import for valid rows", "4xx errors (24h)": "4xx errors (24h)", "5xx errors (24h)": "5xx errors (24h)", - "P95 response time (ms)": "P95 response time (ms)", - "Tokens expiring in 7 days": "Tokens expiring in 7 days", - "Top API error codes (24h)": "Top API error codes (24h)", - "Slowest API endpoints (avg, 24h)": "Slowest API endpoints (avg, 24h)", - "Import runs (7d)": "Import runs (7d)", - "Created rows (7d)": "Created rows (7d)", - "Failed rows (7d)": "Failed rows (7d)", - "Success rate (7d)": "Success rate (7d)", - "Recent import runs": "Recent import runs", - "Imports by profile (7d)": "Imports by profile (7d)", - "Top import error codes (7d)": "Top import error codes (7d)", - "Runs": "Runs", - "Created rows": "Created rows", - "Failed rows": "Failed rows", - "Success rate": "Success rate", - "Requests": "Requests", - "Average duration (ms)": "Average duration (ms)", - "Maximum duration (ms)": "Maximum duration (ms)", - "Error": "Error", - "Active tenants": "Active tenants", - "Inactive tenants": "Inactive tenants", - "Active departments": "Active departments", - "Inactive departments": "Inactive departments", - "Active roles": "Active roles", - "Inactive roles": "Inactive roles", - "Roles without permissions": "Roles without permissions", - "Permissions without roles": "Permissions without roles", - "Users without roles": "Users without roles", - "Users without tenants": "Users without tenants", - "Mail failures": "Mail failures", - "Last email sent": "Last email sent", - "Never": "Never", - "Recent logins": "Recent logins", - "Never logged in": "Never logged in", - "Last login": "Last login", - "Last login via": "Last login via", - "Local": "Local", - "Microsoft": "Microsoft", - "Unknown": "Unknown", - "User": "User", - "No entries found": "No entries found", - "Login status": "Login status", - "Logged in": "Logged in", - "Email unverified": "Email unverified", - "Password resets": "Password resets", - "No password reset requests": "No password reset requests", - "No reset has been requested for this account yet.": "No reset has been requested for this account yet.", - "Requested at": "Requested at", - "Expires at": "Expires at", - "Used at": "Used at", - "Attempts": "Attempts", - "Used": "Used", - "Expired": "Expired", - "Expired by admin": "Expired by admin", - "Login tokens": "Login tokens", - "No login tokens": "No login tokens", - "This user is currently not signed in via remember-me.": "This user is currently not signed in via remember-me.", - "Expire all login tokens": "Expire all login tokens", - "Expire all login tokens?": "Expire all login tokens?", - "%d active login tokens": "%d active login tokens", - "%d login tokens expired": "%d login tokens expired", - "Danger zone": "Danger zone", - "This will mark all remember-me tokens as expired. Users will need to sign in again.": "This will mark all remember-me tokens as expired. Users will need to sign in again.", - "Last used": "Last used", - "Keyboard shortcuts": "Keyboard shortcuts", - "Open search": "Open search", - "Save in edit pages": "Save in edit pages", - "Unsaved changes": "Unsaved changes", - "Unsaved change (%d field)": "Unsaved change (%d field)", - "Unsaved changes (%d fields)": "Unsaved changes (%d fields)", - "Please review the following errors": "Please review the following errors", - "You have unsaved changes. Leave without saving?": "You have unsaved changes. Leave without saving?", - "Switch sidebar section": "Switch sidebar section", + "A new verification code has been sent.": "A new verification code has been sent.", + "About": "About", + "Access & password": "Access & password", + "Access and profile sync": "Access and profile sync", + "Access denied": "Access denied", + "Access email failed": "Access email failed", + "Access email sent": "Access email sent", + "Access emails sent to %d users": "Access emails sent to %d users", + "Access emails sent to %d users, %f failed": "Access emails sent to %d users, %f failed", + "Access PDF": "Access PDF", + "Account": "Account", + "Account is inactive": "Account is inactive", "Action": "Action", - "Mac": "Mac", - "Windows": "Windows", - "Email verification code": "Email verification code", - "Failed to switch tenant": "Failed to switch tenant", - "IDs": "IDs", - "Pages": "Pages", - "Permission": "Permission", - "No effective permissions": "No effective permissions", - "Assign at least one role to show effective permissions.": "Assign at least one role to show effective permissions.", - "Please verify your email first": "Please verify your email first", - "Toggle sidebar": "Toggle sidebar", - "Unverified": "Unverified", - "Imprint": "Imprint", - "Privacy": "Privacy", - "Terms of Service": "Terms of Service", - "Custom fields": "Custom fields", - "User custom fields": "User custom fields", - "Affected tenants": "Affected tenants", - "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).": "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).", - "Issue": "Issue", - "Count": "Count", - "Selection fields without options": "Selection fields without options", - "Tenants with broken selection fields": "Tenants with broken selection fields", - "Inactive custom fields with values": "Inactive custom fields with values", - "Unused active custom fields": "Unused active custom fields", - "Save tenant first to manage custom fields": "Save tenant first to manage custom fields", - "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.": "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.", + "Actions": "Actions", + "Activate": "Activate", + "Activate users?": "Activate users?", + "Active": "Active", + "Active departments": "Active departments", + "Active Modules": "Active Modules", + "Active modules": "Active modules", + "Active permissions": "Active permissions", + "Active roles": "Active roles", + "Active tenants": "Active tenants", + "Active users": "Active users", + "Active value is invalid": "Active value is invalid", + "Actor": "Actor", + "Actor tenant": "Actor tenant", + "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID": "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID", "Add custom field": "Add custom field", - "The label is shown in user custom fields and in address book filters.": "The label is shown in user custom fields and in address book filters.", - "The field type controls input and filter behavior.": "The field type controls input and filter behavior.", - "Field type": "Field type", - "Text": "Text", - "Textarea": "Textarea", - "Select": "Select", - "Multiselect": "Multiselect", - "Boolean": "Boolean", - "Date": "Date", - "Filterable": "Filterable", - "Options (one per line)": "Options (one per line)", - "Example: manager|Manager": "Example: manager|Manager", - "One option per line. Optional format: key|Label.": "One option per line. Optional format: key|Label.", - "No custom fields configured yet": "No custom fields configured yet", - "Delete custom field": "Delete custom field", - "Custom field saved": "Custom field saved", - "Custom field deleted": "Custom field deleted", - "Custom field can not be created": "Custom field can not be created", - "Custom field can not be updated": "Custom field can not be updated", - "Custom field can not be deleted": "Custom field can not be deleted", - "Custom field values can not be saved": "Custom field values can not be saved", - "Custom field not found": "Custom field not found", - "Label cannot be empty": "Label cannot be empty", - "Field key cannot be empty": "Field key cannot be empty", - "Field type is invalid": "Field type is invalid", - "Field key already exists": "Field key already exists", - "Options are required for this field type": "Options are required for this field type", - "Assign tenants first to edit custom fields": "Assign tenants first to edit custom fields", - "Custom fields for tenant": "Custom fields for tenant", - "No custom fields configured for this tenant": "No custom fields configured for this tenant", - "No custom fields configured for selected tenants": "No custom fields configured for selected tenants", - "Select options": "Select options", - "Invalid value for %s": "Invalid value for %s", - "Please select": "Please select", - "perm.custom_fields.manage": "Manage tenant custom fields", - "perm.custom_fields.edit_values": "Edit user custom field values", - "Label": "Label", - "Required": "Required", - "Filterable fields are available in address book filters.": "Filterable fields are available in address book filters.", - "Inactive fields are hidden in forms and filters.": "Inactive fields are hidden in forms and filters.", - "Default theme is invalid": "Default theme is invalid", - "Theme change is disabled for this tenant": "Theme change is disabled for this tenant", - "Controls whether users in this tenant can choose their own theme.": "Controls whether users in this tenant can choose their own theme.", - "Tenants can override color and theme behavior in their appearance settings.": "Tenants can override color and theme behavior in their appearance settings.", - "User theme policy": "User theme policy", - "APP_CRYPTO_KEY is missing or invalid": "APP_CRYPTO_KEY is missing or invalid", + "Address": "Address", + "Admin": "Admin", + "Administrator check could not be executed": "Administrator check could not be executed", + "Administrators": "Administrators", + "Advanced telemetry options": "Advanced telemetry options", + "Affected tenants": "Affected tenants", + "AJAX errors": "AJAX errors", + "All": "All", + "All channels": "All channels", + "All filters cleared": "All filters cleared", + "All methods": "All methods", + "All outcomes": "All outcomes", + "All profiles": "All profiles", + "All required core tables are present": "All required core tables are present", + "All statuses": "All statuses", + "All systems operational": "All systems operational", + "All triggers": "All triggers", + "Allow LDAP-only login (disable local password login)": "Allow LDAP-only login (disable local password login)", + "Allow Microsoft-only login (disable local password login)": "Allow Microsoft-only login (disable local password login)", + "Allow registration": "Allow registration", + "Allow user theme": "Allow user theme", + "Allowed CORS origins": "Allowed CORS origins", "Allowed email domains": "Allowed email domains", + "Allowed file types: PNG": "Allowed file types: PNG", + "Allowed file types: SVG, PNG, JPG, WEBP": "Allowed file types: SVG, PNG, JPG, WEBP", + "Allowed range: 1-365 days (default: 30)": "Allowed range: 1-365 days (default: 30)", + "Allowed range: 1-72 hours (default: 8)": "Allowed range: 1-72 hours (default: 8)", + "Allowed range: 5-1440 minutes (default: 30)": "Allowed range: 5-1440 minutes (default: 30)", + "Allowed telemetry events": "Allowed telemetry events", + "An error happened while fetching the data": "An error happened while fetching the data", + "An error occurred": "An error occurred", + "An unexpected error occurred. If the problem persists, please contact support with the reference below.": "An unexpected error occurred. If the problem persists, please contact support with the reference below.", + "Analyze file": "Analyze file", + "API": "API", + "API audit": "API logs", + "API audit entry not found": "API log entry not found", + "API audit logs": "API logs", + "API docs": "API docs", + "API reference": "API reference", + "API requests (24h)": "API requests (24h)", + "API settings": "API settings", + "API token created. Copy it now — it will not be shown again.": "API token created. Copy it now — it will not be shown again.", + "API token default lifetime (days)": "API token default lifetime (days)", + "API token default lifetime is invalid": "API token default lifetime is invalid", + "API token max lifetime is invalid": "API token max lifetime is invalid", + "API token maximum lifetime (days)": "API token maximum lifetime (days)", + "API token policy and CORS allowlist": "API token policy and CORS allowlist", + "API token revoked": "API token revoked", + "API tokens": "API tokens", + "App credentials (advanced)": "App credentials (advanced)", + "App identity": "App identity", + "App logo": "App logo", + "App logo and favicon": "App logo and favicon", + "App title": "App title", + "App title, language, user creation defaults": "App title, language, user creation defaults", + "APP_CRYPTO_KEY is missing or invalid": "APP_CRYPTO_KEY is missing or invalid", + "Appearance": "Appearance", + "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.": "Appearance is controlled per tenant. Every tenant carries its own primary color and default theme.", + "Application": "Application", + "Apply filters": "Apply filters", + "Architecture & rules": "Architecture & rules", + "Assign at least one role to show effective permissions.": "Assign at least one role to show effective permissions.", + "Assign tenants first to edit custom fields": "Assign tenants first to edit custom fields", + "Assign tenants first to select departments": "Assign tenants first to select departments", + "Assignable roles": "Assignable roles", + "Assigned departments": "Assigned departments", + "Assigned permissions": "Assigned permissions", + "Assigned roles": "Assigned roles", + "Assigned tenant": "Assigned tenant", + "Assigned tenants": "Assigned tenants", + "Assignment columns require additional permission.": "Assignment columns require additional permission.", + "Assignment import permission is required": "Assignment import permission is required", + "At least %d characters": "At least %d characters", + "At least one administrator is active": "At least one administrator is active", + "At least one lowercase letter": "At least one lowercase letter", + "At least one number": "At least one number", + "At least one symbol": "At least one symbol", + "At least one uppercase letter": "At least one uppercase letter", + "At least one weekday is required for weekly schedule": "At least one weekday is required for weekly schedule", + "Attempts": "Attempts", + "Attribute mapping and sync": "Attribute mapping and sync", + "Audit": "Audit", + "Authority endpoint": "Authority endpoint", "Authority URL": "Authority URL", + "Auto-delete is ignored while auto-deactivate is disabled": "Auto-delete is ignored while auto-deactivate is disabled", + "Automation & integrations": "Automation & integrations", + "Avatar": "Avatar", + "Avatar removed": "Profile image removed", + "Avatar updated": "Profile image updated", + "Average duration (ms)": "Average duration (ms)", + "Back": "Back", + "Back to login": "Back to login", + "Back to start": "Back to start", + "Bad Gateway": "Bad Gateway", + "Bad Request": "Bad Request", + "Base DN": "Base DN", + "Baseline permissions are missing": "Baseline permissions are missing", + "Baseline permissions are present": "Baseline permissions are present", + "Billing email": "Billing email", + "Bind DN (service account)": "Bind DN (service account)", + "Bind DN could not be decrypted": "Bind DN could not be decrypted", + "Bind DN could not be encrypted": "Bind DN could not be encrypted", + "Bind method": "Bind method", + "Bind password": "Bind password", + "Bind password could not be decrypted": "Bind password could not be decrypted", + "Bind password could not be encrypted": "Bind password could not be encrypted", + "Boolean": "Boolean", + "Brand color": "Brand color", + "Branding": "Branding", + "Branding settings": "Branding settings", + "Breadcrumb": "Breadcrumb", + "Cached": "Cached", + "Call": "Call", + "Can view API documentation": "Can view API documentation", + "Cancel": "Cancel", + "Catch up once": "Catch up once", + "Caused by": "Caused by", + "Channel": "Channel", + "Check": "Check", + "Choose a new password for your account.": "Choose a new password for your account.", + "Choose color": "Choose color", + "City": "City", + "Clear all filters": "Clear all filters", + "Clear all login tokens for this user?": "Clear all login tokens for this user?", + "Clear bind password": "Clear bind password", + "Clear login tokens": "Clear login tokens", "Clear override secret": "Clear override secret", + "Client credentials are missing": "Client credentials are missing", "Client ID override": "Client ID override", "Client ID override is required": "Client ID override is required", "Client secret could not be encrypted": "Client secret could not be encrypted", "Client secret override": "Client secret override", + "Client secret override is invalid": "Client secret override is invalid", "Client secret override is required": "Client secret override is required", + "Close": "Close", + "close": "close", + "Close filters": "Close filters", + "Close navigation": "Close navigation", + "Code": "Code", + "Code already exists": "Code already exists", + "Code verified": "Code verified", + "Complete": "Complete", + "Complete the required Microsoft configuration before enforcing Microsoft-only login.": "Complete the required Microsoft configuration before enforcing Microsoft-only login.", + "Components": "Components", + "Concepts": "Concepts", + "Configuration complete": "Configuration complete", + "Configuration status": "Configuration status", + "Configured": "Configured", + "Confirm": "Confirm", + "Connection established": "Connection established", + "Contact": "Contact", + "Content copied": "Content copied", + "Content is invalid": "Content is invalid", + "Context": "Context", + "Continue": "Continue", + "Contributor guide": "Contributor guide", + "Controls remember-me token lifetime and Microsoft auto-remember behavior.": "Controls remember-me token lifetime and Microsoft auto-remember behavior.", + "Controls whether Microsoft logins automatically persist a remember-me token.": "Controls whether Microsoft logins automatically persist a remember-me token.", + "Controls whether users in this tenant can choose their own theme.": "Controls whether users in this tenant can choose their own theme.", + "Controls whether users in this tenant can override the tenant default with a personal theme preference.": "Controls whether users in this tenant can override the tenant default with a personal theme preference.", + "Copy": "Copy", + "Copy content to": "Copy content to", + "Copy email address": "Copy email address", + "Copy mobile number": "Copy mobile number", + "Copy phone number": "Copy phone number", + "Copy request ID": "Copy request ID", + "Copy to clipboard": "Copy to clipboard", + "CORS allowed origins are invalid": "CORS allowed origins are invalid", + "CORS allowlist": "CORS allowlist", + "Cost center": "Cost center", + "Could not create API token: %s": "Could not create API token: %s", + "Count": "Count", + "Counters": "Counters", + "Country": "Country", + "Create": "Create", + "Create & close": "Create & close", + "Create a token to enable API access for this user.": "Create a token to enable API access for this user.", + "Create API token": "Create API token", + "Create department": "Create department", + "Create permission": "Create permission", + "Create role": "Create role", + "Create tenant": "Create tenant", + "Create user": "Create user", + "Create your account": "Create your account", + "Create-only: existing entries are skipped": "Create-only: existing entries are skipped", + "Created": "Created", + "Created at": "Created at", + "Created by": "Created by", + "Created count": "Created count", + "Created from": "Created from", + "Created rows": "Created rows", + "Created rows (7d)": "Created rows (7d)", + "Created to": "Created to", + "Credentials source": "Credentials source", + "Cron": "Cron", + "Cron runner active": "Cron runner active", + "CSV file": "CSV file", + "CSV file has no data rows": "CSV file has no data rows", + "CSV header": "CSV header", + "CSV header is invalid": "CSV header is invalid", + "CSV row limit exceeded": "CSV row limit exceeded", + "Current image": "Current image", + "Current tenant": "Current tenant", + "Custom field can not be created": "Custom field can not be created", + "Custom field can not be deleted": "Custom field can not be deleted", + "Custom field can not be updated": "Custom field can not be updated", + "Custom field deleted": "Custom field deleted", + "Custom field not found": "Custom field not found", + "Custom field saved": "Custom field saved", + "Custom field values can not be saved": "Custom field values can not be saved", + "Custom fields": "Custom fields", + "Custom fields for tenant": "Custom fields for tenant", + "Daily": "Daily", + "Daily interval must be between 1 and 365": "Daily interval must be between 1 and 365", + "Danger zone": "Danger zone", + "Dark": "Dark", + "Dark logo": "Dark logo", + "Database": "Database", + "Database check could not be executed": "Database check could not be executed", + "Database did not return the expected response": "Database did not return the expected response", + "Database schema": "Database schema", + "Date": "Date", + "days": "days", + "Deactivate": "Deactivate", + "Deactivate users after inactivity (days)": "Deactivate users after inactivity (days)", + "Deactivate users?": "Deactivate users?", + "Default": "Default", + "Default department": "Default department", + "Default language": "Default language", + "Default role": "Default role", + "Default tenant": "Default tenant", + "Default theme": "Default theme", + "Default theme is invalid": "Default theme is invalid", + "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.": "Define custom fields here. They appear per user in the \"Custom fields\" tab and can be maintained there.", + "Define which origins may call your API from browsers. Use one origin per line.": "Define which origins may call your API from browsers. Use one origin per line.", + "Degraded service": "Degraded service", + "Delete": "Delete", + "Delete custom field": "Delete custom field", + "Delete dark logo": "Delete dark logo", + "Delete department": "Delete department", + "Delete inactive users after (days)": "Delete inactive users after (days)", + "Delete light logo": "Delete light logo", + "Delete permission": "Delete permission", + "Delete role": "Delete role", + "Delete tenant": "Delete tenant", + "Delete this department?": "Delete this department?", + "Delete this favicon?": "Delete this favicon?", + "Delete this image?": "Delete this image?", + "Delete this logo?": "Delete this logo?", + "Delete this permission?": "Delete this permission?", + "Delete this role?": "Delete this role?", + "Delete this tenant?": "Delete this tenant?", + "Delete this user?": "Delete this user?", + "Delete user": "Delete user", + "Delete users?": "Delete users?", + "Delivery information": "Delivery information", + "Denied": "Denied", + "Department": "Department", + "Department already exists for this tenant": "Department already exists for this tenant", + "Department assignments cleaned: %d": "Department assignments cleaned: %d", + "Department can not be created": "Department can not be created", + "Department can not be deleted while users are assigned": "Department can not be deleted while users are assigned", + "Department can not be updated": "Department can not be updated", + "Department code already exists": "Department code already exists", + "Department created": "Department created", + "Department deleted": "Department deleted", + "Department does not belong to tenant": "Department does not belong to tenant", + "Department is missing, inactive or invalid": "Department is missing, inactive or invalid", + "Department not found": "Department not found", + "Department updated": "Department updated", + "Departments": "Departments", + "Departments for tenant": "Departments for tenant", + "Dependencies": "Dependencies", + "Description": "Description", + "Description cannot be empty": "Description cannot be empty", + "Details": "Details", + "Direct bind": "Direct bind", + "Direct bind method requires a username format": "Direct bind method requires a username format", + "Direct bind username format": "Direct bind username format", + "Disabled": "Disabled", + "Display": "Display", + "Documentation": "Documentation", + "Documentation navigation": "Documentation navigation", + "Download access PDFs": "Download access PDFs", + "Download sample CSV": "Download sample CSV", + "Drop file here or click to select": "Drop file here or click to select", + "Duplicate entry in CSV file": "Duplicate entry in CSV file", + "Duration (ms)": "Duration (ms)", + "e.g. CI Pipeline": "e.g. CI Pipeline", + "Edit": "Edit", + "Edit department": "Edit department", + "Edit permission": "Edit permission", + "Edit role": "Edit role", + "Edit scheduled job": "Edit scheduled job", + "Edit tenant": "Edit tenant", + "Edit user": "Edit user", + "Email": "Email", + "Email already exists": "Email already exists", + "Email already verified. Please login.": "Email already verified. Please login.", + "Email cannot be empty": "Email cannot be empty", + "Email details": "Email details", + "Email is already taken": "Email is already taken", + "Email is invalid": "Email is invalid", + "Email is not valid": "Email is not valid", + "Email security": "Email security", + "Email settings": "Email settings", + "Email unverified": "Email unverified", + "Email verification code": "Email verification code", + "Email verified": "Email verified", + "Email verified successfully! Please login.": "Email verified successfully! Please login.", + "Email/password not valid": "Email or password is invalid", + "Employment": "Employment", + "Enable frontend telemetry": "Enable frontend telemetry", + "Enable LDAP login for this tenant": "Enable LDAP login for this tenant", "Enable Microsoft login for this tenant": "Enable Microsoft login for this tenant", + "Enable system audit log": "Enable system audit log", + "Enabled": "Enabled", + "Enabled jobs": "Enabled jobs", + "Encrypted connection": "Encrypted", + "Encryption": "Encryption", + "English": "English", + "Enter the verification code we sent to your email to complete your registration.": "Enter the verification code we sent to your email to complete your registration.", + "Enter the verification code we sent to your email.": "Enter the verification code we sent to your email.", + "Enter your email address and we will send you a verification code.": "Enter your email address and we will send you a verification code.", "Entra tenant ID (tid)": "Entra tenant ID (tid)", "Entra tenant ID is invalid": "Entra tenant ID is invalid", - "Microsoft SSO": "Microsoft SSO", + "Entry could not be created": "Entry could not be created", + "Environment": "Environment", + "Error": "Error", + "Error code": "Error code", + "Error code distribution": "Error code distribution", + "Error details": "Error details", + "Error information": "Error information", + "Error message": "Error message", + "Event": "Event", + "Event details": "Event details", + "Event type": "Event type", + "Every %d day(s) at %s": "Every %d day(s) at %s", + "Every %d hour(s)": "Every %d hour(s)", + "Every %d week(s) on %s at %s": "Every %d week(s) on %s at %s", + "Example: manager|Manager": "Example: manager|Manager", + "Exception": "Exception", + "Existing content in the target language will be overwritten": "Existing content in the target language will be overwritten", + "Expire all login tokens": "Expire all login tokens", + "Expire all login tokens?": "Expire all login tokens?", + "Expired": "Expired", + "Expired by admin": "Expired by admin", + "Expires at": "Expires at", + "Explorer": "Explorer", + "Export": "Export", + "Export as CSV": "Export as CSV", + "Export CSV": "Export CSV", + "Export for Excel": "Export for Excel", + "Extend session": "Extend session", + "Fail": "Fail", + "Failed": "Failed", + "Failed count": "Failed count", + "Failed or denied": "Failed or denied", + "Failed rows": "Failed rows", + "Failed rows (7d)": "Failed rows (7d)", + "Failed scheduler runs (24h)": "Failed scheduler runs (24h)", + "Failed to activate users": "Failed to activate users", + "Failed to deactivate users": "Failed to deactivate users", + "Failed to delete users": "Failed to delete users", + "Failed to generate access PDF": "Failed to generate access PDF", + "Failed to load": "Failed to load", + "Failed to send access emails": "Failed to send access emails", + "Failed to switch tenant": "Failed to switch tenant", + "Failed to update permission roles": "Failed to update permission roles", + "Failed to update role permissions": "Failed to update role permissions", + "Favicon": "Favicon", + "Favicon removed": "Favicon removed", + "Favicon updated": "Favicon updated", + "Fax": "Fax", + "Features": "Features", + "Field key already exists": "Field key already exists", + "Field key cannot be empty": "Field key cannot be empty", + "Field type": "Field type", + "Field type is invalid": "Field type is invalid", + "File": "File", + "File is too large": "File is too large", + "Filter": "Filter", + "Filter removed": "Filter removed", + "Filterable": "Filterable", + "Filterable fields are available in address book filters.": "Filterable fields are available in address book filters.", + "Filters applied": "Filters applied", + "Finished": "Finished", + "First name": "First name", + "First name cannot be empty": "First name cannot be empty", + "Footer navigation": "Footer navigation", + "Forbidden": "Forbidden", + "Force off": "Force off", + "Force on": "Force on", + "Forgot password": "Forgot password", + "Form expired, please try again": "Form expired, please try again", + "Forward": "Forward", + "Fri": "Fri", + "Frontend": "Frontend", + "Frontend telemetry": "Frontend telemetry", + "General": "General", + "General settings": "General settings", + "Generate access PDFs for selected users?": "Generate access PDFs for selected users?", + "German": "German", + "GET Parameters": "GET Parameters", + "Getting started": "Getting started", + "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.": "Global settings are stored in the database. storage/runtime/settings.php is only a runtime cache for selected app settings.", + "Headers": "Headers", + "Heading": "Heading", + "Health Status": "Health Status", + "Here is a CSV template for this import profile.": "Here is a CSV template for this import profile.", + "Hide password": "Hide password", + "High contrast": "High contrast", + "Hire date": "Hire date", + "Hire date must be YYYY-MM-DD": "Hire date must be YYYY-MM-DD", + "Hired": "Hired", + "Home": "Home", + "Hourly": "Hourly", + "Hourly interval must be between 1 and 24": "Hourly interval must be between 1 and 24", + "How the import works": "How the import works", + "How-to guides": "How-to guides", + "HTTPS/TLS 1.2+ in transit": "HTTPS/TLS 1.2+ in transit", + "ID": "ID", + "IDs": "IDs", + "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).": "If a tenant appears here, at least one custom field setup needs review (missing options, inactive fields with values, or unused active fields).", + "If the email exists, a new verification code has been sent.": "If the email exists, a new verification code has been sent.", + "If the email exists, a verification code has been sent.": "If the email exists, a verification code has been sent.", + "If you believe this is an error, please contact your system administrator.": "If you believe this is an error, please contact your system administrator.", + "Ignore column": "Ignore column", + "Import": "Import", + "Import another file": "Import another file", + "Import audit entry not found": "Import audit entry not found", + "Import audit logs": "Import audit logs", + "Import details": "Import details", + "Import finished": "Import finished", + "Import logs": "Import logs", + "Import runs (7d)": "Import runs (7d)", + "Imports": "Imports", + "Imports by profile (7d)": "Imports by profile (7d)", + "Imprint": "Imprint", + "Imprint URL": "Imprint URL", + "in %s on line %s": "in %s on line %s", + "Inactive": "Inactive", + "Inactive (orphaned) permissions": "Inactive (orphaned) permissions", + "Inactive custom fields with values": "Inactive custom fields with values", + "Inactive departments": "Inactive departments", + "Inactive entries are hidden in lists and selections.": "Inactive entries are hidden in lists and selections.", + "Inactive fields are hidden in forms and filters.": "Inactive fields are hidden in forms and filters.", + "Inactive roles": "Inactive roles", + "Inactive tenants": "Inactive tenants", + "Inactive tenants are excluded from user access and tenant-scoped data.": "Inactive tenants are excluded from user access and tenant-scoped data.", + "Inactive users": "Inactive users", + "Incomplete": "Incomplete", + "Inherit global default": "Inherit global default", + "Internal Server Error": "Internal Server Error", + "Internationalization": "Internationalization", + "Invalid file type": "Invalid file type", + "Invalid image file": "Invalid image file", + "Invalid or expired code": "Invalid or expired code", + "Invalid theme": "Invalid theme", + "Invalid value for %s": "Invalid value for %s", + "IP": "IP", + "IP hash": "IP hash", + "Issue": "Issue", + "Job": "Job", + "Job key": "Job key", + "Job title": "Job title", + "Keyboard shortcuts": "Keyboard shortcuts", + "Label": "Label", + "Label cannot be empty": "Label cannot be empty", + "Language": "Language", + "Language not supported": "Language not supported", + "Language switcher": "Language switcher", + "Last checked": "Last checked", + "Last email sent": "Last email sent", + "Last error": "Last error", + "Last heartbeat": "Last heartbeat", + "Last login": "Last login", + "Last login via": "Last login via", + "Last name": "Last name", + "Last name cannot be empty": "Last name cannot be empty", + "Last run": "Last run", + "Last runner result": "Last runner result", + "Last used": "Last used", + "LDAP": "LDAP", + "LDAP attribute map could not be encoded": "LDAP attribute map could not be encoded", + "LDAP base DN is required": "LDAP base DN is required", + "LDAP connection settings": "LDAP connection settings", + "LDAP Host": "LDAP Host", + "LDAP host is required": "LDAP host is required", + "LDAP login": "LDAP login", + "LDAP login is not available for this tenant.": "LDAP login is not available for this tenant.", + "LDAP port must be between 1 and 65535": "LDAP port must be between 1 and 65535", + "LDAP server is not reachable. Please try again later.": "LDAP server is not reachable. Please try again later.", + "LDAP setup is incomplete": "LDAP setup is incomplete", + "LDAP Username": "LDAP Username", + "LDAP-only login requires a complete configuration": "LDAP-only login requires a complete configuration", + "Learning path": "Learning path", + "Leave empty to keep the currently stored client secret.": "Leave empty to keep the currently stored client secret.", + "Leave empty to use the runtime default title.": "Leave empty to use the runtime default title.", + "Legal": "Legal", + "Lifecycle audit entry not found": "Lifecycle audit entry not found", + "Lifecycle event": "Lifecycle event", + "Lifecycle event was already restored": "Lifecycle event was already restored", + "Lifecycle risks (7d)": "Lifecycle risks (7d)", + "Lifecycle runs (7d)": "Lifecycle runs (7d)", + "Lifecycle snapshot unavailable": "Lifecycle snapshot unavailable", + "Light": "Light", + "Light logo": "Light logo", + "Limit which event types are collected to match your privacy and operations requirements.": "Limit which event types are collected to match your privacy and operations requirements.", + "Loaded Extensions (%d)": "Loaded Extensions (%d)", + "Loading": "Loading", + "Loading...": "Loading...", + "Local": "Local", + "Local password + Microsoft": "Local password + Microsoft", + "Local password only": "Local password only", + "Locale": "Locale", + "Locale is invalid": "Locale is invalid", + "Log out": "Log out", + "Logged in": "Logged in", + "Login": "Login", + "Login could not be completed. Please contact your administrator.": "Login could not be completed. Please contact your administrator.", + "Login credentials": "Login credentials", + "Login persistence": "Login persistence", + "Login policy": "Login policy", + "Login provider": "Login provider", + "Login required": "Login required", + "Login status": "Login status", + "Login tokens": "Login tokens", + "Login tokens cleared": "Login tokens cleared", + "Logo": "Logo", + "Logo removed": "Logo removed", + "Logo updated": "Logo updated", + "Logout": "Logout", + "Logs": "Logs", + "Mac": "Mac", + "Mail failures": "Mail failures", + "Mail log": "Mail log", + "Mail log not found": "Mail log not found", + "Mail logs": "Mail logs", + "Main menu": "Main menu", + "Manual": "Manual", + "Map application fields to LDAP directory attributes.": "Map application fields to LDAP directory attributes.", + "Mapped fields": "Mapped fields", + "Master data": "Master data", + "Max size 10MB, max 20000 rows": "Max size 10MB, max 20000 rows", + "Maximum duration (ms)": "Maximum duration (ms)", + "Memory (current)": "Memory (current)", + "Memory (peak)": "Memory (peak)", + "Message": "Message", + "Metadata": "Metadata", + "Method": "Method", + "Method Not Allowed": "Method Not Allowed", + "Microsoft": "Microsoft", + "Microsoft Auto-Remember default": "Microsoft Auto-Remember default", "Microsoft login": "Microsoft login", "Microsoft login could not be started": "Microsoft login could not be started", "Microsoft login failed": "Microsoft login failed", "Microsoft login is not allowed for this account": "Microsoft login is not allowed for this account", "Microsoft login is not available for this tenant": "Microsoft login is not available for this tenant", "Microsoft login was cancelled or failed": "Microsoft login was cancelled or failed", - "Microsoft-only login requires a complete configuration": "Microsoft-only login requires a complete configuration", - "No access to this tenant": "No access to this tenant", - "Shared credentials missing": "Shared credentials missing", - "Optional allow-list, comma or newline separated (example.com).": "Optional allow-list, comma or newline separated (example.com).", - "Password login is disabled for this tenant. Please use Microsoft login.": "Password login is disabled for this tenant. Please use Microsoft login.", - "Password login is disabled for all assigned tenants": "Password login is disabled for all assigned tenants", - "Password login mode": "Password login mode", - "Local password only": "Local password only", - "Local password + Microsoft": "Local password + Microsoft", - "Credentials source": "Credentials source", - "Shared app": "Shared app", - "Tenant override": "Tenant override", - "SSO configuration status": "SSO configuration status", - "Configuration complete": "Configuration complete", - "Required Microsoft configuration": "Required Microsoft configuration", - "Required for Microsoft login.": "Required for Microsoft login.", - "SSO": "SSO", - "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".": "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".", - "Shared client ID": "Shared client ID", - "Shared client secret": "Shared client secret", - "Sign in with Microsoft": "Sign in with Microsoft", - "Tenant SSO settings could not be saved": "Tenant SSO settings could not be saved", - "Tenant login link is invalid": "Tenant login link is invalid", - "Profile sync on Microsoft login": "Profile sync on Microsoft login", - "Sync fields": "Sync fields", - "Sync first name": "Sync first name", - "Sync last name": "Sync last name", - "Sync display name": "Sync display name", - "Sync job title": "Sync job title", - "Sync phone": "Sync phone", - "Sync mobile": "Sync mobile", - "Sync avatar image": "Sync avatar image", - "User profile fields are global and affect all tenants of this user": "User profile fields are global and affect all tenants of this user", - "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)": "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)", - "SSO-enabled tenants": "SSO-enabled tenants", - "SSO-enforced tenants": "SSO-enforced tenants", - "SSO rollout": "SSO rollout", - "Users with Microsoft-only login": "Users with Microsoft-only login", - "Microsoft profile sync gaps": "Microsoft profile sync gaps", "Microsoft only": "Microsoft only", - "Use shared app credentials from settings": "Use shared app credentials from settings", - "Override only if this tenant needs a separate Entra app.": "Override only if this tenant needs a separate Entra app.", - "Write-only. Leave empty to keep current secret.": "Write-only. Leave empty to keep current secret.", - "Client secret override is invalid": "Client secret override is invalid", - "Client credentials are missing": "Client credentials are missing", - "setting.microsoft_shared_client_id": "Setting key for shared Microsoft client ID", - "setting.microsoft_shared_client_secret_enc": "Setting key for shared Microsoft client secret (encrypted)", - "setting.microsoft_authority": "Base OpenID authority URL for Microsoft login", - "API tokens": "API tokens", - "Token name": "Token name", - "Create API token": "Create API token", - "Revoke": "Revoke", - "Revoke this API token?": "Revoke this API token?", - "Revoked": "Revoked", - "Prefix": "Prefix", - "No API tokens": "No API tokens", - "Create a token to enable API access for this user.": "Create a token to enable API access for this user.", - "No API token has been created for this user yet.": "No API token has been created for this user yet.", - "New API token (copy now — shown only once):": "New API token (copy now — shown only once):", - "API token created. Copy it now — it will not be shown again.": "API token created. Copy it now — it will not be shown again.", - "Could not create API token: %s": "Could not create API token: %s", - "API token revoked": "API token revoked", - "%d API tokens revoked": "%d API tokens revoked", - "%d active API tokens": "%d active API tokens", - "Revoke all API tokens": "Revoke all API tokens", - "Revoke all API tokens?": "Revoke all API tokens?", - "API token default lifetime is invalid": "API token default lifetime is invalid", - "API token max lifetime is invalid": "API token max lifetime is invalid", - "nav.logs.mail": "E-mail", + "Microsoft profile sync gaps": "Microsoft profile sync gaps", + "Microsoft SSO": "Microsoft SSO", + "Microsoft SSO settings": "Microsoft SSO settings", + "Microsoft-only login requires a complete configuration": "Microsoft-only login requires a complete configuration", + "Mobile": "Mobile", + "Modified": "Modified", + "Modified by": "Modified by", + "Module": "Module", + "Modules": "Modules", + "Mon": "Mon", + "Multiselect": "Multiselect", + "Must not contain your email": "Must not contain your email", + "My account": "My account", + "Name": "Name", "nav.audit.api": "API", - "nav.audit.system": "System", "nav.audit.imports": "Imports", + "nav.audit.system": "System", "nav.audit.user_lifecycle": "User lifecycle", - "API audit": "API logs", - "API audit logs": "API logs", - "Request ID": "Request ID", - "Method": "Method", - "Path": "Path", - "Status code": "Status code", - "Duration (ms)": "Duration (ms)", - "Error code": "Error code", - "Token ID": "Token ID", - "Token tenant": "Token tenant", - "Purge API audit logs": "Purge API logs", - "Purge entries older than 90 days?": "Purge entries older than 90 days?", - "%d API audit entries purged": "%d API log entries purged", - "API audit entry not found": "API log entry not found", - "View API audit entry": "View API log entry", - "Request details": "Request details", - "Scope": "Scope", - "Query metadata (keys)": "Query metadata (keys)", - "All methods": "All methods", - "Tenant ID": "Tenant ID", - "User ID": "User ID", - "IP": "IP", - "CORS allowed origins are invalid": "CORS allowed origins are invalid", - "Token name is required": "Token name is required", - "e.g. CI Pipeline": "e.g. CI Pipeline", - "Imports": "Imports", - "You do not have permission to run imports.": "You do not have permission to run imports.", - "CSV file": "CSV file", - "Max size 10MB, max 20000 rows": "Max size 10MB, max 20000 rows", - "Download sample CSV": "Download sample CSV", - "Analyze file": "Analyze file", - "CSV header": "CSV header", - "Target field": "Target field", - "Ignore column": "Ignore column", - "Assignment columns require additional permission.": "Assignment columns require additional permission.", - "Run preview": "Run preview", - "Preview": "Preview", - "Rows total": "Rows total", - "Valid rows": "Valid rows", - "Would create": "Would create", - "Would skip": "Would skip", - "Would fail": "Would fail", - "Row issues": "Row issues", - "Start import": "Start import", - "Import finished": "Import finished", - "Processed": "Processed", - "Skipped": "Skipped", - "Import another file": "Import another file", + "nav.logs.mail": "E-mail", + "navigate": "navigate", + "Navigation": "Navigation", + "Network timeout (seconds)": "Network timeout (seconds)", + "Never": "Never", + "Never logged in": "Never logged in", + "New API token (copy now — shown only once):": "New API token (copy now — shown only once):", + "New password (optional)": "New password (optional)", + "Next": "Next", + "Next run": "Next run", + "No": "No", + "No access to this tenant": "No access to this tenant", + "No active permissions are configured yet.": "No active permissions are configured yet.", + "No active roles are configured yet.": "No active roles are configured yet.", + "No active tenant assigned": "No active tenant assigned", + "No active user has the administrator role": "No active user has the administrator role", + "No API token has been created for this user yet.": "No API token has been created for this user yet.", + "No API tokens": "No API tokens", + "No contact details available": "No contact details available", + "No custom fields configured for selected tenants": "No custom fields configured for selected tenants", + "No custom fields configured for this tenant": "No custom fields configured for this tenant", + "No custom fields configured yet": "No custom fields configured yet", + "No departments available for this tenant": "No departments available for this tenant", + "No domain restrictions": "No domain restrictions", + "No effective permissions": "No effective permissions", + "No entries found": "No entries found", + "No file uploaded": "No file uploaded", + "No health checks available.": "No health checks available.", + "No legal links configured": "No legal links configured", + "No login method is available for this tenant": "No login method is available for this tenant", + "No login tokens": "No login tokens", + "No logo for this theme yet": "No logo for this theme yet", + "No modules active.": "No modules active.", + "No password reset requests": "No password reset requests", + "No permissions available": "No permissions available", + "No permissions selected": "No permissions selected", + "No queries were executed before the error occurred.": "No queries were executed before the error occurred.", + "No records found": "No records found", + "No reset has been requested for this account yet.": "No reset has been requested for this account yet.", + "No results found": "No results found", + "No roles available": "No roles available", + "No roles selected": "No roles selected", "No row errors found": "No row errors found", - "Row": "Row", - "Message": "Message", + "No tenant is available in your current scope.": "No tenant is available in your current scope.", + "No tenants available": "No tenants available", "No upload file provided": "No upload file provided", - "Upload exceeds the maximum size": "Upload exceeds the maximum size", - "Invalid file type": "Invalid file type", - "CSV header is invalid": "CSV header is invalid", - "CSV file has no data rows": "CSV file has no data rows", - "CSV row limit exceeded": "CSV row limit exceeded", - "Required mapping is missing": "Required mapping is missing", - "Assignment import permission is required": "Assignment import permission is required", - "Email is invalid": "Email is invalid", - "Email already exists": "Email already exists", - "Locale is invalid": "Locale is invalid", - "Active value is invalid": "Active value is invalid", - "Hire date must be YYYY-MM-DD": "Hire date must be YYYY-MM-DD", - "Tenant is missing, inactive or invalid": "Tenant is missing, inactive or invalid", - "Role is missing, inactive or invalid": "Role is missing, inactive or invalid", - "Department is missing, inactive or invalid": "Department is missing, inactive or invalid", - "Department does not belong to tenant": "Department does not belong to tenant", - "Tenant assignment is out of your scope": "Tenant assignment is out of your scope", - "Unexpected error during import": "Unexpected error during import", + "No valid users selected": "No valid users selected", + "No weekdays": "No weekdays", + "None": "None", + "None (not recommended)": "None (not recommended)", + "Not configured": "Not configured", + "Not Found": "Not Found", + "Not verified": "Not verified", + "Note": "Note", + "of": "of", + "OK": "OK", + "On this page": "On this page", + "One level": "One level", + "One option per line. Optional format: key|Label.": "One option per line. Optional format: key|Label.", + "One origin per line, e.g. https://app.example.com": "One origin per line, e.g. https://app.example.com", + "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com": "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com", + "Open": "Open", + "open": "open", + "Open full page": "Open full page", + "Open navigation": "Open navigation", + "Open search": "Open search", + "Operations": "Operations", + "Optional allow-list, comma or newline separated (example.com).": "Optional allow-list, comma or newline separated (example.com).", + "Optional allow-list, comma or newline separated.": "Optional allow-list, comma or newline separated.", + "Optional note...": "Optional note...", + "Options (one per line)": "Options (one per line)", + "Options are required for this field type": "Options are required for this field type", + "Or": "Or", + "Organization": "Organization", + "Outcome": "Outcome", + "Overdue jobs": "Overdue jobs", + "Override only if this tenant needs a separate Entra app.": "Override only if this tenant needs a separate Entra app.", + "Overview": "Overview", + "P95 response time (ms)": "P95 response time (ms)", + "Page": "Page", + "Page %d": "Page %d", + "Page %d of %d": "Page %d of %d", + "Page can not be updated": "Page can not be updated", + "Page not found": "Page not found", + "Page updated": "Page updated", + "Pages": "Pages", + "Partial": "Partial", + "Password": "Password", + "Password (again)": "Password confirm", + "Password can not be updated": "Password can not be updated", + "Password cannot be empty": "Password cannot be empty", + "Password login is disabled for all assigned tenants": "Password login is disabled for all assigned tenants", + "Password login is disabled for this tenant. Please use Microsoft login.": "Password login is disabled for this tenant. Please use Microsoft login.", + "Password login mode": "Password login mode", + "Password must be at least %d characters": "Password must be at least %d characters", + "Password must include a lowercase letter": "Password must include a lowercase letter", + "Password must include a number": "Password must include a number", + "Password must include a symbol": "Password must include a symbol", + "Password must include an uppercase letter": "Password must include an uppercase letter", + "Password must not contain your email": "Password must not contain your email", + "Password requirements": "Password requirements", + "Password reset code": "Password reset code", + "Password resets": "Password resets", + "Password updated": "Password updated", + "Passwords must match": "Passwords must match", + "Path": "Path", + "Per page": "Per page", + "perm.audit.api.purge": "Purge API logs", + "perm.audit.api.view": "View API logs", + "perm.audit.imports.purge": "Purge import audit logs", + "perm.audit.imports.view": "View import audit logs", + "perm.audit.system.purge": "Purge system logs", + "perm.audit.system.view": "View system logs", + "perm.audit.user_lifecycle.restore": "Restore users from lifecycle audit", + "perm.audit.user_lifecycle.view": "View user lifecycle logs", + "perm.custom_fields.edit_values": "Edit user custom field values", + "perm.custom_fields.manage": "Manage tenant custom fields", + "perm.departments.create": "Create departments", + "perm.departments.delete": "Delete departments", + "perm.departments.update": "Update departments", + "perm.departments.view": "View departments", + "perm.jobs.manage": "Manage scheduled jobs", + "perm.jobs.run_now": "Run scheduled jobs manually", + "perm.jobs.view": "View scheduled jobs", + "perm.mail_log.view": "View mail logs", + "perm.permissions.create": "Create permissions", + "perm.permissions.delete": "Delete permissions", + "perm.permissions.update": "Update permissions", + "perm.permissions.view": "View permissions", + "perm.roles.assign_all": "Assign all roles", + "perm.roles.create": "Create roles", + "perm.roles.delete": "Delete roles", + "perm.roles.update": "Update roles", + "perm.roles.view": "View roles", + "perm.settings.update": "Update settings", + "perm.settings.view": "View settings", + "perm.tenants.create": "Create tenants", + "perm.tenants.delete": "Delete tenants", + "perm.tenants.update": "Update tenants", + "perm.tenants.view": "View tenants", + "perm.user_lifecycle_audit.view": "View user lifecycle logs", + "perm.users.access_pdf": "Generate onboarding PDFs", + "perm.users.create": "Create users", + "perm.users.delete": "Delete users", + "perm.users.lifecycle_restore": "Restore users from lifecycle audit", + "perm.users.self_update": "Update own user", + "perm.users.update": "Update users", + "perm.users.update_assignments": "Update user assignments", + "perm.users.view": "View users", + "Permission": "Permission", + "Permission can not be created": "Permission can not be created", + "Permission can not be updated": "Permission can not be updated", + "Permission check could not be executed": "Permission check could not be executed", + "Permission created": "Permission created", + "Permission deleted": "Permission deleted", + "Permission denied": "Permission denied", + "Permission key": "Permission key", + "Permission key already exists": "Permission key already exists", + "Permission key cannot be empty": "Permission key cannot be empty", + "Permission key is invalid": "Permission key is invalid", + "Permission not found": "Permission not found", + "Permission origin": "Permission origin", + "Permission summary": "Permission summary", + "Permission updated": "Permission updated", + "Permissions": "Permissions", + "Permissions by source": "Permissions by source", + "Permissions without roles": "Permissions without roles", + "Phone": "Phone", + "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)": "Phone/mobile/avatar sync requires Microsoft Graph (User.Read)", + "PHP": "PHP", + "PHP SAPI": "PHP SAPI", + "PHP version": "PHP version", + "Please confirm": "Please confirm", + "Please enter a valid email address": "Please enter a valid email address", + "Please enter the 6-digit code": "Please enter the 6-digit code", + "Please enter your username and password.": "Please enter your username and password.", + "Please review the following errors": "Please review the following errors", + "Please select": "Please select", + "Please select a primary tenant": "Please select a primary tenant", + "Please select at least one tenant": "Please select at least one tenant", + "Please verify your email first": "Please verify your email first", + "Policy": "Policy", + "Port": "Port", + "POST Parameters": "POST Parameters", + "Postal code": "Postal code", + "Preferences": "Preferences", + "Prefix": "Prefix", + "Press Enter to open row": "Press Enter to open row", + "Preview": "Preview", + "Previous": "Previous", + "Primary": "Primary", + "Primary color": "Primary color", + "Primary color is invalid": "Primary color is invalid", + "Primary navigation": "Primary navigation", + "Primary tenant": "Primary tenant", + "Primary tenant must be one of the assigned tenants": "Primary tenant must be one of the assigned tenants", + "Priority": "Priority", + "Privacy": "Privacy", + "Privacy URL": "Privacy URL", + "Problems logging in": "Problems logging in", + "Processed": "Processed", + "Profile": "Profile", + "Profile can not be updated": "Profile can not be updated", + "Profile description": "Profile description", + "Profile image": "Profile image", + "Profile sync": "Profile sync", + "Profile sync on LDAP login": "Profile sync on LDAP login", + "Profile sync on Microsoft login": "Profile sync on Microsoft login", + "Provider message ID": "Provider message ID", + "Purge API audit logs": "Purge API logs", + "Purge entries older than 365 days?": "Purge entries older than 365 days?", + "Purge entries older than 90 days?": "Purge entries older than 90 days?", + "Purge expired system audit entries?": "Purge expired system audit entries?", + "Purge import logs": "Purge import logs", + "Purge run logs older than 90 days?": "Purge run logs older than 90 days?", + "Purge scheduler logs": "Purge scheduler logs", + "Purge system audit logs": "Purge system audit logs", + "Purge user lifecycle logs": "Purge user lifecycle logs", + "Queries": "Queries", + "Queries (%d)": "Queries (%d)", + "Query metadata (keys)": "Query metadata (keys)", + "Query tracking is not available (Debugger disabled or not initialized).": "Query tracking is not available (Debugger disabled or not initialized).", + "Queued": "Queued", + "Reason code": "Reason code", + "Recent import runs": "Recent import runs", + "Recent lifecycle risks (7d)": "Recent lifecycle risks (7d)", + "Recent logins": "Recent logins", + "Recent system audit risks (24h)": "Recent system audit risks (24h)", + "Recipient": "Recipient", + "Reference": "Reference", + "Region": "Region", + "Register": "Register", + "Registration controls whether new users can create an account.": "Registration controls whether new users can create an account.", + "Registration is currently disabled": "Registration is currently disabled.", + "Registration successful! Please check your email for the verification code.": "Registration successful! Please check your email for the verification code.", + "Remember login after Microsoft sign-in": "Remember login after Microsoft sign-in", + "Remember me": "Remember me", + "Remember token lifetime (days)": "Remember token lifetime (days)", + "Remember token lifetime is invalid": "Remember token lifetime is invalid", + "Remove": "Remove", + "Remove filter": "Remove filter", + "Remove permission": "Remove permission", + "Remove role": "Remove role", + "Remove selected file": "Remove selected file", + "Replace": "Replace", + "Request": "Request", + "Request details": "Request details", + "Request ID": "Request ID", + "Request Timeout": "Request Timeout", + "Request trend vs previous 24h": "Request trend vs previous 24h", + "Requested at": "Requested at", + "Requested path": "Requested path", + "Requested URL": "Requested URL", + "Requests": "Requests", + "Required": "Required", + "Required core tables are missing": "Required core tables are missing", + "Required field is empty: description": "Required field is empty: description", "Required field is empty: first_name": "Required field is empty: first_name", "Required field is empty: last_name": "Required field is empty: last_name", - "User assignments can not be updated": "User assignments can not be updated", - "How the import works": "How the import works", - "1. Upload CSV and click analyze": "1. Upload CSV and click analyze", - "2. Map your CSV columns to system fields": "2. Map your CSV columns to system fields", - "3. Review preview counters and row errors": "3. Review preview counters and row errors", - "4. Start import for valid rows": "4. Start import for valid rows", - "Rules": "Rules", - "Create-only: existing entries are skipped": "Create-only: existing entries are skipped", - "Here is a CSV template for this import profile.": "Here is a CSV template for this import profile.", - "Reference": "Reference", "Required fields": "Required fields", - "Required field is empty: description": "Required field is empty: description", - "Tenant must be a valid UUID": "Tenant must be a valid UUID", - "Code already exists": "Code already exists", - "Department already exists for this tenant": "Department already exists for this tenant", - "Duplicate entry in CSV file": "Duplicate entry in CSV file", - "Entry could not be created": "Entry could not be created", - "Import logs": "Import logs", - "Import audit logs": "Import audit logs", - "Run UUID": "Run UUID", - "Mapped fields": "Mapped fields", - "Created count": "Created count", - "Skipped count": "Skipped count", - "Failed count": "Failed count", - "Purge import logs": "Purge import logs", - "%d import audit entries purged": "%d import audit entries purged", - "Import audit entry not found": "Import audit entry not found", - "View import audit entry": "View import audit entry", - "Import details": "Import details", - "Started": "Started", - "Finished": "Finished", - "File": "File", - "Current tenant": "Current tenant", - "Error code distribution": "Error code distribution", - "All profiles": "All profiles", - "Running": "Running", - "Success": "Success", - "Partial": "Partial", - "Import": "Import", - "Counters": "Counters", - "User lifecycle policy": "User lifecycle policy", - "Session policy": "Session policy", - "Registration controls whether new users can create an account.": "Registration controls whether new users can create an account.", - "Session limits define how long logged-in users stay signed in.": "Set idle and absolute limits for active sessions.", - "User lifecycle defines when inactive users are deactivated or deleted.": "User lifecycle defines when inactive users are deactivated or deleted.", - "System audit controls whether security events are logged and how long they are kept.": "System audit controls whether security events are logged and how long they are kept.", - "Session idle timeout (minutes)": "Session idle timeout (minutes)", - "Session absolute timeout (hours)": "Session absolute timeout (hours)", - "Allowed range: 5-1440 minutes (default: 30)": "Allowed range: 5-1440 minutes (default: 30)", - "Allowed range: 1-72 hours (default: 8)": "Allowed range: 1-72 hours (default: 8)", - "Deactivate users after inactivity (days)": "Deactivate users after inactivity (days)", - "Delete inactive users after (days)": "Delete inactive users after (days)", - "0 disables this rule": "0 disables this rule", - "Run user lifecycle now?": "Run user lifecycle now?", - "Run user lifecycle now": "Run user lifecycle now", - "setting.user_inactivity_deactivate_days": "Automatically set users inactive after this many days without login", - "setting.user_inactivity_delete_days": "Automatically delete inactive users after this many additional days", - "setting.session_idle_timeout_minutes": "Maximum idle time in minutes before users are signed out (default: 30)", - "setting.session_absolute_timeout_hours": "Maximum total session duration in hours before users are signed out (default: 8)", - "User lifecycle already running": "User lifecycle already running", - "User lifecycle failed": "User lifecycle failed", - "User lifecycle completed: %d deactivated, %d deleted": "User lifecycle completed: %d deactivated, %d deleted", - "User inactivity deactivation period is invalid": "User inactivity deactivation period is invalid", - "User inactivity deletion period is invalid": "User inactivity deletion period is invalid", - "Session idle timeout is invalid": "Session idle timeout is invalid", - "Session absolute timeout is invalid": "Session absolute timeout is invalid", - "Auto-delete is ignored while auto-deactivate is disabled": "Auto-delete is ignored while auto-deactivate is disabled", - "Scheduled jobs": "Scheduled jobs", - "Scheduled job not found": "Scheduled job not found", - "Scheduled job is not registered": "Scheduled job is not registered", - "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.": "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.", - "Scheduled job could not be saved": "Scheduled job could not be saved", - "Scheduled job saved": "Scheduled job saved", - "Edit scheduled job": "Edit scheduled job", - "View scheduled job": "View scheduled job", - "Job": "Job", - "Job key": "Job key", - "Run history": "Run history", - "Run now": "Run now", - "Next run": "Next run", - "Last run": "Last run", - "Last error": "Last error", - "Schedule": "Schedule", - "Schedule type": "Schedule type", - "Schedule interval": "Schedule interval", - "Schedule time": "Schedule time", - "Weekdays": "Weekdays", - "Hourly": "Hourly", - "Daily": "Daily", - "Weekly": "Weekly", - "Enabled": "Enabled", - "Disabled": "Disabled", - "Timezone": "Timezone", - "Catch up once": "Catch up once", - "Scheduler": "Scheduler", - "Every %d hour(s)": "Every %d hour(s)", - "Every %d day(s) at %s": "Every %d day(s) at %s", - "Every %d week(s) on %s at %s": "Every %d week(s) on %s at %s", - "No weekdays": "No weekdays", - "Mon": "Mon", - "Tue": "Tue", - "Wed": "Wed", - "Thu": "Thu", - "Fri": "Fri", - "Sat": "Sat", - "Sun": "Sun", - "Schedule type is invalid": "Schedule type is invalid", - "Schedule time is required": "Schedule time is required", - "Timezone is invalid": "Timezone is invalid", - "Hourly interval must be between 1 and 24": "Hourly interval must be between 1 and 24", - "Daily interval must be between 1 and 365": "Daily interval must be between 1 and 365", - "Weekly interval must be between 1 and 52": "Weekly interval must be between 1 and 52", - "At least one weekday is required for weekly schedule": "At least one weekday is required for weekly schedule", - "Scheduled job run completed": "Scheduled job run completed", - "Scheduled job run skipped": "Scheduled job run skipped", - "Scheduled job run failed": "Scheduled job run failed", - "Scheduler is already running": "Scheduler is already running", - "Purge scheduler logs": "Purge scheduler logs", - "Purge run logs older than 90 days?": "Purge run logs older than 90 days?", - "%d scheduler run logs purged": "%d scheduler run logs purged", - "User lifecycle logs": "User lifecycle logs", - "View user lifecycle audit entry": "View user lifecycle audit entry", - "Lifecycle audit entry not found": "Lifecycle audit entry not found", - "Purge user lifecycle logs": "Purge user lifecycle logs", - "Purge entries older than 365 days?": "Purge entries older than 365 days?", - "%d user lifecycle audit entries purged": "%d user lifecycle audit entries purged", - "Lifecycle event": "Lifecycle event", - "Trigger": "Trigger", - "Reason code": "Reason code", - "Target": "Target", - "Target UUID": "Target UUID", - "Target email": "Target email", - "Policy": "Policy", - "Snapshot summary": "Snapshot summary", - "Snapshot version": "Snapshot version", + "Required for Microsoft login.": "Required for Microsoft login.", + "Required mapping is missing": "Required mapping is missing", + "Required Microsoft configuration": "Required Microsoft configuration", + "Reset password": "Reset password", + "Reset request already used": "Reset request already used", + "Reset request expired": "Reset request expired", + "Reset request not found": "Reset request not found", + "Restore": "Restore", + "Restore actions (7d)": "Restore actions (7d)", + "Restore not possible: email already exists": "Restore not possible: email already exists", + "Restore not possible: uuid already exists": "Restore not possible: uuid already exists", "Restore status": "Restore status", + "Restore this user from lifecycle snapshot?": "Restore this user from lifecycle snapshot?", + "Restore user": "Restore user", "Restored at": "Restored at", "Restored by": "Restored by", "Restored user": "Restored user", - "Restore user": "Restore user", - "Restore": "Restore", - "Restore this user from lifecycle snapshot?": "Restore this user from lifecycle snapshot?", - "User restored": "User restored", - "User restore failed": "User restore failed", - "Lifecycle event was already restored": "Lifecycle event was already restored", - "Lifecycle snapshot unavailable": "Lifecycle snapshot unavailable", - "Restore not possible: email already exists": "Restore not possible: email already exists", - "Restore not possible: uuid already exists": "Restore not possible: uuid already exists", - "All triggers": "All triggers", - "Manual": "Manual", - "Cron": "Cron", - "Enabled jobs": "Enabled jobs", - "Overdue jobs": "Overdue jobs", - "Scheduler runs (24h)": "Scheduler runs (24h)", - "Failed scheduler runs (24h)": "Failed scheduler runs (24h)", - "Cron runner active": "Cron runner active", - "Last heartbeat": "Last heartbeat", - "Last runner result": "Last runner result", - "Runner lock not acquired": "Runner lock not acquired", - "Locale": "Locale", - "Learning path": "Learning path", - "Concepts": "Concepts", - "How-to guides": "How-to guides", - "Contributor guide": "Contributor guide", - "System audit": "System audit", - "System audit logs": "System audit logs", - "View system audit entry": "View system audit entry", - "System audit entry not found": "System audit entry not found", - "Enable system audit log": "Enable system audit log", - "Purge system audit logs": "Purge system audit logs", - "Purge expired system audit entries?": "Purge expired system audit entries?", - "%d system audit entries purged": "%d system audit entries purged", - "All outcomes": "All outcomes", - "All channels": "All channels", - "Event type": "Event type", - "Outcome": "Outcome", - "Actor": "Actor", - "Actor tenant": "Actor tenant", - "Event details": "Event details", - "Target type": "Target type", - "IP hash": "IP hash", - "User agent hash": "User agent hash", - "Channel": "Channel", - "Denied": "Denied", - "Event": "Event", - "Metadata": "Metadata", - "Select users": "Select users", - "Select actions": "Select actions", - "Select statuses": "Select statuses", - "Select triggers": "Select triggers", - "Tenant #%d": "Tenant #%d", - "Tenant #%d (deleted)": "Tenant #%d (deleted)", - "Select event types": "Select event types", - "Select actor users": "Select actor users", - "User #%d": "User #%d", - "User #%d (deleted)": "User #%d (deleted)", + "Result": "Result", + "results": "results", "Retention (days)": "Retention (days)", - "Frontend telemetry": "Frontend telemetry", - "Enable frontend telemetry": "Enable frontend telemetry", + "Retry": "Retry", + "Revoke": "Revoke", + "Revoke all API tokens": "Revoke all API tokens", + "Revoke all API tokens?": "Revoke all API tokens?", + "Revoke this API token?": "Revoke this API token?", + "Revoked": "Revoked", + "Role": "Role", + "Role can not be created": "Role can not be created", + "Role can not be updated": "Role can not be updated", + "Role code already exists": "Role code already exists", + "Role created": "Role created", + "Role deleted": "Role deleted", + "Role is missing, inactive or invalid": "Role is missing, inactive or invalid", + "Role not found": "Role not found", + "Role updated": "Role updated", + "Roles": "Roles", + "Roles & permissions": "Roles & permissions", + "Roles without permissions": "Roles without permissions", + "Row": "Row", + "Row issues": "Row issues", + "Rows per page": "Rows per page", + "Rows total": "Rows total", + "Rules": "Rules", + "Run history": "Run history", + "Run now": "Run now", + "Run preview": "Run preview", + "Run user lifecycle now": "Run user lifecycle now", + "Run user lifecycle now?": "Run user lifecycle now?", + "Run UUID": "Run UUID", + "Runner lock not acquired": "Runner lock not acquired", + "Running": "Running", + "Runs": "Runs", + "Sales": "Sales", "Sampling rate": "Sampling rate", - "Allowed telemetry events": "Allowed telemetry events", - "warnOnce warnings": "warnOnce warnings", - "AJAX errors": "AJAX errors", - "The percentage of users who will have telemetry enabled.": "The percentage of users who will have telemetry enabled.", - "Advanced telemetry options": "Advanced telemetry options", - "setting.system_audit_enabled": "Enable/disable system audit logging", - "setting.system_audit_retention_days": "Retention in days for system audit entries", - "setting.frontend_telemetry_enabled": "Enable/disable secure frontend UX and error telemetry", - "setting.frontend_telemetry_sample_rate": "Sampling rate between 0 and 1 for accepted frontend telemetry events", - "setting.frontend_telemetry_allowed_events": "Allowed frontend telemetry event groups (warn_once, ajax_error)", - "System audit events (24h)": "System audit events (24h)", - "System audit risks (24h)": "System audit risks (24h)", - "Failed or denied": "Failed or denied", - "Recent system audit risks (24h)": "Recent system audit risks (24h)", - "Lifecycle runs (7d)": "Lifecycle runs (7d)", - "Lifecycle risks (7d)": "Lifecycle risks (7d)", - "Restore actions (7d)": "Restore actions (7d)", - "Recent lifecycle risks (7d)": "Recent lifecycle risks (7d)", - "Your session has expired. Please log in again.": "Your session timed out. Please sign in again. If you chose Remember me, sign-in can happen automatically.", - "Failed to update role permissions": "Failed to update role permissions", - "Failed to update permission roles": "Failed to update permission roles", - "Login persistence": "Login persistence", - "Controls remember-me token lifetime and Microsoft auto-remember behavior.": "Controls remember-me token lifetime and Microsoft auto-remember behavior.", - "Remember token lifetime (days)": "Remember token lifetime (days)", - "Allowed range: 1-365 days (default: 30)": "Allowed range: 1-365 days (default: 30)", - "Microsoft Auto-Remember default": "Microsoft Auto-Remember default", - "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).": "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).", - "Inherit global default": "Inherit global default", - "Force on": "Force on", - "Force off": "Force off", - "Controls whether Microsoft logins automatically persist a remember-me token.": "Controls whether Microsoft logins automatically persist a remember-me token.", - "Complete": "Complete", - "Incomplete": "Incomplete", - "No domain restrictions": "No domain restrictions", - "Configuration status": "Configuration status", - "SSO setup is incomplete": "SSO setup is incomplete", - "Complete the required Microsoft configuration before enforcing Microsoft-only login.": "Complete the required Microsoft configuration before enforcing Microsoft-only login.", - "Login policy": "Login policy", - "Allow Microsoft-only login (disable local password login)": "Allow Microsoft-only login (disable local password login)", - "Remember login after Microsoft sign-in": "Remember login after Microsoft sign-in", - "Access and profile sync": "Access and profile sync", - "Profile sync": "Profile sync", - "App credentials (advanced)": "App credentials (advanced)", - "Remember token lifetime is invalid": "Remember token lifetime is invalid", - "Session expiring": "Session expiring", - "Your session will expire in {countdown}. Would you like to continue?": "Your session will expire in {countdown}. Would you like to continue?", - "Extend session": "Extend session", - "Log out": "Log out", - "System Info": "System Info", - "OK": "OK", - "System status": "System status", - "All systems operational": "All systems operational", - "Degraded service": "Degraded service", - "System outage detected": "System outage detected", - "Last checked": "Last checked", - "Components": "Components", - "Database": "Database", - "Database schema": "Database schema", - "Storage": "Storage", - "Administrators": "Administrators", - "Connection established": "Connection established", - "Database did not return the expected response": "Database did not return the expected response", - "Database check could not be executed": "Database check could not be executed", - "All required core tables are present": "All required core tables are present", - "Required core tables are missing": "Required core tables are missing", - "Schema check could not be executed": "Schema check could not be executed", - "Storage path is writable": "Storage path is writable", - "Storage directory is missing": "Storage directory is missing", - "Storage directory is not writable": "Storage directory is not writable", - "Storage write probe failed": "Storage write probe failed", - "Storage check could not be executed": "Storage check could not be executed", - "Baseline permissions are present": "Baseline permissions are present", - "Baseline permissions are missing": "Baseline permissions are missing", - "Permission check could not be executed": "Permission check could not be executed", - "At least one administrator is active": "At least one administrator is active", - "No active user has the administrator role": "No active user has the administrator role", - "Administrator check could not be executed": "Administrator check could not be executed", - "Scheduler is running on schedule": "Scheduler is running on schedule", - "Scheduler heartbeat is outdated": "Scheduler heartbeat is outdated", + "SAPI": "SAPI", + "Sat": "Sat", + "Save": "Save", + "Save & close": "Save & close", + "Save in edit pages": "Save in edit pages", + "Save tenant first to manage custom fields": "Save tenant first to manage custom fields", + "Schedule": "Schedule", + "Schedule interval": "Schedule interval", + "Schedule time": "Schedule time", + "Schedule time is required": "Schedule time is required", + "Schedule type": "Schedule type", + "Schedule type is invalid": "Schedule type is invalid", + "Scheduled job could not be saved": "Scheduled job could not be saved", + "Scheduled job is not registered": "Scheduled job is not registered", + "Scheduled job not found": "Scheduled job not found", + "Scheduled job run completed": "Scheduled job run completed", + "Scheduled job run failed": "Scheduled job run failed", + "Scheduled job run skipped": "Scheduled job run skipped", + "Scheduled job saved": "Scheduled job saved", + "Scheduled jobs": "Scheduled jobs", + "Scheduler": "Scheduler", + "Scheduler check could not be executed": "Scheduler check could not be executed", "Scheduler has not reported yet": "Scheduler has not reported yet", "Scheduler heartbeat is empty": "Scheduler heartbeat is empty", - "Scheduler check could not be executed": "Scheduler check could not be executed", - "Health Status": "Health Status", - "Check": "Check", - "Details": "Details", - "PHP version": "PHP version", - "PHP SAPI": "PHP SAPI", - "Active modules": "Active modules", - "No modules active.": "No modules active.", - "Module": "Module", - "Dependencies": "Dependencies", - "Permission summary": "Permission summary", - "Active permissions": "Active permissions", - "Inactive (orphaned) permissions": "Inactive (orphaned) permissions", - "Permissions by source": "Permissions by source", - "Source": "Source", - "No health checks available.": "No health checks available.", - "Warning": "Warning", - "Fail": "Fail", - "Environment": "Environment", - "Modules": "Modules", - "Version": "Version", - "Breadcrumb": "Breadcrumb", - "LDAP Username": "LDAP Username", - "Sign in with LDAP": "Sign in with LDAP", - "LDAP login is not available for this tenant.": "LDAP login is not available for this tenant.", - "Your email domain is not allowed for LDAP login on this tenant.": "Your email domain is not allowed for LDAP login on this tenant.", - "LDAP server is not reachable. Please try again later.": "LDAP server is not reachable. Please try again later.", - "Your LDAP account does not have an email address configured.": "Your LDAP account does not have an email address configured.", - "LDAP host is required": "LDAP host is required", - "LDAP base DN is required": "LDAP base DN is required", - "LDAP port must be between 1 and 65535": "LDAP port must be between 1 and 65535", - "Search filter must contain %s placeholder": "Search filter must contain %s placeholder", - "LDAP-only login requires a complete configuration": "LDAP-only login requires a complete configuration", - "Direct bind method requires a username format": "Direct bind method requires a username format", - "Bind DN could not be encrypted": "Bind DN could not be encrypted", - "Bind password could not be encrypted": "Bind password could not be encrypted", - "Tenant LDAP settings could not be saved": "Tenant LDAP settings could not be saved", - "Bind DN could not be decrypted": "Bind DN could not be decrypted", - "Bind password could not be decrypted": "Bind password could not be decrypted", - "LDAP login": "LDAP login", - "LDAP setup is incomplete": "LDAP setup is incomplete", - "LDAP connection settings": "LDAP connection settings", - "Enable LDAP login for this tenant": "Enable LDAP login for this tenant", - "LDAP Host": "LDAP Host", - "Encryption": "Encryption", - "None (not recommended)": "None (not recommended)", - "Verify TLS certificate": "Verify TLS certificate", - "Base DN": "Base DN", - "Bind DN (service account)": "Bind DN (service account)", - "Bind password": "Bind password", - "Clear bind password": "Clear bind password", - "Test connection": "Test connection", + "Scheduler heartbeat is outdated": "Scheduler heartbeat is outdated", + "Scheduler is already running": "Scheduler is already running", + "Scheduler is running on schedule": "Scheduler is running on schedule", + "Scheduler runs (24h)": "Scheduler runs (24h)", + "Schema check could not be executed": "Schema check could not be executed", + "Scope": "Scope", + "Search": "Search", "Search and bind settings": "Search and bind settings", - "Bind method": "Bind method", - "Search then bind (recommended)": "Search then bind (recommended)", - "Direct bind": "Direct bind", - "User search filter": "User search filter", + "Search failed. Please try again.": "Search failed. Please try again.", + "Search filter must contain %s placeholder": "Search filter must contain %s placeholder", + "Search permissions…": "Search permissions…", + "Search results": "Search results", + "Search roles…": "Search roles…", "Search scope": "Search scope", - "Subtree (recursive)": "Subtree (recursive)", - "One level": "One level", - "Network timeout (seconds)": "Network timeout (seconds)", - "Direct bind username format": "Direct bind username format", - "Unique ID attribute": "Unique ID attribute", - "Attribute mapping and sync": "Attribute mapping and sync", - "Map application fields to LDAP directory attributes.": "Map application fields to LDAP directory attributes.", - "Profile sync on LDAP login": "Profile sync on LDAP login", - "Allow LDAP-only login (disable local password login)": "Allow LDAP-only login (disable local password login)", - "Sync email": "Sync email", - "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID": "AD: objectGUID, OpenLDAP: entryUUID, FreeIPA: ipaUniqueID", - "Login could not be completed. Please contact your administrator.": "Login could not be completed. Please contact your administrator.", - "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com": "Only for direct bind. Use %s as placeholder. Example: %s@corp.example.com or uid=%s,ou=People,dc=example,dc=com", - "Optional allow-list, comma or newline separated.": "Optional allow-list, comma or newline separated.", - "Please enter your username and password.": "Please enter your username and password.", - "Port": "Port", + "Search then bind (recommended)": "Search then bind (recommended)", + "Search users, tenants, pages...": "Search users, tenants, pages...", "Search-then-bind uses a service account to find the user DN first, then binds with the user credentials.": "Search-then-bind uses a service account to find the user DN first, then binds with the user credentials.", - "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP": "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP", - "Username or password not valid": "Username or password not valid", - "Write-only. Leave empty to keep current value.": "Write-only. Leave empty to keep current value.", - "Your account is deactivated.": "Your account is deactivated.", - "LDAP": "LDAP", - "LDAP attribute map could not be encoded": "LDAP attribute map could not be encoded", - "Drop file here or click to select": "Drop file here or click to select", - "Remove selected file": "Remove selected file", - "Replace": "Replace", - "Delete this image?": "Delete this image?", - "Current image": "Current image", - "Open navigation": "Open navigation", - "Close navigation": "Close navigation", - "Priority": "Priority", - "Note": "Note", - "Optional note...": "Optional note...", + "Search...": "Search...", + "Searching...": "Searching...", + "Security": "Security", "Security level updated": "Security level updated", - "About": "About", - "Call": "Call", - "Copy email address": "Copy email address", - "Copy phone number": "Copy phone number", - "Copy mobile number": "Copy mobile number", - "Hired": "Hired", - "Primary": "Primary", + "Security settings": "Security settings", + "Select": "Select", + "Select actions": "Select actions", + "Select actor users": "Select actor users", + "Select all": "Select all", + "Select departments": "Select departments", + "Select event types": "Select event types", + "Select options": "Select options", + "Select permissions": "Select permissions", + "Select primary tenant": "Select primary tenant", + "Select roles": "Select roles", + "Select statuses": "Select statuses", + "Select tenant": "Select tenant", + "Select tenants": "Select tenants", + "Select triggers": "Select triggers", + "Select users": "Select users", + "Selection fields without options": "Selection fields without options", + "Send access": "Send access", + "Send access email to this user?": "Send access email to this user?", + "Send access emails to selected users?": "Send access emails to selected users?", + "Send code": "Send code", + "Send code again": "Send code again", "Send email": "Send email", + "Sent": "Sent", + "Sent at": "Sent at", + "Sent emails": "Sent emails", + "Service Unavailable": "Service Unavailable", + "Session": "Session", + "Session (keys + types)": "Session (keys + types)", + "Session absolute timeout (hours)": "Session absolute timeout (hours)", + "Session absolute timeout is invalid": "Session absolute timeout is invalid", + "Session expiring": "Session expiring", + "Session idle timeout (minutes)": "Session idle timeout (minutes)", + "Session idle timeout is invalid": "Session idle timeout is invalid", + "Session limits define how long logged-in users stay signed in.": "Set idle and absolute limits for active sessions.", + "Session policy": "Session policy", + "Sessions, registration, lifecycle, audit, telemetry": "Sessions, registration, lifecycle, audit, telemetry", + "setting.api_cors_allowed_origins": "Allowed browser origins for API CORS (one origin per line)", + "setting.api_token_default_ttl_days": "Default lifetime for newly created API tokens in days (default: 90)", + "setting.api_token_max_ttl_days": "Maximum lifetime for API tokens in days (hard cap)", + "setting.app_locale": "Default language used when no user or URL locale is set", + "setting.app_registration": "Allow public self-registration", + "setting.app_title": "App title shown in the browser title bar", + "setting.default_department": "Default department used when no department is assigned on user creation", + "setting.default_role": "Default role used when no role is assigned on user creation", + "setting.default_tenant": "Default tenant used when no tenant is assigned on user creation", + "setting.frontend_telemetry_allowed_events": "Allowed frontend telemetry event groups (warn_once, ajax_error)", + "setting.frontend_telemetry_enabled": "Enable/disable secure frontend UX and error telemetry", + "setting.frontend_telemetry_sample_rate": "Sampling rate between 0 and 1 for accepted frontend telemetry events", + "setting.microsoft_authority": "Base OpenID authority URL for Microsoft login", + "setting.microsoft_shared_client_id": "Setting key for shared Microsoft client ID", + "setting.microsoft_shared_client_secret_enc": "Setting key for shared Microsoft client secret (encrypted)", + "setting.session_absolute_timeout_hours": "Maximum total session duration in hours before users are signed out (default: 8)", + "setting.session_idle_timeout_minutes": "Maximum idle time in minutes before users are signed out (default: 30)", + "setting.smtp_from": "From address for outgoing emails", + "setting.smtp_from_name": "From name for outgoing emails", + "setting.smtp_host": "SMTP server host (e.g. smtp.example.com)", + "setting.smtp_password": "Leave empty to keep the existing password", + "setting.smtp_port": "SMTP port (e.g. 587)", + "setting.smtp_secure": "SMTP encryption method", + "setting.smtp_user": "SMTP username", + "setting.system_audit_enabled": "Enable/disable system audit logging", + "setting.system_audit_retention_days": "Retention in days for system audit entries", + "setting.user_inactivity_deactivate_days": "Automatically set users inactive after this many days without login", + "setting.user_inactivity_delete_days": "Automatically delete inactive users after this many additional days", + "Settings": "Settings", + "Settings updated": "Settings updated", + "Shared app": "Shared app", + "Shared client ID": "Shared client ID", + "Shared client secret": "Shared client secret", + "Shared credentials missing": "Shared credentials missing", + "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".": "Shared Microsoft app credentials are used by tenants that enable \"Use shared app credentials\".", + "Shared Microsoft credentials": "Shared Microsoft credentials", + "Shared Microsoft Entra ID credentials": "Shared Microsoft Entra ID credentials", + "Short dial": "Short dial", + "Show password": "Show password", + "Showing": "Showing", + "Sign in with LDAP": "Sign in with LDAP", + "Sign in with Microsoft": "Sign in with Microsoft", + "Skip to main content": "Skip to main content", + "Skipped": "Skipped", + "Skipped count": "Skipped count", + "Slowest API endpoints (avg, 24h)": "Slowest API endpoints (avg, 24h)", + "SMTP connection and sender details": "SMTP connection and sender details", + "SMTP from address": "SMTP from address", + "SMTP from name": "SMTP from name", + "SMTP host": "SMTP host", + "SMTP password": "SMTP password", + "SMTP port": "SMTP port", + "SMTP security": "SMTP security", + "SMTP user": "SMTP user", + "Snapshot summary": "Snapshot summary", + "Snapshot version": "Snapshot version", + "Sort column ascending": "Sort column ascending", + "Sort column descending": "Sort column descending", + "Source": "Source", + "Source content not found": "Source content not found", + "Square images are recommended (icons are center-cropped).": "Square images are recommended (icons are center-cropped).", + "Square PNG. Icons are center-cropped.": "Square PNG. Icons are center-cropped.", + "SSO": "SSO", + "SSO configuration status": "SSO configuration status", + "SSO rollout": "SSO rollout", + "SSO setup is incomplete": "SSO setup is incomplete", + "SSO-enabled tenants": "SSO-enabled tenants", + "SSO-enforced tenants": "SSO-enforced tenants", + "Stack Trace": "Stack Trace", + "Start import": "Start import", + "Start writing...": "Start writing...", + "Started": "Started", + "State": "State", + "Statistics": "Statistics", + "Status": "Status", + "Status & meta": "Status & meta", + "Status changed": "Status changed", + "Status changed by": "Status changed by", + "Status code": "Status code", + "Status is invalid": "Status is invalid", + "Storage": "Storage", + "Storage check could not be executed": "Storage check could not be executed", + "Storage directory is missing": "Storage directory is missing", + "Storage directory is not writable": "Storage directory is not writable", + "Storage path is writable": "Storage path is writable", + "Storage write probe failed": "Storage write probe failed", + "Subject": "Subject", + "Subtree (recursive)": "Subtree (recursive)", + "Success": "Success", + "Success rate": "Success rate", + "Success rate (7d)": "Success rate (7d)", "Summary": "Summary", + "Sun": "Sun", + "Support": "Support", + "Support email": "Support email", + "Support phone": "Support phone", + "Switch sidebar section": "Switch sidebar section", + "Switch tenant": "Switch tenant", + "Sync avatar image": "Sync avatar image", + "Sync display name": "Sync display name", + "Sync email": "Sync email", + "Sync fields": "Sync fields", + "Sync first name": "Sync first name", + "Sync job title": "Sync job title", + "Sync last name": "Sync last name", + "Sync mobile": "Sync mobile", + "Sync phone": "Sync phone", + "System": "System", + "System audit": "System audit", + "System audit controls whether security events are logged and how long they are kept.": "System audit controls whether security events are logged and how long they are kept.", + "System audit entry not found": "System audit entry not found", + "System audit events (24h)": "System audit events (24h)", + "System audit logs": "System audit logs", + "System audit risks (24h)": "System audit risks (24h)", + "System Info": "System Info", + "System outage detected": "System outage detected", + "System permission": "System permission", + "System permission can not be deleted": "System permission can not be deleted", + "System permissions are core and should rarely be disabled.": "System permissions are core and should rarely be disabled.", + "System status": "System status", + "Target": "Target", + "Target email": "Target email", + "Target field": "Target field", + "Target language required": "Target language required", + "Target type": "Target type", + "Target UUID": "Target UUID", + "Tax number": "Tax number", + "Telemetry helps detect recurring UI issues and failed requests in production.": "Telemetry helps detect recurring UI issues and failed requests in production.", + "Template": "Template", + "Tenant": "Tenant", + "Tenant #%d": "Tenant #%d", + "Tenant #%d (deleted)": "Tenant #%d (deleted)", + "Tenant assignment is out of your scope": "Tenant assignment is out of your scope", + "Tenant can not be created": "Tenant can not be created", + "Tenant can not be deleted while departments are assigned": "Tenant can not be deleted while departments are assigned", + "Tenant can not be updated": "Tenant can not be updated", + "Tenant created": "Tenant created", + "Tenant deleted": "Tenant deleted", + "Tenant favicon": "Tenant favicon", + "Tenant ID": "Tenant ID", + "Tenant is missing, inactive or invalid": "Tenant is missing, inactive or invalid", + "Tenant LDAP settings could not be saved": "Tenant LDAP settings could not be saved", + "Tenant login link is invalid": "Tenant login link is invalid", + "Tenant logos": "Tenant logos", + "Tenant must be a valid UUID": "Tenant must be a valid UUID", + "Tenant not found": "Tenant not found", + "Tenant override": "Tenant override", + "Tenant SSO settings could not be saved": "Tenant SSO settings could not be saved", + "Tenant updated": "Tenant updated", + "Tenants": "Tenants", + "Tenants can override color and theme behavior in their appearance settings.": "Tenants can override color and theme behavior in their appearance settings.", + "Tenants with broken selection fields": "Tenants with broken selection fields", + "Terms of Service": "Terms of Service", + "Test connection": "Test connection", + "Text": "Text", + "Textarea": "Textarea", + "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.": "The authority URL defines the Microsoft identity tenant endpoint used for sign-in.", + "The field type controls input and filter behavior.": "The field type controls input and filter behavior.", + "The label is shown in user custom fields and in address book filters.": "The label is shown in user custom fields and in address book filters.", + "The page you requested does not exist or has moved.": "The page you requested does not exist or has moved.", + "The percentage of users who will have telemetry enabled.": "The percentage of users who will have telemetry enabled.", + "The primary color affects buttons and accent elements across the app.": "The primary color affects buttons and accent elements across the app.", + "The theme used for users in this tenant who have no personal preference.": "The theme used for users in this tenant who have no personal preference.", + "Theme": "Theme", + "Theme change is disabled for this tenant": "Theme change is disabled for this tenant", + "Theme policy": "Theme policy", + "These defaults prefill tenant, department and role when new users are created.": "These defaults prefill tenant, department and role when new users are created.", + "These limits define default and maximum lifetimes for newly issued API tokens.": "These limits define default and maximum lifetimes for newly issued API tokens.", + "This action cannot be undone.": "This action cannot be undone.", + "This action revokes all active API tokens immediately across all users.": "This action revokes all active API tokens immediately across all users.", + "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.": "This scheduled job is no longer registered and cannot be edited. It has been superseded by a newer version.", + "This setting controls the application name shown across the UI.": "This setting controls the application name shown across the UI.", + "This setting controls the default language for users without a personal preference.": "This setting controls the default language for users without a personal preference.", + "This setting controls the global default theme and whether users may choose their own theme.": "This setting controls the global default theme and whether users may choose their own theme.", + "This setting controls the primary UI accent color for the default app theme.": "This setting controls the primary UI accent color for the default app theme.", + "This user is currently not signed in via remember-me.": "This user is currently not signed in via remember-me.", + "This will expire all remember-me tokens immediately and force users to sign in again.": "This will expire all remember-me tokens immediately and force users to sign in again.", + "This will mark all remember-me tokens as expired. Users will need to sign in again.": "This will mark all remember-me tokens as expired. Users will need to sign in again.", + "This will permanently delete this department.": "This will permanently delete this department.", + "This will permanently delete this permission.": "This will permanently delete this permission.", + "This will permanently delete this role.": "This will permanently delete this role.", + "This will permanently delete this tenant.": "This will permanently delete this tenant.", + "This will permanently delete this user.": "This will permanently delete this user.", + "Thu": "Thu", + "Timezone": "Timezone", + "Timezone is invalid": "Timezone is invalid", + "to": "to", + "Toggle contrast": "Toggle contrast", + "Toggle Detail Sidebar": "Toggle Detail Sidebar", + "Toggle Sidebar": "Toggle Sidebar", + "Toggle sidebar": "Toggle sidebar", + "Token ID": "Token ID", + "Token lifetime policy": "Token lifetime policy", + "Token name": "Token name", + "Token name is required": "Token name is required", + "Token operations": "Token operations", + "Token tenant": "Token tenant", "token_select.clear_all": "Clear all", "token_select.empty_state_title": "No items selected", "token_select.error_invalid_items": "Items could not be loaded.", "token_select.no_matches": "No matches", "token_select.remove": "Remove", - "token_select.selected_count_suffix": "selected" + "token_select.selected_count_suffix": "selected", + "Tokens expiring in 7 days": "Tokens expiring in 7 days", + "Too many failed attempts. Please request a new code.": "Too many failed attempts. Please request a new code.", + "Too many login attempts. Please wait and try again.": "Too many login attempts. Please wait and try again.", + "Too Many Requests": "Too Many Requests", + "Too many users selected": "Too many users selected", + "Top API error codes (24h)": "Top API error codes (24h)", + "Top import error codes (7d)": "Top import error codes (7d)", + "Trigger": "Trigger", + "Tue": "Tue", + "Type": "Type", + "Unauthorized": "Unauthorized", + "Unexpected error during import": "Unexpected error during import", + "Unique ID attribute": "Unique ID attribute", + "Unknown": "Unknown", + "Unprocessable Entity": "Unprocessable Entity", + "Unsaved change (%d field)": "Unsaved change (%d field)", + "Unsaved changes": "Unsaved changes", + "Unsaved changes (%d fields)": "Unsaved changes (%d fields)", + "Unused active custom fields": "Unused active custom fields", + "Unverified": "Unverified", + "Upload dark logo": "Upload dark logo", + "Upload exceeds the maximum size": "Upload exceeds the maximum size", + "Upload failed": "Upload failed", + "Upload favicon": "Upload favicon", + "Upload image": "Upload image", + "Upload light logo": "Upload light logo", + "Upload logo": "Upload logo", + "URL": "URL", + "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP": "Use %s as placeholder for the username. Examples: (&(objectClass=user)(sAMAccountName=%s)) for AD, (&(objectClass=inetOrgPerson)(uid=%s)) for OpenLDAP", + "Use different email": "Use different email", + "Use shared app credentials from settings": "Use shared app credentials from settings", + "Used": "Used", + "Used at": "Used at", + "User": "User", + "User #%d": "User #%d", + "User #%d (deleted)": "User #%d (deleted)", + "User Agent": "User Agent", + "User agent hash": "User agent hash", + "User assignments can not be updated": "User assignments can not be updated", + "User can not be registered": "User can not be registered", + "User can not be updated": "User can not be updated", + "User created": "User created", + "User creation rules": "User creation rules", + "User custom fields": "User custom fields", + "User deleted": "User deleted", + "User ID": "User ID", + "User inactivity deactivation period is invalid": "User inactivity deactivation period is invalid", + "User inactivity deletion period is invalid": "User inactivity deletion period is invalid", + "User lifecycle already running": "User lifecycle already running", + "User lifecycle completed: %d deactivated, %d deleted": "User lifecycle completed: %d deactivated, %d deleted", + "User lifecycle defines when inactive users are deactivated or deleted.": "User lifecycle defines when inactive users are deactivated or deleted.", + "User lifecycle failed": "User lifecycle failed", + "User lifecycle logs": "User lifecycle logs", + "User lifecycle policy": "User lifecycle policy", + "User not found": "User not found", + "User override disabled": "User override disabled", + "User override enabled": "User override enabled", + "User profile fields are global and affect all tenants of this user": "User profile fields are global and affect all tenants of this user", + "User restore failed": "User restore failed", + "User restored": "User restored", + "User search filter": "User search filter", + "User theme policy": "User theme policy", + "User updated": "User updated", + "Username": "Username", + "Username or password not valid": "Username or password not valid", + "Users": "Users", + "Users may choose their own theme": "Users may choose their own theme", + "Users with Microsoft-only login": "Users with Microsoft-only login", + "Users without roles": "Users without roles", + "Users without tenants": "Users without tenants", + "Users, tenants, departments, roles and more": "Users, tenants, departments, roles and more", + "UUID": "UUID", + "Valid rows": "Valid rows", + "VAT ID": "VAT ID", + "Verification code": "Verification code", + "Verified": "Verified", + "Verify": "Verify", + "Verify code": "Verify code", + "Verify email": "Verify email", + "Verify TLS certificate": "Verify TLS certificate", + "Version": "Version", + "View": "View", + "View all results": "View all results", + "View API audit entry": "View API log entry", + "View department": "View department", + "View import audit entry": "View import audit entry", + "View mail log": "View mail log", + "View permission": "View permission", + "View role": "View role", + "View scheduled job": "View scheduled job", + "View system audit entry": "View system audit entry", + "View tenant": "View tenant", + "View user": "View user", + "View user lifecycle audit entry": "View user lifecycle audit entry", + "Visibility": "Visibility", + "Warning": "Warning", + "warnOnce warnings": "warnOnce warnings", + "We could not continue with these login details": "We could not continue with these login details", + "Website": "Website", + "Wed": "Wed", + "Weekdays": "Weekdays", + "Weekly": "Weekly", + "Weekly interval must be between 1 and 52": "Weekly interval must be between 1 and 52", + "Welcome back": "Welcome back", + "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).": "When enabled, successful Microsoft logins automatically persist a remember-me token (unless overridden per tenant).", + "Windows": "Windows", + "Would create": "Would create", + "Would fail": "Would fail", + "Would skip": "Would skip", + "Write-only. Leave empty to keep current secret.": "Write-only. Leave empty to keep current secret.", + "Write-only. Leave empty to keep current value.": "Write-only. Leave empty to keep current value.", + "Yes": "Yes", + "You are not allowed to edit this page": "You are not allowed to edit this page", + "You cannot deactivate your own account": "You cannot deactivate your own account", + "You cannot delete your own account": "You cannot delete your own account", + "You do not have permission to run imports.": "You do not have permission to run imports.", + "You do not have permission to view this content.": "You do not have permission to view this content.", + "You have unsaved changes. Leave without saving?": "You have unsaved changes. Leave without saving?", + "Your access details": "Your access details", + "Your account is deactivated.": "Your account is deactivated.", + "Your email domain is not allowed for LDAP login on this tenant.": "Your email domain is not allowed for LDAP login on this tenant.", + "Your LDAP account does not have an email address configured.": "Your LDAP account does not have an email address configured.", + "Your session has expired. Please log in again.": "Your session timed out. Please sign in again. If you chose Remember me, sign-in can happen automatically.", + "Your session will expire in {countdown}. Would you like to continue?": "Your session will expire in {countdown}. Would you like to continue?", + "ZIP support missing (ext-zip)": "ZIP support missing (ext-zip)" } diff --git a/pages/admin/settings/api().php b/pages/admin/settings/api().php new file mode 100644 index 0000000..90f9f3f --- /dev/null +++ b/pages/admin/settings/api().php @@ -0,0 +1,86 @@ +all(); +Guard::requireLogin(); +$request = requestInput(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +$adminSettingsService = app(AdminSettingsService::class); +$pageData = $adminSettingsService->buildPageData(); +$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; +$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; +$activeApiTokens = (int) ($pageData['active_api_tokens'] ?? 0); + +if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings/api', 'admin/settings/api', 'csrf_expired')) { + return; +} + +if ($request->isMethod('POST')) { + $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ + 'actor_user_id' => $currentUserId, + ]); + if (!$updateDecision->isAllowed()) { + Guard::deny(); + } + + $sectionKeys = [ + 'api_token_default_ttl_days', + 'api_token_max_ttl_days', + 'api_cors_allowed_origins', + ]; + $mergedPost = settingsSectionMergePost($values, $request->bodyAll(), $sectionKeys); + + $updateResult = $adminSettingsService->updateFromAdmin($mergedPost); + $errorBag = formErrors(); + foreach ((array) ($updateResult['errors'] ?? []) as $error) { + if (is_array($error)) { + $message = trim((string) ($error['message'] ?? '')); + $field = trim((string) ($error['field'] ?? 'input')); + if ($message !== '') { + $errorBag->add($field !== '' ? $field : 'input', $message); + } + continue; + } + $message = trim((string) $error); + if ($message !== '') { + $errorBag->addGlobal($message); + } + } + + if ($errorBag->hasAny()) { + flashFormErrors($errorBag, 'admin/settings/api', 'settings_update_error'); + Router::redirect('admin/settings/api'); + } + + $redirectTarget = ((string) $request->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/api'; + Flash::success('Settings updated', $redirectTarget, 'settings_updated'); + Router::redirect($redirectTarget); +} + +Buffer::set('title', t('API settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('API')], +]; diff --git a/pages/admin/settings/api(default).phtml b/pages/admin/settings/api(default).phtml new file mode 100644 index 0000000..9ca5c5f --- /dev/null +++ b/pages/admin/settings/api(default).phtml @@ -0,0 +1,134 @@ + + +
+
+ t('API settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => $canUpdateSettings ? [ + [ + 'form' => 'settings-api-form', + 'name' => 'action', + 'value' => 'save', + 'class' => 'secondary outline', + 'label' => t('Save'), + ], + [ + 'form' => 'settings-api-form', + 'name' => 'action', + 'value' => 'save_close', + 'class' => 'primary', + 'label' => t('Save & close'), + ], + ] : [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+
+ + + + + / + + + +
+
+ +
+
+ + +
+
+
+ + +
+ + + + + + +
+
+ +
+ + +
+
+ + +
+ + + + + + +
+
+ +
+ +
+
+ + + +
+
+ +
diff --git a/pages/admin/settings/branding().php b/pages/admin/settings/branding().php new file mode 100644 index 0000000..f5fbe0d --- /dev/null +++ b/pages/admin/settings/branding().php @@ -0,0 +1,28 @@ +all(); +Guard::requireLogin(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +Buffer::set('title', t('Branding settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('Branding')], +]; diff --git a/pages/admin/settings/branding(default).phtml b/pages/admin/settings/branding(default).phtml new file mode 100644 index 0000000..643967a --- /dev/null +++ b/pages/admin/settings/branding(default).phtml @@ -0,0 +1,106 @@ +hasLogo(); +$hasFavicon = app(\MintyPHP\Service\Branding\BrandingFaviconService::class)->hasFavicon(); +?> + +
+
+ t('Branding settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+ + + + + + +
+
+ + <?php e(t('App logo')); ?> + +
+ +
+ 'logo', + 'accept' => 'image/svg+xml,image/png,image/jpeg,image/webp', + 'hint' => t('Allowed file types: SVG, PNG, JPG, WEBP'), + 'currentSrc' => $hasLogo ? appLogoUrl(128) : '', + 'deleteAction' => $hasLogo ? 'admin/settings/logo-delete' : '', + ]; + require templatePath('partials/app-file-upload.phtml'); + ?> +
+ + +
+ +
+ +
+
+ +
+ + + + + + +
+
+ +
+ +
+ 'favicon', + 'accept' => 'image/png', + 'hint' => t('Allowed file types: PNG'), + 'currentSrc' => $hasFavicon ? asset('favicon/favicon-32x32.png') : '', + 'currentLabel' => t('Favicon'), + 'deleteAction' => $hasFavicon ? 'admin/settings/favicon-delete' : '', + ]; + require templatePath('partials/app-file-upload.phtml'); + ?> +
+ + +
+ +
+ +
+
+
+ +
diff --git a/pages/admin/settings/email().php b/pages/admin/settings/email().php new file mode 100644 index 0000000..b880281 --- /dev/null +++ b/pages/admin/settings/email().php @@ -0,0 +1,89 @@ +all(); +Guard::requireLogin(); +$request = requestInput(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +$adminSettingsService = app(AdminSettingsService::class); +$pageData = $adminSettingsService->buildPageData(); +$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; +$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; + +if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings/email', 'admin/settings/email', 'csrf_expired')) { + return; +} + +if ($request->isMethod('POST')) { + $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ + 'actor_user_id' => $currentUserId, + ]); + if (!$updateDecision->isAllowed()) { + Guard::deny(); + } + + $sectionKeys = [ + 'smtp_host', + 'smtp_port', + 'smtp_user', + 'smtp_password', + 'smtp_secure', + 'smtp_from', + 'smtp_from_name', + ]; + $mergedPost = settingsSectionMergePost($values, $request->bodyAll(), $sectionKeys); + + $updateResult = $adminSettingsService->updateFromAdmin($mergedPost); + $errorBag = formErrors(); + foreach ((array) ($updateResult['errors'] ?? []) as $error) { + if (is_array($error)) { + $message = trim((string) ($error['message'] ?? '')); + $field = trim((string) ($error['field'] ?? 'input')); + if ($message !== '') { + $errorBag->add($field !== '' ? $field : 'input', $message); + } + continue; + } + $message = trim((string) $error); + if ($message !== '') { + $errorBag->addGlobal($message); + } + } + + if ($errorBag->hasAny()) { + flashFormErrors($errorBag, 'admin/settings/email', 'settings_update_error'); + Router::redirect('admin/settings/email'); + } + + $redirectTarget = ((string) $request->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/email'; + Flash::success('Settings updated', $redirectTarget, 'settings_updated'); + Router::redirect($redirectTarget); +} + +Buffer::set('title', t('Email settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('Email')], +]; diff --git a/pages/admin/settings/email(default).phtml b/pages/admin/settings/email(default).phtml new file mode 100644 index 0000000..3878293 --- /dev/null +++ b/pages/admin/settings/email(default).phtml @@ -0,0 +1,112 @@ + + +
+
+ t('Email settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => $canUpdateSettings ? [ + [ + 'form' => 'settings-email-form', + 'name' => 'action', + 'value' => 'save', + 'class' => 'secondary outline', + 'label' => t('Save'), + ], + [ + 'form' => 'settings-email-form', + 'name' => 'action', + 'value' => 'save_close', + 'class' => 'primary', + 'label' => t('Save & close'), + ], + ] : [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+
+ + +
+
+ + +
+
+ + +
+ + + +
+
+ +
diff --git a/pages/admin/settings/expire-remember-tokens().php b/pages/admin/settings/expire-remember-tokens().php index c3de039..18c29d3 100644 --- a/pages/admin/settings/expire-remember-tokens().php +++ b/pages/admin/settings/expire-remember-tokens().php @@ -18,15 +18,15 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/security')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'settings_tokens_expire')) { +if (!actionRequireCsrf('admin/settings/security', 'admin/settings/security', 'settings_tokens_expire')) { return; } $rememberMeService = app(\MintyPHP\Service\Auth\RememberMeService::class); $count = $rememberMeService->expireAllTokensByAdmin(); -Flash::success(sprintf(t('%d login tokens expired'), $count), 'admin/settings', 'login_tokens_expired'); -Router::redirect('admin/settings'); +Flash::success(sprintf(t('%d login tokens expired'), $count), 'admin/settings/security', 'login_tokens_expired'); +Router::redirect('admin/settings/security'); diff --git a/pages/admin/settings/favicon().php b/pages/admin/settings/favicon().php index 76837fc..b73c4f5 100644 --- a/pages/admin/settings/favicon().php +++ b/pages/admin/settings/favicon().php @@ -18,11 +18,11 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/branding')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'favicon_upload')) { +if (!actionRequireCsrf('admin/settings/branding', 'admin/settings/branding', 'favicon_upload')) { return; } @@ -32,10 +32,13 @@ $result = $faviconService->saveUpload(requestInput()->filesAll()['favicon'] ?? [ if (!($result['ok'] ?? false)) { $error = $result['error'] ?? t('Upload failed'); $errorBag->addGlobal((string) $error); - flashFormErrors($errorBag, 'admin/settings', 'favicon_upload'); - Router::redirect('admin/settings'); + flashFormErrors($errorBag, 'admin/settings/branding', 'favicon_upload'); + Router::redirect('admin/settings/branding'); return; } -Flash::success('Favicon updated', 'admin/settings', 'favicon_updated'); -Router::redirect('admin/settings'); +$redirectTarget = ((string) requestInput()->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/branding'; +Flash::success('Favicon updated', $redirectTarget, 'favicon_updated'); +Router::redirect($redirectTarget); diff --git a/pages/admin/settings/favicon-delete().php b/pages/admin/settings/favicon-delete().php index 7f4acc4..3f76901 100644 --- a/pages/admin/settings/favicon-delete().php +++ b/pages/admin/settings/favicon-delete().php @@ -18,15 +18,15 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/branding')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'settings_favicon_delete')) { +if (!actionRequireCsrf('admin/settings/branding', 'admin/settings/branding', 'settings_favicon_delete')) { return; } $faviconService = app(\MintyPHP\Service\Branding\BrandingFaviconService::class); $faviconService->delete(); -Flash::success('Favicon removed', 'admin/settings', 'favicon_removed'); -Router::redirect('admin/settings'); +Flash::success('Favicon removed', 'admin/settings/branding', 'favicon_removed'); +Router::redirect('admin/settings/branding'); diff --git a/pages/admin/settings/general().php b/pages/admin/settings/general().php new file mode 100644 index 0000000..c8110c4 --- /dev/null +++ b/pages/admin/settings/general().php @@ -0,0 +1,90 @@ +all(); +Guard::requireLogin(); +$request = requestInput(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +$adminSettingsService = app(AdminSettingsService::class); +$pageData = $adminSettingsService->buildPageData(); +$tenants = is_array($pageData['tenants'] ?? null) ? $pageData['tenants'] : []; +$roles = is_array($pageData['roles'] ?? null) ? $pageData['roles'] : []; +$departments = is_array($pageData['departments'] ?? null) ? $pageData['departments'] : []; +$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; +$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; + +if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings/general', 'admin/settings/general', 'csrf_expired')) { + return; +} + +if ($request->isMethod('POST')) { + $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ + 'actor_user_id' => $currentUserId, + ]); + if (!$updateDecision->isAllowed()) { + Guard::deny(); + } + + $sectionKeys = [ + 'default_tenant_id', + 'default_role_id', + 'default_department_id', + 'app_title', + 'app_locale', + ]; + $mergedPost = settingsSectionMergePost($values, $request->bodyAll(), $sectionKeys); + + $updateResult = $adminSettingsService->updateFromAdmin($mergedPost); + $errorBag = formErrors(); + foreach ((array) ($updateResult['errors'] ?? []) as $error) { + if (is_array($error)) { + $message = trim((string) ($error['message'] ?? '')); + $field = trim((string) ($error['field'] ?? 'input')); + if ($message !== '') { + $errorBag->add($field !== '' ? $field : 'input', $message); + } + continue; + } + $message = trim((string) $error); + if ($message !== '') { + $errorBag->addGlobal($message); + } + } + + if ($errorBag->hasAny()) { + flashFormErrors($errorBag, 'admin/settings/general', 'settings_update_error'); + Router::redirect('admin/settings/general'); + } + + $redirectTarget = ((string) $request->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/general'; + Flash::success('Settings updated', $redirectTarget, 'settings_updated'); + Router::redirect($redirectTarget); +} + +Buffer::set('title', t('General settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('General')], +]; diff --git a/pages/admin/settings/general(default).phtml b/pages/admin/settings/general(default).phtml new file mode 100644 index 0000000..7243695 --- /dev/null +++ b/pages/admin/settings/general(default).phtml @@ -0,0 +1,183 @@ + + +
+
+ t('General settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => $canUpdateSettings ? [ + [ + 'form' => 'settings-general-form', + 'name' => 'action', + 'value' => 'save', + 'class' => 'secondary outline', + 'label' => t('Save'), + ], + [ + 'form' => 'settings-general-form', + 'name' => 'action', + 'value' => 'save_close', + 'class' => 'primary', + 'label' => t('Save & close'), + ], + ] : [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+
+ + + + + + +
+
+ +
+ +
+
+ +
+ + + + + + +
+
+ +
+ +
+
+ + 0) + (int) ($defaultDepartmentId > 0) + (int) ($defaultRoleId > 0); ?> +
+ + + + + + +
+
+ +
+
+ + +
+ +
+
+ + +
+
+ +
diff --git a/pages/admin/settings/index().php b/pages/admin/settings/index().php index 1de6f99..a9b2286 100644 --- a/pages/admin/settings/index().php +++ b/pages/admin/settings/index().php @@ -2,15 +2,11 @@ use MintyPHP\Buffer; use MintyPHP\Http\SessionStoreInterface; -use MintyPHP\Router; use MintyPHP\Service\Access\SettingsAuthorizationPolicy; -use MintyPHP\Service\Settings\AdminSettingsService; -use MintyPHP\Support\Flash; use MintyPHP\Support\Guard; $session = app(SessionStoreInterface::class)->all(); Guard::requireLogin(); -$request = requestInput(); $currentUserId = (int) ($session['user']['id'] ?? 0); $authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); @@ -20,62 +16,6 @@ $viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::AB if (!$viewDecision->isAllowed()) { Guard::deny(); } -$viewCapabilities = $viewDecision->attribute('capabilities', []); -$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; - -$adminSettingsService = app(AdminSettingsService::class); -$pageData = $adminSettingsService->buildPageData(); -$tenants = is_array($pageData['tenants'] ?? null) ? $pageData['tenants'] : []; -$roles = is_array($pageData['roles'] ?? null) ? $pageData['roles'] : []; -$departments = is_array($pageData['departments'] ?? null) ? $pageData['departments'] : []; -$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; -$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; -$activeLoginTokens = (int) ($pageData['active_login_tokens'] ?? 0); -$activeApiTokens = (int) ($pageData['active_api_tokens'] ?? 0); - -if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings', 'admin/settings', 'csrf_expired')) { - return; -} - -if ($request->isMethod('POST')) { - $post = $request->bodyAll(); - if (!array_key_exists('settings_submit', $post)) { - Router::redirect('admin/settings'); - } - - $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ - 'actor_user_id' => $currentUserId, - ]); - if (!$updateDecision->isAllowed()) { - Guard::deny(); - } - - $updateResult = $adminSettingsService->updateFromAdmin($post); - $errorBag = formErrors(); - foreach ((array) ($updateResult['errors'] ?? []) as $error) { - if (is_array($error)) { - $message = trim((string) ($error['message'] ?? '')); - $field = trim((string) ($error['field'] ?? 'input')); - if ($message !== '') { - $errorBag->add($field !== '' ? $field : 'input', $message); - } - continue; - } - - $message = trim((string) $error); - if ($message !== '') { - $errorBag->addGlobal($message); - } - } - - if ($errorBag->hasAny()) { - flashFormErrors($errorBag, 'admin/settings', 'settings_update_error'); - Router::redirect('admin/settings'); - } - - Flash::success('Settings updated', 'admin/settings', 'settings_updated'); - Router::redirect('admin/settings'); -} Buffer::set('title', t('Settings')); diff --git a/pages/admin/settings/index(default).phtml b/pages/admin/settings/index(default).phtml index 5f4398e..633e8b5 100644 --- a/pages/admin/settings/index(default).phtml +++ b/pages/admin/settings/index(default).phtml @@ -1,755 +1,68 @@ ). This page renders a tile grid of entry points. */ -use MintyPHP\Session; -use MintyPHP\Service\Branding\BrandingServicesFactory; - -$values = $values ?? []; -$settings = $settings ?? []; -$defaultTenantId = (int) ($values['default_tenant_id'] ?? 0); -$defaultRoleId = (int) ($values['default_role_id'] ?? 0); -$defaultDepartmentId = (int) ($values['default_department_id'] ?? 0); -$appTitle = (string) ($values['app_title'] ?? ''); -$appLocale = (string) ($values['app_locale'] ?? ''); -$appRegistration = !empty($values['app_registration']); -$apiTokenDefaultTtlDays = (int) ($values['api_token_default_ttl_days'] ?? 90); -$apiTokenMaxTtlDays = (int) ($values['api_token_max_ttl_days'] ?? 365); -$userInactivityDeactivateDays = (int) ($values['user_inactivity_deactivate_days'] ?? 180); -$userInactivityDeleteDays = (int) ($values['user_inactivity_delete_days'] ?? 365); -$sessionIdleTimeoutMinutes = (int) ($values['session_idle_timeout_minutes'] ?? 30); -$sessionAbsoluteTimeoutHours = (int) ($values['session_absolute_timeout_hours'] ?? 8); -$microsoftAutoRememberDefault = !empty($values['microsoft_auto_remember_default']); -$rememberTokenLifetimeDays = (int) ($values['remember_token_lifetime_days'] ?? 30); -$apiCorsAllowedOrigins = (string) ($values['api_cors_allowed_origins'] ?? ''); -$systemAuditEnabled = !empty($values['system_audit_enabled']); -$systemAuditRetentionDays = (int) ($values['system_audit_retention_days'] ?? 365); -$frontendTelemetryEnabled = !empty($values['frontend_telemetry_enabled']); -$frontendTelemetrySampleRate = (string) ($values['frontend_telemetry_sample_rate'] ?? '0.2'); -$frontendTelemetrySampleRateOptions = ['0.1', '0.2', '0.5', '1']; -if (!in_array($frontendTelemetrySampleRate, $frontendTelemetrySampleRateOptions, true)) { - $frontendTelemetrySampleRate = '0.2'; -} -$frontendTelemetryAllowedEvents = $values['frontend_telemetry_allowed_events'] ?? ['warn_once', 'ajax_error']; -if (!is_array($frontendTelemetryAllowedEvents)) { - $frontendTelemetryAllowedEvents = preg_split('/[\s,]+/', (string) $frontendTelemetryAllowedEvents) ?: []; -} -$frontendTelemetryAllowedEvents = array_values(array_unique(array_filter(array_map( - static fn($entry): string => strtolower(trim((string) $entry)), - $frontendTelemetryAllowedEvents -)))); -if ($frontendTelemetryAllowedEvents === []) { - $frontendTelemetryAllowedEvents = ['warn_once', 'ajax_error']; -} -$microsoftSharedClientId = (string) ($values['microsoft_shared_client_id'] ?? ''); -$microsoftAuthority = (string) ($values['microsoft_authority'] ?? ''); -$smtpHost = (string) ($values['smtp_host'] ?? ''); -$smtpPort = (string) ($values['smtp_port'] ?? ''); -$smtpUser = (string) ($values['smtp_user'] ?? ''); -$smtpSecure = (string) ($values['smtp_secure'] ?? ''); -$smtpFrom = (string) ($values['smtp_from'] ?? ''); -$smtpFromName = (string) ($values['smtp_from_name'] ?? ''); -$activeLoginTokens = (int) ($activeLoginTokens ?? 0); -$activeApiTokens = (int) ($activeApiTokens ?? 0); -$defaultTenantDesc = $settings['default_tenant']['description'] ?? 'setting.default_tenant'; -$defaultRoleDesc = $settings['default_role']['description'] ?? 'setting.default_role'; -$defaultDepartmentDesc = $settings['default_department']['description'] ?? 'setting.default_department'; -$appTitleDesc = $settings['app_title']['description'] ?? 'setting.app_title'; -$appLocaleDesc = $settings['app_locale']['description'] ?? 'setting.app_locale'; -$appRegistrationDesc = $settings['app_registration']['description'] ?? 'setting.app_registration'; -$apiTokenDefaultTtlDaysDesc = $settings['api_token_default_ttl_days']['description'] ?? 'setting.api_token_default_ttl_days'; -$apiTokenMaxTtlDaysDesc = $settings['api_token_max_ttl_days']['description'] ?? 'setting.api_token_max_ttl_days'; -$userInactivityDeactivateDaysDesc = $settings['user_inactivity_deactivate_days']['description'] ?? 'setting.user_inactivity_deactivate_days'; -$userInactivityDeleteDaysDesc = $settings['user_inactivity_delete_days']['description'] ?? 'setting.user_inactivity_delete_days'; -$sessionIdleTimeoutMinutesDesc = $settings['session_idle_timeout_minutes']['description'] ?? 'setting.session_idle_timeout_minutes'; -$sessionAbsoluteTimeoutHoursDesc = $settings['session_absolute_timeout_hours']['description'] ?? 'setting.session_absolute_timeout_hours'; -$microsoftAutoRememberDefaultDesc = $settings['microsoft_auto_remember_default']['description'] ?? 'setting.microsoft_auto_remember_default'; -$rememberTokenLifetimeDaysDesc = $settings['remember_token_lifetime_days']['description'] ?? 'setting.remember_token_lifetime_days'; -$apiCorsAllowedOriginsDesc = $settings['api_cors_allowed_origins']['description'] ?? 'setting.api_cors_allowed_origins'; -$systemAuditEnabledDesc = $settings['system_audit_enabled']['description'] ?? 'setting.system_audit_enabled'; -$systemAuditRetentionDaysDesc = $settings['system_audit_retention_days']['description'] ?? 'setting.system_audit_retention_days'; -$microsoftSharedClientIdDesc = $settings['microsoft_shared_client_id']['description'] ?? 'setting.microsoft_shared_client_id'; -$microsoftSharedClientSecretDesc = $settings['microsoft_shared_client_secret_enc']['description'] ?? 'setting.microsoft_shared_client_secret_enc'; -$microsoftAuthorityDesc = $settings['microsoft_authority']['description'] ?? 'setting.microsoft_authority'; -$smtpHostDesc = $settings['smtp_host']['description'] ?? 'setting.smtp_host'; -$smtpPortDesc = $settings['smtp_port']['description'] ?? 'setting.smtp_port'; -$smtpUserDesc = $settings['smtp_user']['description'] ?? 'setting.smtp_user'; -$smtpPasswordDesc = $settings['smtp_password']['description'] ?? 'setting.smtp_password'; -$smtpSecureDesc = $settings['smtp_secure']['description'] ?? 'setting.smtp_secure'; -$smtpFromDesc = $settings['smtp_from']['description'] ?? 'setting.smtp_from'; -$smtpFromNameDesc = $settings['smtp_from_name']['description'] ?? 'setting.smtp_from_name'; -$locales = defined('APP_LOCALES') ? APP_LOCALES : []; -$hasLogo = app(\MintyPHP\Service\Branding\BrandingLogoService::class)->hasLogo(); -$hasFavicon = app(\MintyPHP\Service\Branding\BrandingFaviconService::class)->hasFavicon(); -$canUpdateSettings = (bool) ($canUpdateSettings ?? false); -$isReadOnly = !$canUpdateSettings; -$readonlyAttr = $isReadOnly ? 'readonly' : ''; -$disabledAttr = $isReadOnly ? 'disabled' : ''; ?> - -
-
- t('Settings'), - 'actions' => $canUpdateSettings ? [ - [ - 'type' => 'submit', - 'form' => 'settings-form', - 'class' => 'primary', - 'label' => t('Save'), - 'detailSavePrimary' => true, - 'detailActionKind' => 'save', - ], - ] : [], - ]; - require templatePath('partials/app-details-titlebar.phtml'); - ?> - -
- - -
-
- - - - - - - - -
- -
-
- - - - - - -
-
- -
- -
-
- -
- - - - - - -
-
- -
- -
-
- - 0) + (int) ($defaultDepartmentId > 0) + (int) ($defaultRoleId > 0); ?> -
- - - - - - -
-
- -
-
- - -
- -
-
-
- -
-
- - - - - - -
-
- -
-
- - - - - - -
-
-
- -
- - - - - - - -
- -
- - - -
-
- - -
-
-
- -
- - - - - - -
-
- -
-
- -
- - - - - -
-
-
-
-
- - - - - - - -
-
- -
-
- - -
- - - - - -
-
-
- - - - - - -
-
- -
- -
- -
-
- -
- - - - - - - -
-
- -
-
- - -
-
> - - -
-
-
-
- - - - - - -
-
- -
-
- - - -
-
-
-
- -
-
- - -
-
- - -
-
- - -
- -
- -
-
- - - - - / - - - -
-
- -
-
- - -
-
-
- - -
- - - - - - -
-
- -
- - -
-
- - -
- - - - - - -
-
- -
- -
-
- -
- -
-
- - - - - - -
-
- -
- - -
-
- -
- - - - - - -
-
- -
- -
-
-
- - -
-
- - - - - - -
-
- -
- -
-
-
- -
- - -
-
- +
+

+
+
+
+
+ 'admin/settings/general', + 'label' => t('General'), + 'icon' => 'bi bi-sliders', + 'iconBg' => '#e0ecff', + 'iconColor' => '#2563eb', + 'tooltip' => t('App title, language, user creation defaults'), + ]); + appTile([ + 'href' => 'admin/settings/security', + 'label' => t('Security'), + 'icon' => 'bi bi-shield-lock', + 'iconBg' => '#ede9fe', + 'iconColor' => '#7c3aed', + 'tooltip' => t('Sessions, registration, lifecycle, audit, telemetry'), + ]); + appTile([ + 'href' => 'admin/settings/email', + 'label' => t('Email'), + 'icon' => 'bi bi-envelope', + 'iconBg' => '#fef3c7', + 'iconColor' => '#d97706', + 'tooltip' => t('SMTP connection and sender details'), + ]); + appTile([ + 'href' => 'admin/settings/api', + 'label' => t('API'), + 'icon' => 'bi bi-key', + 'iconBg' => '#d1fae5', + 'iconColor' => '#059669', + 'tooltip' => t('API token policy and CORS allowlist'), + ]); + appTile([ + 'href' => 'admin/settings/sso', + 'label' => t('Microsoft SSO'), + 'icon' => 'bi bi-microsoft', + 'iconBg' => '#dbeafe', + 'iconColor' => '#0891b2', + 'tooltip' => t('Shared Microsoft Entra ID credentials'), + ]); + appTile([ + 'href' => 'admin/settings/branding', + 'label' => t('Branding'), + 'icon' => 'bi bi-palette', + 'iconBg' => '#fce7f3', + 'iconColor' => '#be185d', + 'tooltip' => t('App logo and favicon'), + ]); + ?> +
diff --git a/pages/admin/settings/logo().php b/pages/admin/settings/logo().php index 426b54d..3173971 100644 --- a/pages/admin/settings/logo().php +++ b/pages/admin/settings/logo().php @@ -18,11 +18,11 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/branding')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'logo_upload')) { +if (!actionRequireCsrf('admin/settings/branding', 'admin/settings/branding', 'logo_upload')) { return; } @@ -32,10 +32,13 @@ $result = $logoService->saveUpload(requestInput()->filesAll()['logo'] ?? []); if (!($result['ok'] ?? false)) { $error = $result['error'] ?? t('Upload failed'); $errorBag->addGlobal((string) $error); - flashFormErrors($errorBag, 'admin/settings', 'logo_upload'); - Router::redirect('admin/settings'); + flashFormErrors($errorBag, 'admin/settings/branding', 'logo_upload'); + Router::redirect('admin/settings/branding'); return; } -Flash::success('Logo updated', 'admin/settings', 'logo_updated'); -Router::redirect('admin/settings'); +$redirectTarget = ((string) requestInput()->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/branding'; +Flash::success('Logo updated', $redirectTarget, 'logo_updated'); +Router::redirect($redirectTarget); diff --git a/pages/admin/settings/logo-delete().php b/pages/admin/settings/logo-delete().php index 0005174..a10337a 100644 --- a/pages/admin/settings/logo-delete().php +++ b/pages/admin/settings/logo-delete().php @@ -18,15 +18,15 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/branding')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'settings_logo_delete')) { +if (!actionRequireCsrf('admin/settings/branding', 'admin/settings/branding', 'settings_logo_delete')) { return; } $logoService = app(\MintyPHP\Service\Branding\BrandingLogoService::class); $logoService->delete(); -Flash::success('Logo removed', 'admin/settings', 'logo_removed'); -Router::redirect('admin/settings'); +Flash::success('Logo removed', 'admin/settings/branding', 'logo_removed'); +Router::redirect('admin/settings/branding'); diff --git a/pages/admin/settings/revoke-api-tokens().php b/pages/admin/settings/revoke-api-tokens().php index 14c884a..6dc3cec 100644 --- a/pages/admin/settings/revoke-api-tokens().php +++ b/pages/admin/settings/revoke-api-tokens().php @@ -18,15 +18,15 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/api')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'settings_tokens_revoke')) { +if (!actionRequireCsrf('admin/settings/api', 'admin/settings/api', 'settings_tokens_revoke')) { return; } $apiTokenService = app(\MintyPHP\Service\Auth\ApiTokenService::class); $count = $apiTokenService->revokeAllByAdmin(); -Flash::success(sprintf(t('%d API tokens revoked'), $count), 'admin/settings', 'api_tokens_revoked'); -Router::redirect('admin/settings'); +Flash::success(sprintf(t('%d API tokens revoked'), $count), 'admin/settings/api', 'api_tokens_revoked'); +Router::redirect('admin/settings/api'); diff --git a/pages/admin/settings/run-user-lifecycle().php b/pages/admin/settings/run-user-lifecycle().php index f4e4249..f12acb9 100644 --- a/pages/admin/settings/run-user-lifecycle().php +++ b/pages/admin/settings/run-user-lifecycle().php @@ -18,11 +18,11 @@ if (!$decision->isAllowed()) { Guard::deny(); } -if (!actionRequirePost('admin/settings')) { +if (!actionRequirePost('admin/settings/security')) { return; } -if (!actionRequireCsrf('admin/settings', 'admin/settings', 'user_lifecycle_run')) { +if (!actionRequireCsrf('admin/settings/security', 'admin/settings/security', 'user_lifecycle_run')) { return; } @@ -35,8 +35,8 @@ if (!($result['ok'] ?? false)) { } else { $errorBag->addGlobal('User lifecycle failed'); } - flashFormErrors($errorBag, 'admin/settings', 'user_lifecycle_run'); - Router::redirect('admin/settings'); + flashFormErrors($errorBag, 'admin/settings/security', 'user_lifecycle_run'); + Router::redirect('admin/settings/security'); } Flash::success( @@ -45,7 +45,7 @@ Flash::success( (int) ($result['deactivated_count'] ?? 0), (int) ($result['deleted_count'] ?? 0) ), - 'admin/settings', + 'admin/settings/security', 'user_lifecycle_completed' ); -Router::redirect('admin/settings'); +Router::redirect('admin/settings/security'); diff --git a/pages/admin/settings/security().php b/pages/admin/settings/security().php new file mode 100644 index 0000000..c6f137a --- /dev/null +++ b/pages/admin/settings/security().php @@ -0,0 +1,95 @@ +all(); +Guard::requireLogin(); +$request = requestInput(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +$adminSettingsService = app(AdminSettingsService::class); +$pageData = $adminSettingsService->buildPageData(); +$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; +$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; +$activeLoginTokens = (int) ($pageData['active_login_tokens'] ?? 0); + +if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings/security', 'admin/settings/security', 'csrf_expired')) { + return; +} + +if ($request->isMethod('POST')) { + $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ + 'actor_user_id' => $currentUserId, + ]); + if (!$updateDecision->isAllowed()) { + Guard::deny(); + } + + $sectionKeys = [ + 'app_registration', + 'session_idle_timeout_minutes', + 'session_absolute_timeout_hours', + 'remember_token_lifetime_days', + 'microsoft_auto_remember_default', + 'user_inactivity_deactivate_days', + 'user_inactivity_delete_days', + 'system_audit_enabled', + 'system_audit_retention_days', + 'frontend_telemetry_enabled', + 'frontend_telemetry_sample_rate', + 'frontend_telemetry_allowed_events', + ]; + $mergedPost = settingsSectionMergePost($values, $request->bodyAll(), $sectionKeys); + + $updateResult = $adminSettingsService->updateFromAdmin($mergedPost); + $errorBag = formErrors(); + foreach ((array) ($updateResult['errors'] ?? []) as $error) { + if (is_array($error)) { + $message = trim((string) ($error['message'] ?? '')); + $field = trim((string) ($error['field'] ?? 'input')); + if ($message !== '') { + $errorBag->add($field !== '' ? $field : 'input', $message); + } + continue; + } + $message = trim((string) $error); + if ($message !== '') { + $errorBag->addGlobal($message); + } + } + + if ($errorBag->hasAny()) { + flashFormErrors($errorBag, 'admin/settings/security', 'settings_update_error'); + Router::redirect('admin/settings/security'); + } + + $redirectTarget = ((string) $request->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/security'; + Flash::success('Settings updated', $redirectTarget, 'settings_updated'); + Router::redirect($redirectTarget); +} + +Buffer::set('title', t('Security settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('Security')], +]; diff --git a/pages/admin/settings/security(default).phtml b/pages/admin/settings/security(default).phtml new file mode 100644 index 0000000..fa196d2 --- /dev/null +++ b/pages/admin/settings/security(default).phtml @@ -0,0 +1,344 @@ + strtolower(trim((string) $entry)), + $frontendTelemetryAllowedEvents +)))); +if ($frontendTelemetryAllowedEvents === []) { + $frontendTelemetryAllowedEvents = ['warn_once', 'ajax_error']; +} +$appRegistrationDesc = $settings['app_registration']['description'] ?? 'setting.app_registration'; +$sessionIdleTimeoutMinutesDesc = $settings['session_idle_timeout_minutes']['description'] ?? 'setting.session_idle_timeout_minutes'; +$sessionAbsoluteTimeoutHoursDesc = $settings['session_absolute_timeout_hours']['description'] ?? 'setting.session_absolute_timeout_hours'; +$rememberTokenLifetimeDaysDesc = $settings['remember_token_lifetime_days']['description'] ?? 'setting.remember_token_lifetime_days'; +$microsoftAutoRememberDefaultDesc = $settings['microsoft_auto_remember_default']['description'] ?? 'setting.microsoft_auto_remember_default'; +$userInactivityDeactivateDaysDesc = $settings['user_inactivity_deactivate_days']['description'] ?? 'setting.user_inactivity_deactivate_days'; +$userInactivityDeleteDaysDesc = $settings['user_inactivity_delete_days']['description'] ?? 'setting.user_inactivity_delete_days'; +$systemAuditRetentionDaysDesc = $settings['system_audit_retention_days']['description'] ?? 'setting.system_audit_retention_days'; +$activeLoginTokens = (int) ($activeLoginTokens ?? 0); +$canUpdateSettings = (bool) ($canUpdateSettings ?? false); +$isReadOnly = !$canUpdateSettings; +$readonlyAttr = $isReadOnly ? 'readonly' : ''; +$disabledAttr = $isReadOnly ? 'disabled' : ''; +?> + +
+
+ t('Security settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => $canUpdateSettings ? [ + [ + 'form' => 'settings-security-form', + 'name' => 'action', + 'value' => 'save', + 'class' => 'secondary outline', + 'label' => t('Save'), + ], + [ + 'form' => 'settings-security-form', + 'name' => 'action', + 'value' => 'save_close', + 'class' => 'primary', + 'label' => t('Save & close'), + ], + ] : [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+
+ + + + + + +
+
+ +
+
+ + + + +
+
+
+ +
+ + + + + + + +
+
+ +
+
+ + +
+
+
+ +
+ + + + + + +
+
+ +
+
+ +
+ + + + + +
+
+
+
+ +
+ + + + + + + +
+
+ +
+
+ + +
+ + + + +
+
+ +
+ + + + + + +
+
+ +
+ +
+ +
+
+ +
+ + + + + + + +
+
+ +
+
+ + +
+
> + + +
+
+
+ +
+ + + + + + +
+
+ +
+
+ + + +
+
+
+ + +
+ + + + + + +
+
+ +
+ +
+
+ + + +
+
+ +
diff --git a/pages/admin/settings/sso().php b/pages/admin/settings/sso().php new file mode 100644 index 0000000..d55b064 --- /dev/null +++ b/pages/admin/settings/sso().php @@ -0,0 +1,85 @@ +all(); +Guard::requireLogin(); +$request = requestInput(); + +$currentUserId = (int) ($session['user']['id'] ?? 0); +$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); +$viewDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW, [ + 'actor_user_id' => $currentUserId, +]); +if (!$viewDecision->isAllowed()) { + Guard::deny(); +} +$viewCapabilities = $viewDecision->attribute('capabilities', []); +$canUpdateSettings = is_array($viewCapabilities) ? (bool) ($viewCapabilities['can_update_settings'] ?? false) : false; + +$adminSettingsService = app(AdminSettingsService::class); +$pageData = $adminSettingsService->buildPageData(); +$values = is_array($pageData['values'] ?? null) ? $pageData['values'] : []; +$settings = is_array($pageData['settings'] ?? null) ? $pageData['settings'] : []; + +if ($request->isMethod('POST') && !actionRequireCsrf('admin/settings/sso', 'admin/settings/sso', 'csrf_expired')) { + return; +} + +if ($request->isMethod('POST')) { + $updateDecision = $authorizationService->authorize(SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE, [ + 'actor_user_id' => $currentUserId, + ]); + if (!$updateDecision->isAllowed()) { + Guard::deny(); + } + + $sectionKeys = [ + 'microsoft_shared_client_id', + 'microsoft_shared_client_secret', + 'microsoft_authority', + ]; + $mergedPost = settingsSectionMergePost($values, $request->bodyAll(), $sectionKeys); + + $updateResult = $adminSettingsService->updateFromAdmin($mergedPost); + $errorBag = formErrors(); + foreach ((array) ($updateResult['errors'] ?? []) as $error) { + if (is_array($error)) { + $message = trim((string) ($error['message'] ?? '')); + $field = trim((string) ($error['field'] ?? 'input')); + if ($message !== '') { + $errorBag->add($field !== '' ? $field : 'input', $message); + } + continue; + } + $message = trim((string) $error); + if ($message !== '') { + $errorBag->addGlobal($message); + } + } + + if ($errorBag->hasAny()) { + flashFormErrors($errorBag, 'admin/settings/sso', 'settings_update_error'); + Router::redirect('admin/settings/sso'); + } + + $redirectTarget = ((string) $request->body('action', 'save') === 'save_close') + ? 'admin/settings' + : 'admin/settings/sso'; + Flash::success('Settings updated', $redirectTarget, 'settings_updated'); + Router::redirect($redirectTarget); +} + +Buffer::set('title', t('Microsoft SSO settings')); + +$breadcrumbs = [ + ['label' => t('Home'), 'path' => 'admin'], + ['label' => t('Settings'), 'path' => 'admin/settings'], + ['label' => t('Microsoft SSO')], +]; diff --git a/pages/admin/settings/sso(default).phtml b/pages/admin/settings/sso(default).phtml new file mode 100644 index 0000000..2f8fe3b --- /dev/null +++ b/pages/admin/settings/sso(default).phtml @@ -0,0 +1,101 @@ + + +
+
+ t('Microsoft SSO settings'), + 'backHref' => 'admin/settings', + 'backTitle' => t('Cancel'), + 'actions' => $canUpdateSettings ? [ + [ + 'form' => 'settings-sso-form', + 'name' => 'action', + 'value' => 'save', + 'class' => 'secondary outline', + 'label' => t('Save'), + ], + [ + 'form' => 'settings-sso-form', + 'name' => 'action', + 'value' => 'save_close', + 'class' => 'primary', + 'label' => t('Save & close'), + ], + ] : [], + ]; + require templatePath('partials/app-details-titlebar.phtml'); + ?> + +
+
+ + + + + + +
+
+ +
+ + +
+
+ +
+ + + + + + +
+
+ +
+ +
+
+ + +
+
+ +
diff --git a/tests/Architecture/AuthzAdminSettingsContractTest.php b/tests/Architecture/AuthzAdminSettingsContractTest.php index 23cf405..4737345 100644 --- a/tests/Architecture/AuthzAdminSettingsContractTest.php +++ b/tests/Architecture/AuthzAdminSettingsContractTest.php @@ -10,10 +10,22 @@ class AuthzAdminSettingsContractTest extends TestCase public function testAdminSettingsActionsUseCentralPolicies(): void { + // Landing hub: VIEW only (no POST handler). $indexContent = $this->readProjectFile('pages/admin/settings/index().php'); $this->assertStringContainsString('AuthorizationService::class', $indexContent); $this->assertStringContainsString('SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW', $indexContent); - $this->assertStringContainsString('SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE', $indexContent); + + // Subpages that expose a settings form: VIEW + UPDATE. + foreach (['general', 'security', 'email', 'api', 'sso'] as $section) { + $content = $this->readProjectFile("pages/admin/settings/{$section}().php"); + $this->assertStringContainsString('AuthorizationService::class', $content, $section); + $this->assertStringContainsString('SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW', $content, $section); + $this->assertStringContainsString('SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_UPDATE', $content, $section); + } + + // Branding landing: VIEW only (uploads post to separate action files). + $brandingIndex = $this->readProjectFile('pages/admin/settings/branding().php'); + $this->assertStringContainsString('SettingsAuthorizationPolicy::ABILITY_ADMIN_SETTINGS_VIEW', $brandingIndex); $logoUpload = $this->readProjectFile('pages/admin/settings/logo().php'); $this->assertStringContainsString('AuthorizationService::class', $logoUpload); diff --git a/tests/Architecture/AuthzUiTemplateContractTest.php b/tests/Architecture/AuthzUiTemplateContractTest.php index 3b695a5..ce6efa1 100644 --- a/tests/Architecture/AuthzUiTemplateContractTest.php +++ b/tests/Architecture/AuthzUiTemplateContractTest.php @@ -56,9 +56,14 @@ class AuthzUiTemplateContractTest extends TestCase public function testAdminSettingsTemplateUsesServerCapabilities(): void { - $templateContent = $this->readProjectFile('pages/admin/settings/index(default).phtml'); - $this->assertStringNotContainsString("can('settings.update')", $templateContent); - $this->assertStringContainsString('$canUpdateSettings', $templateContent); + // Settings was split into a landing hub + per-section subpages. + // The form-carrying subpages must use the server-side $canUpdateSettings + // capability instead of the legacy can() helper. + foreach (['general', 'security', 'email', 'api', 'sso', 'branding'] as $section) { + $templateContent = $this->readProjectFile("pages/admin/settings/{$section}(default).phtml"); + $this->assertStringNotContainsString("can('settings.update')", $templateContent, $section); + $this->assertStringContainsString('$canUpdateSettings', $templateContent, $section); + } } public function testAdminUserEditTemplateUsesServerCapabilities(): void diff --git a/tests/Architecture/DetailActionPolicyContractFiles.php b/tests/Architecture/DetailActionPolicyContractFiles.php index 8494a3f..3e935d0 100644 --- a/tests/Architecture/DetailActionPolicyContractFiles.php +++ b/tests/Architecture/DetailActionPolicyContractFiles.php @@ -17,7 +17,11 @@ final class DetailActionPolicyContractFiles 'pages/admin/departments/edit(default).phtml', 'pages/admin/roles/edit(default).phtml', 'pages/admin/permissions/edit(default).phtml', - 'pages/admin/settings/index(default).phtml', + // Settings subpages that carry danger actions (and therefore need + // the data-detail-confirm-message contract) — general/email/sso/branding + // have no destructive buttons and are deliberately excluded. + 'pages/admin/settings/security(default).phtml', + 'pages/admin/settings/api(default).phtml', 'templates/partials/app-details-titlebar.phtml', 'templates/partials/app-details-aside-actions.phtml', ]; diff --git a/tests/Architecture/DetailPageContractFiles.php b/tests/Architecture/DetailPageContractFiles.php index 07c3c4e..148e019 100644 --- a/tests/Architecture/DetailPageContractFiles.php +++ b/tests/Architecture/DetailPageContractFiles.php @@ -16,7 +16,11 @@ final class DetailPageContractFiles 'pages/admin/roles/_form.phtml', 'pages/admin/permissions/_form.phtml', 'pages/admin/scheduled-jobs/edit(default).phtml', - 'pages/admin/settings/index(default).phtml', + 'pages/admin/settings/general(default).phtml', + 'pages/admin/settings/security(default).phtml', + 'pages/admin/settings/email(default).phtml', + 'pages/admin/settings/api(default).phtml', + 'pages/admin/settings/sso(default).phtml', ]; } } diff --git a/tests/Architecture/FrontendRuntimeHostContractTest.php b/tests/Architecture/FrontendRuntimeHostContractTest.php index b040b2a..a4bea95 100644 --- a/tests/Architecture/FrontendRuntimeHostContractTest.php +++ b/tests/Architecture/FrontendRuntimeHostContractTest.php @@ -45,7 +45,6 @@ class FrontendRuntimeHostContractTest extends TestCase 'pages/admin/departments/_form.phtml', 'pages/admin/permissions/_form.phtml', 'pages/admin/roles/_form.phtml', - 'pages/admin/settings/index(default).phtml', 'pages/admin/stats/index(default).phtml', 'pages/admin/tenants/_form.phtml', 'pages/admin/users/_form.phtml',