64 lines
2.2 KiB
PHP
64 lines
2.2 KiB
PHP
<?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;
|
|
}
|
|
}
|