134 lines
3 KiB
TypeScript
134 lines
3 KiB
TypeScript
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 }
|
|
);
|
|
}
|