Passa il token unsub alla pagina di conferma e lo include anche nell'email di double opt-in. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import type { APIRoute } from 'astro';
|
||
import {
|
||
getEmailBinding,
|
||
getNewsletterDb,
|
||
getRuntimeEnv,
|
||
readEnv,
|
||
required,
|
||
sendCloudflareEmail,
|
||
type NewsletterSubscriber,
|
||
} from '../../../lib/newsletter';
|
||
|
||
export const prerender = false;
|
||
|
||
export const GET: APIRoute = async ({ request, locals, url }) => {
|
||
const runtimeEnv = getRuntimeEnv(locals);
|
||
const mode = (readEnv('NEWSLETTER_MODE', runtimeEnv) || readEnv('CONTACT_FORM_MODE', runtimeEnv) || 'dev').toLowerCase();
|
||
const token = required(url.searchParams.get('token'));
|
||
const okPath = '/newsletter/confermata';
|
||
const failPath = '/newsletter/conferma-errore';
|
||
|
||
if (!token) {
|
||
return Response.redirect(new URL(failPath, url).toString(), 303);
|
||
}
|
||
|
||
if (mode !== 'live') {
|
||
console.info('[newsletter:dev] Confirm token received', { token: token.slice(0, 8) + '…' });
|
||
return Response.redirect(new URL(okPath, url).toString(), 303);
|
||
}
|
||
|
||
const db = getNewsletterDb(runtimeEnv);
|
||
if (!db) {
|
||
return new Response('Newsletter database binding NEWSLETTER_DB is not configured.', {
|
||
status: 500,
|
||
});
|
||
}
|
||
|
||
const row = await db
|
||
.prepare(
|
||
`SELECT * FROM newsletter_subscribers
|
||
WHERE confirm_token = ? AND status = 'pending'
|
||
LIMIT 1`,
|
||
)
|
||
.bind(token)
|
||
.first<NewsletterSubscriber>();
|
||
|
||
if (!row) {
|
||
return Response.redirect(new URL(failPath, url).toString(), 303);
|
||
}
|
||
|
||
await db
|
||
.prepare(
|
||
`UPDATE newsletter_subscribers
|
||
SET status = 'active',
|
||
confirmed_at = datetime('now'),
|
||
confirm_token = NULL
|
||
WHERE id = ?`,
|
||
)
|
||
.bind(row.id)
|
||
.run();
|
||
|
||
const emailBinding = getEmailBinding(runtimeEnv);
|
||
const fromEmail =
|
||
readEnv('NEWSLETTER_FROM_EMAIL', runtimeEnv) ||
|
||
readEnv('CONTACT_FORM_FROM_EMAIL', runtimeEnv);
|
||
const notifyTo =
|
||
readEnv('NEWSLETTER_NOTIFY_TO_EMAIL', runtimeEnv) ||
|
||
readEnv('CONTACT_FORM_TO_EMAIL', runtimeEnv);
|
||
|
||
if (emailBinding && fromEmail && notifyTo) {
|
||
try {
|
||
await sendCloudflareEmail(emailBinding, {
|
||
fromEmail,
|
||
toEmail: notifyTo,
|
||
subject: 'Iscrizione newsletter confermata — NexStudio',
|
||
text: `L’indirizzo ${row.email} ha confermato l’iscrizione alla newsletter.`,
|
||
});
|
||
} catch (error) {
|
||
console.warn('[newsletter] confirm notify failed', error);
|
||
}
|
||
}
|
||
|
||
return Response.redirect(
|
||
new URL(`${okPath}?unsub=${encodeURIComponent(row.unsubscribe_token)}`, request.url).toString(),
|
||
303,
|
||
);
|
||
};
|