delete user
parent
a662087197
commit
65938e3147
|
@ -8,7 +8,7 @@ import {
|
||||||
} from "../utils/constants";
|
} from "../utils/constants";
|
||||||
import UserPendingPayment from "../models/userPendingPayment";
|
import UserPendingPayment from "../models/userPendingPayment";
|
||||||
import User from "../models/user";
|
import User from "../models/user";
|
||||||
import { getUserSession } from "../utils/utils";
|
import { getUserSession, stripe } from "../utils/utils";
|
||||||
import Store from "../models/store";
|
import Store from "../models/store";
|
||||||
import Session from "../models/session";
|
import Session from "../models/session";
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ const ZeitAdlerBasicYearly = "zeitadler-basic-yearly";
|
||||||
const ZeitAdlerPremiumMonthly = "zeitadler-premium-monthly";
|
const ZeitAdlerPremiumMonthly = "zeitadler-premium-monthly";
|
||||||
const ZeitAdlerPremiumYearly = "zeitadler-premium-yearly";
|
const ZeitAdlerPremiumYearly = "zeitadler-premium-yearly";
|
||||||
|
|
||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
|
|
||||||
let cachedPrices = [] as any[];
|
let cachedPrices = [] as any[];
|
||||||
|
|
||||||
export async function loadPrices() {
|
export async function loadPrices() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import User from "../models/user";
|
||||||
import {
|
import {
|
||||||
isCompanyNameValid,
|
isCompanyNameValid,
|
||||||
isEmailValid,
|
isEmailValid,
|
||||||
|
isFeedbackValid,
|
||||||
isLanguageCodeValid,
|
isLanguageCodeValid,
|
||||||
isPasswordValid,
|
isPasswordValid,
|
||||||
isPaymentIntervalValid,
|
isPaymentIntervalValid,
|
||||||
|
@ -33,6 +34,7 @@ import {
|
||||||
newStoreId,
|
newStoreId,
|
||||||
newUserId,
|
newUserId,
|
||||||
saveSession,
|
saveSession,
|
||||||
|
stripe,
|
||||||
} from "../utils/utils";
|
} from "../utils/utils";
|
||||||
import Store from "../models/store";
|
import Store from "../models/store";
|
||||||
import Session from "../models/session";
|
import Session from "../models/session";
|
||||||
|
@ -44,6 +46,13 @@ import EmailVerification from "../models/emailVerification";
|
||||||
import UserPendingEmailChange from "../models/userPendingEmailChange";
|
import UserPendingEmailChange from "../models/userPendingEmailChange";
|
||||||
import { CreateCheckoutSession, getPriceId } from "./paymentController";
|
import { CreateCheckoutSession, getPriceId } from "./paymentController";
|
||||||
import UserPendingPayment from "../models/userPendingPayment";
|
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) {
|
export async function SignUp(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
|
@ -799,7 +808,8 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
const { reason, feedback, password } = req.body;
|
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" });
|
return res.status(400).send({ err: "invalid request" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,7 +823,7 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
||||||
where: {
|
where: {
|
||||||
user_id: session.user_id,
|
user_id: session.user_id,
|
||||||
},
|
},
|
||||||
attributes: ["password"],
|
attributes: ["password", "stripe_customer_id"],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
|
@ -828,18 +838,176 @@ export async function DeleteUserProfile(req: Request, res: Response) {
|
||||||
return res.status(400).send({ err: "invalid request" });
|
return res.status(400).send({ err: "invalid request" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// set user state to pending deletion
|
// delete stripe subscription
|
||||||
|
|
||||||
await User.update(
|
if (user.stripe_customer_id) {
|
||||||
{
|
const subscription = await stripe.subscriptions.list({
|
||||||
state: ACCOUNT_STATE.PENDING_DELETION,
|
customer: user.stripe_customer_id,
|
||||||
},
|
});
|
||||||
{
|
|
||||||
where: {
|
if (subscription.data.length > 0) {
|
||||||
user_id: session.user_id,
|
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
|
// 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}`,
|
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" });
|
res.status(200).send({ msg: "user deleted" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Stripe from "stripe";
|
||||||
|
|
||||||
export const DEFAULT_SESSION_EXPIRY = 365 * 24 * 60 * 60 * 1000; // 365 days
|
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 SESSION_EXPIRY_NOT_REMEMBER_ME = 60 * 60 * 1000; // 1 hour
|
||||||
export const USER_SESSION_LENGTH = 32;
|
export const USER_SESSION_LENGTH = 32;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
SESSION_EXPIRY_NOT_REMEMBER_ME,
|
SESSION_EXPIRY_NOT_REMEMBER_ME,
|
||||||
USER_SESSION_LENGTH,
|
USER_SESSION_LENGTH,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
|
import Stripe from "stripe";
|
||||||
|
|
||||||
export async function matchPassword(decodedPassword: string, password: string) {
|
export async function matchPassword(decodedPassword: string, password: string) {
|
||||||
return await bcrypt.compare(decodedPassword, password);
|
return await bcrypt.compare(decodedPassword, password);
|
||||||
|
@ -115,3 +116,5 @@ export function getEmailVerificationUrl(
|
||||||
) {
|
) {
|
||||||
return `${DASHBOARD_URL}/verify/${String(state)}/${emailVerificationId}`;
|
return `${DASHBOARD_URL}/verify/${String(state)}/${emailVerificationId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
|
||||||
|
|
Loading…
Reference in New Issue