ensureForAddress((string) $mailbox->address, (string) $mailbox->display_name, $password); $this->syncHolderPassword($mailbox, $password); return $user; } public function ensureForAddress(string $address, string $displayName = '', ?string $password = null): User { $email = strtolower(trim($address)); if ($email === '' || ! str_contains($email, '@')) { throw new \InvalidArgumentException('Invalid mailbox address.'); } $attributes = [ 'name' => ($name = trim($displayName) ?: Str::headline(Str::before($email, '@'))), 'first_name' => Str::before($name, ' '), 'last_name' => trim(Str::after($name, ' ')) ?: '', 'password' => $password ?? Str::random(40), ]; $user = User::firstOrCreate(['email' => $email], $attributes); if (! $user->wasRecentlyCreated && $password !== null && $password !== '') { $user->password = $password; $user->save(); } if ($user->email_verified_at === null) { $user->forceFill(['email_verified_at' => now()])->save(); } return $user; } /** * Keep the Ladill account password aligned with the mailbox password. * Uses the plaintext when available; otherwise copies the stored bcrypt hash. */ public function syncHolderPassword(Mailbox $mailbox, ?string $plaintextPassword = null): void { $email = strtolower(trim((string) $mailbox->address)); if ($email === '' || ! str_contains($email, '@')) { return; } $user = User::query()->where('email', $email)->first(); if (! $user) { return; } if ($plaintextPassword !== null && $plaintextPassword !== '') { $user->password = $plaintextPassword; $user->save(); $this->vault->store($mailbox, $plaintextPassword); return; } $hash = (string) $mailbox->password_hash; if ($hash !== '') { $this->assignPasswordHash($user, $hash); } } public function provisionSilently(string $address, string $displayName = '', ?string $password = null): ?User { try { return $this->ensureForAddress($address, $displayName, $password); } catch (\Throwable $e) { report($e); return null; } } public function provisionMailboxSilently(Mailbox $mailbox, ?string $password = null): ?User { try { return $this->ensureForMailbox($mailbox, $password); } catch (\Throwable $e) { report($e); return null; } } private function assignPasswordHash(User $user, string $passwordHash): void { $user->getConnection() ->table($user->getTable()) ->where($user->getKeyName(), $user->getKey()) ->update(['password' => $passwordHash]); } }