delete user
parent
a662087197
commit
65938e3147
|
@ -8,7 +8,7 @@ import {
|
|||
} from "../utils/constants";
|
||||
import UserPendingPayment from "../models/userPendingPayment";
|
||||
import User from "../models/user";
|
||||
import { getUserSession } from "../utils/utils";
|
||||
import { getUserSession, stripe } from "../utils/utils";
|
||||
import Store from "../models/store";
|
||||
import Session from "../models/session";
|
||||
|
||||
|
@ -17,7 +17,6 @@ const ZeitAdlerBasicYearly = "zeitadler-basic-yearly";
|
|||
const ZeitAdlerPremiumMonthly = "zeitadler-premium-monthly";
|
||||
const ZeitAdlerPremiumYearly = "zeitadler-premium-yearly";
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
|
||||
let cachedPrices = [] as any[];
|
||||
|
||||
export async function loadPrices() {
|
||||
|
|
|
@ -4,6 +4,7 @@ import User from "../models/user";
|
|||
import {
|
||||
isCompanyNameValid,
|
||||
isEmailValid,
|
||||
isFeedbackValid,
|
||||
isLanguageCodeValid,
|
||||
isPasswordValid,
|
||||
isPaymentIntervalValid,
|
||||
|
@ -33,6 +34,7 @@ import {
|
|||
newStoreId,
|
||||
newUserId,
|
||||
saveSession,
|
||||
stripe,
|
||||
} from "../utils/utils";
|
||||
import Store from "../models/store";
|
||||
import Session from "../models/session";
|
||||
|
@ -44,6 +46,13 @@ import EmailVerification from "../models/emailVerification";
|
|||
import UserPendingEmailChange from "../models/userPendingEmailChange";
|
||||
import { CreateCheckoutSession, getPriceId } from "./paymentController";
|
||||
import UserPendingPayment from "../models/userPendingPayment";
|
||||
import StoreServiceActivity from "../models/storeServiceActivity";
|
||||
import StoreService from "../models/storeService";
|
||||
import StoreServiceActivityUsers from "../models/storeServiceActivityUsers";
|
||||
import {
|
||||
isTerminPlanerGoogleCalendarConnected,
|
||||
terminPlanerRequest,
|
||||
} from "../utils/terminPlaner";
|
||||
|
||||
export async function SignUp(req: Request, res: Response) {
|
||||
try {
|
||||
|
@ -799,7 +808,8 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
|||
try {
|
||||
const { reason, feedback, password } = req.body;
|
||||
|
||||
if (!reason || !feedback || !password) {
|
||||
if (!reason || !feedback || !password || !isFeedbackValid(feedback)) {
|
||||
console.log("invalid request");
|
||||
return res.status(400).send({ err: "invalid request" });
|
||||
}
|
||||
|
||||
|
@ -813,7 +823,7 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
|||
where: {
|
||||
user_id: session.user_id,
|
||||
},
|
||||
attributes: ["password"],
|
||||
attributes: ["password", "stripe_customer_id"],
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
|
@ -828,18 +838,176 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
|||
return res.status(400).send({ err: "invalid request" });
|
||||
}
|
||||
|
||||
// set user state to pending deletion
|
||||
// delete stripe subscription
|
||||
|
||||
await User.update(
|
||||
{
|
||||
state: ACCOUNT_STATE.PENDING_DELETION,
|
||||
},
|
||||
{
|
||||
where: {
|
||||
user_id: session.user_id,
|
||||
},
|
||||
if (user.stripe_customer_id) {
|
||||
const subscription = await stripe.subscriptions.list({
|
||||
customer: user.stripe_customer_id,
|
||||
});
|
||||
|
||||
if (subscription.data.length > 0) {
|
||||
const subscriptionId = subscription.data[0].id;
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Canceling stripe subscription id:",
|
||||
subscriptionId
|
||||
);
|
||||
|
||||
await stripe.subscriptions.cancel(subscriptionId);
|
||||
}
|
||||
);
|
||||
|
||||
await stripe.customers.del(user.stripe_customer_id);
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted stripe customer id:",
|
||||
user.stripe_customer_id
|
||||
);
|
||||
}
|
||||
|
||||
// delete store if user is a store owner
|
||||
|
||||
const store = await Store.findOne({
|
||||
where: {
|
||||
owner_user_id: session.user_id,
|
||||
},
|
||||
attributes: ["store_id"],
|
||||
});
|
||||
|
||||
// user is a store owner
|
||||
if (store) {
|
||||
await Store.destroy({
|
||||
where: {
|
||||
store_id: store.store_id,
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(session.user_id, "Deleted store id:", store.store_id);
|
||||
|
||||
// delete all employees of this store
|
||||
|
||||
const employees = await User.findAll({
|
||||
where: {
|
||||
store_id: store.store_id,
|
||||
},
|
||||
attributes: ["user_id"],
|
||||
});
|
||||
|
||||
if (employees) {
|
||||
for (const employee of employees) {
|
||||
const googleCalendarConnected =
|
||||
await isTerminPlanerGoogleCalendarConnected(employee.user_id);
|
||||
|
||||
if (googleCalendarConnected) {
|
||||
await terminPlanerRequest("/api/v1/removeGoogleAccount", "POST", {
|
||||
userId: employee.user_id,
|
||||
});
|
||||
}
|
||||
|
||||
await Session.destroy({
|
||||
where: {
|
||||
user_id: employee.user_id,
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted store employee id:",
|
||||
employee.user_id
|
||||
);
|
||||
}
|
||||
|
||||
await User.destroy({
|
||||
where: {
|
||||
user_id: employees.map((employee) => employee.user_id),
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted store employees, count:",
|
||||
employees.length.toString()
|
||||
);
|
||||
}
|
||||
|
||||
// delete all store services, store service activities, and store service activity users
|
||||
|
||||
const storeServices = await StoreService.findAll({
|
||||
where: {
|
||||
store_id: store.store_id,
|
||||
},
|
||||
attributes: ["service_id"],
|
||||
});
|
||||
|
||||
if (storeServices) {
|
||||
const storeServiceActivities = await StoreServiceActivity.findAll({
|
||||
where: {
|
||||
service_id: storeServices.map((service) => service.service_id),
|
||||
},
|
||||
});
|
||||
|
||||
if (storeServiceActivities) {
|
||||
const storeServiceActivityUsers =
|
||||
await StoreServiceActivityUsers.findAll({
|
||||
where: {
|
||||
activity_id: storeServiceActivities.map(
|
||||
(activity) => activity.activity_id
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
if (storeServiceActivityUsers) {
|
||||
await StoreServiceActivityUsers.destroy({
|
||||
where: {
|
||||
activity_id: storeServiceActivityUsers.map(
|
||||
(activity) => activity.activity_id
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted store service activity users, count:",
|
||||
storeServiceActivityUsers.length.toString()
|
||||
);
|
||||
}
|
||||
|
||||
await StoreServiceActivity.destroy({
|
||||
where: {
|
||||
activity_id: storeServiceActivities.map(
|
||||
(activity) => activity.activity_id
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted store service activities, count:",
|
||||
storeServiceActivities.length.toString()
|
||||
);
|
||||
|
||||
await StoreService.destroy({
|
||||
where: {
|
||||
service_id: storeServices.map((service) => service.service_id),
|
||||
},
|
||||
});
|
||||
|
||||
userLogger.info(
|
||||
session.user_id,
|
||||
"Deleted store services, count:",
|
||||
storeServices.length.toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// destroy user
|
||||
|
||||
await User.destroy({
|
||||
where: {
|
||||
user_id: session.user_id,
|
||||
},
|
||||
});
|
||||
|
||||
// delete all sessions of this user by deleting all sessions with this user_id
|
||||
|
||||
|
@ -857,7 +1025,7 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
|||
feedback: `${reason} - ${feedback}`,
|
||||
});
|
||||
|
||||
userLogger.info(session.user_id, "User deleted profile");
|
||||
userLogger.info(session.user_id, "Deleted user account");
|
||||
|
||||
res.status(200).send({ msg: "user deleted" });
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Stripe from "stripe";
|
||||
|
||||
export const DEFAULT_SESSION_EXPIRY = 365 * 24 * 60 * 60 * 1000; // 365 days
|
||||
export const SESSION_EXPIRY_NOT_REMEMBER_ME = 60 * 60 * 1000; // 1 hour
|
||||
export const USER_SESSION_LENGTH = 32;
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
SESSION_EXPIRY_NOT_REMEMBER_ME,
|
||||
USER_SESSION_LENGTH,
|
||||
} from "./constants";
|
||||
import Stripe from "stripe";
|
||||
|
||||
export async function matchPassword(decodedPassword: string, password: string) {
|
||||
return await bcrypt.compare(decodedPassword, password);
|
||||
|
@ -115,3 +116,5 @@ export function getEmailVerificationUrl(
|
|||
) {
|
||||
return `${DASHBOARD_URL}/verify/${String(state)}/${emailVerificationId}`;
|
||||
}
|
||||
|
||||
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
|
||||
|
|
Loading…
Reference in New Issue