mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #20756 from overleaf/jpa-clear-admin-sessions
[web] add script for clearing admin sessions GitOrigin-RevId: c5103b233073db62276698067b2262d7a785592b
This commit is contained in:
parent
85bc305df2
commit
39ee8de1a5
3 changed files with 87 additions and 5 deletions
|
@ -133,7 +133,9 @@ const UserSessionsManager = {
|
||||||
*/
|
*/
|
||||||
removeSessionsFromRedis(user, retainSessionID, callback) {
|
removeSessionsFromRedis(user, retainSessionID, callback) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return callback(null)
|
return callback(
|
||||||
|
new Error('bug: user not passed to removeSessionsFromRedis')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||||
rclient.smembers(sessionSetKey, function (err, sessionKeys) {
|
rclient.smembers(sessionSetKey, function (err, sessionKeys) {
|
||||||
|
@ -155,7 +157,7 @@ const UserSessionsManager = {
|
||||||
{ userId: user._id },
|
{ userId: user._id },
|
||||||
'no sessions in UserSessions set to delete, returning'
|
'no sessions in UserSessions set to delete, returning'
|
||||||
)
|
)
|
||||||
return callback(null)
|
return callback(null, 0)
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
{ userId: user._id, count: keysToDelete.length },
|
{ userId: user._id, count: keysToDelete.length },
|
||||||
|
@ -180,7 +182,7 @@ const UserSessionsManager = {
|
||||||
})
|
})
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
callback(null)
|
callback(null, keysToDelete.length)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
70
services/web/scripts/clear_admin_sessions.js
Normal file
70
services/web/scripts/clear_admin_sessions.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
const {
|
||||||
|
db,
|
||||||
|
waitForDb,
|
||||||
|
READ_PREFERENCE_SECONDARY,
|
||||||
|
} = require('../app/src/infrastructure/mongodb')
|
||||||
|
const UserSessionsManager = require('../app/src/Features/User/UserSessionsManager')
|
||||||
|
|
||||||
|
const COMMIT = process.argv.includes('--commit')
|
||||||
|
const LOG_SESSIONS = !process.argv.includes('--log-sessions=false')
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
await waitForDb()
|
||||||
|
const adminUsers = await db.users
|
||||||
|
.find(
|
||||||
|
{ isAdmin: true },
|
||||||
|
{
|
||||||
|
projection: {
|
||||||
|
_id: 1,
|
||||||
|
email: 1,
|
||||||
|
},
|
||||||
|
readPreference: READ_PREFERENCE_SECONDARY,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.toArray()
|
||||||
|
|
||||||
|
if (LOG_SESSIONS) {
|
||||||
|
for (const user of adminUsers) {
|
||||||
|
user.sessions = JSON.stringify(
|
||||||
|
await UserSessionsManager.promises.getAllUserSessions(user, [])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('All Admin users before clearing:')
|
||||||
|
console.table(adminUsers)
|
||||||
|
|
||||||
|
if (COMMIT) {
|
||||||
|
let anyFailed = false
|
||||||
|
for (const user of adminUsers) {
|
||||||
|
console.error(
|
||||||
|
`Clearing sessions for ${user.email} (${user._id.toString()})`
|
||||||
|
)
|
||||||
|
user.clearedSessions = 0
|
||||||
|
try {
|
||||||
|
user.clearedSessions =
|
||||||
|
await UserSessionsManager.promises.removeSessionsFromRedis(user)
|
||||||
|
} catch (err) {
|
||||||
|
anyFailed = true
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('All Admin users after clearing:')
|
||||||
|
console.table(adminUsers)
|
||||||
|
|
||||||
|
if (anyFailed) {
|
||||||
|
throw new Error('failed to clear some sessions, see above for details')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('Use --commit to clear sessions.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.then(() => {
|
||||||
|
console.error('Done.')
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error({ error })
|
||||||
|
process.exit(1)
|
||||||
|
})
|
|
@ -363,6 +363,14 @@ describe('UserSessionsManager', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should yield the number of purged sessions', function (done) {
|
||||||
|
return this.call((err, n) => {
|
||||||
|
expect(err).to.not.exist
|
||||||
|
expect(n).to.equal(this.sessionKeys.length)
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should call the appropriate redis methods', function (done) {
|
it('should call the appropriate redis methods', function (done) {
|
||||||
return this.call(err => {
|
return this.call(err => {
|
||||||
this.rclient.smembers.callCount.should.equal(1)
|
this.rclient.smembers.callCount.should.equal(1)
|
||||||
|
@ -465,9 +473,11 @@ describe('UserSessionsManager', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not produce an error', function (done) {
|
it('should produce an error', function (done) {
|
||||||
return this.call(err => {
|
return this.call(err => {
|
||||||
expect(err).to.not.exist
|
expect(err).to.match(
|
||||||
|
/bug: user not passed to removeSessionsFromRedis/
|
||||||
|
)
|
||||||
return done()
|
return done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue