updated deployer code
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\License;
|
||||
use App\Services\Payments\CustomerAccountProvisioner;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
final class SonarDeskAccountsBackfill extends Command
|
||||
{
|
||||
protected $signature = 'sonardesk:accounts:backfill {--dry-run : Show missing customer accounts without creating them}';
|
||||
|
||||
protected $description = 'Create portal accounts for existing licence customers that do not yet have a user account';
|
||||
|
||||
public function handle(CustomerAccountProvisioner $accounts): int
|
||||
{
|
||||
$customers = License::query()
|
||||
->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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Payments;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
final class CustomerAccountProvisioner
|
||||
{
|
||||
public function ensure(?string $email, ?string $name = null): ?User
|
||||
{
|
||||
$email = strtolower(trim((string) $email));
|
||||
if ($email === '' || ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = User::whereRaw('lower(email) = ?', [$email])->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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user