Umlaut-Fix: zentrale Transliteration (ae/oe/ue/ss) fuer E-Mails, UPN und sAMAccountName + Release v10
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { useToast, ConfirmModal } from './Toast';
|
||||
import { apiFetch } from '../utils/api';
|
||||
import { toEmailLocalPart, toSamAccountName } from '../utils/umlauts';
|
||||
|
||||
export default function FillModal({ template, onSubmit, onClose }) {
|
||||
const { user: currentUser } = useAuth();
|
||||
@@ -95,7 +96,8 @@ export default function FillModal({ template, onSubmit, onClose }) {
|
||||
const parts = sourceFields.map((fieldLabel) => {
|
||||
const sourceStep = template.steps.find((s) => s.label === fieldLabel);
|
||||
if (!sourceStep || !values[sourceStep.id]) return '';
|
||||
return values[sourceStep.id].trim().toLowerCase().replace(/\s+/g, '.');
|
||||
// FIX: Umlaute konvertieren (ä→ae etc.) — sonst ungültige E-Mails wie j.schröder@...
|
||||
return toEmailLocalPart(values[sourceStep.id]);
|
||||
}).filter(Boolean);
|
||||
if (parts.length === 0) return '';
|
||||
const domain = step.email_domain.startsWith('@') ? step.email_domain : '@' + step.email_domain;
|
||||
@@ -151,13 +153,7 @@ export default function FillModal({ template, onSubmit, onClose }) {
|
||||
return sourceStep ? (values[sourceStep.id] || '').trim() : '';
|
||||
}).filter(Boolean);
|
||||
if (sourceValues.length > 0) {
|
||||
value = sourceValues.join('.')
|
||||
.toLowerCase()
|
||||
.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
|
||||
.replace(/Ä/g, 'ae').replace(/Ö/g, 'oe').replace(/Ü/g, 'ue')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/\s+/g, '.')
|
||||
.replace(/[^a-zA-Z0-9.]/g, '');
|
||||
value = toEmailLocalPart(sourceValues.join('.'));
|
||||
} else {
|
||||
value = '';
|
||||
}
|
||||
@@ -168,11 +164,7 @@ export default function FillModal({ template, onSubmit, onClose }) {
|
||||
const vorname = vornameStep ? (values[vornameStep.id] || '').trim() : '';
|
||||
const nachname = nachnameStep ? (values[nachnameStep.id] || '').trim() : '';
|
||||
if (vorname && nachname) {
|
||||
value = (nachname + vorname.charAt(0))
|
||||
.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
|
||||
.replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/[^a-zA-Z0-9]/g, '');
|
||||
value = toSamAccountName(nachname + vorname.charAt(0));
|
||||
} else {
|
||||
value = values[s.id] || '';
|
||||
}
|
||||
@@ -337,13 +329,7 @@ export default function FillModal({ template, onSubmit, onClose }) {
|
||||
return sourceStep ? (values[sourceStep.id] || '').trim() : '';
|
||||
}).filter(Boolean);
|
||||
if (sourceValues.length > 0) {
|
||||
return sourceValues.join('.')
|
||||
.toLowerCase()
|
||||
.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
|
||||
.replace(/Ä/g, 'ae').replace(/Ö/g, 'oe').replace(/Ü/g, 'ue')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/\s+/g, '.')
|
||||
.replace(/[^a-zA-Z0-9.]/g, '');
|
||||
return toEmailLocalPart(sourceValues.join('.'));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -353,11 +339,7 @@ export default function FillModal({ template, onSubmit, onClose }) {
|
||||
const vorname = vornameStep ? (values[vornameStep.id] || '').trim() : '';
|
||||
const nachname = nachnameStep ? (values[nachnameStep.id] || '').trim() : '';
|
||||
if (vorname && nachname) {
|
||||
return (nachname + vorname.charAt(0))
|
||||
.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
|
||||
.replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/[^a-zA-Z0-9]/g, '');
|
||||
return toSamAccountName(nachname + vorname.charAt(0));
|
||||
}
|
||||
return '';
|
||||
})()}
|
||||
|
||||
49
frontend/src/utils/umlauts.js
Normal file
49
frontend/src/utils/umlauts.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Umlaut-Transliteration für AD-kompatible Namen (E-Mails, sAMAccountName, UPN).
|
||||
* Frontend-Variante (ES-Module) von backend/umlauts.js — Logik identisch halten!
|
||||
*
|
||||
* Wandelt deutsche Sonderzeichen in ASCII-Äquivalente um:
|
||||
* ä→ae, ö→oe, ü→ue, ß→ss (und Großvarianten)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Umlaute → ASCII-Äquivalente. Großbuchstaben-Varianten werden erhalten
|
||||
* ("Schröder" → "Schroeder", "Straße" → "Strasse").
|
||||
*/
|
||||
export function transliterateUmlauts(str) {
|
||||
if (typeof str !== 'string') return '';
|
||||
return str
|
||||
.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
|
||||
.replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue')
|
||||
.replace(/ß/g, 'ss');
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalisiert einen Namen für den lokalen Teil einer E-Mail-Adresse:
|
||||
* Umlaute → ASCII, Kleinbuchstaben, Leerzeichen → Punkte, nur a-z0-9. erlaubt.
|
||||
* Beispiel: "Jürgen Schröder" → "juergen.schroeder"
|
||||
*/
|
||||
export function toEmailLocalPart(str) {
|
||||
if (typeof str !== 'string') return '';
|
||||
return transliterateUmlauts(str)
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '.')
|
||||
.replace(/[^a-z0-9.]/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalisiert einen Namen für sAMAccountName/UPN (Punkt-Format).
|
||||
*/
|
||||
export function toAdAccountName(str) {
|
||||
return toEmailLocalPart(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalisiert einen Namen für das Pre-Windows-2000-Format (Nachname+Initial):
|
||||
* Umlaute → ASCII, nur a-zA-Z0-9, Groß-/Kleinschreibung bleibt erhalten.
|
||||
* Beispiel: "Schröder" + "J" → "SchroederJ"
|
||||
*/
|
||||
export function toSamAccountName(str) {
|
||||
if (typeof str !== 'string') return '';
|
||||
return transliterateUmlauts(str).replace(/[^a-zA-Z0-9]/g, '');
|
||||
}
|
||||
Reference in New Issue
Block a user