` mechanism. Every setting reachable from * outside is a setting whose value depends on where you look, and the * blast radius of getting that wrong is the whole settings table. One * named key per setting that needs it, added when it needs it. */ class SeedSettingsCommand extends Command { protected $signature = 'projectsend:seed-settings'; protected $description = 'Apply provisioning defaults from the environment to settings that have never been set'; public function handle(Settings $settings): int { $enforcement = config('projectsend.platform.two_factor_enforcement'); if (is_string($enforcement) && $enforcement !== '') { $this->seedTwoFactorEnforcement($settings, $enforcement); } return self::SUCCESS; } private function seedTwoFactorEnforcement(Settings $settings, string $value): void { if (TwoFactorEnforcement::tryFrom($value) === null) { // Named rather than ignored. A typo here means a tenant // provisioned without the policy it was meant to have, and // silence would make that indistinguishable from success. $this->warn("PROJECTSEND_TWO_FACTOR_ENFORCEMENT='{$value}' is not one of none, staff, clients, all — leaving the setting alone."); return; } // Asked of the table rather than of Settings::get(), which cannot // tell a stored value apart from the enum's own default — and // 'none' is that default, so get() would report the thing we are // trying to detect the absence of. if (StoredSetting::query()->where('key', Setting::TwoFactorEnforcement->value)->exists()) { return; } $settings->set(Setting::TwoFactorEnforcement, $value); $this->info("Two-factor enforcement seeded to '{$value}' (first boot)."); } }