diff --git a/config/ipdr.php b/config/ipdr.php new file mode 100644 index 0000000..4ed38fe --- /dev/null +++ b/config/ipdr.php @@ -0,0 +1,15 @@ + [ + 'host' => env('IPDR_DB_HOST'), + 'port' => env('IPDR_DB_PORT'), + 'database' => env('IPDR_DB_DATABASE'), + 'username' => env('IPDR_DB_USERNAME'), + 'password' => env('IPDR_DB_PASSWORD'), + ], +]; diff --git a/resources/views/livewire/session-records/session-records.php b/resources/views/livewire/session-records/session-records.php index 7694540..75ea6a5 100644 --- a/resources/views/livewire/session-records/session-records.php +++ b/resources/views/livewire/session-records/session-records.php @@ -6,6 +6,7 @@ use Illuminate\Validation\Rule; use Ispgrid\Ipdr\Archive\CopySessions; use Ispgrid\Ipdr\Archive\KeepDays; +use Ispgrid\Ipdr\Search\CsvCell; use Ispgrid\Ipdr\Search\SessionRows; use Ispgrid\Ipdr\Search\SessionSearch; use Livewire\Attributes\Computed; @@ -82,7 +83,7 @@ public function export(): StreamedResponse fputcsv($output, $header, escape: ''); foreach ($rows as $row) { - fputcsv($output, [$row['username'], $row['customer'], $row['mobile'], $row['address'], $row['mac'], $row['ip'], $row['nas'], $row['start'], $row['end'], $row['duration'], $row['down'], $row['up']], escape: ''); + fputcsv($output, array_map(CsvCell::safe(...), [$row['username'], $row['customer'], $row['mobile'], $row['address'], $row['mac'], $row['ip'], $row['nas'], $row['start'], $row['end'], $row['duration'], $row['down'], $row['up']]), escape: ''); } fclose($output); diff --git a/src/IpdrServiceProvider.php b/src/IpdrServiceProvider.php index 1cbe8c6..d9a331d 100644 --- a/src/IpdrServiceProvider.php +++ b/src/IpdrServiceProvider.php @@ -24,17 +24,14 @@ class IpdrServiceProvider extends ServiceProvider { public function register(): void { + $this->mergeConfigFrom(__DIR__.'/../config/ipdr.php', 'ipdr'); + /** @var array $base */ $base = config('database.connections.mysql'); + $own = array_filter((array) config('ipdr.database', []), fn (mixed $value): bool => $value !== null && $value !== ''); $default = $this->app->environment('testing') ? 'ispgrid_ipdr_test' : 'ispgrid_ipdr'; - config(['database.connections.ipdr' => array_merge($base, [ - 'host' => env('IPDR_DB_HOST', $base['host']), - 'port' => env('IPDR_DB_PORT', $base['port']), - 'database' => env('IPDR_DB_DATABASE', $default), - 'username' => env('IPDR_DB_USERNAME', $base['username']), - 'password' => env('IPDR_DB_PASSWORD', $base['password']), - ])]); + config(['database.connections.ipdr' => array_merge($base, ['database' => $default], $own)]); } public function boot(): void diff --git a/src/Search/CsvCell.php b/src/Search/CsvCell.php new file mode 100644 index 0000000..3d9433d --- /dev/null +++ b/src/Search/CsvCell.php @@ -0,0 +1,17 @@ +getDatabaseName())->toBe('ispgrid_ipdr_test') @@ -10,6 +11,15 @@ ->and(Schema::connection('ipdr')->hasTable('ipdr_state'))->toBeTrue(); }); +it('takes its database settings from its config file, so they survive config:cache', function () { + config(['ipdr.database.database' => 'ispgrid_ipdr_other', 'ipdr.database.host' => '']); + + (new IpdrServiceProvider(app()))->register(); + + expect(config('database.connections.ipdr.database'))->toBe('ispgrid_ipdr_other') + ->and(config('database.connections.ipdr.host'))->toBe(config('database.connections.mysql.host')); +}); + it('adds the Search session records permission', function () { expect(DB::table('permissions')->where('name', 'search-session-records')->exists())->toBeTrue(); }); diff --git a/tests/Feature/SearchPageTest.php b/tests/Feature/SearchPageTest.php index 048dfbd..e9a7074 100644 --- a/tests/Feature/SearchPageTest.php +++ b/tests/Feature/SearchPageTest.php @@ -91,3 +91,16 @@ function closedSessionWithIp(string $username): void expect(Activity::query()->where('event', 'session-records-exported')->count())->toBe(1); }); + +it('exports a name a spreadsheet would run as a formula as plain text', function () { + $this->actingAs(User::factory()->create()); + Account::factory()->create(['username' => 'asha', 'fullname' => '=HYPERLINK("http://x.test")']); + closedSessionWithIp('asha'); + + $page = Livewire::test('ipdr::session-records') + ->set('by', 'ip')->set('value', '100.64.10.7')->set('at', '2026-10-15T10:00') + ->set('reference', 'R1')->set('reason', 'Test') + ->call('export'); + + expect(base64_decode((string) data_get($page->effects, 'download.content')))->toContain('"\'=HYPERLINK(""http://x.test"")"'); +});