From 954a57734893604bb2f870457890484acf9a2515 Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Thu, 2 Oct 2025 14:41:22 -0700 Subject: [PATCH] Refactor: Add Turnstile and login on signup --- functions/api/signup.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/functions/api/signup.js b/functions/api/signup.js index c50afb0..5f8cac3 100644 --- a/functions/api/signup.js +++ b/functions/api/signup.js @@ -6,14 +6,30 @@ const json = (d, o = {}) => { export async function onRequestPost({ request, env }) { try { - const { username, email, pass_hash } = await request.json(); + const body = await request.json(); + const fd = new FormData(); + fd.append('secret', env.SEC_TURNSTILE); + fd.append('response', body['cf-turnstile-response']); + fd.append('remoteip', request.headers.get('CF-Connecting-IP')); + const ts = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { body: fd, method: 'POST' }); + if (!(await ts.json()).success) return json({ error: 'Invalid CAPTCHA' }, { status: 403 }); + + const { username, email, pass_hash } = body; if (!username || !email || !pass_hash) return json({ error: 'Missing fields' }, { status: 400 }); await env.D1_SPCHCAP.prepare( 'INSERT INTO users (username, email, pass_hash, ip_address) VALUES (?, ?, ?, ?)' ).bind(username, email, pass_hash, request.headers.get('CF-Connecting-IP')).run(); + + const user = await env.D1_SPCHCAP.prepare('SELECT role FROM users WHERE username = ?').bind(username).first(); + const exp = new Date(Date.now() + 2592e6); // 30 days + const opts = `Domain=.speech.capital; Path=/; Expires=${exp.toUTCString()}; HttpOnly; Secure; SameSite=Strict`; + const headers = new Headers(); + headers.append('Set-Cookie', `auth_user=${username}; ${opts}`); + headers.append('Set-Cookie', `auth_hash=${pass_hash}; ${opts}`); + headers.append('Set-Cookie', `auth_role=${user.role}; ${opts}`); - return json({ success: true }, { status: 201 }); + return json({ success: true }, { headers }); } catch (e) { const msg = e.message?.includes('UNIQUE') ? 'Username or email taken' : e.message; return json({ error: { message: msg } }, { status: e.message?.includes('UNIQUE') ? 409 : 500 });