From 41f8b42f1ca79cbe01dc4adda0acd0aba143e442 Mon Sep 17 00:00:00 2001 From: alikia2x Date: Tue, 1 Apr 2025 10:30:44 +0800 Subject: [PATCH] improve: the registration API --- packages/backend/register.ts | 70 +++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/packages/backend/register.ts b/packages/backend/register.ts index 29b624b..401ef6b 100644 --- a/packages/backend/register.ts +++ b/packages/backend/register.ts @@ -1,27 +1,65 @@ import { createHandlers } from "./utils.ts"; import Argon2id from "@rabbit-company/argon2id"; +import { object, string, ValidationError } from "yup"; +import type { Context } from "hono"; +import type { Bindings, BlankEnv, BlankInput } from "hono/types"; +import type { Client } from "https://deno.land/x/postgres@v0.19.3/mod.ts"; + +const RegistrationBodySchema = object({ + username: string().trim().required("Username is required").max(50, "Username cannot exceed 50 characters"), + password: string().required("Password is required"), + nickname: string().optional(), +}); + +type ContextType = Context; + +export const userExists = async (username: string, client: Client) => { + const query = ` + SELECT * FROM users WHERE username = $1 + `; + const result = await client.queryObject(query, [username]); + return result.rows.length > 0; +} + +export const registerHandler = createHandlers(async (c: ContextType) => { + const client = c.get("dbCred"); -export const registerHandler = createHandlers(async (c) => { try { - const client = c.get("dbCred"); - const body = await c.req.json(); - const username = body.username; - const password = body.password; + const body = await RegistrationBodySchema.validate(await c.req.json()); + const { username, password, nickname } = body; + + if (await userExists(username, client)) { + return c.json({ + message: `User "${username}" already exists.`, + }, 400); + } + const hash = await Argon2id.hashEncoded(password); + const query = ` - INSERT INTO users (username, password) VALUES ($1, $2) + INSERT INTO users (username, password, nickname) VALUES ($1, $2, $3) `; - await client.queryObject(query, [username, hash]); + await client.queryObject(query, [username, hash, nickname || null]); + return c.json({ - success: true, - message: "Registered", - }); + message: `User "${username}" registered successfully.`, + }, 201); } catch (e) { - if (e instanceof SyntaxError) { - return c.json({ error: "Invalid JSON" }, 400); - } - else { - return c.json({ error: (e as Error).message }, 500); - } + if (e instanceof ValidationError) { + return c.json({ + message: "Invalid registration data.", + errors: e.errors, + }, 400); + } else if (e instanceof SyntaxError) { + return c.json({ + message: "Invalid JSON in request body.", + }, 400); + } else { + console.error("Registration error:", e); + return c.json({ + message: "An unexpected error occurred during registration.", + error: (e as Error).message, + }, 500); + } } });