Update resend confirmation flow with improved messaging

Improve the resend confirmation flow by:
- Consolidating multiple status messages into a single generic response
- Adding HTML support for the result message
- Moving the instruction text after the message display
- Simplifying the PHP logic by removing redundant checks
- Making the messaging more privacy-conscious by not revealing email
  existence
- Adding a link to sign again in the result message

The changes follow the project's minimal PHP philosophy while improving
user experience and security.
This commit is contained in:
Ruben 2026-02-02 00:26:42 +01:00
parent c8efa479bc
commit 201f5ebb6a
3 changed files with 25 additions and 33 deletions

View file

@ -1295,60 +1295,51 @@ function petitionGetPageData(?Context $ctx): ?array {
}
}
// Handle resend confirmation request (POST from thank-you page)
// Handle resend confirmation request (POST from resend page)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['petition_resend'])) {
$resendEmail = strtolower(trim($_POST['resend_email'] ?? ''));
// Build petition URL for the result message
$langPrefix = $ctx->get('langPrefix', '');
$currentPath = trim($ctx->requestPath, '/');
$petitionPath = preg_replace('#/(takk|send-bekreftelse-pa-nytt)$#', '', $currentPath);
$petitionUrl = "{$langPrefix}/{$petitionPath}/#sign-now";
// Rate limit check (reuse existing IP rate limiting)
if (!petitionCheckIPRateLimit($petitionId . '-resend', 3, 300)) {
$confirmMessage = ['type' => 'error', 'text' => petitionT($ctx, 'petition', 'resend_rate_limit')];
} elseif (empty($resendEmail) || !filter_var($resendEmail, FILTER_VALIDATE_EMAIL)) {
$confirmMessage = ['type' => 'error', 'text' => petitionT($ctx, 'petition', 'email_required')];
} else {
// Look up signature by email
// Look up signature by email and attempt to resend if pending
$signature = petitionGetPendingSignatureByEmail($csvPath, $resendEmail);
if ($signature === null) {
// Email not found at all
$confirmMessage = ['type' => 'error', 'text' => petitionT($ctx, 'petition', 'resend_not_found')];
} elseif ($signature['status'] === 'confirmed') {
// Already confirmed
$confirmMessage = ['type' => 'info', 'text' => petitionT($ctx, 'petition', 'resend_already_confirmed')];
} else {
// Generate new token and update signature
if ($signature !== null && $signature['status'] === 'pending') {
// Generate new token and send email
$newToken = bin2hex(random_bytes(32));
if (petitionUpdateSignatureToken($csvPath, $resendEmail, $newToken)) {
// Build confirmation URL
$langPrefix = $ctx->get('langPrefix', '');
$currentPath = trim($ctx->requestPath, '/');
// Remove subpage suffixes to get petition base path
$currentPath = preg_replace('#/(takk|send-bekreftelse-pa-nytt)$#', '', $currentPath);
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$confirmUrl = "{$protocol}://{$host}{$langPrefix}/{$currentPath}/?confirm={$newToken}#sign-now";
$confirmUrl = "{$protocol}://{$host}{$langPrefix}/{$petitionPath}/?confirm={$newToken}#sign-now";
// Send confirmation email
$signatureData = [
'email' => $signature['email'],
'firstname' => $signature['firstname'],
'surname' => $signature['surname']
];
if (petitionSendConfirmationEmail($signatureData, $confirmUrl, $petitionTitle, $petitionId, $ctx)) {
$confirmMessage = ['type' => 'success', 'text' => petitionT($ctx, 'petition', 'resend_success')];
} else {
$confirmMessage = ['type' => 'error', 'text' => petitionT($ctx, 'petition', 'error_email_send')];
}
} else {
$confirmMessage = ['type' => 'error', 'text' => petitionT($ctx, 'petition', 'resend_not_found')];
// Send email (ignore result - show same message regardless)
petitionSendConfirmationEmail($signatureData, $confirmUrl, $petitionTitle, $petitionId, $ctx);
}
}
// Always show the same generic message (privacy: don't reveal if email exists)
$resultText = petitionT($ctx, 'petition', 'resend_result', ['petition_url' => $petitionUrl]);
$confirmMessage = ['type' => 'info', 'text' => $resultText, 'html' => true];
}
// Store message in session and redirect back (PRG pattern)
$_SESSION['petition_resend_message'] = $confirmMessage;
$langPrefix = $ctx->get('langPrefix', '');
$currentPath = trim($ctx->requestPath, '/');
header("Location: {$langPrefix}/{$currentPath}/");
exit;
}