presseportale/app/Http/Controllers/EmailUnsubscribeController.php
2026-07-10 17:15:05 +00:00

83 lines
2.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Enums\EmailNotificationType;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\URL;
use Illuminate\View\View;
/**
* One-Click-Abmeldung von Benachrichtigungs-Mails, ohne Login.
*
* Die Links in den Mail-Footern sind signiert und ohne Ablauf (Links aus
* alten Mails bleiben gültig). Der GET-Aufruf trägt den Empfänger direkt
* aus und zeigt die Bestätigungsseite mit der Möglichkeit, die Abmeldung
* rückgängig zu machen. Der POST auf dieselbe URL bedient den
* List-Unsubscribe-Header (RFC 8058) — Mail-Clients senden ihn ohne
* Nutzer-Interaktion auf der Seite.
*/
class EmailUnsubscribeController extends Controller
{
public function show(Request $request, User $user, string $type): View
{
$notificationType = $this->resolveType($type);
if (! $request->hasValidSignature()) {
return view('web.email-unsubscribe', [
'state' => 'invalid',
'notificationType' => $notificationType,
]);
}
$user->optOutOfEmailNotification($notificationType);
return view('web.email-unsubscribe', [
'state' => 'unsubscribed',
'notificationType' => $notificationType,
'resubscribeUrl' => URL::signedRoute('email-preferences.resubscribe', [
'user' => $user->id,
'type' => $notificationType->value,
]),
]);
}
/**
* RFC-8058-Endpunkt: Mail-Clients senden `List-Unsubscribe=One-Click`
* per POST, ohne die Seite zu öffnen. Antwort bewusst schlicht (2xx).
*/
public function oneClickUnsubscribe(Request $request, User $user, string $type): Response
{
abort_unless($request->hasValidSignature(), 403);
$user->optOutOfEmailNotification($this->resolveType($type));
return response('Sie wurden erfolgreich abgemeldet.');
}
public function resubscribe(Request $request, User $user, string $type): View|RedirectResponse
{
abort_unless($request->hasValidSignature(), 403);
$notificationType = $this->resolveType($type);
$user->optIntoEmailNotification($notificationType);
return view('web.email-unsubscribe', [
'state' => 'resubscribed',
'notificationType' => $notificationType,
]);
}
private function resolveType(string $type): EmailNotificationType
{
$notificationType = EmailNotificationType::tryFrom($type);
abort_if($notificationType === null, 404);
return $notificationType;
}
}