import { Response } from 'express'; import { AuthRequest } from '../types/index.js'; import * as birthdayService from '../services/birthday.service.js'; import { sendEmail, SmtpCredentials } from '../services/smtpService.js'; import { getSystemEmailCredentials } from '../services/emailProvider/emailProviderService.js'; import { createAuditLog } from '../services/audit.service.js'; /** * Admin/Mitarbeiter: Kommende und vergangene Geburtstage * Query: ?past=7&future=30 (Default) */ export async function getUpcomingBirthdays(req: AuthRequest, res: Response) { try { // Portal-Kunden haben hier nichts zu suchen. Endpoint listet Namen, E-Mail, // Telefon und Geburtsdatum ALLER Kunden – ausschließlich Mitarbeiter-UI. // Pentest Runde 6 (2026-05-16) – HOCH. if (req.user?.isCustomerPortal) { res.status(403).json({ success: false, error: 'Nicht erlaubt' }); return; } const past = req.query.past ? parseInt(String(req.query.past)) : 7; const future = req.query.future ? parseInt(String(req.query.future)) : 30; const entries = await birthdayService.getUpcomingBirthdays(past, future); res.json({ success: true, data: entries }); } catch (error) { console.error('Fehler beim Abrufen der Geburtstage:', error); res.status(500).json({ success: false, error: 'Fehler beim Abrufen der Geburtstage' }); } } /** * Portal: Eigenen Geburtstags-Check – soll das Modal angezeigt werden? */ export async function getMyBirthday(req: AuthRequest, res: Response) { try { const user = req.user as any; if (!user?.isCustomerPortal || !user?.customerId) { return res.status(403).json({ success: false, error: 'Nur für Kundenportal-Benutzer' }); } const data = await birthdayService.checkMyBirthday(user.customerId); res.json({ success: true, data }); } catch (error) { console.error('Fehler beim Geburtstags-Check:', error); res.status(500).json({ success: false, error: 'Fehler beim Abruf' }); } } /** * Portal: Modal als gesehen markieren */ export async function acknowledgeMyBirthday(req: AuthRequest, res: Response) { try { const user = req.user as any; if (!user?.isCustomerPortal || !user?.customerId) { return res.status(403).json({ success: false, error: 'Nur für Kundenportal-Benutzer' }); } await birthdayService.acknowledgeBirthdayGreeting(user.customerId); res.json({ success: true }); } catch (error) { console.error('Fehler beim Bestätigen:', error); res.status(500).json({ success: false, error: 'Fehler beim Speichern' }); } } /** * Admin: Geburtstagsgruß-Marker für einen Kunden zurücksetzen (Debug / Re-Trigger). */ export async function resetBirthdayGreeting(req: AuthRequest, res: Response) { try { const customerId = parseInt(req.params.customerId); await birthdayService.resetBirthdayGreeting(customerId); await createAuditLog({ userId: req.user?.userId, userEmail: req.user?.email || 'unknown', action: 'UPDATE', resourceType: 'Customer', resourceId: customerId.toString(), resourceLabel: `Geburtstagsgruß-Marker zurückgesetzt`, endpoint: req.path, httpMethod: req.method, ipAddress: req.socket.remoteAddress || 'unknown', dataSubjectId: customerId, }); res.json({ success: true }); } catch (error) { console.error('Fehler beim Zurücksetzen:', error); res.status(500).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Zurücksetzen', }); } } /** * Admin: Geburtstagsgruß manuell senden (Email oder Link für WhatsApp/Telegram/Signal). */ export async function sendBirthdayGreeting(req: AuthRequest, res: Response) { try { const customerId = parseInt(req.params.customerId); const { channel } = req.body; // 'email', 'whatsapp', 'telegram', 'signal' if (!['email', 'whatsapp', 'telegram', 'signal'].includes(channel)) { return res.status(400).json({ success: false, error: 'Ungültiger Kanal' }); } const data = await birthdayService.getBirthdayGreetingData(customerId); if (!data) { return res.status(400).json({ success: false, error: 'Kunde hat kein Geburtsdatum hinterlegt', }); } const { subject, plain, html } = birthdayService.buildBirthdayGreetingText(data, data.age); if (channel === 'email') { if (!data.email) { return res.status(400).json({ success: false, error: 'Kunde hat keine E-Mail-Adresse hinterlegt', }); } const systemEmail = await getSystemEmailCredentials(); if (!systemEmail) { return res.status(400).json({ success: false, error: 'Keine System-E-Mail konfiguriert. Bitte in den Email-Provider-Einstellungen hinterlegen.', }); } const credentials: SmtpCredentials = { host: systemEmail.smtpServer, port: systemEmail.smtpPort, user: systemEmail.emailAddress, password: systemEmail.password, encryption: systemEmail.smtpEncryption, allowSelfSignedCerts: systemEmail.allowSelfSignedCerts, }; const result = await sendEmail(credentials, systemEmail.emailAddress, { to: data.email, subject, html, }, { context: 'birthday-greeting', customerId, triggeredBy: req.user?.email, }); if (!result.success) { return res.status(400).json({ success: false, error: `E-Mail-Versand fehlgeschlagen: ${result.error}`, }); } } await createAuditLog({ userId: req.user?.userId, userEmail: req.user?.email || 'unknown', action: 'CREATE', resourceType: 'Customer', resourceId: customerId.toString(), resourceLabel: `Geburtstagsgruß gesendet (${channel})`, endpoint: req.path, httpMethod: req.method, ipAddress: req.socket.remoteAddress || 'unknown', dataSubjectId: customerId, }); res.json({ success: true, data: { channel, messageText: plain }, }); } catch (error) { console.error('Fehler beim Senden des Geburtstagsgrußes:', error); res.status(500).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Senden', }); } }