Add good validation to all existing endpoints
This commit is contained in:
@@ -1,11 +1,30 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { fetchAllUsers, fetchUserData, createNewUser } from "../controller/userController";
|
import { fetchAllUsers, fetchUserData, createNewUser } from "../controller/userController";
|
||||||
import { createUserSchema } from "../validators/userValidator";
|
import { createUserSchema, queryAllUsersByInstanceId, queryUserByIdSchema } from "../validators/userValidator";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { describeRoute, resolver } from "hono-openapi";
|
import { describeRoute, resolver } from "hono-openapi";
|
||||||
const actions = new Hono();
|
const actions = new Hono();
|
||||||
|
|
||||||
actions.get("user/:id", async (c) => {
|
actions.get("user/:id",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get user by id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting user",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(queryUserByIdSchema) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "User id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(queryUserByIdSchema) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
zValidator('param', queryUserByIdSchema),
|
||||||
|
async (c) => {
|
||||||
const id = c.req.param("id");
|
const id = c.req.param("id");
|
||||||
const userData = await fetchUserData(id);
|
const userData = await fetchUserData(id);
|
||||||
if (userData) {
|
if (userData) {
|
||||||
@@ -13,10 +32,24 @@ actions.get("user/:id", async (c) => {
|
|||||||
} else {
|
} else {
|
||||||
return c.json({ error: "User not found" }, 404);
|
return c.json({ error: "User not found" }, 404);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
actions.get("user", async (c) => {
|
actions.get("user",
|
||||||
const instanceId = c.req.query("instance_id");
|
describeRoute({
|
||||||
|
description: "Get all users by instance id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting all users in instance",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(queryAllUsersByInstanceId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
zValidator('query', queryAllUsersByInstanceId),
|
||||||
|
async (c) => {
|
||||||
|
const instanceId = c.req.query("instanceId");
|
||||||
if (!instanceId) {
|
if (!instanceId) {
|
||||||
return c.json({ error: "No instance id provided" }, 400);
|
return c.json({ error: "No instance id provided" }, 400);
|
||||||
}
|
}
|
||||||
@@ -27,7 +60,8 @@ actions.get("user", async (c) => {
|
|||||||
} else {
|
} else {
|
||||||
return c.json({ error: "Error getting all users from instance" }, 500);
|
return c.json({ error: "Error getting all users from instance" }, 500);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
actions.post(
|
actions.post(
|
||||||
"user",
|
"user",
|
||||||
@@ -39,6 +73,12 @@ actions.post(
|
|||||||
content: {
|
content: {
|
||||||
'application/json': { schema: resolver(createUserSchema) },
|
'application/json': { schema: resolver(createUserSchema) },
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad request (user exists)",
|
||||||
|
content: {
|
||||||
|
'application/json': { schema: resolver(createUserSchema) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -47,6 +87,9 @@ actions.post(
|
|||||||
try {
|
try {
|
||||||
const data = await c.req.json();
|
const data = await c.req.json();
|
||||||
const newUser = await createNewUser(data);
|
const newUser = await createNewUser(data);
|
||||||
|
if (!newUser) {
|
||||||
|
return c.json({ error: "User already exists" }, 400);
|
||||||
|
}
|
||||||
return c.json(newUser, 201);
|
return c.json(newUser, 201);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return c.json({ error: "Error creating user" }, 500);
|
return c.json({ error: "Error creating user" }, 500);
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ import { CreateUserInput } from '../validators/userValidator';
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
export async function createUser(data: CreateUserInput) {
|
export async function createUser(data: CreateUserInput) {
|
||||||
|
if (await prisma.user.count({ where: { username: data.username }}) >= 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return await prisma.user.create({
|
return await prisma.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: data.username,
|
username: data.username,
|
||||||
@@ -111,9 +115,13 @@ export async function getAllUsersFrom(instanceId: string): Promise<
|
|||||||
| null
|
| null
|
||||||
> {
|
> {
|
||||||
try {
|
try {
|
||||||
const instances = await prisma.instance.findMany();
|
const instances = await prisma.instance.count({
|
||||||
if (!instances) {
|
where: {
|
||||||
throw new Error("could not get all instances");
|
id: instanceId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (instances < 1) {
|
||||||
|
throw new Error("could not find given instance id");
|
||||||
}
|
}
|
||||||
|
|
||||||
const users = await prisma.user.findMany({
|
const users = await prisma.user.findMany({
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const queryUserByIdSchema = z.object({
|
||||||
|
id: z.uuidv7()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const queryAllUsersByInstanceId = z.object({
|
||||||
|
instanceId: z.uuidv7()
|
||||||
|
})
|
||||||
|
|
||||||
export const createUserSchema = z.object({
|
export const createUserSchema = z.object({
|
||||||
username: z.string().min(3).max(30),
|
username: z.string().min(3).max(30),
|
||||||
nickname: z.string().min(1).max(30).optional(),
|
nickname: z.string().min(1).max(30).optional(),
|
||||||
|
|||||||
Reference in New Issue
Block a user