feat(webstatement): tambah proteksi password untuk ZIP file multi-account

Perubahan yang dilakukan:
- Memodifikasi fungsi createZipFile() di GenerateMultiAccountPdfJob untuk menambahkan proteksi password.
- Mengimplementasikan enkripsi AES-256 untuk setiap file PDF di dalam file ZIP.
- Menambahkan konfigurasi zip_password di file konfigurasi webstatement.
- Menambahkan environment variable WEBSTATEMENT_ZIP_PASSWORD sebagai default fallback.
- Mengambil password dari field statement->password, konfigurasi, atau nilai default.
- Menambahkan logging untuk mencatat aktivitas proteksi file ZIP.
- Menambahkan error handling pada proses enkripsi ZIP agar lebih stabil.
- Mendukung fleksibilitas sumber password (database, konfigurasi, atau default).
- Menambahkan lapisan keamanan tambahan pada proses distribusi file statement multi-account.
- Kompatibel dengan ekstensi PHP Zip dan library libzip untuk proses kompresi dan enkripsi.

Tujuan perubahan:
- Menjamin keamanan file ZIP yang dikirimkan untuk request multi-account.
- Memberikan fleksibilitas konfigurasi password tanpa mengganggu alur proses yang sudah ada.
- Meningkatkan kontrol keamanan distribusi file statement melalui proteksi terpusat.
This commit is contained in:
Daeng Deni Mardaeni
2025-07-10 20:05:50 +07:00
parent 5469045b5a
commit 9c5f8b1de4
2 changed files with 71 additions and 50 deletions

View File

@@ -675,7 +675,7 @@ class GenerateMultiAccountPdfJob implements ShouldQueue
}
/**
* Create ZIP file dari multiple PDF files
* Create ZIP file dari multiple PDF files dengan password protection
*
* @param array $pdfFiles
* @return string|null Path to ZIP file
@@ -692,15 +692,32 @@ class GenerateMultiAccountPdfJob implements ShouldQueue
$zipPath = storage_path("app/{$fullZipPath}");
// Get password from statement or use default
$password = $this->statement->password ?? config('webstatement.zip_password', 'statement123');
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE) !== TRUE) {
throw new Exception('Cannot create ZIP file');
}
// Set password for the ZIP file
if (!empty($password)) {
$zip->setPassword($password);
Log::info('ZIP password protection enabled', [
'statement_id' => $this->statement->id,
'zip_path' => $zipPath
]);
}
foreach ($pdfFiles as $pdfFile) {
if (file_exists($pdfFile)) {
$filename = basename($pdfFile);
$zip->addFile($pdfFile, $filename);
// Set encryption for each file in ZIP
if (!empty($password)) {
$zip->setEncryptionName($filename, ZipArchive::EM_AES_256);
}
}
}
@@ -711,10 +728,11 @@ class GenerateMultiAccountPdfJob implements ShouldQueue
throw new Exception('ZIP file was not created');
}
Log::info('ZIP file created successfully', [
Log::info('ZIP file created successfully with password protection', [
'zip_path' => $zipPath,
'pdf_count' => count($pdfFiles),
'statement_id' => $this->statement->id
'statement_id' => $this->statement->id,
'password_protected' => !empty($password)
]);
// Clean up individual PDF files after creating ZIP

View File

@@ -2,4 +2,7 @@
return [
'name' => 'Webstatement',
// ZIP file password configuration
'zip_password' => env('WEBSTATEMENT_ZIP_PASSWORD', 'statement123'),
];