import { Hono } from "hono"; import pool from "../../lib/database.js"; import type { RowDataPacket } from "mysql2"; import { getKeys as TurnstileKeys, isEnabled as Turnstile } from "../../lib/turnstile.js"; import { getConnInfo } from "@hono/node-server/conninfo"; import { hash as generatePasswordHash } from "bcrypt"; import { v4 as uuid } from "uuid"; import MailVerifySend from "../../lib/mailverify.js"; const SignUpAPI = new Hono(); SignUpAPI.post("/", async (c) => { const body = await c.req.json(); if ( body.username === undefined || body.email === undefined || body.password === undefined ) { return c.json({ success: false, error: "input_lack", }, 400); } if ( body.username.length < 3 || body.username.length > 15 || body.password.length < 8 || body.password.length > 15 ) { return c.json({ success: false, error: "length_different", }, 400); } if ( await Turnstile() && body.turnstile === undefined ) { return c.json({ success: false, error: "input_lack", }, 400); } if (await Turnstile()) { const sendData = new FormData(); const ip = getConnInfo(c).remote.address; if (ip !== undefined) { sendData.append("remoteip", ip); } sendData.append("secret", (await TurnstileKeys())[1]); sendData.append("response", body.turnstile); sendData.append("idempotency_key", uuid()) try { const req = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", { method: "POST", cache: "no-store", body: sendData, }); if (!req.ok) { return c.json({ success: false, error: "turnstile_request_failed", }, 500); } const res = await req.json(); if (res.success === false) { return c.json({ success: false, error: "turnstile_failed", }, 400); } } catch (err) { return c.json({ success: false, error: "turnstile_request_failed", }, 500); } } const [duplicateUsers] = await pool.execute( "SELECT * FROM users WHERE id = ?", [body.username], ); const [duplicateEmails] = await pool.execute( "SELECT * FROM users WHERE email = ?", [body.email], ); if (duplicateUsers.length > 0) { return c.json({ success: false, error: "username_duplicate", }, 400); } if (duplicateEmails.length > 0) { return c.json({ success: false, error: "email_duplicate", }, 400); } const passwordHash = await generatePasswordHash(body.password, 10); const [result] = await pool.execute( "INSERT INTO `users` (`id`, `password`, `email`, `mailverified`, `time`) VALUES (?, ?, ?, '0', current_timestamp(3))", [body.username, passwordHash, body.email], ); if ((result as RowDataPacket).affectedRows === 1) { const send = await MailVerifySend(body.username, body.email, c.get("language")); if (send === true) { return c.json({ success: true, }, 201); } else { return c.json({ success: false, error: send, }, 500); } } else { return c.json({ success: false, error: "account_create_failed", }, 500); } }); export default SignUpAPI;