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 { compareSync as passwordHashCheck } from "bcrypt"; import { v4 as uuid } from "uuid"; import MailVerifySend from "../../lib/mailverify.js"; import { createAPIToken } from "src/lib/token.js"; import { UAParser } from "ua-parser-js"; import { setCookie } from "hono/cookie"; const SignInAPI = new Hono(); SignInAPI.post("/", async (c) => { const body = await c.req.json(); if ( body.username === 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 [user] = await pool.execute( "SELECT * FROM users WHERE id = ?", [body.username], ); if (user === undefined) { return c.json({ success: false, error: "user_not_found", }, 400); } if (passwordHashCheck(body.password, user[0].password)) { const token = await createAPIToken( body.username, ["client"], "Peas Client" ); setCookie(c, "token", token, { path: "/", sameSite: "Lax", maxAge: 86400 * 365, }); return c.json({ success: true, token: token, }); } else { return c.json({ success: false, error: "password_invalid", }, 400); } }); export default SignInAPI;