diff options
| author | Adam Soltys <[email protected]> | 2026-01-21 12:07:05 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-01-21 12:07:07 -0800 |
| commit | a665d7f229e17d691e371d8683e578d59c19b297 (patch) | |
| tree | f5a46ff5273fda79289debade10faa1f687c0565 /routes | |
| parent | 792cea0773dd5ce25c1618137688abadfb2ad8f3 (diff) | |
| download | coinos-server-a665d7f229e17d691e371d8683e578d59c19b297.tar.gz coinos-server-a665d7f229e17d691e371d8683e578d59c19b297.zip | |
recaptcha on login
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/users.ts | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/routes/users.ts b/routes/users.ts index 3b56c9c6..fee39344 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -14,6 +14,7 @@ import { bail, fail, fields, getUser, pick } from "$lib/utils"; import whitelist from "$lib/whitelist"; import rpc from "@coinos/rpc"; import { $ } from "bun"; +import got from "got"; import jwt from "jsonwebtoken"; import { getPublicKey, nip19, verifyEvent } from "nostr-tools"; import { authenticator } from "otplib"; @@ -25,6 +26,26 @@ import type { ProfilePointer } from "nostr-tools/nip19"; const { host } = new URL(process.env.URL); const relay = encodeURIComponent(config.publicRelay); +const verifyRecaptcha = async (response) => { + const { recaptcha: secret } = config; + if (!secret) return true; + if (!response) return false; + + try { + const { success } = await got + .post("https://www.google.com/recaptcha/api/siteverify", { + form: { + secret, + response, + }, + }) + .json(); + return success || response === config.adminpass; + } catch { + return false; + } +}; + export default { upload, @@ -326,7 +347,12 @@ export default { async login(req, res) { try { - let { challenge, username, password, token: twofa } = req.body; + let { challenge, username, password, token: twofa, recaptcha } = req.body; + + const recaptchaOk = await verifyRecaptcha(recaptcha); + if (!recaptchaOk) { + return res.code(401).send("failed captcha"); + } username = username.toLowerCase().replace(/\s/g, ""); @@ -385,8 +411,12 @@ export default { async nostrAuth(req, res) { try { - const { event, challenge, twofa } = req.body; + const { event, challenge, twofa, recaptcha } = req.body; const ip = req.headers["cf-connecting-ip"]; + const recaptchaOk = await verifyRecaptcha(recaptcha); + if (!recaptchaOk) { + return res.code(401).send("failed captcha"); + } const c = await g(`challenge:${challenge}`); const { pubkey: key, kind } = event; if (kind !== 27235) fail("Invalid event"); |
