63 lines
1.7 KiB
PHP
63 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Mail\RegistrationVerificationMail;
|
|
use App\Services\Auth\RegistrationEmailQuotaService;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Queue\Queueable;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
|
|
class SendVerificationEmailJob implements ShouldQueue
|
|
{
|
|
use Queueable;
|
|
|
|
public int $tries = 5;
|
|
|
|
public function __construct(
|
|
public readonly int $emailEventId,
|
|
public readonly string $email,
|
|
public readonly string $token,
|
|
public readonly ?int $userId,
|
|
public readonly ?string $ip
|
|
) {
|
|
$this->onQueue('mail');
|
|
}
|
|
|
|
public function handle(RegistrationEmailQuotaService $quotaService): void
|
|
{
|
|
$key = 'registration:verification-email:global';
|
|
$maxPerMinute = max(1, (int) config('registration.email_global_send_per_minute', 30));
|
|
|
|
$allowed = RateLimiter::attempt($key, $maxPerMinute, static fn () => true, 60);
|
|
if (! $allowed) {
|
|
$this->release(10);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($quotaService->isExceeded()) {
|
|
$this->updateEvent('blocked', 'quota');
|
|
|
|
return;
|
|
}
|
|
|
|
Mail::to($this->email)->queue(new RegistrationVerificationMail($this->token));
|
|
$quotaService->incrementSentCount();
|
|
|
|
$this->updateEvent('sent', null);
|
|
}
|
|
|
|
private function updateEvent(string $status, ?string $reason): void
|
|
{
|
|
DB::table('email_send_events')
|
|
->where('id', $this->emailEventId)
|
|
->update([
|
|
'status' => $status,
|
|
'reason' => $reason,
|
|
]);
|
|
}
|
|
}
|