diff options
Diffstat (limited to 'src/app/api/users/route.ts')
| -rw-r--r-- | src/app/api/users/route.ts | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts new file mode 100644 index 0000000..dbb114c --- /dev/null +++ b/src/app/api/users/route.ts @@ -0,0 +1,44 @@ +import { z } from 'zod'; +import { ROLES } from '@/lib/constants'; +import { uuid } from '@/lib/crypto'; +import { hashPassword } from '@/lib/password'; +import { parseRequest } from '@/lib/request'; +import { badRequest, json, unauthorized } from '@/lib/response'; +import { canCreateUser } from '@/permissions'; +import { createUser, getUserByUsername } from '@/queries/prisma'; + +export async function POST(request: Request) { + const schema = z.object({ + id: z.uuid().optional(), + username: z.string().max(255), + password: z.string(), + role: z.string().regex(/admin|user|view-only/i), + }); + + const { auth, body, error } = await parseRequest(request, schema); + + if (error) { + return error(); + } + + if (!(await canCreateUser(auth))) { + return unauthorized(); + } + + const { id, username, password, role } = body; + + const existingUser = await getUserByUsername(username, { showDeleted: true }); + + if (existingUser) { + return badRequest({ message: 'User already exists' }); + } + + const user = await createUser({ + id: id || uuid(), + username, + password: hashPassword(password), + role: role ?? ROLES.user, + }); + + return json(user); +} |