Sfoglia il codice sorgente

Script for removing user enrollment from a subscription (#24627)

* Script for removing user enrollment to a subcription

* Add "release-managed-user"  audit log event for an user id

GitOrigin-RevId: adf2dd97ac82977bcfa07d9a24d1f3c190d095a2
Domagoj Kriskovic 1 anno fa
parent
commit
830d0daa38

+ 2 - 0
services/web/app/src/Features/User/UserAuditLogHandler.js

@@ -7,6 +7,7 @@ function _canHaveNoIpAddressId(operation, info) {
   if (operation === 'leave-group-subscription') return true
   if (operation === 'must-reset-password-set') return true
   if (operation === 'remove-email' && info.script) return true
+  if (operation === 'release-managed-user' && info.script) return true
   return false
 }
 
@@ -22,6 +23,7 @@ function _canHaveNoInitiatorId(operation, info) {
   if (operation === 'must-reset-password-set') return true
   if (operation === 'must-reset-password-unset') return true
   if (operation === 'account-suspension' && info.script) return true
+  if (operation === 'release-managed-user' && info.script) return true
 }
 
 /**

+ 93 - 0
services/web/scripts/remove_user_enrollment.mjs

@@ -0,0 +1,93 @@
+// This script will:
+// 1. remove enrollment.managedBy and enrollment.enrolledAt fields from the User record
+// 2. remove the user_id from member_ids on the Subscription record
+//
+// Usage:
+// $ node scripts/remove_user_enrollment.mjs --id USER_ID --commit
+
+import minimist from 'minimist'
+import { ObjectId } from '../app/src/infrastructure/mongodb.js'
+import { User } from '../app/src/models/User.js'
+import { Subscription } from '../app/src/models/Subscription.js'
+import UserAuditLogHandler from '../app/src/Features/User/UserAuditLogHandler.js'
+
+const argv = minimist(process.argv.slice(2))
+const COMMIT = argv.commit !== undefined
+if (!COMMIT) {
+  console.warn('Doing dry run without --commit')
+}
+
+const userId = argv.id
+if (!userId) throw new Error('missing user ID (use --id)')
+
+async function _handleUser(userId) {
+  const user = await User.findById(userId, { enrollment: 1 })
+  if (!user) {
+    throw new Error(`user ${userId} does not exist`)
+  }
+
+  if (!user.enrollment?.managedBy) {
+    throw new Error(`user ${userId} has no enrollment`)
+  }
+
+  const subscriptionId = user.enrollment.managedBy
+
+  if (COMMIT) {
+    await Subscription.updateOne(
+      { _id: subscriptionId },
+      { $pull: { member_ids: userId } }
+    )
+  } else {
+    console.log(
+      `Would remove user ${userId} from subscription ${subscriptionId}`
+    )
+  }
+
+  if (COMMIT) {
+    await User.updateOne(
+      { _id: userId },
+      {
+        $unset: {
+          'enrollment.managedBy': 1,
+          'enrollment.enrolledAt': 1,
+        },
+      }
+    )
+  } else {
+    console.log(`Would remove enrollment from user ${userId}`)
+  }
+
+  if (COMMIT) {
+    await UserAuditLogHandler.promises.addEntry(
+      userId,
+      'release-managed-user',
+      undefined,
+      undefined,
+      { script: true, subscriptionId, comment: 'removed by support' }
+    )
+  } else {
+    console.log(
+      `Would create user audit log "release-managed-user" with comment "removed by support"`
+    )
+  }
+}
+
+async function processUser(userId) {
+  console.log('---Starting remove enrollment script---')
+  console.log(`Will process user: ${userId}`)
+
+  if (!ObjectId.isValid(userId)) {
+    throw new Error(`user ID not valid: ${userId}`)
+  }
+
+  try {
+    await _handleUser(new ObjectId(userId))
+    console.log(`User ${userId} processed successfully`)
+  } catch (error) {
+    console.log(`Failed to process user ${userId}:`, error)
+  }
+
+  process.exit()
+}
+
+await processUser(userId)