added delete user endpoint
This commit is contained in:
parent
4252b79586
commit
97d8c35d2a
|
@ -0,0 +1,118 @@
|
||||||
|
import { prisma } from "@/lib/api/db";
|
||||||
|
import bcrypt from "bcrypt";
|
||||||
|
import removeFolder from "@/lib/api/storage/removeFolder";
|
||||||
|
import Stripe from "stripe";
|
||||||
|
|
||||||
|
type DeleteUserBody = {
|
||||||
|
password: string;
|
||||||
|
cancellation_details?: {
|
||||||
|
comment?: string;
|
||||||
|
feedback?: Stripe.SubscriptionCancelParams.CancellationDetails.Feedback;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function deleteUserById(
|
||||||
|
userId: number,
|
||||||
|
body: DeleteUserBody
|
||||||
|
) {
|
||||||
|
// First, we retrieve the user from the database
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: { id: userId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
response: "User not found.",
|
||||||
|
status: 404,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, we check if the provided password matches the one stored in the database
|
||||||
|
const isPasswordValid = bcrypt.compareSync(body.password, user.password);
|
||||||
|
|
||||||
|
if (!isPasswordValid) {
|
||||||
|
return {
|
||||||
|
response: "Invalid password.",
|
||||||
|
status: 401, // Unauthorized
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the user and all related data within a transaction
|
||||||
|
await prisma.$transaction(async (prisma) => {
|
||||||
|
// Delete whitelisted users
|
||||||
|
await prisma.whitelistedUser.deleteMany({
|
||||||
|
where: { userId },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete links
|
||||||
|
await prisma.link.deleteMany({
|
||||||
|
where: { collection: { ownerId: userId } },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete tags
|
||||||
|
await prisma.tag.deleteMany({
|
||||||
|
where: { ownerId: userId },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete collections
|
||||||
|
const collections = await prisma.collection.findMany({
|
||||||
|
where: { ownerId: userId },
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const collection of collections) {
|
||||||
|
// Delete related users and collections relations
|
||||||
|
await prisma.usersAndCollections.deleteMany({
|
||||||
|
where: { collectionId: collection.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optionally delete archive folders associated with collections
|
||||||
|
removeFolder({ filePath: `archives/${collection.id}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete collections after cleaning up related data
|
||||||
|
await prisma.collection.deleteMany({
|
||||||
|
where: { ownerId: userId },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optionally delete user's avatar
|
||||||
|
removeFolder({ filePath: `uploads/avatar/${userId}.jpg` });
|
||||||
|
|
||||||
|
// Finally, delete the user
|
||||||
|
await prisma.user.delete({
|
||||||
|
where: { id: userId },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.STRIPE_SECRET_KEY) {
|
||||||
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
|
||||||
|
apiVersion: "2022-11-15",
|
||||||
|
});
|
||||||
|
|
||||||
|
const listByEmail = await stripe.customers.list({
|
||||||
|
email: user.email?.toLowerCase(),
|
||||||
|
expand: ["data.subscriptions"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (listByEmail.data[0].subscriptions?.data[0].id) {
|
||||||
|
const deleted = await stripe.subscriptions.cancel(
|
||||||
|
listByEmail.data[0].subscriptions?.data[0].id,
|
||||||
|
{
|
||||||
|
cancellation_details: {
|
||||||
|
comment: body.cancellation_details?.comment,
|
||||||
|
feedback: body.cancellation_details?.feedback,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: deleted,
|
||||||
|
status: 200,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: "User account and all related data deleted successfully.",
|
||||||
|
status: 200,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import { prisma } from "@/lib/api/db";
|
import { prisma } from "@/lib/api/db";
|
||||||
|
|
||||||
export default async function getUser(
|
export default async function getPublicUserById(
|
||||||
targetId: number | string,
|
targetId: number | string,
|
||||||
isId: boolean,
|
isId: boolean,
|
||||||
requestingUsername?: string
|
requestingUsername?: string
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { prisma } from "@/lib/api/db";
|
import { prisma } from "@/lib/api/db";
|
||||||
|
|
||||||
export default async function getUser(userId: number) {
|
export default async function getUserById(userId: number) {
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: userId,
|
id: userId,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import createFolder from "@/lib/api/storage/createFolder";
|
||||||
const emailEnabled =
|
const emailEnabled =
|
||||||
process.env.EMAIL_FROM && process.env.EMAIL_SERVER ? true : false;
|
process.env.EMAIL_FROM && process.env.EMAIL_SERVER ? true : false;
|
||||||
|
|
||||||
export default async function updateUser(
|
export default async function updateUserById(
|
||||||
sessionUser: {
|
sessionUser: {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||||
import getUserById from "@/lib/api/controllers/users/userId/getUserById";
|
import getUserById from "@/lib/api/controllers/users/userId/getUserById";
|
||||||
import getPublicUserById from "@/lib/api/controllers/users/userId/getPublicUserById";
|
import getPublicUserById from "@/lib/api/controllers/users/userId/getPublicUserById";
|
||||||
import updateUserById from "@/lib/api/controllers/users/userId/updateUserById";
|
import updateUserById from "@/lib/api/controllers/users/userId/updateUserById";
|
||||||
|
import deleteUserById from "@/lib/api/controllers/users/userId/deleteUserById";
|
||||||
|
|
||||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const session = await getServerSession(req, res, authOptions);
|
const session = await getServerSession(req, res, authOptions);
|
||||||
|
@ -36,5 +37,12 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||||
} else if (req.method === "PUT") {
|
} else if (req.method === "PUT") {
|
||||||
const updated = await updateUserById(session.user, req.body);
|
const updated = await updateUserById(session.user, req.body);
|
||||||
return res.status(updated.status).json({ response: updated.response });
|
return res.status(updated.status).json({ response: updated.response });
|
||||||
|
} else if (
|
||||||
|
req.method === "DELETE" &&
|
||||||
|
session.user.id === Number(req.query.id)
|
||||||
|
) {
|
||||||
|
console.log(req.body);
|
||||||
|
const updated = await deleteUserById(session.user.id, req.body);
|
||||||
|
return res.status(updated.status).json({ response: updated.response });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ŝarĝante…
Reference in New Issue