improve: the registration API
This commit is contained in:
parent
fba56106cc
commit
41f8b42f1c
@ -1,27 +1,65 @@
|
|||||||
import { createHandlers } from "./utils.ts";
|
import { createHandlers } from "./utils.ts";
|
||||||
import Argon2id from "@rabbit-company/argon2id";
|
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";
|
||||||
|
|
||||||
export const registerHandler = createHandlers(async (c) => {
|
const RegistrationBodySchema = object({
|
||||||
try {
|
username: string().trim().required("Username is required").max(50, "Username cannot exceed 50 characters"),
|
||||||
const client = c.get("dbCred");
|
password: string().required("Password is required"),
|
||||||
const body = await c.req.json();
|
nickname: string().optional(),
|
||||||
const username = body.username;
|
});
|
||||||
const password = body.password;
|
|
||||||
const hash = await Argon2id.hashEncoded(password);
|
type ContextType = Context<BlankEnv & { Bindings: Bindings }, "/user", BlankInput>;
|
||||||
|
|
||||||
|
export const userExists = async (username: string, client: Client) => {
|
||||||
const query = `
|
const query = `
|
||||||
INSERT INTO users (username, password) VALUES ($1, $2)
|
SELECT * FROM users WHERE username = $1
|
||||||
`;
|
`;
|
||||||
await client.queryObject(query, [username, hash]);
|
const result = await client.queryObject(query, [username]);
|
||||||
|
return result.rows.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const registerHandler = createHandlers(async (c: ContextType) => {
|
||||||
|
const client = c.get("dbCred");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const body = await RegistrationBodySchema.validate(await c.req.json());
|
||||||
|
const { username, password, nickname } = body;
|
||||||
|
|
||||||
|
if (await userExists(username, client)) {
|
||||||
return c.json({
|
return c.json({
|
||||||
success: true,
|
message: `User "${username}" already exists.`,
|
||||||
message: "Registered",
|
}, 400);
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof SyntaxError) {
|
|
||||||
return c.json({ error: "Invalid JSON" }, 400);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return c.json({ error: (e as Error).message }, 500);
|
const hash = await Argon2id.hashEncoded(password);
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
INSERT INTO users (username, password, nickname) VALUES ($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.queryObject(query, [username, hash, nickname || null]);
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
message: `User "${username}" registered successfully.`,
|
||||||
|
}, 201);
|
||||||
|
} catch (e) {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user