feat(admin): eigene Vorlage fuer die Willkommensmail mit Platzhaltern, Vorschau und Testmail
Administrator -> Willkommensmail: Betreff, Ueberschrift, Einleitung, Abschluss je
Mandant (Tabelle WelcomeMailTemplate, RLS je Mandant, Migration 20260930150000);
Platzhalter {{name}} {{vorname}} {{benutzername}} {{email}} {{adresse}} {{firma}},
unbekannte -> 400 bzw. Hinweis beim Tippen; Werte escaped, Vorlage reiner Text.
Live-Vorschau per API gerendert, Testmail an die eigene Adresse ohne Token,
Zuruecksetzen auf Standard. Feste Bausteine (Kopf, Zugangsdaten, Anmeldehinweis,
Knoepfe, Fusszeile) bleiben immer drin.
Kopf: Wellenzelle dunkel statt weiss, Streifen 600x40, Inhalt 24 px naeher –
keine weisse Luecke, wenn OWA das CID-Bild nicht zeigt.
Lokal nachgewiesen: Hinweis/Sperre bei {{xyz}}, Speichern, Testmail (Link nur
/login), echte Mail mit eigener Vorlage und 7-Tage-Link.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -288,3 +288,80 @@ export const CUSTOM_MODULE_CATEGORY = "custom-modules" as const;
|
||||
export const CUSTOM_MODULE_CATEGORIES = [...MODULE_CATEGORIES, CUSTOM_MODULE_CATEGORY] as const;
|
||||
|
||||
export type CustomModuleCategory = (typeof CUSTOM_MODULE_CATEGORIES)[number];
|
||||
|
||||
/**
|
||||
* Eigene Vorlage der Willkommensmail (Administrator → Willkommensmail).
|
||||
*
|
||||
* Eine Stelle fuer API und Oberflaeche: welche Platzhalter es gibt, wie lang
|
||||
* die vier Textfelder sein duerfen, wie die Standardtexte lauten (Vorbelegung
|
||||
* im Formular, "Auf Standard zuruecksetzen", Versand ohne eigene Vorlage) und
|
||||
* wie unbekannte Platzhalter erkannt werden. Die API lehnt eine Vorlage mit
|
||||
* unbekanntem Platzhalter mit 400 ab; das Formular benennt ihn schon vorher.
|
||||
*
|
||||
* Die festen Bausteine der Mail (Kopf, Kasten Adresse/Benutzername,
|
||||
* Anmeldehinweis mit "Passwort festlegen", Knopf "Zu Tessera", Fusszeile)
|
||||
* sind KEIN Teil der Vorlage — so kann eine eigene Vorlage die Anmeldung
|
||||
* nicht kaputt machen.
|
||||
*/
|
||||
export const WELCOME_MAIL_PLACEHOLDERS = [
|
||||
'name',
|
||||
'vorname',
|
||||
'benutzername',
|
||||
'email',
|
||||
'adresse',
|
||||
'firma',
|
||||
] as const;
|
||||
|
||||
export type WelcomeMailPlaceholder = (typeof WELCOME_MAIL_PLACEHOLDERS)[number];
|
||||
|
||||
/** Die vier bearbeitbaren Texte der Willkommensmail. */
|
||||
export interface WelcomeMailTexts {
|
||||
subject: string;
|
||||
heading: string;
|
||||
intro: string;
|
||||
closing: string;
|
||||
}
|
||||
|
||||
/** Hoechstlaengen je Feld (Zeichen). */
|
||||
export const WELCOME_MAIL_LIMITS: Readonly<Record<keyof WelcomeMailTexts, number>> = {
|
||||
subject: 200,
|
||||
heading: 200,
|
||||
intro: 4000,
|
||||
closing: 4000,
|
||||
};
|
||||
|
||||
/**
|
||||
* Standardtexte — entsprechen der Willkommensmail vor der eigenen Vorlage.
|
||||
* Leerzeile = neuer Absatz, einfacher Zeilenumbruch = Umbruch im Absatz.
|
||||
*/
|
||||
export const DEFAULT_WELCOME_MAIL_TEXTS: Readonly<WelcomeMailTexts> = {
|
||||
subject: 'Willkommen bei Tessera',
|
||||
heading: 'Willkommen bei Tessera, {{name}}!',
|
||||
intro:
|
||||
'Für Sie wurde ein Zugang zu Tessera eingerichtet – Ihrer zentralen Plattform für Werkzeuge und Abläufe im Unternehmen. Alles, was Sie für Ihre tägliche Arbeit brauchen, finden Sie dort an einem Ort.',
|
||||
closing:
|
||||
'Tipp: Tessera gibt es auch als Desktop-App – den Download finden Sie auf der Anmeldeseite.\n\nViel Erfolg mit Tessera!',
|
||||
};
|
||||
|
||||
/** Findet `{{ … }}`; der Name ohne Leerraum steht in Gruppe 1. */
|
||||
export const WELCOME_MAIL_PLACEHOLDER_RE = /\{\{\s*([^{}]*?)\s*\}\}/g;
|
||||
|
||||
/** Ob `name` (Gross-/Kleinschreibung egal) ein bekannter Platzhalter ist. */
|
||||
export function isWelcomeMailPlaceholder(name: string): name is WelcomeMailPlaceholder {
|
||||
return (WELCOME_MAIL_PLACEHOLDERS as readonly string[]).includes(name.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle unbekannten Platzhalter eines Textes in der Form `{{xyz}}`, ohne
|
||||
* Doppelte, in Reihenfolge des ersten Auftretens.
|
||||
*/
|
||||
export function findUnknownWelcomeMailPlaceholders(text: string): string[] {
|
||||
const unknown: string[] = [];
|
||||
for (const match of text.matchAll(WELCOME_MAIL_PLACEHOLDER_RE)) {
|
||||
const token = `{{${match[1]}}}`;
|
||||
if (!isWelcomeMailPlaceholder(match[1]) && !unknown.includes(token)) {
|
||||
unknown.push(token);
|
||||
}
|
||||
}
|
||||
return unknown;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user