# Plan: Issue #48 — Encrypted export (password-protected ZIP) ## Summary Add encrypted export functionality that wraps sensitive CSV/PDF export files in AES-256 password-protected ZIP archives. The user provides a password at export time, and only users with banking visibility can export banking reports. All sensitive exports are audit-logged. ## Existing Code Context - `EncryptionService.php` — field-level encryption (Issue #60), NOT file-level - `CsvExportService.php` — generates CSV exports with UTF-8 BOM - `ExportController.php` — REST endpoints for CSV downloads - `AuditService.php` — audit logging with field-level diffs - `PermissionService.php` — access control with `canSeeBanking()` method - Routes in `appinfo/routes.php` ## Implementation Steps ### Step 1: Create EncryptedExportService **File:** `lib/Service/EncryptedExportService.php` Service that wraps any export content (CSV or PDF binary) in a password-protected ZIP. ```php class EncryptedExportService { // Dependencies: AuditService, PermissionService, IUserSession, LoggerInterface // createEncryptedZip(string $content, string $filename, string $password): string // - Creates temp ZipArchive // - Sets encryption to AES-256 (ZipArchive::EM_AES_256) // - Adds content as file inside ZIP // - Returns ZIP binary // - Cleanup: unlink temp files // createEncryptedExport(string $content, string $innerFilename, string $password, string $userId, string $exportType): array // - Permission check for sensitive exports // - Calls createEncryptedZip // - Audit logs the export // - Returns {content: binary, filename: "Export_encrypted_.zip"} } ``` ### Step 2: Add Encrypted Export Endpoints to ExportController **File:** `lib/Controller/ExportController.php` Add new endpoints that accept a `password` POST parameter and return encrypted ZIPs: - `POST /api/v1/export/members/encrypted` — encrypted member list - `POST /api/v1/export/fees/encrypted` — encrypted fee records - `POST /api/v1/export/birthdays/encrypted` — encrypted birthday list - `POST /api/v1/export/banking/encrypted` — encrypted banking data (requires canSeeBanking) POST method used because password must not appear in URL/query string. ### Step 3: Add Banking Export to CsvExportService **File:** `lib/Service/CsvExportService.php` Add `exportBankingList()` method that exports IBAN/Kontoinhaber data (decrypted) for members. This is a sensitive export that requires banking permission. ### Step 4: Register New Routes **File:** `appinfo/routes.php` Add routes for the encrypted export endpoints. ### Step 5: Add Unit Test **File:** `tests/Unit/EncryptedExportServiceTest.php` Test ZIP creation, encryption flag usage, audit logging. ## Acceptance Criteria Checklist 1. [ ] Sensitive exports prompt for password and produce AES-256 encrypted ZIP 2. [ ] ZIP contains the original PDF or CSV file inside 3. [ ] ZipArchive with EM_AES_256 encryption is used 4. [ ] Fallback handling if ZipArchive encryption is not available 5. [ ] Audit log entry for every sensitive export (who exported what, when) 6. [ ] Permission check: only users with banking visibility can export banking reports 7. [ ] Clear separation of encrypted vs. plain export endpoints 8. [ ] POST method used for encrypted endpoints (password not in URL)