Merge pull request #1717 from overleaf/as-decaffeinate-backend
Decaffeinate backend GitOrigin-RevId: 4ca9f94fc809cab6f47cec8254cacaf1bb3806fa
This commit is contained in:
committed by
sharelatex
parent
d4eb71b525
commit
0ca81de78c
@@ -0,0 +1,294 @@
|
||||
/* eslint-disable
|
||||
camelcase,
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS103: Rewrite code to no longer use __guard__
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let UserSessionsManager
|
||||
const Settings = require('settings-sharelatex')
|
||||
const logger = require('logger-sharelatex')
|
||||
const Async = require('async')
|
||||
const _ = require('underscore')
|
||||
const UserSessionsRedis = require('./UserSessionsRedis')
|
||||
const rclient = UserSessionsRedis.client()
|
||||
|
||||
module.exports = UserSessionsManager = {
|
||||
// mimic the key used by the express sessions
|
||||
_sessionKey(sessionId) {
|
||||
return `sess:${sessionId}`
|
||||
},
|
||||
|
||||
trackSession(user, sessionId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
if (user == null) {
|
||||
logger.log({ sessionId }, 'no user to track, returning')
|
||||
return callback(null)
|
||||
}
|
||||
if (sessionId == null) {
|
||||
logger.log({ user_id: user._id }, 'no sessionId to track, returning')
|
||||
return callback(null)
|
||||
}
|
||||
logger.log({ user_id: user._id, sessionId }, 'onLogin handler')
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
const value = UserSessionsManager._sessionKey(sessionId)
|
||||
return rclient
|
||||
.multi()
|
||||
.sadd(sessionSetKey, value)
|
||||
.expire(sessionSetKey, `${Settings.cookieSessionLength}`)
|
||||
.exec(function(err, response) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'error while adding session key to UserSessions set'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
UserSessionsManager._checkSessions(user, function() {})
|
||||
return callback()
|
||||
})
|
||||
},
|
||||
|
||||
untrackSession(user, sessionId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
if (user == null) {
|
||||
logger.log({ sessionId }, 'no user to untrack, returning')
|
||||
return callback(null)
|
||||
}
|
||||
if (sessionId == null) {
|
||||
logger.log({ user_id: user._id }, 'no sessionId to untrack, returning')
|
||||
return callback(null)
|
||||
}
|
||||
logger.log({ user_id: user._id, sessionId }, 'onLogout handler')
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
const value = UserSessionsManager._sessionKey(sessionId)
|
||||
return rclient
|
||||
.multi()
|
||||
.srem(sessionSetKey, value)
|
||||
.expire(sessionSetKey, `${Settings.cookieSessionLength}`)
|
||||
.exec(function(err, response) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'error while removing session key from UserSessions set'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
UserSessionsManager._checkSessions(user, function() {})
|
||||
return callback()
|
||||
})
|
||||
},
|
||||
|
||||
getAllUserSessions(user, exclude, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err, sessionKeys) {}
|
||||
}
|
||||
exclude = _.map(exclude, UserSessionsManager._sessionKey)
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
return rclient.smembers(sessionSetKey, function(err, sessionKeys) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ user_id: user._id },
|
||||
'error getting all session keys for user from redis'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
sessionKeys = _.filter(sessionKeys, k => !_.contains(exclude, k))
|
||||
if (sessionKeys.length === 0) {
|
||||
logger.log({ user_id: user._id }, 'no other sessions found, returning')
|
||||
return callback(null, [])
|
||||
}
|
||||
|
||||
return Async.mapSeries(
|
||||
sessionKeys,
|
||||
(k, cb) => rclient.get(k, cb),
|
||||
function(err, sessions) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ user_id: user._id },
|
||||
'error getting all sessions for user from redis'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
const result = []
|
||||
for (let session of Array.from(sessions)) {
|
||||
if (session === null) {
|
||||
continue
|
||||
}
|
||||
session = JSON.parse(session)
|
||||
const session_user =
|
||||
(session != null ? session.user : undefined) ||
|
||||
__guard__(
|
||||
session != null ? session.passport : undefined,
|
||||
x => x.user
|
||||
)
|
||||
result.push({
|
||||
ip_address: session_user.ip_address,
|
||||
session_created: session_user.session_created
|
||||
})
|
||||
}
|
||||
|
||||
return callback(null, result)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
revokeAllUserSessions(user, retain, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
if (retain == null) {
|
||||
retain = []
|
||||
}
|
||||
retain = retain.map(i => UserSessionsManager._sessionKey(i))
|
||||
if (user == null) {
|
||||
logger.log({}, 'no user to revoke sessions for, returning')
|
||||
return callback(null)
|
||||
}
|
||||
logger.log({ user_id: user._id }, 'revoking all existing sessions for user')
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
return rclient.smembers(sessionSetKey, function(err, sessionKeys) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'error getting contents of UserSessions set'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
const keysToDelete = _.filter(
|
||||
sessionKeys,
|
||||
k => !Array.from(retain).includes(k)
|
||||
)
|
||||
if (keysToDelete.length === 0) {
|
||||
logger.log(
|
||||
{ user_id: user._id },
|
||||
'no sessions in UserSessions set to delete, returning'
|
||||
)
|
||||
return callback(null)
|
||||
}
|
||||
logger.log(
|
||||
{ user_id: user._id, count: keysToDelete.length },
|
||||
'deleting sessions for user'
|
||||
)
|
||||
|
||||
const deletions = keysToDelete.map(k => cb => rclient.del(k, cb))
|
||||
|
||||
return Async.series(deletions, function(err, _result) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'errror revoking all sessions for user'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
return rclient.srem(sessionSetKey, keysToDelete, function(err) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'error removing session set for user'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
return callback(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
touch(user, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
if (user == null) {
|
||||
logger.log({}, 'no user to touch sessions for, returning')
|
||||
return callback(null)
|
||||
}
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
return rclient.expire(
|
||||
sessionSetKey,
|
||||
`${Settings.cookieSessionLength}`,
|
||||
function(err, response) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id },
|
||||
'error while updating ttl on UserSessions set'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
return callback(null)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
_checkSessions(user, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
if (user == null) {
|
||||
logger.log({}, 'no user, returning')
|
||||
return callback(null)
|
||||
}
|
||||
logger.log({ user_id: user._id }, 'checking sessions for user')
|
||||
const sessionSetKey = UserSessionsRedis.sessionSetKey(user)
|
||||
return rclient.smembers(sessionSetKey, function(err, sessionKeys) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err, user_id: user._id, sessionSetKey },
|
||||
'error getting contents of UserSessions set'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
logger.log(
|
||||
{ user_id: user._id, count: sessionKeys.length },
|
||||
'checking sessions for user'
|
||||
)
|
||||
return Async.series(
|
||||
sessionKeys.map(key => next =>
|
||||
rclient.get(key, function(err, val) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
if (val == null) {
|
||||
logger.log(
|
||||
{ user_id: user._id, key },
|
||||
'>> removing key from UserSessions set'
|
||||
)
|
||||
return rclient.srem(sessionSetKey, key, function(err, result) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
return next(null)
|
||||
})
|
||||
} else {
|
||||
return next()
|
||||
}
|
||||
})
|
||||
),
|
||||
function(err, results) {
|
||||
logger.log({ user_id: user._id }, 'done checking sessions for user')
|
||||
return callback(err)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
return typeof value !== 'undefined' && value !== null
|
||||
? transform(value)
|
||||
: undefined
|
||||
}
|
||||
Reference in New Issue
Block a user