fix: Better error reporting & some fixes to deleteUser API (#12439)
This commit is contained in:
parent
608b891536
commit
8e7785ca64
|
@ -1,5 +1,6 @@
|
|||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { deleteUser } from "@calcom/features/users/lib/userDeletionService";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
|
@ -41,10 +42,18 @@ export async function deleteHandler(req: NextApiRequest) {
|
|||
// Here we only check for ownership of the user if the user is not admin, otherwise we let ADMIN's edit any user
|
||||
if (!isAdmin && query.userId !== req.userId) throw new HttpError({ statusCode: 403, message: "Forbidden" });
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: query.userId } });
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: query.userId },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
metadata: true,
|
||||
},
|
||||
});
|
||||
if (!user) throw new HttpError({ statusCode: 404, message: "User not found" });
|
||||
|
||||
await prisma.user.delete({ where: { id: user.id } });
|
||||
await deleteUser(user);
|
||||
|
||||
return { message: `User with id: ${user.id} deleted successfully` };
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import type { User } from "@prisma/client";
|
||||
|
||||
import { deleteStripeCustomer } from "@calcom/app-store/stripepayment/lib/customer";
|
||||
import { deleteWebUser as syncServicesDeleteWebUser } from "@calcom/lib/sync/SyncServiceManager";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
export async function deleteUser(user: Pick<User, "id" | "email" | "metadata">) {
|
||||
// If 2FA is disabled or totpCode is valid then delete the user from stripe and database
|
||||
await deleteStripeCustomer(user).catch(console.warn);
|
||||
// Remove my account
|
||||
// TODO: Move this to Repository pattern.
|
||||
const deletedUser = await prisma.user.delete({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
// Sync Services
|
||||
syncServicesDeleteWebUser(deletedUser);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { deleteStripeCustomer } from "@calcom/app-store/stripepayment/lib/customer";
|
||||
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
|
||||
import { verifyPassword } from "@calcom/features/auth/lib/verifyPassword";
|
||||
import { deleteUser } from "@calcom/features/users/lib/userDeletionService";
|
||||
import { symmetricDecrypt } from "@calcom/lib/crypto";
|
||||
import { deleteWebUser as syncServicesDeleteWebUser } from "@calcom/lib/sync/SyncServiceManager";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { totpAuthenticatorCheck } from "@calcom/lib/totp";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { IdentityProvider } from "@calcom/prisma/enums";
|
||||
|
@ -18,32 +18,43 @@ type DeleteMeOptions = {
|
|||
};
|
||||
|
||||
export const deleteMeHandler = async ({ ctx, input }: DeleteMeOptions) => {
|
||||
// TODO: First check password is part of input and meets requirements.
|
||||
|
||||
// Check if input.password is correct
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
email: ctx.user.email.toLowerCase(),
|
||||
},
|
||||
select: {
|
||||
identityProvider: true,
|
||||
twoFactorEnabled: true,
|
||||
twoFactorSecret: true,
|
||||
password: true,
|
||||
email: true,
|
||||
metadata: true,
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!user) {
|
||||
throw new Error(ErrorCode.UserNotFound);
|
||||
throw new HttpError({ statusCode: 404, message: ErrorCode.UserNotFound });
|
||||
}
|
||||
|
||||
if (user.identityProvider !== IdentityProvider.CAL) {
|
||||
throw new Error(ErrorCode.ThirdPartyIdentityProviderEnabled);
|
||||
throw new HttpError({ statusCode: 400, message: ErrorCode.ThirdPartyIdentityProviderEnabled });
|
||||
}
|
||||
|
||||
if (!user.password) {
|
||||
throw new Error(ErrorCode.UserMissingPassword);
|
||||
throw new HttpError({ statusCode: 400, message: ErrorCode.UserMissingPassword });
|
||||
}
|
||||
|
||||
const isCorrectPassword = await verifyPassword(input.password, user.password);
|
||||
if (!isCorrectPassword) {
|
||||
throw new Error(ErrorCode.IncorrectPassword);
|
||||
throw new HttpError({ statusCode: 403, message: ErrorCode.IncorrectPassword });
|
||||
}
|
||||
|
||||
if (user.twoFactorEnabled) {
|
||||
if (!input.totpCode) {
|
||||
throw new Error(ErrorCode.SecondFactorRequired);
|
||||
throw new HttpError({ statusCode: 400, message: ErrorCode.SecondFactorRequired });
|
||||
}
|
||||
|
||||
if (!user.twoFactorSecret) {
|
||||
|
@ -67,20 +78,10 @@ export const deleteMeHandler = async ({ ctx, input }: DeleteMeOptions) => {
|
|||
// If user has 2fa enabled, check if input.totpCode is correct
|
||||
const isValidToken = totpAuthenticatorCheck(input.totpCode, secret);
|
||||
if (!isValidToken) {
|
||||
throw new Error(ErrorCode.IncorrectTwoFactorCode);
|
||||
throw new HttpError({ statusCode: 403, message: ErrorCode.IncorrectTwoFactorCode });
|
||||
}
|
||||
}
|
||||
|
||||
// If 2FA is disabled or totpCode is valid then delete the user from stripe and database
|
||||
await deleteStripeCustomer(user).catch(console.warn);
|
||||
// Remove my account
|
||||
const deletedUser = await prisma.user.delete({
|
||||
where: {
|
||||
id: ctx.user.id,
|
||||
},
|
||||
});
|
||||
|
||||
// Sync Services
|
||||
syncServicesDeleteWebUser(deletedUser);
|
||||
await deleteUser(user);
|
||||
return;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user