mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-01 05:11:34 +02:00
[web] Re-add remove_unwanted_ieee_collabratec_users script (#32603)
* Revert "Merge pull request #19398 from overleaf/rh-rm-ieee-notification" This reverts commit 14ec3e50ed4913b815620f5215df59b17fc03054, reversing changes made to 326352c7c459063bfddf98937e830565c5422ce2. * Convert remove_unwanted_ieee_collabratec_users to ESM * Use scriptRunner * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> GitOrigin-RevId: f7d9a4c74173e38789b053792597f761d91efa4f
This commit is contained in:
195
services/web/scripts/remove_unwanted_ieee_collabratec_users.mjs
Normal file
195
services/web/scripts/remove_unwanted_ieee_collabratec_users.mjs
Normal file
@@ -0,0 +1,195 @@
|
||||
import path from 'node:path'
|
||||
import fs from 'node:fs'
|
||||
import AnalyticsManager from '../app/src/Features/Analytics/AnalyticsManager.mjs'
|
||||
import { waitForDb, db } from '../app/src/infrastructure/mongodb.mjs'
|
||||
import { Subscription } from '../app/src/models/Subscription.mjs'
|
||||
import minimist from 'minimist'
|
||||
import { promiseMapWithLimit } from '@overleaf/promise-utils'
|
||||
import _ from 'lodash'
|
||||
import { scriptRunner } from './lib/ScriptRunner.mjs'
|
||||
|
||||
/**
|
||||
* This script is used to remove some users from the IEEEPublications group.
|
||||
*
|
||||
* Parameters:
|
||||
* --filename: the filename of the JSON file containing emails of users that
|
||||
* should **not** be removed
|
||||
* --commit: if present, the script will commit the changes to the database.
|
||||
*
|
||||
* Usage:
|
||||
* - dry run:
|
||||
* node scripts/remove_unwanted_ieee_collabratec_users.mjs --filename=emails-to-keep.json
|
||||
* - commit:
|
||||
* node scripts/remove_unwanted_ieee_collabratec_users.mjs --filename=emails-to-keep.json --commit
|
||||
*/
|
||||
|
||||
let COMMIT = false
|
||||
let EMAILS_FILENAME
|
||||
|
||||
/**
|
||||
* The IEEE have provided us with a list of active users that should not be removed
|
||||
* This method retrieves those users.
|
||||
*/
|
||||
function getActiveUserEmails(filename) {
|
||||
const data = fs.readFileSync(path.join(import.meta.dirname, filename), 'utf8')
|
||||
const emailsArray = JSON.parse(data)
|
||||
const emailsSet = new Set(emailsArray)
|
||||
console.log(
|
||||
`Read ${emailsSet.size} (${emailsArray.length} in array) emails from ${filename}`
|
||||
)
|
||||
return emailsSet
|
||||
}
|
||||
|
||||
async function getIEEEUsers() {
|
||||
const results = await db.subscriptions
|
||||
.aggregate([
|
||||
{ $match: { teamName: 'IEEEPublications' } },
|
||||
{ $unwind: '$member_ids' },
|
||||
{
|
||||
$lookup: {
|
||||
from: 'users',
|
||||
localField: 'member_ids',
|
||||
foreignField: '_id',
|
||||
as: 'member_details',
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 1,
|
||||
teamName: 1,
|
||||
'member_details._id': 1,
|
||||
'member_details.email': 1,
|
||||
'member_details.emails.email': 1,
|
||||
},
|
||||
},
|
||||
])
|
||||
.toArray()
|
||||
|
||||
return results
|
||||
.map(subscription => subscription.member_details[0])
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const start = performance.now()
|
||||
|
||||
if (!EMAILS_FILENAME) {
|
||||
throw new Error('No email filename provided')
|
||||
}
|
||||
|
||||
await waitForDb()
|
||||
const subscription = await Subscription.findOne({
|
||||
teamName: 'IEEEPublications',
|
||||
})
|
||||
|
||||
if (!subscription) {
|
||||
console.error(`No IEEEPublications group subscription found so quitting`)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
const oldMemberIds = subscription.member_ids.map(id => id.toString())
|
||||
|
||||
console.log(
|
||||
`Found ${oldMemberIds.length} members_ids in IEEEPublications group`
|
||||
)
|
||||
|
||||
const usersArray = await getIEEEUsers()
|
||||
console.log(
|
||||
`Found ${usersArray.length} users in IEEEPublications group. (${oldMemberIds.length - usersArray.length} missing)`
|
||||
)
|
||||
|
||||
const activeUsers = getActiveUserEmails(EMAILS_FILENAME)
|
||||
|
||||
const activeUsersFound = new Set()
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
const memberIdsToRemove = []
|
||||
|
||||
let index = 0
|
||||
|
||||
// Then go through each IEEEPublications group member to see if we need to remove them
|
||||
await promiseMapWithLimit(10, usersArray, async userDetails => {
|
||||
if (index % 1000 === 0)
|
||||
console.log(
|
||||
`progress: ${index} / ${usersArray.length} (${memberIdsToRemove.length} to remove)`
|
||||
)
|
||||
|
||||
index = index + 1
|
||||
|
||||
if (COMMIT) {
|
||||
await AnalyticsManager.setUserPropertyForUser(
|
||||
userDetails._id.toString(),
|
||||
'ieee-retirement',
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
for (const email of userDetails.emails) {
|
||||
if (activeUsers.has(email.email)) {
|
||||
activeUsersFound.add(email.email)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
memberIdsToRemove.push(userDetails._id.toString())
|
||||
})
|
||||
|
||||
console.log(`Found ${memberIdsToRemove.length} users to remove`)
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
const memberIdsToKeep = _.difference(oldMemberIds, memberIdsToRemove)
|
||||
|
||||
console.log(`Keeping ${memberIdsToKeep.length} users`)
|
||||
|
||||
if (COMMIT) {
|
||||
await Subscription.updateOne(
|
||||
{ teamName: 'IEEEPublications' },
|
||||
{ member_ids: memberIdsToKeep }
|
||||
)
|
||||
}
|
||||
|
||||
console.log(`Found ${activeUsersFound.size} active users`)
|
||||
|
||||
const activeUsersNotFound = Array.from(activeUsers).filter(
|
||||
user => !activeUsersFound.has(user)
|
||||
)
|
||||
|
||||
console.log(`${activeUsersNotFound.length} IEEE active users not found:`)
|
||||
console.log(activeUsersNotFound)
|
||||
|
||||
const subscriptionAfter = await Subscription.findOne({
|
||||
teamName: 'IEEEPublications',
|
||||
})
|
||||
console.log(
|
||||
`There are now ${subscriptionAfter?.member_ids?.length} member_ids in IEEEPublications group`
|
||||
)
|
||||
|
||||
const end = performance.now()
|
||||
console.log(`Took ${end - start} ms`)
|
||||
}
|
||||
|
||||
const setup = () => {
|
||||
const argv = minimist(process.argv.slice(2))
|
||||
COMMIT = argv.commit !== undefined
|
||||
EMAILS_FILENAME = argv.filename
|
||||
if (!COMMIT) {
|
||||
console.warn('Doing dry run. Add --commit to commit changes')
|
||||
}
|
||||
}
|
||||
|
||||
setup()
|
||||
|
||||
try {
|
||||
await scriptRunner(main)
|
||||
process.exit(0)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user