import * as ldap from "@/ldap"; import prisma from "@/prisma"; import { getUser } from "@/auth"; import { getDiscordAvatar } from "@/app/oauth/discord/oauth"; import { getLogger } from "@/logger"; type RequestBody = { username: string; displayName: string; email: string; password: string; avatarBase64: string | null; }; export async function POST(request: Request) { const logger = getLogger("/api/register"); const user = await getUser(); if (user == null) return new Response(null, { status: 401 }); if (user.username !== null) { if (!(await ldap.checkUserExists(user.username))) { logger.warn( { username: user.username }, "user doesn't exist in ldap anymore" ); user.username = null; await prisma.user.update({ where: { id: user.id }, data: { username: null } }); } else { logger.info(`user ${user.username} tried to register twice`); // user already has an account, don't re-register return new Response(null, { status: 403 }); } } const { username, displayName, email, password, avatarBase64 } = (await request.json()) as RequestBody; // runtime type verification when :pleading: if ( username == undefined || typeof username !== "string" || displayName == undefined || typeof displayName !== "string" || email == undefined || typeof email !== "string" || password == undefined || typeof password !== "string" ) { return new Response( JSON.stringify({ ok: false, error: "invalidBody" }), { status: 400 } ); } if (password.length < 12) { return new Response( JSON.stringify({ ok: false, error: "passwordShort" }), { status: 400 } ); } let avatarBuf: Buffer | undefined; if (avatarBase64 !== null && typeof avatarBase64 === "string") { avatarBuf = Buffer.from(avatarBase64, "base64"); if (avatarBuf.length > 1_000_000) { return new Response( JSON.stringify({ ok: false, error: "avatarBig" }), { status: 400 } ); } } const discordAuth = await prisma.discordAuth.findFirst({ where: { userId: user.id } }); if (discordAuth !== null && avatarBuf === undefined) { avatarBuf = await getDiscordAvatar(discordAuth.accessToken); } const users = await ldap.getUsers(); for (const user of users) { if (user.id.toLowerCase() === username.toLowerCase()) { return new Response( JSON.stringify({ ok: false, error: "usernameTaken" }), { status: 400 } ); } } await ldap.createUser(username, displayName, email, avatarBuf); await ldap.setPassword(username, password); const outputUser = await prisma.user.update({ where: { id: user.id }, data: { username } }); logger.info(outputUser, "registered user"); return new Response( JSON.stringify({ ok: true }), { status: 201 } ); }