fix(i18n): drei uebersehene Umlaute und die Luecke, durch die sie schluepften

Die Gegenprobe im Browser hat drei Stellen gefunden, die der erste Durchgang nicht
erwischt hat — darunter zwei gut sichtbare Schaltflaechen:

  Aenderungen speichern  ->  Änderungen speichern
  Oeffnen                ->  Öffnen
  Eine Aenderung ...     ->  Eine Änderung ...

Die Ursache ist dieselbe fuer alle drei und steckte im Waechter selbst: sein
Verdachtsmuster /(ae|oe|ue|ss)/ war case-sensitiv. "Aenderungen" beginnt mit "Ae",
nicht mit "ae", und ist deshalb durchgerutscht — der Waechter konnte gar nicht
anschlagen. Muster jetzt case-insensitiv; damit erfasst es auch die
grossgeschriebenen Formen.

Durch die schaerfere Pruefung melden sich neu die Abkuerzungen RSS, RSSGenerator und
SSL. Sie tragen ein doppeltes S ohne Umlaut-Bezug und stehen jetzt auf der
Positivliste.

Ausserdem zwei Meldungen des LDAP-Abgleichs korrigiert, die dem Administrator in der
Oberflaeche angezeigt werden (result.errors landet in der Fehlerliste der
LDAP-Seite): "ungueltiger ldapObjectGuid-Wert" und "Base-DN-Konfiguration pruefen.
Nicht geloescht." Drei Tests pinnen diese Texte bewusst und wurden mitgezogen.

Bewusst NICHT angefasst: die Warnung in crypto.service.ts. Sie geht ueber
logger.warn ins Protokoll und nicht an einen Nutzer.

Unabhaengig gegengeprueft: von allen Tokens in de.json, die ae/oe/ue tragen, ist
keines mehr eine Ersatzschreibung. 642 API-Tests und 225 Web-Tests gruen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5jtbGzC5Sf9npJ3JCjKhq
This commit is contained in:
2026-09-07 13:16:57 +02:00
parent cb6ba7188a
commit 85d2d772b6
5 changed files with 26 additions and 10 deletions
+4 -4
View File
@@ -128,7 +128,7 @@
"uploadCta": "Bild hochladen",
"uploadSuccess": "Profilbild wurde erfolgreich aktualisiert.",
"uploadError": "Hochladen fehlgeschlagen. Bitte prüfen Sie das Dateiformat und die Dateigröße.",
"ldapManagedNotice": "Ihr Passwort wird über das Verzeichnis (LDAP) verwaltet. Eine Aenderung ist hier nicht möglich.",
"ldapManagedNotice": "Ihr Passwort wird über das Verzeichnis (LDAP) verwaltet. Eine Änderung ist hier nicht möglich.",
"passwordSectionTitle": "Passwort ändern",
"accentColorLabel": "Akzentfarbe",
"accentColorHelp": "Passt die Hauptfarbe der Oberfläche an.",
@@ -173,9 +173,9 @@
"catalogTitle": "Widget hinzufügen",
"deleteTooltip": "Widget entfernen",
"editMode": "Dashboard bearbeiten",
"saveChanges": "Aenderungen speichern",
"saveChanges": "Änderungen speichern",
"layoutLoadError": "Dashboard konnte nicht geladen werden. Bitte laden Sie die Seite neu.",
"widgetSaveError": "Aenderungen konnten nicht gespeichert werden. Bitte versuchen Sie es erneut.",
"widgetSaveError": "Änderungen konnten nicht gespeichert werden. Bitte versuchen Sie es erneut.",
"clock": {
"name": "Uhr",
"description": "Zeigt die aktuelle Uhrzeit an",
@@ -479,7 +479,7 @@
},
"modules": {
"categoryTitle": "Module: {category}",
"openModule": "Oeffnen",
"openModule": "Öffnen",
"noModules": "Keine aktiven Module in dieser Kategorie",
"notFound": "Modul nicht gefunden",
"notFoundDescription": "Das angeforderte Modul existiert nicht oder ist nicht aktiviert.",
@@ -42,6 +42,12 @@ export const UMLAUT_REPLACEMENTS: Record<string, string> = {
Ueberpruefe: 'Überprüfe',
Zertifikatspruefung: 'Zertifikatsprüfung',
aendern: 'ändern',
// Nachtrag 2026-09-07: die grossgeschriebenen Formen fehlten. Der Waechter
// hat sie nicht gemeldet, weil sein Verdachtsmuster case-sensitiv war und
// "Ae"/"Oe" deshalb durchrutschten — mitbehoben in umlaut-guard.spec.ts.
Aenderung: 'Änderung',
Aenderungen: 'Änderungen',
Oeffnen: 'Öffnen',
geaendert: 'geändert',
Moechten: 'Möchten',
moeglich: 'möglich',
@@ -162,4 +168,10 @@ export const UMLAUT_ALLOWLIST: readonly string[] = [
'vertrauenswürdigen',
'ausschließen',
'entschlüsselt',
// Nachtrag 2026-09-07: Abkuerzungen mit doppeltem S. Sie tauchen erst auf,
// seit das Verdachtsmuster case-insensitiv prueft — vorher fiel jedes
// grossgeschriebene "SS" durch dasselbe Loch wie "Aenderungen".
'RSS',
'RSSGenerator',
'SSL',
];
+5 -1
View File
@@ -22,7 +22,11 @@ import { UMLAUT_ALLOWLIST, UMLAUT_REPLACEMENTS } from './umlaut-dictionary';
*/
const UMLAUT_TOKEN_RE = /[A-Za-zÄÖÜäöüß]+/g;
const SUSPECT_RE = /(ae|oe|ue|ss)/;
// Case-insensitive, sonst rutscht jede grossgeschriebene Ersatzschreibung durch:
// "Aenderungen" beginnt mit "Ae", nicht mit "ae". Genau daran sind beim ersten
// Durchgang "Aenderung", "Aenderungen" und "Oeffnen" vorbeigekommen — darunter
// zwei gut sichtbare Schaltflaechen.
const SUSPECT_RE = /(ae|oe|ue|ss)/i;
/** Recursively flattens a nested message object into dot-joined leaf key paths. */
function flattenKeys(obj: unknown, prefix = ''): string[] {