presseportale/app/Models/MagicLink.php
Kevin Adametz 1ccb4a8479 auth/security: API-Firmenzuordnung nur für Mitglieder oder Allowlist, Google-Vorabübernahme geschlossen, gemeinsamer Login-Abschluss (Umsetzungsaudit 29.09.: R-01, K-04, K-07, K-08, B-10)
- R-01: ApiNewsroomAssignment hängt an eine bestehende Firma nur noch Owner,
  Mitglieder oder Nutzer aus NEWSROOM_API_ASSIGNMENT_USER_IDS; Pivot mit
  granted_via = api; Befehl company-memberships:api-assignments (Liste,
  --remove mit Vorschau)
- K-04: OAuth-Verifikation eines offenen Kontos verwirft Passwort,
  remember_token und Sanctum-Tokens; SessionRevocation + Middleware
  EnsureSessionIsNotRevoked widerruft alte Sessions (Redis-tauglich)
- K-08: LoginCompletion für Passwort, Magic Link und Google — last_login_at
  und Anmeldemethode auch nach 2FA, Landeziel über die Challenge, Google
  ohne erzwungenes remember, magic-login ohne guest für eigene Links
- B-10: eigener Magic-Link-Zweck image_confirmation (Migration)
- K-07: legalAcceptanceVersions #[Locked], Versionswechsel beim Absenden
  wird abgelehnt, Gate-Abfragen je Request zwischengespeichert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:00 +00:00

54 lines
1.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class MagicLink extends Model
{
public const PURPOSE_LOGIN = 'login';
/**
* Link „Bild bestätigen" (Decision-Update E10): meldet an wie ein
* Login-Link, wird aber von späteren Login-Links nicht entwertet
* (Umsetzungsaudit 29.09.2026, B-10).
*/
public const PURPOSE_IMAGE_CONFIRMATION = 'image_confirmation';
/**
* Zwecke, die der Endpunkt magic-login einlöst.
*
* @var list<string>
*/
public const LOGIN_PURPOSES = [self::PURPOSE_LOGIN, self::PURPOSE_IMAGE_CONFIRMATION];
protected $fillable = [
'user_id',
'token_hash',
'purpose',
'source',
'payload',
'expires_at',
'consumed_at',
'ip_requested',
'ip_consumed',
];
protected function casts(): array
{
return [
'payload' => 'array',
'expires_at' => 'datetime',
'consumed_at' => 'datetime',
];
}
/**
* @return BelongsTo<User, $this>
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}