el.xwx.moe/lib/api/controllers/users/postUser.ts

138 lines
4.0 KiB
TypeScript
Raw Normal View History

2023-02-18 21:32:02 -06:00
import { prisma } from "@/lib/api/db";
2023-02-06 11:59:23 -06:00
import type { NextApiRequest, NextApiResponse } from "next";
import bcrypt from "bcrypt";
2024-09-14 15:00:19 -05:00
import { PostUserSchema } from "@/lib/shared/schemaValidation";
import isAuthenticatedRequest from "../../isAuthenticatedRequest";
import { Subscription, User } from "@prisma/client";
2023-02-06 11:59:23 -06:00
const emailEnabled =
2023-07-12 13:26:34 -05:00
process.env.EMAIL_FROM && process.env.EMAIL_SERVER ? true : false;
2024-05-03 09:22:45 -05:00
const stripeEnabled = process.env.STRIPE_SECRET_KEY ? true : false;
2023-07-12 13:26:34 -05:00
2023-02-06 11:59:23 -06:00
interface Data {
response: string | object;
status: number;
2023-02-06 11:59:23 -06:00
}
export default async function postUser(
2023-02-06 11:59:23 -06:00
req: NextApiRequest,
res: NextApiResponse
): Promise<Data> {
const parentUser = await isAuthenticatedRequest({ req });
const isAdmin =
parentUser && parentUser.id === Number(process.env.NEXT_PUBLIC_ADMIN || 1);
const DISABLE_INVITES = process.env.DISABLE_INVITES === "true";
if (process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true" && !isAdmin) {
return { response: "Registration is disabled.", status: 400 };
}
2024-09-14 15:00:19 -05:00
const dataValidation = PostUserSchema().safeParse(req.body);
2023-11-19 21:28:02 -06:00
2024-09-14 15:00:19 -05:00
if (!dataValidation.success) {
return {
response: `Error: ${
dataValidation.error.issues[0].message
} [${dataValidation.error.issues[0].path.join(", ")}]`,
status: 400,
};
}
2023-07-19 00:23:53 -05:00
const { name, email, password, invite } = dataValidation.data;
2024-09-14 15:00:19 -05:00
let { username } = dataValidation.data;
2024-08-14 16:26:38 -05:00
if (invite && (DISABLE_INVITES || !emailEnabled)) {
return { response: "You are not authorized to invite users.", status: 401 };
} else if (invite && !parentUser) {
return { response: "You must be logged in to invite users.", status: 401 };
}
2024-08-14 16:26:38 -05:00
const autoGeneratedUsername = "user" + Math.round(Math.random() * 1000000000);
2024-09-14 15:00:19 -05:00
if (!username) {
username = autoGeneratedUsername;
2024-08-14 16:26:38 -05:00
}
2023-07-19 00:23:53 -05:00
if (!emailEnabled && !password) {
return {
response: "Password is required.",
status: 400,
};
}
2023-07-12 13:26:34 -05:00
const checkIfUserExists = await prisma.user.findFirst({
2024-05-03 09:22:45 -05:00
where: {
OR: [
{
2024-09-14 15:00:19 -05:00
email: email ? email.toLowerCase().trim() : undefined,
2024-05-03 09:22:45 -05:00
},
{
2024-09-14 15:00:19 -05:00
username: username ? username.toLowerCase().trim() : undefined,
2023-07-12 13:26:34 -05:00
},
2024-05-03 09:22:45 -05:00
],
},
2023-07-12 13:26:34 -05:00
});
2023-02-06 11:59:23 -06:00
if (!checkIfUserExists) {
2024-05-12 23:27:29 -05:00
const autoGeneratedUsername =
"user" + Math.round(Math.random() * 1000000000);
2023-02-06 11:59:23 -06:00
const saltRounds = 10;
const hashedPassword = bcrypt.hashSync(password || "", saltRounds);
const user = await prisma.user.create({
data: {
name: name,
username: emailEnabled ? username || autoGeneratedUsername : username,
email: emailEnabled ? email : undefined,
emailVerified: isAdmin ? new Date() : undefined,
password: password ? hashedPassword : undefined,
parentSubscription:
parentUser && invite
? {
connect: {
id: (parentUser.subscriptions as Subscription).id,
},
}
: undefined,
subscriptions:
stripeEnabled && isAdmin
2024-05-03 09:22:45 -05:00
? {
create: {
stripeSubscriptionId:
"fake_sub_" + Math.round(Math.random() * 10000000000000),
active: true,
currentPeriodStart: new Date(),
currentPeriodEnd: new Date(
new Date().setFullYear(new Date().getFullYear() + 1000)
), // 1000 years from now
2024-05-03 09:22:45 -05:00
},
}
: undefined,
},
select: isAdmin
? {
id: true,
username: true,
email: true,
emailVerified: true,
password: true,
subscriptions: {
select: {
active: true,
},
2024-05-03 09:22:45 -05:00
},
createdAt: true,
}
: undefined,
});
2023-02-06 11:59:23 -06:00
const { password: pass, ...userWithoutPassword } = user as User;
return { response: userWithoutPassword, status: 201 };
} else {
return { response: "Email or Username already exists.", status: 400 };
2023-02-06 11:59:23 -06:00
}
}