From df61a1e789e6a607c3576f8ba75b6846e8dd6160 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Wed, 30 Sep 2026 11:44:14 +0100 Subject: [PATCH] updated deployer code --- .../Commands/SonarDeskAccountsBackfill.php | 53 ++++++++++++++++ .../Payments/CustomerAccountProvisioner.php | 63 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 app/Console/Commands/SonarDeskAccountsBackfill.php create mode 100644 app/Services/Payments/CustomerAccountProvisioner.php diff --git a/app/Console/Commands/SonarDeskAccountsBackfill.php b/app/Console/Commands/SonarDeskAccountsBackfill.php new file mode 100644 index 0000000..499179d --- /dev/null +++ b/app/Console/Commands/SonarDeskAccountsBackfill.php @@ -0,0 +1,53 @@ +whereNotNull('customer_email') + ->where('customer_email', '!=', '') + ->orderBy('id') + ->get(['customer_email', 'customer_name']) + ->unique(fn (License $license) => strtolower(trim((string) $license->customer_email))); + + $created = 0; + + foreach ($customers as $license) { + $email = strtolower(trim((string) $license->customer_email)); + $exists = \App\Models\User::whereRaw('lower(email) = ?', [$email])->exists(); + if ($exists) { + continue; + } + + if ($this->option('dry-run')) { + $this->line("Missing account: {$email}"); + $created++; + continue; + } + + $user = $accounts->ensure($email, $license->customer_name); + if ($user) { + $this->info("Created account: {$email}"); + $created++; + } + } + + $this->newLine(); + $this->info($this->option('dry-run') + ? "{$created} customer account(s) need creating." + : "{$created} customer account(s) created."); + + return self::SUCCESS; + } +} diff --git a/app/Services/Payments/CustomerAccountProvisioner.php b/app/Services/Payments/CustomerAccountProvisioner.php new file mode 100644 index 0000000..f970ea9 --- /dev/null +++ b/app/Services/Payments/CustomerAccountProvisioner.php @@ -0,0 +1,63 @@ +first(); + if ($user) { + return $user; + } + + $displayName = trim((string) $name); + if ($displayName === '') { + $displayName = Str::headline(Str::before($email, '@')) ?: 'SonarDesk Customer'; + } + + $user = User::firstOrCreate( + ['email' => $email], + [ + 'name' => $displayName, + // The customer never receives or knows this password. They choose their + // own password through Laravel's signed, single-use reset flow. + 'password' => Str::random(64), + // Access still requires possession of the mailbox because account setup + // is completed using the reset link sent to this address. + 'email_verified_at' => now(), + ], + ); + + if ($user->wasRecentlyCreated) { + DB::afterCommit(function () use ($email): void { + try { + $status = Password::sendResetLink(['email' => $email]); + if ($status !== Password::RESET_LINK_SENT) { + Log::warning('SonarDesk customer account created but setup email was not sent.', [ + 'email' => $email, + 'status' => $status, + ]); + } + } catch (\Throwable $exception) { + // A mail outage must never undo a paid licence. The customer can + // also use Forgot Password once mail is restored. + report($exception); + } + }); + } + + return $user; + } +}