ConfirmationChannel::class, 'declaration_snapshot' => 'array', 'precheck_snapshot' => 'array', 'confirmed_at' => 'datetime', ]; } /** * Pseudonymisierte IP-Ableitung: HMAC mit eigenem Schlüssel und * Versionspräfix (Decision-Update 3.7). Kein reiner Hash — ohne den * Schlüssel lässt sich keine Adresse zuordnen. */ public static function hashIp(?string $ip): ?string { if (blank($ip)) { return null; } $key = (string) config('images.confirmation_ip_key'); $version = (string) config('images.confirmation_ip_hash_version', 'v1'); return $version.':'.hash_hmac('sha256', $ip, $key); } /** * Sofortlöschung eines nie veröffentlichten Uploads (E.3). Nur hier * darf eine Bestätigung verschwinden — der Observer prüft das Flag. */ public function purgeForUnpublished(): void { $this->purgingUnpublished = true; $this->delete(); } /** * @return MorphTo */ public function subject(): MorphTo { return $this->morphTo(); } /** * @return BelongsTo */ public function pressRelease(): BelongsTo { return $this->belongsTo(PressRelease::class); } /** * @return BelongsTo */ public function company(): BelongsTo { return $this->belongsTo(Company::class); } /** * @return BelongsTo */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * @return BelongsTo */ public function legalText(): BelongsTo { return $this->belongsTo(LegalText::class); } }