security/api/betrieb: Fortify-2FA-Nebenwege gesperrt, Policy nur für aktive Super-Admins, Nachprüfungen aus dem Umsetzungsaudit (Block 7, U08–U10, U13, 7.1, 7.2, 7.5)
- Fortifys sieben 2FA-Verwaltungsrouten antworten mit 404 (Middleware über fortify.middleware); die Sicherheitsseite verlangt weiter den zweiten Faktor (U09) - PressReleasePolicy/CompanyPolicy::before() bejahen nur aktive Super-Admins (7.2) - API-Update prüft bei Portalwechsel die bestehende Kategorie gegen das neue Portal (U10) - Aggregation: Zeitbudget 480 s unter dem Lock von 600 s, Marke nur unter Zeilensperre vom erwarteten Stand aus, sonst Fehler-Exit (U13) - Newsletter-Bereinigungsmigration behält je Paar die sent-Zeile (U08) - E-Mail-Wechsel stößt den Rechte-Sync sofort an; company-memberships:audit --classify zeigt vorher die Kandidaten und begrenzt mit --before (7.1) - Detailseite wählt bei Slug-Kollision wie der Melde-Resolver (7.5) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
c46dfd3b83
commit
05cf53e17d
18 changed files with 447 additions and 26 deletions
|
|
@ -104,6 +104,35 @@ test('the unique index migration removes existing duplicates and keeps the oldes
|
|||
->and($campaign->recipients()->whereNull('user_id')->count())->toBe(2);
|
||||
});
|
||||
|
||||
test('the unique index migration keeps the delivered row of a duplicated recipient (Audit U08)', function () {
|
||||
/** @var TestCase $this */
|
||||
$migration = 'database/migrations/2026_09_18_110000_add_unique_user_to_newsletter_campaign_recipients_table.php';
|
||||
|
||||
$this->artisan('migrate:rollback', ['--path' => $migration])->assertSuccessful();
|
||||
|
||||
$campaign = NewsletterCampaign::factory()->create();
|
||||
|
||||
// Pending → Sent: die ältere Zeile ist offen, die jüngere trägt den Nachweis.
|
||||
$pendingThenSent = User::factory()->create();
|
||||
$campaign->recipients()->create(['user_id' => $pendingThenSent->id, 'email' => $pendingThenSent->email]);
|
||||
$keptA = $campaign->recipients()->create(['user_id' => $pendingThenSent->id, 'email' => $pendingThenSent->email, 'status' => NewsletterRecipientStatus::Sent->value, 'sent_at' => now()]);
|
||||
|
||||
// Failed → Sent
|
||||
$failedThenSent = User::factory()->create();
|
||||
$campaign->recipients()->create(['user_id' => $failedThenSent->id, 'email' => $failedThenSent->email, 'status' => NewsletterRecipientStatus::Failed->value]);
|
||||
$keptB = $campaign->recipients()->create(['user_id' => $failedThenSent->id, 'email' => $failedThenSent->email, 'status' => NewsletterRecipientStatus::Sent->value, 'sent_at' => now()]);
|
||||
|
||||
// Sent → Sent: der ältere Nachweis bleibt.
|
||||
$sentTwice = User::factory()->create();
|
||||
$keptC = $campaign->recipients()->create(['user_id' => $sentTwice->id, 'email' => $sentTwice->email, 'status' => NewsletterRecipientStatus::Sent->value, 'sent_at' => now()]);
|
||||
$campaign->recipients()->create(['user_id' => $sentTwice->id, 'email' => $sentTwice->email, 'status' => NewsletterRecipientStatus::Sent->value, 'sent_at' => now()]);
|
||||
|
||||
$this->artisan('migrate', ['--path' => $migration])->assertSuccessful();
|
||||
|
||||
expect($campaign->recipients()->orderBy('id')->pluck('id')->all())->toBe([$keptA->id, $keptB->id, $keptC->id])
|
||||
->and($campaign->recipients()->where('status', NewsletterRecipientStatus::Sent->value)->count())->toBe(3);
|
||||
});
|
||||
|
||||
test('a campaign cannot hold the same user twice', function () {
|
||||
$user = User::factory()->create();
|
||||
$campaign = NewsletterCampaign::factory()->create();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue