Merge branch 'latest' of forge.dmz.skyfritt.net:stopplidelsen/innhold into latest
This commit is contained in:
commit
702f2cd73e
7 changed files with 208 additions and 1 deletions
|
|
@ -1,4 +1,7 @@
|
|||
<h1 id="sign-now">Signer her for å vise din støtte</h1>
|
||||
|
||||
<?= $petition_form ?? '' ?>
|
||||
|
||||
<p class="text-small text-muted">Har du allerede signert, men ikke mottatt bekreftelsesmail? <a href="send-bekreftelse-pa-nytt/">Send bekreftelse på nytt</a></p>
|
||||
|
||||
<?= $petition_signatures ?? '' ?>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<h1>Send bekreftelse på nytt</h1>
|
||||
|
||||
<p>Skriv inn e-postadressen du brukte da du signerte, så sender vi en ny bekreftelseslenke.</p>
|
||||
|
||||
<?php if (!empty($petition_resend_message)): ?>
|
||||
<div class="form-message form-message--<?= htmlspecialchars($petition_resend_message['type']) ?>" role="alert">
|
||||
<p><?= htmlspecialchars($petition_resend_message['text']) ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="" class="resend-form">
|
||||
<div class="form-group">
|
||||
<label for="resend_email">E-post</label>
|
||||
<input type="email" id="resend_email" name="resend_email" placeholder="din@epost.no" required maxlength="100">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" name="petition_resend" class="button">Send på nytt</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p><a href="../">Tilbake til underskriftskampanjen</a></p>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
title = "Send bekreftelse på nytt"
|
||||
plugins = "petition-form"
|
||||
petition_id = "medisinsk-cannabis-pa-resept"
|
||||
petition_title = "Underskriftskampanje: Ja til medisinsk cannabis på resept!"
|
||||
|
||||
[en]
|
||||
title = "Resend confirmation"
|
||||
petition_title = "Petition: Yes to medical cannabis on prescription!"
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import url("../styles.css");
|
||||
|
|
@ -8,4 +8,6 @@
|
|||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<p>Fikk du ikke e-posten? <a href="../send-bekreftelse-pa-nytt/">Send bekreftelse på nytt</a></p>
|
||||
|
||||
<p><a href="../">Tilbake til underskriftskampanjen</a></p>
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ gdpr_consent_text = "Jeg har lest <a href=\"/personvern/\" target=\"_blank\">per
|
|||
gdpr_consent_required = "Du må samtykke til personvernerklæringen for å signere."
|
||||
newsletter_subscribe = "Jeg ønsker å motta nyhetsbrev fra Stopp Lidelsen (omtrent 12 i året). Du kan melde deg av når som helst."
|
||||
email_rights_info = "Du har rett til innsyn, retting og sletting av dine opplysninger. Kontakt oss på kontakt@stopplidelsen.no eller klag til Datatilsynet (datatilsynet.no)."
|
||||
resend_title = "Fikk du ikke e-posten?"
|
||||
resend_description = "Skriv inn e-postadressen du brukte da du signerte, så sender vi en ny bekreftelseslenke."
|
||||
resend_email_placeholder = "din@epost.no"
|
||||
resend_submit = "Send på nytt"
|
||||
resend_success = "Hvis e-postadressen finnes i vårt system, har vi sendt en ny bekreftelseslenke."
|
||||
resend_not_found = "Vi fant ingen ubekreftet signatur med denne e-postadressen. Kanskje du skrev feil da du signerte? Du kan gjerne prøve å signere på nytt."
|
||||
resend_already_confirmed = "Denne signaturen er allerede bekreftet."
|
||||
resend_rate_limit = "Vennligst vent litt før du ber om en ny e-post."
|
||||
|
||||
[regions]
|
||||
agder = "Agder"
|
||||
|
|
|
|||
|
|
@ -799,6 +799,105 @@ function petitionGetSignatureByToken(string $csvPath, string $token): ?array {
|
|||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pending signature data by email address
|
||||
* Returns signature data if found and pending, null otherwise
|
||||
*/
|
||||
function petitionGetPendingSignatureByEmail(string $csvPath, string $email): ?array {
|
||||
if (!file_exists($csvPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$fp = fopen($csvPath, 'r');
|
||||
if (!$fp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$signature = null;
|
||||
$email = strtolower(trim($email));
|
||||
|
||||
if (flock($fp, LOCK_SH)) {
|
||||
fgetcsv($fp, null, ',', '"', ''); // Skip header
|
||||
|
||||
// CSV format: timestamp, email, firstname, surname, region, display, status, token, token_created, ip_hash
|
||||
while (($row = fgetcsv($fp, null, ',', '"', '')) !== false) {
|
||||
if (isset($row[1]) && strtolower($row[1]) === $email) {
|
||||
$signature = [
|
||||
'email' => $row[1],
|
||||
'firstname' => $row[2],
|
||||
'surname' => $row[3],
|
||||
'region' => $row[4],
|
||||
'display' => $row[5],
|
||||
'status' => $row[6],
|
||||
'token' => $row[7],
|
||||
'token_created' => $row[8] ?? 0
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update token for an existing signature (for resend functionality)
|
||||
*/
|
||||
function petitionUpdateSignatureToken(string $csvPath, string $email, string $newToken): bool {
|
||||
if (!file_exists($csvPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = fopen($csvPath, 'r+');
|
||||
if (!$fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!flock($fp, LOCK_EX)) {
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
$header = fgetcsv($fp, null, ',', '"', '');
|
||||
$rows[] = $header;
|
||||
|
||||
$found = false;
|
||||
$email = strtolower(trim($email));
|
||||
$currentTime = time();
|
||||
|
||||
while (($row = fgetcsv($fp, null, ',', '"', '')) !== false) {
|
||||
if (isset($row[1]) && strtolower($row[1]) === $email && $row[6] === 'pending') {
|
||||
$row[7] = $newToken; // Update token
|
||||
$row[8] = $currentTime; // Update token_created
|
||||
$found = true;
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rewrite file
|
||||
rewind($fp);
|
||||
ftruncate($fp, 0);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
fputcsv($fp, $row, ',', '"', '');
|
||||
}
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send thank you email with delete link (with retry wrapper)
|
||||
*/
|
||||
|
|
@ -1136,7 +1235,8 @@ function petitionGetPageData(?Context $ctx): ?array {
|
|||
|
||||
$csvPath = petitionGetCsvPath($petitionId);
|
||||
// loadMetadata() already merges language-specific metadata via Hook::PROCESS_CONTENT
|
||||
$petitionTitle = $metadata['title'] ?? $petitionId;
|
||||
// Use petition_title if set (for subpages), otherwise fall back to page title
|
||||
$petitionTitle = $metadata['petition_title'] ?? $metadata['title'] ?? $petitionId;
|
||||
$thankYouPage = $metadata['thank_you_page'] ?? 'takk';
|
||||
|
||||
$formErrors = [];
|
||||
|
|
@ -1195,6 +1295,64 @@ function petitionGetPageData(?Context $ctx): ?array {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle resend confirmation request (POST from thank-you page)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['petition_resend'])) {
|
||||
$resendEmail = strtolower(trim($_POST['resend_email'] ?? ''));
|
||||
|
||||
// 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
|
||||
$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
|
||||
$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";
|
||||
|
||||
// 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')];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['petition_submit'])) {
|
||||
|
||||
|
|
@ -1401,5 +1559,11 @@ Hooks::add(Hook::TEMPLATE_VARS, function(array $vars, Context $ctx) {
|
|||
unset($_SESSION['petition_subscribed_newsletter']);
|
||||
}
|
||||
|
||||
// Check for resend confirmation message (for thank you page)
|
||||
if (isset($_SESSION['petition_resend_message'])) {
|
||||
$vars['petition_resend_message'] = $_SESSION['petition_resend_message'];
|
||||
unset($_SESSION['petition_resend_message']);
|
||||
}
|
||||
|
||||
return $vars;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue