Datenschutzerklärung als unterschreibbare PDF-Vorlage
Neuer Endpoint GET /api/gdpr/customer/:customerId/privacy-pdf generiert eine PDF mit: - Titel - Personalisiertem Kopf (Name / Firma + Kundennummer + Datum) - Voller Datenschutzerklärung (HTML → Text) - Einwilligungsklausel - Unterschriftenblock (Ort/Datum links, Unterschrift rechts, zweite Linie "Name in Druckbuchstaben" mit vorausgefuelltem Kundennamen) Auth: customers:read + canAccessCustomer. Filename: "datenschutzerklaerung-<kundennummer>.pdf". Im Tab "Einwilligungen / Datenschutz" beim Kunden gibt es jetzt direkt neben dem Upload-Feld den Link "Vorlage zum Unterschreiben" – Ausdrucken, unterschreiben lassen, scannen, wieder hochladen. Verifiziert auf dev: Magic-Bytes %PDF-1.3, %%EOF-Marker am Ende, 2 KB Output, pdftotext zeigt korrekten Aufbau inkl. Unterschrift- Linien. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4122,11 +4122,23 @@ function ConsentTab({
|
||||
<p className="text-sm text-gray-500 mb-2">
|
||||
Unterschriebene Datenschutzerklärung als PDF hochladen. Dies gilt als vollständige Einwilligung.
|
||||
</p>
|
||||
<FileUpload
|
||||
onUpload={handlePrivacyPolicyUpload}
|
||||
accept=".pdf"
|
||||
label="PDF hochladen"
|
||||
/>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<a
|
||||
href={gdprApi.getSignablePrivacyPdfUrl(customerId)}
|
||||
download
|
||||
className="inline-flex items-center gap-1 text-sm text-blue-600 hover:underline"
|
||||
title="PDF mit personalisiertem Kopf + Unterschriftsfeld zum Ausdrucken"
|
||||
>
|
||||
<Download className="w-4 h-4" />
|
||||
Vorlage zum Unterschreiben
|
||||
</a>
|
||||
<span className="text-gray-300">·</span>
|
||||
<FileUpload
|
||||
onUpload={handlePrivacyPolicyUpload}
|
||||
accept=".pdf"
|
||||
label="Unterschriebene PDF hochladen"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1812,6 +1812,14 @@ export const gdprApi = {
|
||||
const res = await api.post<ApiResponse<{ url: string; channel: string; hash: string }>>(`/gdpr/customer/${customerId}/send-consent-link`, { channel });
|
||||
return res.data;
|
||||
},
|
||||
// Unterschreibbare Datenschutzerklärung als PDF (Papierform).
|
||||
// Liefert die URL inkl. Auth-Token, damit window.open/<a download> klappt
|
||||
// (Browser senden bei plain links keinen Authorization-Header).
|
||||
getSignablePrivacyPdfUrl: (customerId: number): string => {
|
||||
const token = getAccessToken();
|
||||
const base = `/api/gdpr/customer/${customerId}/privacy-pdf`;
|
||||
return token ? `${base}?token=${encodeURIComponent(token)}` : base;
|
||||
},
|
||||
// Portal: Eigene Datenschutzseite
|
||||
getMyPrivacy: async () => {
|
||||
const res = await api.get<ApiResponse<{ privacyPolicyHtml: string; consents: CustomerConsent[] }>>('/gdpr/my-privacy');
|
||||
|
||||
Reference in New Issue
Block a user