2c7a87ccd3
Erweitert das bestehende Factory-Defaults-Bundle um vier HTML-Standardtexte (Datenschutzerklärung, Impressum, Vollmacht-Vorlage, Website-Datenschutz) und ergänzt den bisherigen CLI-Only-Import um einen Upload-Pfad in der UI. Backend: - collectFactoryDefaults() zieht jetzt auch die Whitelist-AppSettings - exportFactoryDefaults() legt sie als app-settings/app-settings.json ins ZIP - importFactoryDefaults(buffer) liest die ZIP idempotent ein – upserts pro Kategorie, Whitelist-Filter für AppSettings, Anti-Zip-Slip durch basename beim PDF-Lookup - POST /api/factory-defaults/import (multer memoryStorage, max 50 MB, settings:update) - seed-factory-defaults.ts (CLI) gleichermaßen um seedAppSettings() erweitert Frontend: - Import-Card in FactoryDefaults.tsx: Datei-Upload statt CLI-Anleitung - Erfolgs-Box mit Counts pro Kategorie + Warnings (z.B. fehlende PDFs im ZIP) - Preview zeigt jetzt auch die Anzahl HTML-Templates Live verifiziert: Round-Trip Export → DELETE privacyPolicyHtml → Import → Wert (13.6 KB) wieder vollständig hergestellt, Audit-Log zeigt EXPORT + UPDATE-Eintrag mit Detail-Counts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import { Router } from 'express';
|
||
import multer from 'multer';
|
||
import * as factoryDefaultsController from '../controllers/factoryDefaults.controller.js';
|
||
import { authenticate, requirePermission } from '../middleware/auth.js';
|
||
|
||
const router = Router();
|
||
|
||
// In-Memory-Upload für die ZIP – wird direkt verarbeitet, keine temporäre Datei.
|
||
const upload = multer({
|
||
storage: multer.memoryStorage(),
|
||
fileFilter: (_req, file, cb) => {
|
||
const ok =
|
||
file.mimetype === 'application/zip' ||
|
||
file.mimetype === 'application/x-zip-compressed' ||
|
||
file.mimetype === 'application/octet-stream' || // manche Browser senden das für .zip
|
||
file.originalname.toLowerCase().endsWith('.zip');
|
||
if (ok) cb(null, true);
|
||
else cb(new Error('Nur ZIP-Dateien sind erlaubt'));
|
||
},
|
||
limits: { fileSize: 50 * 1024 * 1024 },
|
||
});
|
||
|
||
// Preview (was wäre im Export drin?)
|
||
router.get(
|
||
'/preview',
|
||
authenticate,
|
||
requirePermission('settings:read'),
|
||
factoryDefaultsController.previewFactoryDefaults,
|
||
);
|
||
|
||
// Export als ZIP-Download
|
||
router.get(
|
||
'/export',
|
||
authenticate,
|
||
requirePermission('settings:update'),
|
||
factoryDefaultsController.exportFactoryDefaults,
|
||
);
|
||
|
||
// Import aus ZIP (multipart, Feld 'zip')
|
||
router.post(
|
||
'/import',
|
||
authenticate,
|
||
requirePermission('settings:update'),
|
||
upload.single('zip'),
|
||
factoryDefaultsController.importFactoryDefaults,
|
||
);
|
||
|
||
export default router;
|