Skip to content
This repository was archived by the owner on Aug 23, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/Jobs/ProcessHqWhitelistJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ private function notifyAdmin(Host $hqHost, string $modsecLogs): void
'email' => $adminEmail,
]);

$ttl = (int) (config('unblock.hq.ttl') ?? 7200);
$ttl = (int) config('unblock.hq.ttl');

Mail::to($adminEmail)->send(new HqWhitelistMail(
user: $adminUser,
Expand Down
2 changes: 1 addition & 1 deletion app/Services/Firewall/DirectAdminFirewallAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ private function checkAndRemoveFromBfmBlacklist(string $ip, string $sshKeyName):
$this->firewallService->checkProblems($this->host, $sshKeyName, 'da_bfm_whitelist_add', $ip);

// 3. Track in database for automatic removal after TTL
$ttl = (int) (config('unblock.hq.ttl') ?? 7200); // Default 2 hours
$ttl = (int) config('unblock.hq.ttl');
BfmWhitelistEntry::create([
'host_id' => $this->host->id,
'ip_address' => $ip,
Expand Down
16 changes: 16 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
use Rector\ValueObject\PhpVersion;
use RectorLaravel\Rector\ClassMethod\MakeModelAttributesAndScopesProtectedRector;
use RectorLaravel\Rector\Coalesce\ApplyDefaultInsteadOfNullCoalesceRector;
use RectorLaravel\Rector\FuncCall\{AppToResolveRector, RemoveDumpDataDeadCodeRector, ThrowIfAndThrowUnlessExceptionsToUseClassStringRector};
use RectorLaravel\Rector\If_\ThrowIfRector;
use RectorLaravel\Set\LaravelSetList;
Expand Down Expand Up @@ -111,6 +112,21 @@
// consumes scopes through the builder proxy. This app is final, not a
// library: no external consumers exist.
MakeModelAttributesAndScopesProtectedRector::class,
// Wave 6 (AID-542), split from AID-531 over the ??/?: lesson. The
// rule turns `helper('key') ?? $default` into `helper('key',
// $default)` — NOT ??→?:, but it still has a non-equivalent corner:
// a key present with an explicit null returns $default under ??,
// null under the parameter form. Both sites it flagged used
// `config('unblock.hq.ttl') ?? 7200`, where that corner is
// unreachable by construction (config/unblock.php casts `(int)
// env(..., 14000)`, so the key always exists as int) — which also
// made the 7200 a dead phantom default lying about the real 14000.
// The fallbacks were removed by hand (the default's single owner is
// the config file); the rule stays on as the guard against future
// `config('x') ?? $d`, which is always either dead or a duplicated
// default. If a legitimate present-but-null key ever appears, skip
// that call site here rather than dropping the rule.
ApplyDefaultInsteadOfNullCoalesceRector::class,
])
// Wave 4 (AID-532): LARAVEL_COLLECTION (4 sites, all element types are
// scalars/plain arrays so toArray()≡all(); filter(!empty)→reject(empty)
Expand Down
11 changes: 8 additions & 3 deletions tests/Unit/Jobs/ProcessHqWhitelistJobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,17 @@
// SCENARIO 8: TTL Configuration
// ============================================================================

test('job uses default TTL when not configured', function () {
test('job uses the config-owned default TTL when env is not set', function () {
$hqHost = Host::factory()->create(['hash' => 'test-key']); // ggignore

config()->set('unblock.hq.host_id', $hqHost->id);
config()->set('unblock.admin_email', 'admin@example.com');
config()->set('unblock.hq.ttl', null); // ← Not configured
// "Not configured" means the HQ_WHITELIST_TTL env var is absent, in which
// case config/unblock.php resolves `(int) env(..., 14000)` at load time —
// the key always exists as an int, never null. The job carries no local
// fallback anymore (AID-542); the default's single owner is the config
// file, so this test pins that owner's value flowing through untouched.
expect(config('unblock.hq.ttl'))->toBe(14000);

$firewallService = Mockery::mock(FirewallService::class);
$firewallService->allows('generateSshKey')->andReturn('/tmp/key');
Expand All @@ -473,7 +478,7 @@
$job->handle($firewallService);

Mail::assertQueued(HqWhitelistMail::class, function ($mail) {
return $mail->ttlSeconds === 7200; // Default 7200s
return $mail->ttlSeconds === 14000; // config/unblock.php default
});
});

Expand Down