Files
Mieterportal/src/lib/mail.ts
T
ah-admin 5503ce5fc5 v1.2: E-Mail-Benachrichtigungen an Portal angeschlossen
- nginx-Proxy POST /api/mail/send -> mp-mail-api:8080 (nur POST, 64k Limit)
- Token serverseitig via envsubst-Template + portal.env (gitignored, nur Server)
- src/lib/mail.ts: fire-and-forget Versand, Empfaenger-Aufloesung (Verwaltung/Mieter)
- Benachrichtigung: neue Schadensmeldung -> Verwaltung, Nachrichten/Antworten -> Gegenstelle
- E2E live verifiziert (versandt: true an axel@hocks.eu), GET 403
- Doku (kimi.md, README) nachgefuehrt
2026-10-02 12:21:12 +02:00

65 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** E-Mail-Benachrichtigungen über die Portal-Mail-API.
*
* Der Browser ruft nur denselben Ursprung an: POST /api/mail/send wird vom
* Portal-nginx (Container mp-portal) an die Mail-API (mp-mail-api:8080)
* weitergereicht und dabei serverseitig mit dem API-Token authentifiziert.
* Das Token liegt also weder im Repo noch im JavaScript.
*
* Versand ist bewusst „fire-and-forget": Klappt der Versand nicht (Offline,
* API down), bleibt die Portal-Aktion trotzdem erhalten – der Fehler landet
* nur in der Browser-Konsole.
*/
import type { Benutzer } from '../types'
const ENDPUNKT = '/api/mail/send'
export async function sendeMail(an: string, betreff: string, text: string): Promise<boolean> {
try {
const res = await fetch(ENDPUNKT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ to: an, subject: betreff, text }),
})
return res.ok
} catch {
return false
}
}
/** Fire-and-forget an eine oder mehrere Adressen (null/leer = nichts senden). */
export function sendeBenachrichtigung(an: string | string[] | null | undefined, betreff: string, text: string) {
const adressen = (Array.isArray(an) ? an : an ? [an] : []).filter(Boolean)
for (const adresse of adressen) {
sendeMail(adresse, betreff, text).then((ok) => {
if (!ok) console.warn(`[mail] Versand an ${adresse} fehlgeschlagen`)
})
}
}
const FUSSZEILE =
'\n\n— Automatische Benachrichtigung aus dem Mieterportal der Hinterstein Immobilien'
export function nachrichtenText(koerper: string): string {
return `${koerper}${FUSSZEILE}`
}
/** E-Mail-Adressen aller aktiven Verwaltungsbenutzer. */
export function verwaltungsAdressen(benutzer: Benutzer[]): string[] {
return benutzer
.filter((b) => b.rolle === 'verwaltung' && b.aktiv && b.email)
.map((b) => b.email)
}
/** E-Mail-Adressen der Mieter einer bestimmten Wohnung. */
export function mieterAdressenFuerEinheit(benutzer: Benutzer[], einheitId: string): string[] {
return benutzer
.filter((b) => b.rolle === 'mieter' && b.aktiv && b.einheitId === einheitId && b.email)
.map((b) => b.email)
}
/** Anzeigename einer Wohnung, z. B. „Hauptstraße 12, Whg. 7". */
export function einheitLabel(einheit: { building: string; number: string }): string {
return `${einheit.building}, Whg. ${einheit.number}`
}