From 7e1fbc0fa96281de20ad2e654433597b27c6a824 Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Mon, 10 Nov 2025 13:10:32 -0800 Subject: [PATCH] Feat: Notify ntfy on signin --- functions/api/signin.js | 64 ++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/functions/api/signin.js b/functions/api/signin.js index 85ec6e5..6b2a290 100644 --- a/functions/api/signin.js +++ b/functions/api/signin.js @@ -1,17 +1,55 @@ +const notify = (env, title, message, level = 2) => + env.NTFY_TOPIC + ? fetch(`https://ntfy.sh/${env.NTFY_TOPIC}`, { + method: "POST", + headers: { + "Content-Type": "text/plain", + Title: title, + Priority: String(level), + }, + body: message, + }).catch(() => {}) + : Promise.resolve(); + export async function onRequestPost({ request, env }) { - try { - const { 'g-recaptcha-response': token, ...body } = await request.json(); - const vR = await fetch("https://www.google.com/recaptcha/api/siteverify", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: `secret=${env.RECAPCHA_KEY}&response=${token}` }); - if (!(await vR.json()).success) return new Response("CAPTCHA verification failed.", { status: 403 }); + try { + const { "g-recaptcha-response": token, ...body } = await request.json(); - const { username, pass_hash } = body; - if (!username || !pass_hash) return new Response("Missing fields", { status: 400 }); + const vR = await fetch( + "https://www.google.com/recaptcha/api/siteverify", + { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `secret=${env.RECAPCHA_KEY}&response=${token}`, + } + ); - const user = await env.D1_EV.prepare("SELECT pass_hash FROM users WHERE username = ?").bind(username).first(); - if (user?.pass_hash !== pass_hash) return new Response("Invalid credentials", { status: 401 }); - - return Response.json({ success: true, username: username }); - } catch (e) { - return new Response(e.message, { status: 500 }); - } + if (!(await vR.json()).success) + return new Response("CAPTCHA verification failed.", { status: 403 }); + + const { username, pass_hash } = body; + if (!username || !pass_hash) + return new Response("Missing fields", { status: 400 }); + + const user = await env.D1_EV.prepare( + "SELECT pass_hash FROM users WHERE username = ?" + ) + .bind(username) + .first(); + + if (user?.pass_hash !== pass_hash) + return new Response("Invalid credentials", { status: 401 }); + + env.NTFY_TOPIC && + notify( + env, + "4ev.link: signin", + `user=${username}`, + 2 + ); + + return Response.json({ success: true, username }); + } catch (e) { + return new Response(e.message, { status: 500 }); + } }