Bläddra i källkod

Merge pull request #25886 from overleaf/msm-add-skip-email-to-delete-user

[CE] Add `--skip-email` to `delete-user` script

GitOrigin-RevId: d0f5ced26930060df1e9f40dee97839076743bbd
Miguel Serrano 1 år sedan
förälder
incheckning
3cf436c89e

+ 6 - 2
services/web/app/src/Features/User/UserDeleter.js

@@ -60,8 +60,12 @@ async function deleteUser(userId, options) {
     await _createDeletedUser(user, options)
     logger.info({ userId }, 'deleting user projects')
     await ProjectDeleter.promises.deleteUsersProjects(user._id)
-    logger.info({ userId }, 'sending deletion email to user')
-    await _sendDeleteEmail(user, options.force)
+    if (options.skipEmail) {
+      logger.info({ userId }, 'skipping sending deletion email to user')
+    } else {
+      logger.info({ userId }, 'sending deletion email to user')
+      await _sendDeleteEmail(user, options.force)
+    }
     logger.info({ userId }, 'deleting user record')
     await deleteMongoUser(user._id)
     logger.info({ userId }, 'user deletion complete')

+ 18 - 2
services/web/modules/server-ce-scripts/scripts/delete-user.mjs

@@ -1,13 +1,28 @@
 import UserGetter from '../../../app/src/Features/User/UserGetter.js'
 import UserDeleter from '../../../app/src/Features/User/UserDeleter.js'
 import { fileURLToPath } from 'url'
+import minimist from 'minimist'
 
 const filename = fileURLToPath(import.meta.url)
 
 async function main() {
-  const email = (process.argv.slice(2).pop() || '').replace(/^--email=/, '')
+  const argv = minimist(process.argv.slice(2), {
+    string: ['email'],
+    boolean: ['skip-email'],
+  })
+
+  const { email, 'skip-email': skipEmail } = argv
   if (!email) {
-    console.error(`Usage: node ${filename} --email=joe@example.com`)
+    console.error(
+      `Usage: node ${filename} [--skip-email] --email=joe@example.com
+
+Deletes a user. All users' projects will also be deleted.
+
+Options:
+    --email          email address of the user being deleted
+    --skip-email    (optional) when present, the user is not notified of the deletion via email
+`
+    )
     process.exit(1)
   }
 
@@ -25,6 +40,7 @@ async function main() {
       const options = {
         ipAddress: '0.0.0.0',
         force: true,
+        skipEmail,
       }
       UserDeleter.deleteUser(user._id, options, function (err) {
         if (err) {

+ 9 - 0
services/web/test/unit/src/User/UserDeleterTests.js

@@ -314,6 +314,15 @@ describe('UserDeleter', function () {
               ).to.have.been.calledWith('securityAlert', emailOptions)
             })
 
+            it('should not email the user with skipEmail === true', async function () {
+              await this.UserDeleter.promises.deleteUser(this.userId, {
+                ipAddress: this.ipAddress,
+                skipEmail: true,
+              })
+              expect(this.EmailHandler.promises.sendEmail).not.to.have.been
+                .called
+            })
+
             it('should fail when the email service fails', async function () {
               this.EmailHandler.promises.sendEmail = sinon
                 .stub()