import type { APIRoute } from 'astro'; import { getNewsletterDb, getRuntimeEnv, readEnv, required, type NewsletterSubscriber, } from '../../../lib/newsletter'; export const prerender = false; async function unsubscribeByToken( locals: unknown, token: string, ): Promise<'ok' | 'missing' | 'not_found' | 'no_db'> { if (!token) return 'missing'; const runtimeEnv = getRuntimeEnv(locals); const mode = (readEnv('NEWSLETTER_MODE', runtimeEnv) || readEnv('CONTACT_FORM_MODE', runtimeEnv) || 'dev').toLowerCase(); if (mode !== 'live') { console.info('[newsletter:dev] Unsubscribe token received', { token: token.slice(0, 8) + '…' }); return 'ok'; } const db = getNewsletterDb(runtimeEnv); if (!db) return 'no_db'; const row = await db .prepare( `SELECT * FROM newsletter_subscribers WHERE unsubscribe_token = ? LIMIT 1`, ) .bind(token) .first(); if (!row) return 'not_found'; if (row.status !== 'unsubscribed') { await db .prepare( `UPDATE newsletter_subscribers SET status = 'unsubscribed', unsubscribed_at = datetime('now'), confirm_token = NULL WHERE id = ?`, ) .bind(row.id) .run(); } return 'ok'; } export const GET: APIRoute = async ({ locals, url }) => { const token = required(url.searchParams.get('token')); const result = await unsubscribeByToken(locals, token); if (result === 'no_db') { return new Response('Newsletter database binding NEWSLETTER_DB is not configured.', { status: 500, }); } const path = result === 'ok' ? '/newsletter/disiscrizione' : '/newsletter/disiscrizione-errore'; return Response.redirect(new URL(path, url).toString(), 303); }; export const POST: APIRoute = async ({ request, locals, url }) => { const form = await request.formData(); const token = required(form.get('token')) || required(url.searchParams.get('token')); const result = await unsubscribeByToken(locals, token); if (result === 'no_db') { return new Response('Newsletter database binding NEWSLETTER_DB is not configured.', { status: 500, }); } const path = result === 'ok' ? '/newsletter/disiscrizione' : '/newsletter/disiscrizione-errore'; return Response.redirect(new URL(path, url).toString(), 303); };