import { Request, Response } from 'express'; import * as consentPublicService from '../services/consent-public.service.js'; import { createAuditLog } from '../services/audit.service.js'; import { CONSENT_TYPE_LABELS } from '../services/consent.service.js'; import { ConsentType } from '@prisma/client'; import { sendEmail } from '../services/smtpService.js'; import { getSystemEmailCredentials } from '../services/emailProvider/emailProviderService.js'; /** * Öffentliche Consent-Seite: Kundendaten + Datenschutztext + Status */ export async function getConsentPage(req: Request, res: Response) { try { const { hash } = req.params; const result = await consentPublicService.getCustomerByConsentHash(hash); if (!result) { return res.status(404).json({ success: false, error: 'Ungültiger Link' }); } const privacyPolicyHtml = await consentPublicService.getPrivacyPolicyHtml(result.customer.id); // Consent-Status mit Labels const consentsWithLabels = result.consents.map((c) => ({ consentType: c.consentType, status: c.status, label: CONSENT_TYPE_LABELS[c.consentType as ConsentType]?.label || c.consentType, description: CONSENT_TYPE_LABELS[c.consentType as ConsentType]?.description || '', grantedAt: c.grantedAt, })); res.json({ success: true, data: { customer: { firstName: result.customer.firstName, lastName: result.customer.lastName, customerNumber: result.customer.customerNumber, }, privacyPolicyHtml, consents: consentsWithLabels, allGranted: consentsWithLabels.every((c) => c.status === 'GRANTED'), }, }); } catch (error) { console.error('Fehler beim Laden der Consent-Seite:', error); res.status(500).json({ success: false, error: 'Fehler beim Laden' }); } } /** * Alle 4 Einwilligungen erteilen (öffentlicher Link) */ export async function grantAllConsents(req: Request, res: Response) { try { const { hash } = req.params; const ipAddress = req.ip || req.socket.remoteAddress || 'unknown'; const results = await consentPublicService.grantAllConsentsPublic(hash, ipAddress); // Audit-Log (manuell, da keine Auth-Middleware) const customer = await consentPublicService.getCustomerByConsentHash(hash); if (customer) { for (const type of Object.values(ConsentType)) { await createAuditLog({ userEmail: customer.customer.email || 'public-link', action: 'UPDATE', sensitivity: 'HIGH', resourceType: 'CustomerConsent', resourceId: `${customer.customer.id}:${type}`, resourceLabel: `Einwilligung ${type} erteilt via Public-Link`, endpoint: `/api/public/consent/${hash}/grant`, httpMethod: 'POST', ipAddress, dataSubjectId: customer.customer.id, legalBasis: 'DSGVO Art. 6 Abs. 1 lit. a', }); } } // Bestätigungs-E-Mail senden if (customer?.customer.email) { try { const systemEmail = await getSystemEmailCredentials(); if (systemEmail) { const consentList = Object.values(ConsentType) .map(t => CONSENT_TYPE_LABELS[t]?.label || t) .map(label => `
  • ${label}
  • `) .join(''); const confirmationHtml = `

    Bestätigung Ihrer Einwilligungen

    Sehr geehrte(r) ${customer.customer.firstName} ${customer.customer.lastName},

    vielen Dank! Hiermit bestätigen wir, dass Sie am ${new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })} folgenden Einwilligungen zugestimmt haben:

    Sie können Ihre Einwilligungen jederzeit über Ihr Kundenportal widerrufen.


    Hacker-Net Telekommunikation – Stefan Hacker
    Am Wunderburgpark 5b, 26135 Oldenburg
    info@hacker-net.de

    `; await sendEmail( { host: systemEmail.smtpServer, port: systemEmail.smtpPort, user: systemEmail.emailAddress, password: systemEmail.password, encryption: systemEmail.smtpEncryption, allowSelfSignedCerts: systemEmail.allowSelfSignedCerts, }, systemEmail.emailAddress, { to: customer.customer.email, subject: 'Bestätigung Ihrer Datenschutz-Einwilligungen', html: confirmationHtml, }, { context: 'consent-confirmation', customerId: customer.customer.id, } ); } } catch (emailError) { // E-Mail-Fehler soll den Consent-Grant nicht blockieren console.error('Bestätigungs-E-Mail konnte nicht gesendet werden:', emailError); } } res.json({ success: true, data: results }); } catch (error: any) { console.error('Fehler beim Erteilen der Einwilligungen:', error); res.status(400).json({ success: false, error: error.message || 'Fehler beim Erteilen' }); } } /** * Datenschutzerklärung als PDF */ export async function getConsentPdf(req: Request, res: Response) { try { const { hash } = req.params; const result = await consentPublicService.getCustomerByConsentHash(hash); if (!result) { return res.status(404).json({ success: false, error: 'Ungültiger Link' }); } const pdfBuffer = await consentPublicService.generateConsentPdf(result.customer.id); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'inline; filename="datenschutzerklaerung.pdf"'); res.send(pdfBuffer); } catch (error) { console.error('Fehler beim Generieren des PDFs:', error); res.status(500).json({ success: false, error: 'Fehler beim Generieren' }); } }