purpose => mailbox key */ public array $purposes = []; /** * Whether credentials can be stored at all on this installation. * * Public so the page can say it rather than throwing on the first password * a mailbox tries to decrypt — the same courtesy the secrets page already * extends. A missing SECRETS_KEY is a setup state, not an error. */ public bool $usable = true; public function mount(): void { $this->authorize('mail.manage'); $this->host = (string) Settings::get('mail.host', ''); $this->port = (int) Settings::get('mail.port', 587); $this->encryption = (string) Settings::get('mail.encryption', 'tls'); foreach (MailPurpose::ALL as $purpose) { $this->purposes[$purpose] = (string) Settings::get(MailPurpose::settingKey($purpose), ''); } } public function saveServer(): void { $this->authorize('mail.manage'); // Rules on the ACTION, not on the property: a #[Validate] attribute on // a Livewire property applies class-wide, and savePurposes() below // would drag these along. $this->validate([ 'host' => ['required', 'string', 'max:255'], 'port' => ['required', 'integer', 'min:1', 'max:65535'], 'encryption' => ['required', 'in:tls,ssl,none'], ]); Settings::set('mail.host', $this->host); Settings::set('mail.port', (int) $this->port); Settings::set('mail.encryption', $this->encryption); $this->dispatch('notify', message: __('mail_settings.server_saved')); } public function savePurposes(): void { $this->authorize('mail.manage'); // system is the fallback, so it is the one that may not be empty — // there is nothing left to fall back to. $this->validate( ['purposes.system' => ['required', 'string']], ['purposes.system.required' => __('mail_settings.system_required')], ); foreach (MailPurpose::ALL as $purpose) { Settings::set(MailPurpose::settingKey($purpose), $this->purposes[$purpose] ?? ''); } $this->dispatch('notify', message: __('mail_settings.purposes_saved')); } public function render() { $this->usable = app(SecretCipher::class)->isUsable(); return view('livewire.admin.mail', [ 'mailboxes' => Mailbox::query()->orderBy('key')->get(), 'purposeList' => MailPurpose::ALL, ]); } }