feat(auth): complete registration anti-spam and quota hardening

This commit is contained in:
2026-02-21 12:13:01 +01:00
parent 4fb95c872b
commit b239af9619
33 changed files with 1288 additions and 142 deletions

View File

@@ -0,0 +1,67 @@
<?php
use App\Jobs\SendVerificationEmailJob;
use App\Services\Auth\RegistrationEmailQuotaService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\DB;
uses(RefreshDatabase::class);
it('returns generic success even when quota is exceeded', function () {
Queue::fake();
DB::table('system_email_quota')->insert([
'period' => now()->format('Y-m'),
'sent_count' => 10,
'limit_count' => 10,
'updated_at' => now(),
]);
$response = $this->post('/register', [
'email' => 'quota-hit@example.com',
]);
$response->assertRedirect('/register/notice');
$response->assertSessionHas('status', 'If that email is valid, we sent a verification link.');
Queue::assertPushed(SendVerificationEmailJob::class);
});
it('blocks actual send in job when monthly quota is exceeded', function () {
Mail::fake();
DB::table('system_email_quota')->insert([
'period' => now()->format('Y-m'),
'sent_count' => 10,
'limit_count' => 10,
'updated_at' => now(),
]);
$eventId = DB::table('email_send_events')->insertGetId([
'type' => 'verify_email',
'email' => 'quota-block@example.com',
'ip' => '127.0.0.1',
'user_id' => null,
'status' => 'queued',
'reason' => null,
'created_at' => now(),
]);
$job = new SendVerificationEmailJob(
emailEventId: (int) $eventId,
email: 'quota-block@example.com',
token: 'raw-token',
userId: null,
ip: '127.0.0.1'
);
$job->handle(app(RegistrationEmailQuotaService::class));
Mail::assertNothingSent();
$this->assertDatabaseHas('email_send_events', [
'id' => $eventId,
'status' => 'blocked',
'reason' => 'quota',
]);
});