- Move completed plan files to .plans/done/ - Move 18 open plan files to .plans/open/ - Update .gitignore to exclude .verified_plans temp file - Verified all 18 open plans still describe unimplemented issues
3.3 KiB
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-levelCsvExportService.php— generates CSV exports with UTF-8 BOMExportController.php— REST endpoints for CSV downloadsAuditService.php— audit logging with field-level diffsPermissionService.php— access control withcanSeeBanking()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.
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_<date>.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 listPOST /api/v1/export/fees/encrypted— encrypted fee recordsPOST /api/v1/export/birthdays/encrypted— encrypted birthday listPOST /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
- Sensitive exports prompt for password and produce AES-256 encrypted ZIP
- ZIP contains the original PDF or CSV file inside
- ZipArchive with EM_AES_256 encryption is used
- Fallback handling if ZipArchive encryption is not available
- Audit log entry for every sensitive export (who exported what, when)
- Permission check: only users with banking visibility can export banking reports
- Clear separation of encrypted vs. plain export endpoints
- POST method used for encrypted endpoints (password not in URL)