| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- const { callbackify } = require('util')
- const logger = require('@overleaf/logger')
- const moment = require('moment')
- const { User } = require('../../models/User')
- const { DeletedUser } = require('../../models/DeletedUser')
- const NewsletterManager = require('../Newsletter/NewsletterManager')
- const ProjectDeleter = require('../Project/ProjectDeleter')
- const SubscriptionHandler = require('../Subscription/SubscriptionHandler')
- const SubscriptionUpdater = require('../Subscription/SubscriptionUpdater')
- const SubscriptionLocator = require('../Subscription/SubscriptionLocator')
- const UserMembershipsHandler = require('../UserMembership/UserMembershipsHandler')
- const UserSessionsManager = require('./UserSessionsManager')
- const InstitutionsAPI = require('../Institutions/InstitutionsAPI')
- const Errors = require('../Errors/Errors')
- module.exports = {
- deleteUser: callbackify(deleteUser),
- deleteMongoUser: callbackify(deleteMongoUser),
- expireDeletedUser: callbackify(expireDeletedUser),
- ensureCanDeleteUser: callbackify(ensureCanDeleteUser),
- expireDeletedUsersAfterDuration: callbackify(expireDeletedUsersAfterDuration),
- promises: {
- deleteUser,
- deleteMongoUser,
- expireDeletedUser,
- ensureCanDeleteUser,
- expireDeletedUsersAfterDuration,
- },
- }
- async function deleteUser(userId, options = {}) {
- if (!userId) {
- logger.warn('user_id is null when trying to delete user')
- throw new Error('no user_id')
- }
- try {
- const user = await User.findById(userId).exec()
- logger.debug({ user }, 'deleting user')
- await ensureCanDeleteUser(user)
- await _cleanupUser(user)
- await _createDeletedUser(user, options)
- await ProjectDeleter.promises.deleteUsersProjects(user._id)
- await deleteMongoUser(user._id)
- } catch (error) {
- logger.warn({ error, userId }, 'something went wrong deleting the user')
- throw error
- }
- }
- /**
- * delete a user document only
- */
- async function deleteMongoUser(userId) {
- if (!userId) {
- throw new Error('no user_id')
- }
- await User.deleteOne({ _id: userId }).exec()
- }
- async function expireDeletedUser(userId) {
- const deletedUser = await DeletedUser.findOne({
- 'deleterData.deletedUserId': userId,
- }).exec()
- deletedUser.user = undefined
- deletedUser.deleterData.deleterIpAddress = undefined
- await deletedUser.save()
- }
- async function expireDeletedUsersAfterDuration() {
- const DURATION = 90
- const deletedUsers = await DeletedUser.find({
- 'deleterData.deletedAt': {
- $lt: new Date(moment().subtract(DURATION, 'days')),
- },
- user: {
- $ne: null,
- },
- }).exec()
- if (deletedUsers.length === 0) {
- return
- }
- for (let i = 0; i < deletedUsers.length; i++) {
- await expireDeletedUser(deletedUsers[i].deleterData.deletedUserId)
- }
- }
- async function ensureCanDeleteUser(user) {
- const subscription = await SubscriptionLocator.promises.getUsersSubscription(
- user
- )
- if (subscription) {
- throw new Errors.SubscriptionAdminDeletionError({})
- }
- }
- async function _createDeletedUser(user, options) {
- await DeletedUser.updateOne(
- { 'deleterData.deletedUserId': user._id },
- {
- user,
- deleterData: {
- deletedAt: new Date(),
- deleterId: options.deleterUser ? options.deleterUser._id : undefined,
- deleterIpAddress: options.ipAddress,
- deletedUserId: user._id,
- deletedUserLastLoggedIn: user.lastLoggedIn,
- deletedUserSignUpDate: user.signUpDate,
- deletedUserLoginCount: user.loginCount,
- deletedUserReferralId: user.referal_id,
- deletedUserReferredUsers: user.refered_users,
- deletedUserReferredUserCount: user.refered_user_count,
- deletedUserOverleafId: user.overleaf ? user.overleaf.id : undefined,
- },
- },
- { upsert: true }
- )
- }
- async function _cleanupUser(user) {
- await UserSessionsManager.promises.revokeAllUserSessions(user._id, [])
- await NewsletterManager.promises.unsubscribe(user, { delete: true })
- await SubscriptionHandler.promises.cancelSubscription(user)
- await InstitutionsAPI.promises.deleteAffiliations(user._id)
- await SubscriptionUpdater.promises.removeUserFromAllGroups(user._id)
- await UserMembershipsHandler.promises.removeUserFromAllEntities(user._id)
- }
|