diff --git a/app/Services/Documents/TokenValueResolver.php b/app/Services/Documents/TokenValueResolver.php index 81121e0..4a098c7 100644 --- a/app/Services/Documents/TokenValueResolver.php +++ b/app/Services/Documents/TokenValueResolver.php @@ -19,8 +19,12 @@ public function resolve(array $tokens, DocumentTemplate $template, Contract $con { $values = []; $unresolved = []; - $globalWhitelist = config('documents.whitelist', []); - $templateEntities = $template->entities ?: array_keys($globalWhitelist); + // Retrieve whitelist from DB settings (if present) and merge with config baseline (config acts as baseline; DB can add or override entity arrays) + $settingsWhitelist = app(\App\Services\Documents\DocumentSettings::class)->get()->whitelist ?? []; + $configWhitelist = config('documents.whitelist', []); + // Merge preserving DB additions/overrides + $globalWhitelist = array_replace($configWhitelist, $settingsWhitelist); + $templateEntities = $template->entities ?: array_keys($globalWhitelist); foreach ($tokens as $token) { [$entity,$attr] = explode('.', $token, 2); if ($entity === 'generation') { diff --git a/tests/Feature/DocumentSettingsWhitelistTest.php b/tests/Feature/DocumentSettingsWhitelistTest.php new file mode 100644 index 0000000..6f118c6 --- /dev/null +++ b/tests/Feature/DocumentSettingsWhitelistTest.php @@ -0,0 +1,74 @@ +create(); + $role = Role::firstOrCreate(['slug' => 'admin'], ['name' => 'Admin']); + $user->roles()->sync([$role->id]); + $this->actingAs($user); + + // Extend DB whitelist: add duplicate safe attribute (description already in config but we will ensure merge works) + $settings = DocumentSetting::instance(); + $wl = $settings->whitelist; + $wl['contract'] = array_values(array_unique(array_merge($wl['contract'] ?? [], ['reference','description']))); + $settings->whitelist = $wl; + $settings->save(); + app(\App\Services\Documents\DocumentSettings::class)->refresh(); + + // Build minimal docx with new token {{contract.amount}} + $tmp = tempnam(sys_get_temp_dir(), 'doc'); + $zip = new \ZipArchive; + $zip->open($tmp, \ZipArchive::OVERWRITE); + $zip->addFromString('[Content_Types].xml', ''); + $zip->addFromString('word/document.xml', '{{contract.description}}'); + $zip->close(); + $bytes = file_get_contents($tmp); + Storage::disk('public')->put('templates/whitelist-attr.docx', $bytes); + + $template = new \App\Models\DocumentTemplate; + $template->fill([ + 'name' => 'WL Test', + 'slug' => 'wl-template', + 'core_entity' => 'contract', + 'version' => 1, + 'engine' => 'docx', + 'file_path' => 'templates/whitelist-attr.docx', + 'file_hash' => sha1($bytes), + 'file_size' => strlen($bytes), + 'mime_type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'active' => true, + 'output_filename_pattern' => null, + 'fail_on_unresolved' => false, + 'entities' => [], + 'columns' => [], + 'tokens' => [], + 'created_by' => $user->id, + 'updated_by' => $user->id, + ]); + $template->save(); + + $contract = Contract::factory()->create(['description' => 'Opis test']); + + $resp = $this->postJson(route('contracts.generate-document', ['contract' => $contract->uuid]), [ + 'template_slug' => 'wl-template', + ]); + $resp->assertOk(); + } +}