136 lines
3.5 KiB
TypeScript
136 lines
3.5 KiB
TypeScript
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<RowDataPacket[]>(
|
|
"SELECT * FROM users WHERE id = ?",
|
|
[body.username],
|
|
);
|
|
|
|
const [duplicateEmails] = await pool.execute<RowDataPacket[]>(
|
|
"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<RowDataPacket[]>(
|
|
"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;
|