feat(auth): complete registration anti-spam and quota hardening
This commit is contained in:
62
app/Jobs/SendVerificationEmailJob.php
Normal file
62
app/Jobs/SendVerificationEmailJob.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user