clear_sessions_set_must_reconfirm.mjs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import fs from 'node:fs'
  2. import { ObjectId } from '../app/src/infrastructure/mongodb.js'
  3. import UserUpdater from '../app/src/Features/User/UserUpdater.js'
  4. import UserSessionsManager from '../app/src/Features/User/UserSessionsManager.js'
  5. import UserAuditLogHandler from '../app/src/Features/User/UserAuditLogHandler.js'
  6. import { promiseMapWithLimit } from '@overleaf/promise-utils'
  7. const ASYNC_LIMIT = 10
  8. const processLogger = {
  9. failedClear: [],
  10. failedSet: [],
  11. success: [],
  12. printSummary: () => {
  13. console.log(
  14. {
  15. success: processLogger.success,
  16. failedClear: processLogger.failedClear,
  17. failedSet: processLogger.failedSet,
  18. },
  19. `\nDONE. ${processLogger.success.length} successful. ${processLogger.failedClear.length} failed to clear sessions. ${processLogger.failedSet.length} failed to set must_reconfirm.`
  20. )
  21. },
  22. }
  23. function _validateUserIdList(userIds) {
  24. if (!Array.isArray(userIds)) throw new Error('users is not an array')
  25. userIds.forEach(userId => {
  26. if (!ObjectId.isValid(userId)) throw new Error('user ID not valid')
  27. })
  28. }
  29. async function _handleUser(userId) {
  30. try {
  31. await UserUpdater.promises.updateUser(userId, {
  32. $set: { must_reconfirm: true },
  33. })
  34. } catch (error) {
  35. console.log(`Failed to set must_reconfirm ${userId}`, error)
  36. processLogger.failedSet.push(userId)
  37. return
  38. }
  39. try {
  40. await UserAuditLogHandler.promises.addEntry(
  41. userId,
  42. 'must-reset-password-set',
  43. undefined,
  44. undefined,
  45. { script: true }
  46. )
  47. } catch (error) {
  48. console.log(`Failed to create audit log for ${userId}`, error)
  49. // don't block the process if audit log fails
  50. }
  51. try {
  52. await UserSessionsManager.promises.removeSessionsFromRedis(
  53. { _id: userId },
  54. null
  55. )
  56. } catch (error) {
  57. console.log(`Failed to clear sessions for ${userId}`, error)
  58. processLogger.failedClear.push(userId)
  59. return
  60. }
  61. processLogger.success.push(userId)
  62. }
  63. async function _loopUsers(userIds) {
  64. return promiseMapWithLimit(ASYNC_LIMIT, userIds, _handleUser)
  65. }
  66. const fileName = process.argv[2]
  67. if (!fileName) throw new Error('missing filename')
  68. const usersFile = fs.readFileSync(fileName, 'utf8')
  69. const userIds = usersFile
  70. .trim()
  71. .split('\n')
  72. .map(id => id.trim())
  73. async function processUsers(userIds) {
  74. console.log('---Starting set_must_reconfirm script---')
  75. _validateUserIdList(userIds)
  76. console.log(`---Starting to process ${userIds.length} users---`)
  77. await _loopUsers(userIds)
  78. processLogger.printSummary()
  79. process.exit()
  80. }
  81. processUsers(userIds)