mail: adressbezogene Abmeldung fuer Empfaenger ohne Konto (Roadmap 1d.3)
Der Abmeldelink in API-Benachrichtigungen zeigte auf das Konto des Einlieferers - ein Klick des Pressekontakts haette connektar abgemeldet. Jetzt traegt der Link die Empfaengeradresse (signiert), der Zustand liegt als Unsubscribed in der Sperrliste. Anmeldelinks, die die Person selbst anfordert, gehen weiter durch; harte Bounces sperren alles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
13716b9c06
commit
9380937562
15 changed files with 362 additions and 20 deletions
|
|
@ -6,6 +6,8 @@ use App\Enums\ActivityType;
|
|||
use App\Enums\EmailNotificationType;
|
||||
use App\Models\User;
|
||||
use App\Services\ActivityLog;
|
||||
use App\Services\Company\NewsroomClaimService;
|
||||
use App\Services\Mail\EmailSuppressionService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
|
@ -89,6 +91,75 @@ class EmailUnsubscribeController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adressbezogene Abmeldung (Roadmap 1d.3): Empfänger ohne Konto. Die
|
||||
* Sperrliste hält den Zustand; Anmeldelinks, die die Person selbst
|
||||
* anfordert, gehen weiter durch (GateOutgoingMail).
|
||||
*/
|
||||
public function showAddress(Request $request, EmailSuppressionService $suppressions): View
|
||||
{
|
||||
$notificationType = $this->resolveType((string) $request->query('type', ''));
|
||||
$email = EmailSuppressionService::normalise((string) $request->query('email', ''));
|
||||
|
||||
if (! $request->hasValidSignature() || $email === null) {
|
||||
return view('web.email-unsubscribe', ['state' => 'invalid', 'notificationType' => $notificationType]);
|
||||
}
|
||||
|
||||
$this->unsubscribeAddress($suppressions, $email, $notificationType, 'link');
|
||||
|
||||
return view('web.email-unsubscribe', [
|
||||
'state' => 'unsubscribed',
|
||||
'notificationType' => $notificationType,
|
||||
'address' => NewsroomClaimService::mask($email),
|
||||
'addressMode' => true,
|
||||
'resubscribeUrl' => URL::signedRoute('email-preferences.resubscribe-address', ['email' => $email, 'type' => $notificationType->value]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function oneClickUnsubscribeAddress(Request $request, EmailSuppressionService $suppressions): Response
|
||||
{
|
||||
abort_unless($request->hasValidSignature(), 403);
|
||||
$email = EmailSuppressionService::normalise((string) $request->query('email', ''));
|
||||
abort_if($email === null, 404);
|
||||
|
||||
$this->unsubscribeAddress($suppressions, $email, $this->resolveType((string) $request->query('type', '')), 'one-click');
|
||||
|
||||
return response('Sie wurden erfolgreich abgemeldet.');
|
||||
}
|
||||
|
||||
public function resubscribeAddress(Request $request, EmailSuppressionService $suppressions): View
|
||||
{
|
||||
abort_unless($request->hasValidSignature(), 403);
|
||||
$email = EmailSuppressionService::normalise((string) $request->query('email', ''));
|
||||
abort_if($email === null, 404);
|
||||
$notificationType = $this->resolveType((string) $request->query('type', ''));
|
||||
|
||||
if ($suppressions->resubscribe($email)) {
|
||||
$this->activityLog->record(
|
||||
ActivityType::EmailUnsubscribe,
|
||||
sprintf('%s hat die Abmeldung zurückgenommen.', $email),
|
||||
meta: ['email' => $email, 'action' => 'resubscribe'],
|
||||
);
|
||||
}
|
||||
|
||||
return view('web.email-unsubscribe', ['state' => 'resubscribed', 'notificationType' => $notificationType, 'addressMode' => true]);
|
||||
}
|
||||
|
||||
private function unsubscribeAddress(EmailSuppressionService $suppressions, string $email, EmailNotificationType $notificationType, string $method): void
|
||||
{
|
||||
if ($suppressions->isSuppressed($email)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suppressions->unsubscribe($email, $method);
|
||||
|
||||
$this->activityLog->record(
|
||||
ActivityType::EmailUnsubscribe,
|
||||
sprintf('%s hat sich von Benachrichtigungen abgemeldet (%s).', $email, $notificationType->unsubscribeLabel()),
|
||||
meta: ['email' => $email, 'type' => $notificationType->value, 'action' => 'unsubscribe', 'method' => $method],
|
||||
);
|
||||
}
|
||||
|
||||
private function optOut(User $user, EmailNotificationType $notificationType, string $method): void
|
||||
{
|
||||
if (! $user->wantsEmailNotification($notificationType)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue