mail: Prüfmail führt Pressekontakte per Anmeldelink zur Meldung
Die Mail „Ihre Pressemitteilung wird persönlich geprüft“ verlinkte auch bei API-Meldungen in den Kundenbereich. Empfänger ohne Konto landeten auf der Passwort-Anmeldung. Wie in der Veröffentlichungs- und Ablehnungsmail schickt jetzt ein Klick einen Anmeldelink an die Adresse der Mail; die Zugangsseite übernimmt die Herkunft mail_review für den Funnel. Changelog: Verbessert Public: Auch die Mail zur persönlichen Prüfung führt Pressekontakte ohne Passwort zu ihrer Meldung. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
209a79f173
commit
67016ed549
5 changed files with 59 additions and 5 deletions
|
|
@ -7,6 +7,7 @@ use App\Enums\EmailNotificationType;
|
|||
use App\Mail\Concerns\Unsubscribable;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\MailAccessLink;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
|
|
@ -35,6 +36,16 @@ class PressReleaseHeldForReview extends Mailable
|
|||
|
||||
public int $maxAttempts;
|
||||
|
||||
/**
|
||||
* Empfänger ohne Konto (API-Meldung, Roadmap 6.17): Adresse dieser Mail
|
||||
* und Link, der einen Anmeldelink an sie schickt. Der Link zum Kundenbereich
|
||||
* führte sonst auf eine Anmeldeseite für ein Konto, das der Empfänger
|
||||
* nicht kennt.
|
||||
*/
|
||||
public ?string $accessEmail = null;
|
||||
|
||||
public ?string $accessUrl = null;
|
||||
|
||||
public function __construct(
|
||||
public readonly User $user,
|
||||
public readonly PressRelease $pressRelease,
|
||||
|
|
@ -55,6 +66,8 @@ class PressReleaseHeldForReview extends Mailable
|
|||
]);
|
||||
|
||||
if ($recipientEmail !== null && mb_strtolower(trim($recipientEmail)) !== mb_strtolower((string) $user->email)) {
|
||||
$this->accessEmail = trim($recipientEmail);
|
||||
$this->accessUrl = app(MailAccessLink::class)->url($this->accessEmail, $pressRelease, ConversionSource::MailReview);
|
||||
$this->configureAddressUnsubscribe($recipientEmail, EmailNotificationType::PressReleaseRejected);
|
||||
} else {
|
||||
$this->configureUnsubscribe($user, EmailNotificationType::PressReleaseRejected);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use Illuminate\Support\Facades\URL;
|
|||
/**
|
||||
* „Anmeldelink an diese Adresse“ aus einer Kundenmail (Roadmap 6.17).
|
||||
*
|
||||
* Veröffentlichungs- und Ablehnungsmails zu API-Meldungen gehen an den
|
||||
* Veröffentlichungs-, Ablehnungs- und Prüfmails zu API-Meldungen gehen an den
|
||||
* Pressekontakt oder die Firmen-E-Mail — Empfänger, die aus ihrer Sicht kein
|
||||
* Konto haben. Der Link führt auf eine Seite, die mit einem Klick einen
|
||||
* Anmeldelink an genau die Adresse schickt, an die die Mail ging, und nach
|
||||
|
|
|
|||
|
|
@ -24,7 +24,21 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<x-emails.button :url="$showUrl">Stand der Prüfung ansehen</x-emails.button>
|
||||
@if ($accessUrl)
|
||||
{{-- Empfänger ohne Konto (API-Meldung, Roadmap 6.17): ein Klick
|
||||
schickt einen Anmeldelink an genau diese Adresse. --}}
|
||||
<div class="meta">
|
||||
<p><strong>Den Stand der Prüfung sehen?</strong></p>
|
||||
<p>
|
||||
Dafür brauchen Sie weder ein Konto noch ein Passwort. Wir schicken einen Anmeldelink an
|
||||
<strong>{{ $accessEmail }}</strong>, die Adresse, an die diese Mail ging. Nach der Anmeldung
|
||||
sehen Sie die Meldung und ihren Stand. Das ist kostenlos.
|
||||
</p>
|
||||
<x-emails.button :url="$accessUrl">Anmeldelink anfordern</x-emails.button>
|
||||
</div>
|
||||
@else
|
||||
<x-emails.button :url="$showUrl">Stand der Prüfung ansehen</x-emails.button>
|
||||
@endif
|
||||
|
||||
<p style="font-size: 12.5px; color: #6b7280;">
|
||||
Bei Fragen erreichen Sie uns über den <a href="{{ config('domains.domain_portal_url') }}/de/hilfe">Hilfe-Bereich auf pressekonto</a>.
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ use Livewire\Component;
|
|||
/**
|
||||
* Anmeldelink an die Adresse, an die eine Kundenmail ging (Roadmap 6.17).
|
||||
*
|
||||
* Erreichbar nur über den signierten Link aus der Veröffentlichungs- oder
|
||||
* Ablehnungsmail (MailAccessLink). Ein Klick schickt den Anmeldelink; nach
|
||||
* Erreichbar nur über den signierten Link aus der Veröffentlichungs-,
|
||||
* Ablehnungs- oder Prüfmail (MailAccessLink). Ein Klick schickt den Anmeldelink; nach
|
||||
* der Anmeldung landet der Empfänger auf der Meldung. Die Seite zeigt die
|
||||
* Adresse nur maskiert.
|
||||
*/
|
||||
|
|
@ -98,7 +98,7 @@ new #[Layout('components.layouts.auth.pressekonto', ['heading' => 'Ohne Passwort
|
|||
{
|
||||
$source = ConversionSource::parse((string) request()->query('src'));
|
||||
|
||||
return in_array($source, [ConversionSource::MailPublish, ConversionSource::MailReject], true) ? $source : ConversionSource::Organic;
|
||||
return in_array($source, [ConversionSource::MailPublish, ConversionSource::MailReject, ConversionSource::MailReview], true) ? $source : ConversionSource::Organic;
|
||||
}
|
||||
|
||||
private function pressRelease(int $id): ?PressRelease
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use App\Enums\ConversionSource;
|
|||
use App\Enums\Portal;
|
||||
use App\Enums\PressReleaseStatus;
|
||||
use App\Mail\MagicLoginLink;
|
||||
use App\Mail\PressReleaseHeldForReview;
|
||||
use App\Mail\PressReleasePublished;
|
||||
use App\Mail\PressReleaseRejected;
|
||||
use App\Models\Company;
|
||||
|
|
@ -93,6 +94,32 @@ test('the rejection mail tells recipients without an account that they can revis
|
|||
->and($own)->not->toContain('Anmeldelink anfordern');
|
||||
});
|
||||
|
||||
test('the held-for-review mail lets recipients without an account see the status via a sign-in link', function () {
|
||||
/** @var TestCase $this */
|
||||
$release = apiRelease(['status' => PressReleaseStatus::Review->value]);
|
||||
$mail = new PressReleaseHeldForReview($release->user, $release, false, 'Frau Muster', 'presse@firma.de');
|
||||
$html = $mail->render();
|
||||
|
||||
expect($mail->accessUrl)->toContain('/zugang?')
|
||||
->and(accessQuery($mail->accessUrl)['src'])->toBe(ConversionSource::MailReview->value)
|
||||
->and($html)->toContain('Sie müssen nichts tun')
|
||||
->and($html)->toContain('Den Stand der Prüfung sehen?')
|
||||
->and($html)->toContain('weder ein Konto noch ein Passwort')
|
||||
->and($html)->toContain('presse@firma.de')
|
||||
->and($html)->toContain('Anmeldelink anfordern')
|
||||
->and($html)->not->toContain('Stand der Prüfung ansehen');
|
||||
|
||||
// Die Zugangsseite übernimmt die Herkunft aus der Prüfmail.
|
||||
$this->get($mail->accessUrl)->assertOk();
|
||||
expect(ConversionEvent::query()->where('type', ConversionEventType::ManagePageOpened->value)->sole()->source)
|
||||
->toBe(ConversionSource::MailReview);
|
||||
|
||||
// Wer selbst eingereicht hat, öffnet die Meldung wie bisher im Konto.
|
||||
$own = (new PressReleaseHeldForReview($release->user, $release, false))->render();
|
||||
expect($own)->toContain('Stand der Prüfung ansehen')
|
||||
->and($own)->not->toContain('Anmeldelink anfordern');
|
||||
});
|
||||
|
||||
// --------------------------------------------------------- Zugangsseite
|
||||
|
||||
test('the access page only opens with a valid signature and shows the address masked', function () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue