mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #12211 from overleaf/em-camel-case-real-time
Camel case variables in real-time GitOrigin-RevId: 0a35d2e39d54c258bed017ea4dcdbf9a19a2a9b1
This commit is contained in:
parent
5ae698ec6c
commit
d9e0215aee
35 changed files with 528 additions and 587 deletions
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const { NotAuthorizedError } = require('./Errors')
|
||||
|
||||
let AuthorizationManager
|
||||
|
@ -29,39 +26,39 @@ module.exports = AuthorizationManager = {
|
|||
}
|
||||
},
|
||||
|
||||
assertClientCanViewProjectAndDoc(client, doc_id, callback) {
|
||||
assertClientCanViewProjectAndDoc(client, docId, callback) {
|
||||
AuthorizationManager.assertClientCanViewProject(client, function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
AuthorizationManager._assertClientCanAccessDoc(client, doc_id, callback)
|
||||
AuthorizationManager._assertClientCanAccessDoc(client, docId, callback)
|
||||
})
|
||||
},
|
||||
|
||||
assertClientCanEditProjectAndDoc(client, doc_id, callback) {
|
||||
assertClientCanEditProjectAndDoc(client, docId, callback) {
|
||||
AuthorizationManager.assertClientCanEditProject(client, function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
AuthorizationManager._assertClientCanAccessDoc(client, doc_id, callback)
|
||||
AuthorizationManager._assertClientCanAccessDoc(client, docId, callback)
|
||||
})
|
||||
},
|
||||
|
||||
_assertClientCanAccessDoc(client, doc_id, callback) {
|
||||
if (client.ol_context[`doc:${doc_id}`] === 'allowed') {
|
||||
_assertClientCanAccessDoc(client, docId, callback) {
|
||||
if (client.ol_context[`doc:${docId}`] === 'allowed') {
|
||||
callback(null)
|
||||
} else {
|
||||
callback(new NotAuthorizedError())
|
||||
}
|
||||
},
|
||||
|
||||
addAccessToDoc(client, doc_id, callback) {
|
||||
client.ol_context[`doc:${doc_id}`] = 'allowed'
|
||||
addAccessToDoc(client, docId, callback) {
|
||||
client.ol_context[`doc:${docId}`] = 'allowed'
|
||||
callback(null)
|
||||
},
|
||||
|
||||
removeAccessToDoc(client, doc_id, callback) {
|
||||
delete client.ol_context[`doc:${doc_id}`]
|
||||
removeAccessToDoc(client, docId, callback) {
|
||||
delete client.ol_context[`doc:${docId}`]
|
||||
callback(null)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const async = require('async')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const logger = require('@overleaf/logger')
|
||||
|
@ -20,52 +17,52 @@ module.exports = {
|
|||
// Use the same method for when a user connects, and when a user sends a cursor
|
||||
// update. This way we don't care if the connected_user key has expired when
|
||||
// we receive a cursor update.
|
||||
updateUserPosition(project_id, client_id, user, cursorData, callback) {
|
||||
logger.debug(
|
||||
{ project_id, client_id },
|
||||
'marking user as joined or connected'
|
||||
)
|
||||
updateUserPosition(projectId, clientId, user, cursorData, callback) {
|
||||
logger.debug({ projectId, clientId }, 'marking user as joined or connected')
|
||||
|
||||
const multi = rclient.multi()
|
||||
|
||||
multi.sadd(Keys.clientsInProject({ project_id }), client_id)
|
||||
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
||||
multi.sadd(Keys.clientsInProject({ project_id: projectId }), clientId)
|
||||
multi.expire(
|
||||
Keys.clientsInProject({ project_id: projectId }),
|
||||
FOUR_DAYS_IN_S
|
||||
)
|
||||
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'last_updated_at',
|
||||
Date.now()
|
||||
)
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'user_id',
|
||||
user._id
|
||||
)
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'first_name',
|
||||
user.first_name || ''
|
||||
)
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'last_name',
|
||||
user.last_name || ''
|
||||
)
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'email',
|
||||
user.email || ''
|
||||
)
|
||||
|
||||
if (cursorData) {
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'cursorData',
|
||||
JSON.stringify(cursorData)
|
||||
)
|
||||
}
|
||||
multi.expire(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
USER_TIMEOUT_IN_S
|
||||
)
|
||||
|
||||
|
@ -77,34 +74,39 @@ module.exports = {
|
|||
})
|
||||
},
|
||||
|
||||
refreshClient(project_id, client_id) {
|
||||
logger.debug({ project_id, client_id }, 'refreshing connected client')
|
||||
refreshClient(projectId, clientId) {
|
||||
logger.debug({ projectId, clientId }, 'refreshing connected client')
|
||||
const multi = rclient.multi()
|
||||
multi.hset(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
'last_updated_at',
|
||||
Date.now()
|
||||
)
|
||||
multi.expire(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
USER_TIMEOUT_IN_S
|
||||
)
|
||||
multi.exec(function (err) {
|
||||
if (err) {
|
||||
logger.err(
|
||||
{ err, project_id, client_id },
|
||||
{ err, projectId, clientId },
|
||||
'problem refreshing connected client'
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
markUserAsDisconnected(project_id, client_id, callback) {
|
||||
logger.debug({ project_id, client_id }, 'marking user as disconnected')
|
||||
markUserAsDisconnected(projectId, clientId, callback) {
|
||||
logger.debug({ projectId, clientId }, 'marking user as disconnected')
|
||||
const multi = rclient.multi()
|
||||
multi.srem(Keys.clientsInProject({ project_id }), client_id)
|
||||
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
||||
multi.del(Keys.connectedUser({ project_id, client_id }))
|
||||
multi.srem(Keys.clientsInProject({ project_id: projectId }), clientId)
|
||||
multi.expire(
|
||||
Keys.clientsInProject({ project_id: projectId }),
|
||||
FOUR_DAYS_IN_S
|
||||
)
|
||||
multi.del(
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId })
|
||||
)
|
||||
multi.exec(function (err) {
|
||||
if (err) {
|
||||
err = new OError('problem marking user as disconnected').withCause(err)
|
||||
|
@ -113,24 +115,24 @@ module.exports = {
|
|||
})
|
||||
},
|
||||
|
||||
_getConnectedUser(project_id, client_id, callback) {
|
||||
_getConnectedUser(projectId, clientId, callback) {
|
||||
rclient.hgetall(
|
||||
Keys.connectedUser({ project_id, client_id }),
|
||||
Keys.connectedUser({ project_id: projectId, client_id: clientId }),
|
||||
function (err, result) {
|
||||
if (err) {
|
||||
err = new OError('problem fetching connected user details', {
|
||||
other_client_id: client_id,
|
||||
other_client_id: clientId,
|
||||
}).withCause(err)
|
||||
return callback(err)
|
||||
}
|
||||
if (!(result && result.user_id)) {
|
||||
result = {
|
||||
connected: false,
|
||||
client_id,
|
||||
client_id: clientId,
|
||||
}
|
||||
} else {
|
||||
result.connected = true
|
||||
result.client_id = client_id
|
||||
result.client_id = clientId
|
||||
result.client_age =
|
||||
(Date.now() - parseInt(result.last_updated_at, 10)) / 1000
|
||||
if (result.cursorData) {
|
||||
|
@ -138,7 +140,7 @@ module.exports = {
|
|||
result.cursorData = JSON.parse(result.cursorData)
|
||||
} catch (e) {
|
||||
OError.tag(e, 'error parsing cursorData JSON', {
|
||||
other_client_id: client_id,
|
||||
other_client_id: clientId,
|
||||
cursorData: result.cursorData,
|
||||
})
|
||||
return callback(e)
|
||||
|
@ -150,17 +152,17 @@ module.exports = {
|
|||
)
|
||||
},
|
||||
|
||||
getConnectedUsers(project_id, callback) {
|
||||
getConnectedUsers(projectId, callback) {
|
||||
const self = this
|
||||
rclient.smembers(
|
||||
Keys.clientsInProject({ project_id }),
|
||||
Keys.clientsInProject({ project_id: projectId }),
|
||||
function (err, results) {
|
||||
if (err) {
|
||||
err = new OError('problem getting clients in project').withCause(err)
|
||||
return callback(err)
|
||||
}
|
||||
const jobs = results.map(
|
||||
client_id => cb => self._getConnectedUser(project_id, client_id, cb)
|
||||
clientId => cb => self._getConnectedUser(projectId, clientId, cb)
|
||||
)
|
||||
async.series(jobs, function (err, users) {
|
||||
if (err) {
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const logger = require('@overleaf/logger')
|
||||
const settings = require('@overleaf/settings')
|
||||
const RedisClientManager = require('./RedisClientManager')
|
||||
|
@ -49,18 +46,15 @@ module.exports = DocumentUpdaterController = {
|
|||
|
||||
handleRoomUpdates(rclientSubList) {
|
||||
const roomEvents = RoomManager.eventSource()
|
||||
roomEvents.on('doc-active', function (doc_id) {
|
||||
roomEvents.on('doc-active', function (docId) {
|
||||
const subscribePromises = rclientSubList.map(rclient =>
|
||||
ChannelManager.subscribe(rclient, 'applied-ops', doc_id)
|
||||
)
|
||||
RoomManager.emitOnCompletion(
|
||||
subscribePromises,
|
||||
`doc-subscribed-${doc_id}`
|
||||
ChannelManager.subscribe(rclient, 'applied-ops', docId)
|
||||
)
|
||||
RoomManager.emitOnCompletion(subscribePromises, `doc-subscribed-${docId}`)
|
||||
})
|
||||
roomEvents.on('doc-empty', doc_id =>
|
||||
roomEvents.on('doc-empty', docId =>
|
||||
rclientSubList.map(rclient =>
|
||||
ChannelManager.unsubscribe(rclient, 'applied-ops', doc_id)
|
||||
ChannelManager.unsubscribe(rclient, 'applied-ops', docId)
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -104,9 +98,9 @@ module.exports = DocumentUpdaterController = {
|
|||
})
|
||||
},
|
||||
|
||||
_applyUpdateFromDocumentUpdater(io, doc_id, update) {
|
||||
_applyUpdateFromDocumentUpdater(io, docId, update) {
|
||||
let client
|
||||
const clientList = io.sockets.clients(doc_id)
|
||||
const clientList = io.sockets.clients(docId)
|
||||
// avoid unnecessary work if no clients are connected
|
||||
if (clientList.length === 0) {
|
||||
return
|
||||
|
@ -114,7 +108,7 @@ module.exports = DocumentUpdaterController = {
|
|||
// send updates to clients
|
||||
logger.debug(
|
||||
{
|
||||
doc_id,
|
||||
docId,
|
||||
version: update.v,
|
||||
source: update.meta && update.meta.source,
|
||||
socketIoClients: clientList.map(client => client.id),
|
||||
|
@ -129,7 +123,7 @@ module.exports = DocumentUpdaterController = {
|
|||
if (client.publicId === update.meta.source) {
|
||||
logger.debug(
|
||||
{
|
||||
doc_id,
|
||||
docId,
|
||||
version: update.v,
|
||||
source: update.meta.source,
|
||||
},
|
||||
|
@ -140,10 +134,10 @@ module.exports = DocumentUpdaterController = {
|
|||
// Duplicate ops should just be sent back to sending client for acknowledgement
|
||||
logger.debug(
|
||||
{
|
||||
doc_id,
|
||||
docId,
|
||||
version: update.v,
|
||||
source: update.meta.source,
|
||||
client_id: client.id,
|
||||
clientId: client.id,
|
||||
},
|
||||
'distributing update to collaborator'
|
||||
)
|
||||
|
@ -155,7 +149,7 @@ module.exports = DocumentUpdaterController = {
|
|||
metrics.inc('socket-io.duplicate-clients', 0.1)
|
||||
logger.debug(
|
||||
{
|
||||
doc_id,
|
||||
docId,
|
||||
socketIoClients: clientList.map(client => client.id),
|
||||
},
|
||||
'discarded duplicate clients'
|
||||
|
@ -163,10 +157,10 @@ module.exports = DocumentUpdaterController = {
|
|||
}
|
||||
},
|
||||
|
||||
_processErrorFromDocumentUpdater(io, doc_id, error, message) {
|
||||
for (const client of io.sockets.clients(doc_id)) {
|
||||
_processErrorFromDocumentUpdater(io, docId, error, message) {
|
||||
for (const client of io.sockets.clients(docId)) {
|
||||
logger.warn(
|
||||
{ err: error, doc_id, client_id: client.id },
|
||||
{ err: error, docId, clientId: client.id },
|
||||
'error from document updater, disconnecting client'
|
||||
)
|
||||
client.emit('otUpdateError', error, message)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const request = require('request')
|
||||
const _ = require('underscore')
|
||||
const OError = require('@overleaf/o-error')
|
||||
|
@ -20,11 +17,11 @@ const rclient = require('@overleaf/redis-wrapper').createClient(
|
|||
const Keys = settings.redis.documentupdater.key_schema
|
||||
|
||||
const DocumentUpdaterManager = {
|
||||
getDocument(project_id, doc_id, fromVersion, callback) {
|
||||
getDocument(projectId, docId, fromVersion, callback) {
|
||||
const timer = new metrics.Timer('get-document')
|
||||
const url = `${settings.apis.documentupdater.url}/project/${project_id}/doc/${doc_id}?fromVersion=${fromVersion}`
|
||||
const url = `${settings.apis.documentupdater.url}/project/${projectId}/doc/${docId}?fromVersion=${fromVersion}`
|
||||
logger.debug(
|
||||
{ project_id, doc_id, fromVersion },
|
||||
{ projectId, docId, fromVersion },
|
||||
'getting doc from document updater'
|
||||
)
|
||||
request.get(url, function (err, res, body) {
|
||||
|
@ -35,7 +32,7 @@ const DocumentUpdaterManager = {
|
|||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.debug(
|
||||
{ project_id, doc_id },
|
||||
{ projectId, docId },
|
||||
'got doc from document document updater'
|
||||
)
|
||||
try {
|
||||
|
@ -56,18 +53,18 @@ const DocumentUpdaterManager = {
|
|||
})
|
||||
},
|
||||
|
||||
checkDocument(project_id, doc_id, callback) {
|
||||
checkDocument(projectId, docId, callback) {
|
||||
// in this call fromVersion = -1 means get document without docOps
|
||||
DocumentUpdaterManager.getDocument(project_id, doc_id, -1, callback)
|
||||
DocumentUpdaterManager.getDocument(projectId, docId, -1, callback)
|
||||
},
|
||||
|
||||
flushProjectToMongoAndDelete(project_id, callback) {
|
||||
flushProjectToMongoAndDelete(projectId, callback) {
|
||||
// this method is called when the last connected user leaves the project
|
||||
logger.debug({ project_id }, 'deleting project from document updater')
|
||||
logger.debug({ projectId }, 'deleting project from document updater')
|
||||
const timer = new metrics.Timer('delete.mongo.project')
|
||||
// flush the project in the background when all users have left
|
||||
const url =
|
||||
`${settings.apis.documentupdater.url}/project/${project_id}?background=true` +
|
||||
`${settings.apis.documentupdater.url}/project/${projectId}?background=true` +
|
||||
(settings.shutDownInProgress ? '&shutdown=true' : '')
|
||||
request.del(url, function (err, res) {
|
||||
timer.done()
|
||||
|
@ -75,7 +72,7 @@ const DocumentUpdaterManager = {
|
|||
OError.tag(err, 'error deleting project from document updater')
|
||||
callback(err)
|
||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.debug({ project_id }, 'deleted project from document updater')
|
||||
logger.debug({ projectId }, 'deleted project from document updater')
|
||||
callback(null)
|
||||
} else {
|
||||
callback(
|
||||
|
@ -97,7 +94,7 @@ const DocumentUpdaterManager = {
|
|||
}
|
||||
},
|
||||
|
||||
queueChange(project_id, doc_id, change, callback) {
|
||||
queueChange(projectId, docId, change, callback) {
|
||||
const allowedKeys = [
|
||||
'doc',
|
||||
'op',
|
||||
|
@ -122,11 +119,11 @@ const DocumentUpdaterManager = {
|
|||
// record metric for each update added to queue
|
||||
metrics.summary('redis.pendingUpdates', updateSize, { status: 'push' })
|
||||
|
||||
const doc_key = `${project_id}:${doc_id}`
|
||||
const docKey = `${projectId}:${docId}`
|
||||
// Push onto pendingUpdates for doc_id first, because once the doc updater
|
||||
// gets an entry on pending-updates-list, it starts processing.
|
||||
rclient.rpush(
|
||||
Keys.pendingUpdates({ doc_id }),
|
||||
Keys.pendingUpdates({ doc_id: docId }),
|
||||
jsonChange,
|
||||
function (error) {
|
||||
if (error) {
|
||||
|
@ -134,7 +131,7 @@ const DocumentUpdaterManager = {
|
|||
return callback(error)
|
||||
}
|
||||
const queueKey = DocumentUpdaterManager._getPendingUpdateListKey()
|
||||
rclient.rpush(queueKey, doc_key, function (error) {
|
||||
rclient.rpush(queueKey, docKey, function (error) {
|
||||
if (error) {
|
||||
error = new OError('error pushing doc_id into redis')
|
||||
.withInfo({ queueKey })
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = {
|
|||
if (!this.RECONNECTED_CLIENTS[client.id]) {
|
||||
this.RECONNECTED_CLIENTS[client.id] = true
|
||||
logger.debug(
|
||||
{ client_id: client.id },
|
||||
{ clientId: client.id },
|
||||
'Asking client to reconnect gracefully'
|
||||
)
|
||||
client.emit('reconnectGracefully')
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
let EventLogger
|
||||
const logger = require('@overleaf/logger')
|
||||
const metrics = require('@overleaf/metrics')
|
||||
|
@ -26,12 +23,12 @@ module.exports = EventLogger = {
|
|||
}
|
||||
},
|
||||
|
||||
checkEventOrder(channel, message_id) {
|
||||
if (typeof message_id !== 'string') {
|
||||
checkEventOrder(channel, messageId) {
|
||||
if (typeof messageId !== 'string') {
|
||||
return
|
||||
}
|
||||
let result
|
||||
if (!(result = message_id.match(/^(.*)-(\d+)$/))) {
|
||||
if (!(result = messageId.match(/^(.*)-(\d+)$/))) {
|
||||
return
|
||||
}
|
||||
const key = result[1]
|
||||
|
@ -48,12 +45,12 @@ module.exports = EventLogger = {
|
|||
}
|
||||
if (count === previous) {
|
||||
metrics.inc(`event.${channel}.duplicate`)
|
||||
logger.warn({ channel, message_id }, 'duplicate event')
|
||||
logger.warn({ channel, messageId }, 'duplicate event')
|
||||
return 'duplicate'
|
||||
} else {
|
||||
metrics.inc(`event.${channel}.out-of-order`)
|
||||
logger.warn(
|
||||
{ channel, message_id, key, previous, count },
|
||||
{ channel, messageId, key, previous, count },
|
||||
'out of order event'
|
||||
)
|
||||
return 'out-of-order'
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const WebsocketLoadBalancer = require('./WebsocketLoadBalancer')
|
||||
const DrainManager = require('./DrainManager')
|
||||
const logger = require('@overleaf/logger')
|
||||
|
@ -37,15 +34,15 @@ module.exports = {
|
|||
|
||||
disconnectClient(req, res, next) {
|
||||
const io = req.app.get('io')
|
||||
const { client_id } = req.params
|
||||
const client = io.sockets.sockets[client_id]
|
||||
const { client_id: clientId } = req.params
|
||||
const client = io.sockets.sockets[clientId]
|
||||
|
||||
if (!client) {
|
||||
logger.debug({ client_id }, 'api: client already disconnected')
|
||||
logger.debug({ clientId }, 'api: client already disconnected')
|
||||
res.sendStatus(404)
|
||||
return
|
||||
}
|
||||
logger.info({ client_id }, 'api: requesting client disconnect')
|
||||
logger.info({ clientId }, 'api: requesting client disconnect')
|
||||
client.on('disconnect', () => res.sendStatus(204))
|
||||
client.disconnect()
|
||||
},
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
|
||||
let HttpController
|
||||
module.exports = HttpController = {
|
||||
// The code in this controller is hard to unit test because of a lot of
|
||||
|
@ -10,25 +6,25 @@ module.exports = HttpController = {
|
|||
// and for checking internal state in acceptance tests. The acceptances tests
|
||||
// should provide appropriate coverage.
|
||||
_getConnectedClientView(ioClient) {
|
||||
const client_id = ioClient.id
|
||||
const clientId = ioClient.id
|
||||
const {
|
||||
project_id,
|
||||
user_id,
|
||||
first_name,
|
||||
last_name,
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email,
|
||||
connected_time,
|
||||
connected_time: connectedTime,
|
||||
} = ioClient.ol_context
|
||||
const client = {
|
||||
client_id,
|
||||
project_id,
|
||||
user_id,
|
||||
first_name,
|
||||
last_name,
|
||||
client_id: clientId,
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email,
|
||||
connected_time,
|
||||
connected_time: connectedTime,
|
||||
}
|
||||
client.rooms = Object.keys(ioClient.manager.roomClients[client_id] || {})
|
||||
client.rooms = Object.keys(ioClient.manager.roomClients[clientId] || {})
|
||||
// drop the namespace
|
||||
.filter(room => room !== '')
|
||||
// room names are composed as '<NAMESPACE>/<ROOM>' and the default
|
||||
|
@ -45,9 +41,9 @@ module.exports = HttpController = {
|
|||
},
|
||||
|
||||
getConnectedClient(req, res) {
|
||||
const { client_id } = req.params
|
||||
const { client_id: clientId } = req.params
|
||||
const io = req.app.get('io')
|
||||
const ioClient = io.sockets.sockets[client_id]
|
||||
const ioClient = io.sockets.sockets[clientId]
|
||||
if (!ioClient) {
|
||||
res.sendStatus(404)
|
||||
return
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const logger = require('@overleaf/logger')
|
||||
const metrics = require('@overleaf/metrics')
|
||||
const { EventEmitter } = require('events')
|
||||
|
@ -20,16 +17,16 @@ const RoomEvents = new EventEmitter() // emits {project,doc}-active and {project
|
|||
// The pubsub side is handled by ChannelManager
|
||||
|
||||
module.exports = {
|
||||
joinProject(client, project_id, callback) {
|
||||
this.joinEntity(client, 'project', project_id, callback)
|
||||
joinProject(client, projectId, callback) {
|
||||
this.joinEntity(client, 'project', projectId, callback)
|
||||
},
|
||||
|
||||
joinDoc(client, doc_id, callback) {
|
||||
this.joinEntity(client, 'doc', doc_id, callback)
|
||||
joinDoc(client, docId, callback) {
|
||||
this.joinEntity(client, 'doc', docId, callback)
|
||||
},
|
||||
|
||||
leaveDoc(client, doc_id) {
|
||||
this.leaveEntity(client, 'doc', doc_id)
|
||||
leaveDoc(client, docId) {
|
||||
this.leaveEntity(client, 'doc', docId)
|
||||
},
|
||||
|
||||
leaveProjectAndDocs(client) {
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const metrics = require('@overleaf/metrics')
|
||||
const logger = require('@overleaf/logger')
|
||||
const settings = require('@overleaf/settings')
|
||||
|
@ -184,7 +181,7 @@ module.exports = Router = {
|
|||
metrics.inc('socket-io.connection', 1, { status: client.transport })
|
||||
metrics.gauge('socket-io.clients', io.sockets.clients().length)
|
||||
|
||||
logger.debug({ session, client_id: client.id }, 'client connected')
|
||||
logger.debug({ session, clientId: client.id }, 'client connected')
|
||||
|
||||
let user
|
||||
if (session && session.passport && session.passport.user) {
|
||||
|
@ -230,11 +227,11 @@ module.exports = Router = {
|
|||
disconnect: 1,
|
||||
})
|
||||
}
|
||||
const { project_id, anonymousAccessToken } = data
|
||||
const { project_id: projectId, anonymousAccessToken } = data
|
||||
// only allow connection to a single project
|
||||
if (
|
||||
client.ol_current_project_id &&
|
||||
project_id !== client.ol_current_project_id
|
||||
projectId !== client.ol_current_project_id
|
||||
) {
|
||||
return Router._handleError(
|
||||
callback,
|
||||
|
@ -244,18 +241,18 @@ module.exports = Router = {
|
|||
{ disconnect: 1 }
|
||||
)
|
||||
}
|
||||
client.ol_current_project_id = project_id
|
||||
client.ol_current_project_id = projectId
|
||||
if (anonymousAccessToken) {
|
||||
user.anonymousAccessToken = anonymousAccessToken
|
||||
}
|
||||
WebsocketController.joinProject(
|
||||
client,
|
||||
user,
|
||||
project_id,
|
||||
projectId,
|
||||
function (err, ...args) {
|
||||
if (err) {
|
||||
Router._handleError(callback, err, client, 'joinProject', {
|
||||
project_id,
|
||||
project_id: projectId,
|
||||
user_id: user._id,
|
||||
})
|
||||
} else {
|
||||
|
@ -281,7 +278,7 @@ module.exports = Router = {
|
|||
// doc_id, fromVersion, callback
|
||||
// doc_id, options, callback
|
||||
// doc_id, fromVersion, options, callback
|
||||
client.on('joinDoc', function (doc_id, fromVersion, options, callback) {
|
||||
client.on('joinDoc', function (docId, fromVersion, options, callback) {
|
||||
if (typeof fromVersion === 'function' && !options) {
|
||||
callback = fromVersion
|
||||
fromVersion = -1
|
||||
|
@ -310,7 +307,7 @@ module.exports = Router = {
|
|||
}
|
||||
try {
|
||||
Joi.assert(
|
||||
{ doc_id, fromVersion, options },
|
||||
{ doc_id: docId, fromVersion, options },
|
||||
Joi.object({
|
||||
doc_id: JOI_OBJECT_ID,
|
||||
fromVersion: Joi.number().integer(),
|
||||
|
@ -324,13 +321,13 @@ module.exports = Router = {
|
|||
}
|
||||
WebsocketController.joinDoc(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
fromVersion,
|
||||
options,
|
||||
function (err, ...args) {
|
||||
if (err) {
|
||||
Router._handleError(callback, err, client, 'joinDoc', {
|
||||
doc_id,
|
||||
doc_id: docId,
|
||||
fromVersion,
|
||||
})
|
||||
} else {
|
||||
|
@ -340,21 +337,21 @@ module.exports = Router = {
|
|||
)
|
||||
})
|
||||
|
||||
client.on('leaveDoc', function (doc_id, callback) {
|
||||
client.on('leaveDoc', function (docId, callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
return Router._handleInvalidArguments(client, 'leaveDoc', arguments)
|
||||
}
|
||||
try {
|
||||
Joi.assert(doc_id, JOI_OBJECT_ID)
|
||||
Joi.assert(docId, JOI_OBJECT_ID)
|
||||
} catch (error) {
|
||||
return Router._handleError(callback, error, client, 'joinDoc', {
|
||||
disconnect: 1,
|
||||
})
|
||||
}
|
||||
WebsocketController.leaveDoc(client, doc_id, function (err, ...args) {
|
||||
WebsocketController.leaveDoc(client, docId, function (err, ...args) {
|
||||
if (err) {
|
||||
Router._handleError(callback, err, client, 'leaveDoc', {
|
||||
doc_id,
|
||||
doc_id: docId,
|
||||
})
|
||||
} else {
|
||||
callback(null, ...args)
|
||||
|
@ -421,7 +418,7 @@ module.exports = Router = {
|
|||
}
|
||||
)
|
||||
|
||||
client.on('applyOtUpdate', function (doc_id, update, callback) {
|
||||
client.on('applyOtUpdate', function (docId, update, callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
return Router._handleInvalidArguments(
|
||||
client,
|
||||
|
@ -431,7 +428,7 @@ module.exports = Router = {
|
|||
}
|
||||
try {
|
||||
Joi.assert(
|
||||
{ doc_id, update },
|
||||
{ doc_id: docId, update },
|
||||
Joi.object({
|
||||
doc_id: JOI_OBJECT_ID,
|
||||
update: Joi.object().required(),
|
||||
|
@ -444,12 +441,12 @@ module.exports = Router = {
|
|||
}
|
||||
WebsocketController.applyOtUpdate(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
update,
|
||||
function (err) {
|
||||
if (err) {
|
||||
Router._handleError(callback, err, client, 'applyOtUpdate', {
|
||||
doc_id,
|
||||
doc_id: docId,
|
||||
update,
|
||||
})
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const request = require('request')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const settings = require('@overleaf/settings')
|
||||
|
@ -13,10 +10,10 @@ const {
|
|||
} = require('./Errors')
|
||||
|
||||
module.exports = {
|
||||
joinProject(project_id, user, callback) {
|
||||
const user_id = user._id
|
||||
logger.debug({ project_id, user_id }, 'sending join project request to web')
|
||||
const url = `${settings.apis.web.url}/project/${project_id}/join`
|
||||
joinProject(projectId, user, callback) {
|
||||
const userId = user._id
|
||||
logger.debug({ projectId, userId }, 'sending join project request to web')
|
||||
const url = `${settings.apis.web.url}/project/${projectId}/join`
|
||||
const headers = {}
|
||||
if (user.anonymousAccessToken) {
|
||||
headers['x-sl-anonymous-access-token'] = user.anonymousAccessToken
|
||||
|
@ -24,7 +21,7 @@ module.exports = {
|
|||
request.post(
|
||||
{
|
||||
url,
|
||||
qs: { user_id },
|
||||
qs: { user_id: userId },
|
||||
auth: {
|
||||
user: settings.apis.web.user,
|
||||
pass: settings.apis.web.pass,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const OError = require('@overleaf/o-error')
|
||||
const logger = require('@overleaf/logger')
|
||||
const metrics = require('@overleaf/metrics')
|
||||
|
@ -23,7 +20,7 @@ module.exports = WebsocketController = {
|
|||
// compatible protocol changes. Use only in extreme need.
|
||||
PROTOCOL_VERSION: 2,
|
||||
|
||||
joinProject(client, user, project_id, callback) {
|
||||
joinProject(client, user, projectId, callback) {
|
||||
if (client.disconnected) {
|
||||
metrics.inc('editor.join-project.disconnected', 1, {
|
||||
status: 'immediately',
|
||||
|
@ -31,20 +28,20 @@ module.exports = WebsocketController = {
|
|||
return callback()
|
||||
}
|
||||
|
||||
const user_id = user._id
|
||||
const userId = user._id
|
||||
logger.info(
|
||||
{
|
||||
user_id,
|
||||
project_id,
|
||||
client_id: client.id,
|
||||
remote_ip: client.remoteIp,
|
||||
user_agent: client.userAgent,
|
||||
userId,
|
||||
projectId,
|
||||
clientId: client.id,
|
||||
remoteIp: client.remoteIp,
|
||||
userAgent: client.userAgent,
|
||||
},
|
||||
'user joining project'
|
||||
)
|
||||
metrics.inc('editor.join-project', 1, { status: client.transport })
|
||||
WebApiManager.joinProject(
|
||||
project_id,
|
||||
projectId,
|
||||
user,
|
||||
function (error, project, privilegeLevel, isRestrictedUser) {
|
||||
if (error) {
|
||||
|
@ -52,7 +49,7 @@ module.exports = WebsocketController = {
|
|||
}
|
||||
if (client.disconnected) {
|
||||
logger.info(
|
||||
{ user_id, project_id, client_id: client.id },
|
||||
{ userId, projectId, clientId: client.id },
|
||||
'client disconnected before joining project'
|
||||
)
|
||||
metrics.inc('editor.join-project.disconnected', 1, {
|
||||
|
@ -67,8 +64,8 @@ module.exports = WebsocketController = {
|
|||
|
||||
client.ol_context = {}
|
||||
client.ol_context.privilege_level = privilegeLevel
|
||||
client.ol_context.user_id = user_id
|
||||
client.ol_context.project_id = project_id
|
||||
client.ol_context.user_id = userId
|
||||
client.ol_context.project_id = projectId
|
||||
client.ol_context.owner_id = project.owner && project.owner._id
|
||||
client.ol_context.first_name = user.first_name
|
||||
client.ol_context.last_name = user.last_name
|
||||
|
@ -78,15 +75,15 @@ module.exports = WebsocketController = {
|
|||
client.ol_context.login_count = user.loginCount
|
||||
client.ol_context.is_restricted_user = !!isRestrictedUser
|
||||
|
||||
RoomManager.joinProject(client, project_id, function (err) {
|
||||
RoomManager.joinProject(client, projectId, function (err) {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
logger.debug(
|
||||
{
|
||||
user_id,
|
||||
project_id,
|
||||
client_id: client.id,
|
||||
userId,
|
||||
projectId,
|
||||
clientId: client.id,
|
||||
privilegeLevel,
|
||||
isRestrictedUser,
|
||||
},
|
||||
|
@ -102,14 +99,14 @@ module.exports = WebsocketController = {
|
|||
|
||||
// No need to block for setting the user as connected in the cursor tracking
|
||||
ConnectedUsersManager.updateUserPosition(
|
||||
project_id,
|
||||
projectId,
|
||||
client.publicId,
|
||||
user,
|
||||
null,
|
||||
function (err) {
|
||||
if (err) {
|
||||
logger.warn(
|
||||
{ err, project_id, user_id, client_id: client.id },
|
||||
{ err, projectId, userId, clientId: client.id },
|
||||
'background cursor update failed'
|
||||
)
|
||||
}
|
||||
|
@ -124,30 +121,30 @@ module.exports = WebsocketController = {
|
|||
// is determined by FLUSH_IF_EMPTY_DELAY.
|
||||
FLUSH_IF_EMPTY_DELAY: 500, // ms
|
||||
leaveProject(io, client, callback) {
|
||||
const { project_id, user_id } = client.ol_context
|
||||
if (!project_id) {
|
||||
const { project_id: projectId, user_id: userId } = client.ol_context
|
||||
if (!projectId) {
|
||||
return callback()
|
||||
} // client did not join project
|
||||
|
||||
metrics.inc('editor.leave-project', 1, { status: client.transport })
|
||||
logger.info(
|
||||
{ project_id, user_id, client_id: client.id },
|
||||
{ projectId, userId, clientId: client.id },
|
||||
'client leaving project'
|
||||
)
|
||||
WebsocketLoadBalancer.emitToRoom(
|
||||
project_id,
|
||||
projectId,
|
||||
'clientTracking.clientDisconnected',
|
||||
client.publicId
|
||||
)
|
||||
|
||||
// We can do this in the background
|
||||
ConnectedUsersManager.markUserAsDisconnected(
|
||||
project_id,
|
||||
projectId,
|
||||
client.publicId,
|
||||
function (err) {
|
||||
if (err) {
|
||||
logger.error(
|
||||
{ err, project_id, user_id, client_id: client.id },
|
||||
{ err, projectId, userId, clientId: client.id },
|
||||
'error marking client as disconnected'
|
||||
)
|
||||
}
|
||||
|
@ -156,15 +153,15 @@ module.exports = WebsocketController = {
|
|||
|
||||
RoomManager.leaveProjectAndDocs(client)
|
||||
setTimeout(function () {
|
||||
const remainingClients = io.sockets.clients(project_id)
|
||||
const remainingClients = io.sockets.clients(projectId)
|
||||
if (remainingClients.length === 0) {
|
||||
// Flush project in the background
|
||||
DocumentUpdaterManager.flushProjectToMongoAndDelete(
|
||||
project_id,
|
||||
projectId,
|
||||
function (err) {
|
||||
if (err) {
|
||||
logger.error(
|
||||
{ err, project_id, user_id, client_id: client.id },
|
||||
{ err, projectId, userId, clientId: client.id },
|
||||
'error flushing to doc updater after leaving project'
|
||||
)
|
||||
}
|
||||
|
@ -175,7 +172,7 @@ module.exports = WebsocketController = {
|
|||
}, WebsocketController.FLUSH_IF_EMPTY_DELAY)
|
||||
},
|
||||
|
||||
joinDoc(client, doc_id, fromVersion, options, callback) {
|
||||
joinDoc(client, docId, fromVersion, options, callback) {
|
||||
if (client.disconnected) {
|
||||
metrics.inc('editor.join-doc.disconnected', 1, { status: 'immediately' })
|
||||
return callback()
|
||||
|
@ -183,18 +180,22 @@ module.exports = WebsocketController = {
|
|||
|
||||
const joinLeaveEpoch = ++client.joinLeaveEpoch
|
||||
metrics.inc('editor.join-doc', 1, { status: client.transport })
|
||||
const { project_id, user_id, is_restricted_user } = client.ol_context
|
||||
if (!project_id) {
|
||||
const {
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
is_restricted_user: isRestrictedUser,
|
||||
} = client.ol_context
|
||||
if (!projectId) {
|
||||
return callback(new NotJoinedError())
|
||||
}
|
||||
logger.debug(
|
||||
{ user_id, project_id, doc_id, fromVersion, client_id: client.id },
|
||||
{ userId, projectId, docId, fromVersion, clientId: client.id },
|
||||
'client joining doc'
|
||||
)
|
||||
|
||||
WebsocketController._assertClientAuthorization(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
|
@ -212,7 +213,7 @@ module.exports = WebsocketController = {
|
|||
}
|
||||
// ensure the per-doc applied-ops channel is subscribed before sending the
|
||||
// doc to the client, so that no events are missed.
|
||||
RoomManager.joinDoc(client, doc_id, function (error) {
|
||||
RoomManager.joinDoc(client, docId, function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
|
@ -225,8 +226,8 @@ module.exports = WebsocketController = {
|
|||
}
|
||||
|
||||
DocumentUpdaterManager.getDocument(
|
||||
project_id,
|
||||
doc_id,
|
||||
projectId,
|
||||
docId,
|
||||
fromVersion,
|
||||
function (error, lines, version, ranges, ops) {
|
||||
if (error) {
|
||||
|
@ -240,7 +241,7 @@ module.exports = WebsocketController = {
|
|||
return callback()
|
||||
}
|
||||
|
||||
if (is_restricted_user && ranges && ranges.comments) {
|
||||
if (isRestrictedUser && ranges && ranges.comments) {
|
||||
ranges.comments = []
|
||||
}
|
||||
|
||||
|
@ -281,14 +282,14 @@ module.exports = WebsocketController = {
|
|||
}
|
||||
}
|
||||
|
||||
AuthorizationManager.addAccessToDoc(client, doc_id, () => {})
|
||||
AuthorizationManager.addAccessToDoc(client, docId, () => {})
|
||||
logger.debug(
|
||||
{
|
||||
user_id,
|
||||
project_id,
|
||||
doc_id,
|
||||
userId,
|
||||
projectId,
|
||||
docId,
|
||||
fromVersion,
|
||||
client_id: client.id,
|
||||
clientId: client.id,
|
||||
},
|
||||
'client joined doc'
|
||||
)
|
||||
|
@ -300,7 +301,7 @@ module.exports = WebsocketController = {
|
|||
)
|
||||
},
|
||||
|
||||
_assertClientAuthorization(client, doc_id, callback) {
|
||||
_assertClientAuthorization(client, docId, callback) {
|
||||
// Check for project-level access first
|
||||
AuthorizationManager.assertClientCanViewProject(client, function (error) {
|
||||
if (error) {
|
||||
|
@ -309,20 +310,20 @@ module.exports = WebsocketController = {
|
|||
// Check for doc-level access next
|
||||
AuthorizationManager.assertClientCanViewProjectAndDoc(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
function (error) {
|
||||
if (error) {
|
||||
// No cached access, check docupdater
|
||||
const { project_id } = client.ol_context
|
||||
const { project_id: projectId } = client.ol_context
|
||||
DocumentUpdaterManager.checkDocument(
|
||||
project_id,
|
||||
doc_id,
|
||||
projectId,
|
||||
docId,
|
||||
function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
} else {
|
||||
// Success
|
||||
AuthorizationManager.addAccessToDoc(client, doc_id, callback)
|
||||
AuthorizationManager.addAccessToDoc(client, docId, callback)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -335,16 +336,16 @@ module.exports = WebsocketController = {
|
|||
})
|
||||
},
|
||||
|
||||
leaveDoc(client, doc_id, callback) {
|
||||
leaveDoc(client, docId, callback) {
|
||||
// client may have disconnected, but we have to cleanup internal state.
|
||||
client.joinLeaveEpoch++
|
||||
metrics.inc('editor.leave-doc', 1, { status: client.transport })
|
||||
const { project_id, user_id } = client.ol_context
|
||||
const { project_id: projectId, user_id: userId } = client.ol_context
|
||||
logger.debug(
|
||||
{ user_id, project_id, doc_id, client_id: client.id },
|
||||
{ userId, projectId, docId, clientId: client.id },
|
||||
'client leaving doc'
|
||||
)
|
||||
RoomManager.leaveDoc(client, doc_id)
|
||||
RoomManager.leaveDoc(client, docId)
|
||||
// we could remove permission when user leaves a doc, but because
|
||||
// the connection is per-project, we continue to allow access
|
||||
// after the initial joinDoc since we know they are already authorised.
|
||||
|
@ -360,10 +361,15 @@ module.exports = WebsocketController = {
|
|||
metrics.inc('editor.update-client-position', 0.1, {
|
||||
status: client.transport,
|
||||
})
|
||||
const { project_id, first_name, last_name, email, user_id } =
|
||||
client.ol_context
|
||||
const {
|
||||
project_id: projectId,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email,
|
||||
user_id: userId,
|
||||
} = client.ol_context
|
||||
logger.debug(
|
||||
{ user_id, project_id, client_id: client.id, cursorData },
|
||||
{ userId, projectId, clientId: client.id, cursorData },
|
||||
'updating client position'
|
||||
)
|
||||
|
||||
|
@ -373,36 +379,36 @@ module.exports = WebsocketController = {
|
|||
function (error) {
|
||||
if (error) {
|
||||
logger.debug(
|
||||
{ err: error, client_id: client.id, project_id, user_id },
|
||||
{ err: error, clientId: client.id, projectId, userId },
|
||||
"silently ignoring unauthorized updateClientPosition. Client likely hasn't called joinProject yet."
|
||||
)
|
||||
return callback()
|
||||
}
|
||||
cursorData.id = client.publicId
|
||||
if (user_id) {
|
||||
cursorData.user_id = user_id
|
||||
if (userId) {
|
||||
cursorData.user_id = userId
|
||||
}
|
||||
if (email) {
|
||||
cursorData.email = email
|
||||
}
|
||||
// Don't store anonymous users in redis to avoid influx
|
||||
if (!user_id || user_id === 'anonymous-user') {
|
||||
if (!userId || userId === 'anonymous-user') {
|
||||
cursorData.name = ''
|
||||
// consistent async behaviour
|
||||
setTimeout(callback)
|
||||
} else {
|
||||
cursorData.name =
|
||||
first_name && last_name
|
||||
? `${first_name} ${last_name}`
|
||||
: first_name || last_name || ''
|
||||
firstName && lastName
|
||||
? `${firstName} ${lastName}`
|
||||
: firstName || lastName || ''
|
||||
ConnectedUsersManager.updateUserPosition(
|
||||
project_id,
|
||||
projectId,
|
||||
client.publicId,
|
||||
{
|
||||
first_name,
|
||||
last_name,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email,
|
||||
_id: user_id,
|
||||
_id: userId,
|
||||
},
|
||||
{
|
||||
row: cursorData.row,
|
||||
|
@ -413,7 +419,7 @@ module.exports = WebsocketController = {
|
|||
)
|
||||
}
|
||||
WebsocketLoadBalancer.emitToRoom(
|
||||
project_id,
|
||||
projectId,
|
||||
'clientTracking.clientUpdated',
|
||||
cursorData
|
||||
)
|
||||
|
@ -429,32 +435,36 @@ module.exports = WebsocketController = {
|
|||
}
|
||||
|
||||
metrics.inc('editor.get-connected-users', { status: client.transport })
|
||||
const { project_id, user_id, is_restricted_user } = client.ol_context
|
||||
if (is_restricted_user) {
|
||||
const {
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
is_restricted_user: isRestrictedUser,
|
||||
} = client.ol_context
|
||||
if (isRestrictedUser) {
|
||||
return callback(null, [])
|
||||
}
|
||||
if (!project_id) {
|
||||
if (!projectId) {
|
||||
return callback(new NotJoinedError())
|
||||
}
|
||||
logger.debug(
|
||||
{ user_id, project_id, client_id: client.id },
|
||||
{ userId, projectId, clientId: client.id },
|
||||
'getting connected users'
|
||||
)
|
||||
AuthorizationManager.assertClientCanViewProject(client, function (error) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
WebsocketLoadBalancer.emitToRoom(project_id, 'clientTracking.refresh')
|
||||
WebsocketLoadBalancer.emitToRoom(projectId, 'clientTracking.refresh')
|
||||
setTimeout(
|
||||
() =>
|
||||
ConnectedUsersManager.getConnectedUsers(
|
||||
project_id,
|
||||
projectId,
|
||||
function (error, users) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
logger.debug(
|
||||
{ user_id, project_id, client_id: client.id },
|
||||
{ userId, projectId, clientId: client.id },
|
||||
'got connected users'
|
||||
)
|
||||
callback(null, users)
|
||||
|
@ -465,16 +475,16 @@ module.exports = WebsocketController = {
|
|||
})
|
||||
},
|
||||
|
||||
applyOtUpdate(client, doc_id, update, callback) {
|
||||
applyOtUpdate(client, docId, update, callback) {
|
||||
// client may have disconnected, but we can submit their update to doc-updater anyways.
|
||||
const { user_id, project_id } = client.ol_context
|
||||
if (!project_id) {
|
||||
const { user_id: userId, project_id: projectId } = client.ol_context
|
||||
if (!projectId) {
|
||||
return callback(new NotJoinedError())
|
||||
}
|
||||
|
||||
WebsocketController._assertClientCanApplyUpdate(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
update,
|
||||
function (error) {
|
||||
if (error) {
|
||||
|
@ -490,30 +500,30 @@ module.exports = WebsocketController = {
|
|||
update.meta = {}
|
||||
}
|
||||
update.meta.source = client.publicId
|
||||
update.meta.user_id = user_id
|
||||
update.meta.user_id = userId
|
||||
metrics.inc('editor.doc-update', 0.3, { status: client.transport })
|
||||
|
||||
logger.debug(
|
||||
{
|
||||
user_id,
|
||||
doc_id,
|
||||
project_id,
|
||||
client_id: client.id,
|
||||
userId,
|
||||
docId,
|
||||
projectId,
|
||||
clientId: client.id,
|
||||
version: update.v,
|
||||
},
|
||||
'sending update to doc updater'
|
||||
)
|
||||
|
||||
DocumentUpdaterManager.queueChange(
|
||||
project_id,
|
||||
doc_id,
|
||||
projectId,
|
||||
docId,
|
||||
update,
|
||||
function (error) {
|
||||
if ((error && error.message) === 'update is too large') {
|
||||
metrics.inc('update_too_large')
|
||||
const { updateSize } = error.info
|
||||
logger.warn(
|
||||
{ user_id, project_id, doc_id, updateSize },
|
||||
{ userId, projectId, docId, updateSize },
|
||||
'update is too large'
|
||||
)
|
||||
|
||||
|
@ -522,8 +532,8 @@ module.exports = WebsocketController = {
|
|||
|
||||
// trigger an out-of-sync error
|
||||
const message = {
|
||||
project_id,
|
||||
doc_id,
|
||||
project_id: projectId,
|
||||
doc_id: docId,
|
||||
error: 'update is too large',
|
||||
}
|
||||
setTimeout(function () {
|
||||
|
@ -552,10 +562,10 @@ module.exports = WebsocketController = {
|
|||
)
|
||||
},
|
||||
|
||||
_assertClientCanApplyUpdate(client, doc_id, update, callback) {
|
||||
_assertClientCanApplyUpdate(client, docId, update, callback) {
|
||||
AuthorizationManager.assertClientCanEditProjectAndDoc(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
function (error) {
|
||||
if (
|
||||
error &&
|
||||
|
@ -565,7 +575,7 @@ module.exports = WebsocketController = {
|
|||
// This might be a comment op, which we only need read-only priveleges for
|
||||
AuthorizationManager.assertClientCanViewProjectAndDoc(
|
||||
client,
|
||||
doc_id,
|
||||
docId,
|
||||
callback
|
||||
)
|
||||
return
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
const Settings = require('@overleaf/settings')
|
||||
const logger = require('@overleaf/logger')
|
||||
const RedisClientManager = require('./RedisClientManager')
|
||||
|
@ -28,8 +25,8 @@ module.exports = WebsocketLoadBalancer = {
|
|||
rclientPubList: RedisClientManager.createClientList(Settings.redis.pubsub),
|
||||
rclientSubList: RedisClientManager.createClientList(Settings.redis.pubsub),
|
||||
|
||||
emitToRoom(room_id, message, ...payload) {
|
||||
if (!room_id) {
|
||||
emitToRoom(roomId, message, ...payload) {
|
||||
if (!roomId) {
|
||||
logger.warn(
|
||||
{ message, payload },
|
||||
'no room_id provided, ignoring emitToRoom'
|
||||
|
@ -37,17 +34,17 @@ module.exports = WebsocketLoadBalancer = {
|
|||
return
|
||||
}
|
||||
const data = JSON.stringify({
|
||||
room_id,
|
||||
room_id: roomId,
|
||||
message,
|
||||
payload,
|
||||
})
|
||||
logger.debug(
|
||||
{ room_id, message, payload, length: data.length },
|
||||
{ roomId, message, payload, length: data.length },
|
||||
'emitting to room'
|
||||
)
|
||||
|
||||
this.rclientPubList.map(rclientPub =>
|
||||
ChannelManager.publish(rclientPub, 'editor-events', room_id, data)
|
||||
ChannelManager.publish(rclientPub, 'editor-events', roomId, data)
|
||||
)
|
||||
},
|
||||
|
||||
|
@ -74,18 +71,18 @@ module.exports = WebsocketLoadBalancer = {
|
|||
|
||||
handleRoomUpdates(rclientSubList) {
|
||||
const roomEvents = RoomManager.eventSource()
|
||||
roomEvents.on('project-active', function (project_id) {
|
||||
roomEvents.on('project-active', function (projectId) {
|
||||
const subscribePromises = rclientSubList.map(rclient =>
|
||||
ChannelManager.subscribe(rclient, 'editor-events', project_id)
|
||||
ChannelManager.subscribe(rclient, 'editor-events', projectId)
|
||||
)
|
||||
RoomManager.emitOnCompletion(
|
||||
subscribePromises,
|
||||
`project-subscribed-${project_id}`
|
||||
`project-subscribed-${projectId}`
|
||||
)
|
||||
})
|
||||
roomEvents.on('project-empty', project_id =>
|
||||
roomEvents.on('project-empty', projectId =>
|
||||
rclientSubList.map(rclient =>
|
||||
ChannelManager.unsubscribe(rclient, 'editor-events', project_id)
|
||||
ChannelManager.unsubscribe(rclient, 'editor-events', projectId)
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -107,8 +104,8 @@ module.exports = WebsocketLoadBalancer = {
|
|||
{
|
||||
channel,
|
||||
message: message.message,
|
||||
room_id: message.room_id,
|
||||
message_id: message._id,
|
||||
roomId: message.room_id,
|
||||
messageId: message._id,
|
||||
socketIoClients: clientList.map(client => client.id),
|
||||
},
|
||||
'refreshing client list'
|
||||
|
@ -128,7 +125,7 @@ module.exports = WebsocketLoadBalancer = {
|
|||
}
|
||||
}
|
||||
|
||||
const is_restricted_message =
|
||||
const isRestrictedMessage =
|
||||
!RESTRICTED_USER_MESSAGE_TYPE_PASS_LIST.includes(message.message)
|
||||
|
||||
// send messages only to unique clients (due to duplicate entries in io.sockets.clients)
|
||||
|
@ -136,7 +133,7 @@ module.exports = WebsocketLoadBalancer = {
|
|||
.clients(message.room_id)
|
||||
.filter(
|
||||
client =>
|
||||
!(is_restricted_message && client.ol_context.is_restricted_user)
|
||||
!(isRestrictedMessage && client.ol_context.is_restricted_user)
|
||||
)
|
||||
|
||||
// avoid unnecessary work if no clients are connected
|
||||
|
@ -147,8 +144,8 @@ module.exports = WebsocketLoadBalancer = {
|
|||
{
|
||||
channel,
|
||||
message: message.message,
|
||||
room_id: message.room_id,
|
||||
message_id: message._id,
|
||||
roomId: message.room_id,
|
||||
messageId: message._id,
|
||||
socketIoClients: clientList.map(client => client.id),
|
||||
},
|
||||
'distributing event to clients'
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -68,9 +67,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -80,8 +79,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -120,8 +119,8 @@ describe('applyOtUpdate', function () {
|
|||
it('should push the doc into the pending updates list', function (done) {
|
||||
getPendingUpdatesList((error, ...rest) => {
|
||||
if (error) return done(error)
|
||||
const [doc_id] = Array.from(rest[0])
|
||||
doc_id.should.equal(`${this.project_id}:${this.doc_id}`)
|
||||
const [docId] = Array.from(rest[0])
|
||||
docId.should.equal(`${this.project_id}:${this.doc_id}`)
|
||||
return done()
|
||||
})
|
||||
return null
|
||||
|
@ -187,9 +186,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -199,8 +198,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -284,9 +283,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readOnly',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -296,8 +295,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -374,9 +373,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readOnly',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -386,8 +385,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -426,8 +425,8 @@ describe('applyOtUpdate', function () {
|
|||
it('should push the doc into the pending updates list', function (done) {
|
||||
getPendingUpdatesList((error, ...rest) => {
|
||||
if (error) return done(error)
|
||||
const [doc_id] = Array.from(rest[0])
|
||||
doc_id.should.equal(`${this.project_id}:${this.doc_id}`)
|
||||
const [docId] = Array.from(rest[0])
|
||||
docId.should.equal(`${this.project_id}:${this.doc_id}`)
|
||||
return done()
|
||||
})
|
||||
return null
|
||||
|
@ -487,9 +486,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readOnly',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -499,8 +498,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -574,9 +573,9 @@ describe('applyOtUpdate', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -586,8 +585,8 @@ describe('applyOtUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -30,10 +29,10 @@ describe('clientTracking', function () {
|
|||
privilegeLevel: 'owner',
|
||||
project: { name: 'Test Project' },
|
||||
},
|
||||
(error, { user_id, project_id }) => {
|
||||
(error, { user_id: userId, project_id: projectId }) => {
|
||||
if (error) return done(error)
|
||||
this.user_id = user_id
|
||||
this.project_id = project_id
|
||||
this.user_id = userId
|
||||
this.project_id = projectId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -43,8 +42,8 @@ describe('clientTracking', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -155,10 +154,10 @@ describe('clientTracking', function () {
|
|||
project: { name: 'Test Project' },
|
||||
publicAccess: 'readAndWrite',
|
||||
},
|
||||
(error, { user_id, project_id }) => {
|
||||
(error, { user_id: userId, project_id: projectId }) => {
|
||||
if (error) return done(error)
|
||||
this.user_id = user_id
|
||||
this.project_id = project_id
|
||||
this.user_id = userId
|
||||
this.project_id = projectId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -168,8 +167,8 @@ describe('clientTracking', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
|
@ -35,9 +32,9 @@ describe('DrainManagerTests', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return done()
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -34,8 +33,8 @@ describe('EarlyDisconnect', function () {
|
|||
// slow down web-api requests to force the race condition
|
||||
let joinProject
|
||||
this.actualWebAPIjoinProject = joinProject = MockWebServer.joinProject
|
||||
return (MockWebServer.joinProject = (project_id, user_id, cb) =>
|
||||
setTimeout(() => joinProject(project_id, user_id, cb), 300))
|
||||
return (MockWebServer.joinProject = (projectId, userId, cb) =>
|
||||
setTimeout(() => joinProject(projectId, userId, cb), 300))
|
||||
})
|
||||
|
||||
after(function () {
|
||||
|
@ -53,9 +52,9 @@ describe('EarlyDisconnect', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -114,9 +113,9 @@ describe('EarlyDisconnect', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -144,8 +143,8 @@ describe('EarlyDisconnect', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -202,9 +201,9 @@ describe('EarlyDisconnect', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -232,8 +231,8 @@ describe('EarlyDisconnect', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
|
@ -20,10 +17,10 @@ const FixturesManager = require('./helpers/FixturesManager')
|
|||
describe('HttpControllerTests', function () {
|
||||
describe('without a user', function () {
|
||||
return it('should return 404 for the client view', function (done) {
|
||||
const client_id = 'not-existing'
|
||||
const clientId = 'not-existing'
|
||||
return request.get(
|
||||
{
|
||||
url: `/clients/${client_id}`,
|
||||
url: `/clients/${clientId}`,
|
||||
json: true,
|
||||
},
|
||||
(error, response, data) => {
|
||||
|
@ -46,9 +43,9 @@ describe('HttpControllerTests', function () {
|
|||
{
|
||||
privilegeLevel: 'owner',
|
||||
},
|
||||
(error, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(error, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(error)
|
||||
}
|
||||
)
|
||||
|
@ -58,8 +55,8 @@ describe('HttpControllerTests', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{},
|
||||
(error, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(error, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(error)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -35,9 +34,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -52,8 +51,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -123,9 +122,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readOnly',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -140,8 +139,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -211,9 +210,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'owner',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -228,8 +227,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -303,9 +302,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'owner',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -320,8 +319,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -389,9 +388,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -406,8 +405,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -479,9 +478,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -496,8 +495,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -570,9 +569,9 @@ describe('joinDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -587,8 +586,8 @@ describe('joinDoc', function () {
|
|||
ops: this.ops,
|
||||
ranges: this.ranges,
|
||||
},
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
|
@ -30,9 +27,9 @@ describe('joinProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -127,9 +124,9 @@ describe('joinProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -189,9 +186,9 @@ describe('joinProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -251,9 +248,9 @@ describe('joinProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -346,9 +343,9 @@ describe('joinProject', function () {
|
|||
name: 'Other Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.other_project_id = project_id
|
||||
this.other_user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.other_project_id = projectId
|
||||
this.other_user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -363,9 +360,9 @@ describe('joinProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
|
@ -48,9 +47,9 @@ describe('leaveDoc', function () {
|
|||
{
|
||||
privilegeLevel: 'readAndWrite',
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -60,8 +59,8 @@ describe('leaveDoc', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-throw-literal,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -37,9 +36,9 @@ describe('leaveProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -93,8 +92,8 @@ describe('leaveProject', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -184,9 +183,9 @@ describe('leaveProject', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -214,8 +213,8 @@ describe('leaveProject', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -44,9 +44,7 @@ There is additional meta-data that UserItems and SessionItems may use to skip
|
|||
UserItem: { hasOwnProject: true, setup(cb) { cb(null, { project_id, ... }) }}
|
||||
SessionItem: { needsOwnProject: true }
|
||||
*/
|
||||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
|
||||
const { expect } = require('chai')
|
||||
const async = require('async')
|
||||
|
||||
|
@ -58,11 +56,11 @@ const Keys = settings.redis.documentupdater.key_schema
|
|||
const redis = require('@overleaf/redis-wrapper')
|
||||
const rclient = redis.createClient(settings.redis.pubsub)
|
||||
|
||||
function getPendingUpdates(doc_id, cb) {
|
||||
rclient.lrange(Keys.pendingUpdates({ doc_id }), 0, 10, cb)
|
||||
function getPendingUpdates(docId, cb) {
|
||||
rclient.lrange(Keys.pendingUpdates({ doc_id: docId }), 0, 10, cb)
|
||||
}
|
||||
function cleanupPreviousUpdates(doc_id, cb) {
|
||||
rclient.del(Keys.pendingUpdates({ doc_id }), cb)
|
||||
function cleanupPreviousUpdates(docId, cb) {
|
||||
rclient.del(Keys.pendingUpdates({ doc_id: docId }), cb)
|
||||
}
|
||||
|
||||
describe('MatrixTests', function () {
|
||||
|
@ -72,10 +70,10 @@ describe('MatrixTests', function () {
|
|||
before(function setupPrivateProject(done) {
|
||||
FixturesManager.setUpEditorSession(
|
||||
{ privilegeLevel: 'owner' },
|
||||
(err, { project_id, doc_id }) => {
|
||||
(err, { project_id: projectId, doc_id: docId }) => {
|
||||
if (err) return done(err)
|
||||
privateProjectId = project_id
|
||||
privateDocId = doc_id
|
||||
privateProjectId = projectId
|
||||
privateDocId = docId
|
||||
privateClient = RealTimeClient.connect()
|
||||
privateClient.on('connectionAccepted', () => {
|
||||
privateClient.emit(
|
||||
|
@ -96,9 +94,9 @@ describe('MatrixTests', function () {
|
|||
{
|
||||
publicAccess: 'readAndWrite',
|
||||
},
|
||||
(err, { project_id, doc_id }) => {
|
||||
readWriteProjectId = project_id
|
||||
readWriteDocId = doc_id
|
||||
(err, { project_id: projectId, doc_id: docId }) => {
|
||||
readWriteProjectId = projectId
|
||||
readWriteDocId = docId
|
||||
done(err)
|
||||
}
|
||||
)
|
||||
|
@ -118,11 +116,11 @@ describe('MatrixTests', function () {
|
|||
|
||||
registered: {
|
||||
setup(cb) {
|
||||
const user_id = FixturesManager.getRandomId()
|
||||
const userId = FixturesManager.getRandomId()
|
||||
RealTimeClient.setSession(
|
||||
{
|
||||
user: {
|
||||
_id: user_id,
|
||||
_id: userId,
|
||||
first_name: 'Joe',
|
||||
last_name: 'Bloggs',
|
||||
},
|
||||
|
@ -130,7 +128,7 @@ describe('MatrixTests', function () {
|
|||
err => {
|
||||
if (err) return cb(err)
|
||||
cb(null, {
|
||||
user_id,
|
||||
user_id: userId,
|
||||
client: RealTimeClient.connect(),
|
||||
})
|
||||
}
|
||||
|
@ -142,12 +140,12 @@ describe('MatrixTests', function () {
|
|||
setup(cb) {
|
||||
FixturesManager.setUpEditorSession(
|
||||
{ privilegeLevel: 'owner' },
|
||||
(err, { project_id, user_id, doc_id }) => {
|
||||
(err, { project_id: projectId, user_id: userId, doc_id: docId }) => {
|
||||
if (err) return cb(err)
|
||||
cb(null, {
|
||||
user_id,
|
||||
project_id,
|
||||
doc_id,
|
||||
user_id: userId,
|
||||
project_id: projectId,
|
||||
doc_id: docId,
|
||||
client: RealTimeClient.connect(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -36,9 +35,9 @@ describe('PubSubRace', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -66,8 +65,8 @@ describe('PubSubRace', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -112,9 +111,9 @@ describe('PubSubRace', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -142,8 +141,8 @@ describe('PubSubRace', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -195,9 +194,9 @@ describe('PubSubRace', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -225,8 +224,8 @@ describe('PubSubRace', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -277,9 +276,9 @@ describe('PubSubRace', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -307,8 +306,8 @@ describe('PubSubRace', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -36,10 +35,10 @@ describe('receiveUpdate', function () {
|
|||
privilegeLevel: 'owner',
|
||||
project: { name: 'Test Project' },
|
||||
},
|
||||
(error, { user_id, project_id }) => {
|
||||
(error, { user_id: userId, project_id: projectId }) => {
|
||||
if (error) return done(error)
|
||||
this.user_id = user_id
|
||||
this.project_id = project_id
|
||||
this.user_id = userId
|
||||
this.project_id = projectId
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -49,8 +48,8 @@ describe('receiveUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id }) => {
|
||||
this.doc_id = doc_id
|
||||
(e, { doc_id: docId }) => {
|
||||
this.doc_id = docId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -100,13 +99,10 @@ describe('receiveUpdate', function () {
|
|||
privilegeLevel: 'owner',
|
||||
project: { name: 'Test Project' },
|
||||
},
|
||||
(
|
||||
error,
|
||||
{ user_id: user_id_second, project_id: project_id_second }
|
||||
) => {
|
||||
(error, { user_id: userIdSecond, project_id: projectIdSecond }) => {
|
||||
if (error) return done(error)
|
||||
this.user_id_second = user_id_second
|
||||
this.project_id_second = project_id_second
|
||||
this.user_id_second = userIdSecond
|
||||
this.project_id_second = projectIdSecond
|
||||
return cb()
|
||||
}
|
||||
)
|
||||
|
@ -116,8 +112,8 @@ describe('receiveUpdate', function () {
|
|||
return FixturesManager.setUpDoc(
|
||||
this.project_id_second,
|
||||
{ lines: this.lines, version: this.version, ops: this.ops },
|
||||
(e, { doc_id: doc_id_second }) => {
|
||||
this.doc_id_second = doc_id_second
|
||||
(e, { doc_id: docIdSecond }) => {
|
||||
this.doc_id_second = docIdSecond
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
|
@ -34,9 +31,9 @@ describe('Router', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
@ -84,9 +81,9 @@ describe('Router', function () {
|
|||
name: 'Test Project',
|
||||
},
|
||||
},
|
||||
(e, { project_id, user_id }) => {
|
||||
this.project_id = project_id
|
||||
this.user_id = user_id
|
||||
(e, { project_id: projectId, user_id: userId }) => {
|
||||
this.project_id = projectId
|
||||
this.user_id = userId
|
||||
return cb(e)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
|
@ -31,16 +28,21 @@ module.exports = FixturesManager = {
|
|||
if (!options.project) {
|
||||
options.project = { name: 'Test Project' }
|
||||
}
|
||||
const { project_id, user_id, privilegeLevel, project, publicAccess } =
|
||||
options
|
||||
const {
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
privilegeLevel,
|
||||
project,
|
||||
publicAccess,
|
||||
} = options
|
||||
|
||||
const privileges = {}
|
||||
privileges[user_id] = privilegeLevel
|
||||
privileges[userId] = privilegeLevel
|
||||
if (publicAccess) {
|
||||
privileges['anonymous-user'] = publicAccess
|
||||
}
|
||||
|
||||
MockWebServer.createMockProject(project_id, privileges, project)
|
||||
MockWebServer.createMockProject(projectId, privileges, project)
|
||||
return MockWebServer.run(error => {
|
||||
if (error != null) {
|
||||
throw error
|
||||
|
@ -48,7 +50,7 @@ module.exports = FixturesManager = {
|
|||
return RealTimeClient.setSession(
|
||||
{
|
||||
user: {
|
||||
_id: user_id,
|
||||
_id: userId,
|
||||
first_name: 'Joe',
|
||||
last_name: 'Bloggs',
|
||||
},
|
||||
|
@ -58,8 +60,8 @@ module.exports = FixturesManager = {
|
|||
throw error
|
||||
}
|
||||
return callback(null, {
|
||||
project_id,
|
||||
user_id,
|
||||
project_id: projectId,
|
||||
user_id: userId,
|
||||
privilegeLevel,
|
||||
project,
|
||||
})
|
||||
|
@ -68,7 +70,7 @@ module.exports = FixturesManager = {
|
|||
})
|
||||
},
|
||||
|
||||
setUpDoc(project_id, options, callback) {
|
||||
setUpDoc(projectId, options, callback) {
|
||||
if (options == null) {
|
||||
options = {}
|
||||
}
|
||||
|
@ -87,9 +89,9 @@ module.exports = FixturesManager = {
|
|||
if (!options.ops) {
|
||||
options.ops = ['mock', 'ops']
|
||||
}
|
||||
const { doc_id, lines, version, ops, ranges } = options
|
||||
const { doc_id: docId, lines, version, ops, ranges } = options
|
||||
|
||||
MockDocUpdaterServer.createMockDoc(project_id, doc_id, {
|
||||
MockDocUpdaterServer.createMockDoc(projectId, docId, {
|
||||
lines,
|
||||
version,
|
||||
ops,
|
||||
|
@ -99,7 +101,13 @@ module.exports = FixturesManager = {
|
|||
if (error != null) {
|
||||
throw error
|
||||
}
|
||||
return callback(null, { project_id, doc_id, lines, version, ops })
|
||||
return callback(null, {
|
||||
project_id: projectId,
|
||||
doc_id: docId,
|
||||
lines,
|
||||
version,
|
||||
ops,
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -17,26 +16,26 @@ const express = require('express')
|
|||
module.exports = MockDocUpdaterServer = {
|
||||
docs: {},
|
||||
|
||||
createMockDoc(project_id, doc_id, data) {
|
||||
return (MockDocUpdaterServer.docs[`${project_id}:${doc_id}`] = data)
|
||||
createMockDoc(projectId, docId, data) {
|
||||
return (MockDocUpdaterServer.docs[`${projectId}:${docId}`] = data)
|
||||
},
|
||||
|
||||
getDocument(project_id, doc_id, fromVersion, callback) {
|
||||
getDocument(projectId, docId, fromVersion, callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
return callback(null, MockDocUpdaterServer.docs[`${project_id}:${doc_id}`])
|
||||
return callback(null, MockDocUpdaterServer.docs[`${projectId}:${docId}`])
|
||||
},
|
||||
|
||||
deleteProject: sinon.stub().callsArg(1),
|
||||
|
||||
getDocumentRequest(req, res, next) {
|
||||
const { project_id, doc_id } = req.params
|
||||
const { project_id: projectId, doc_id: docId } = req.params
|
||||
let { fromVersion } = req.query
|
||||
fromVersion = parseInt(fromVersion, 10)
|
||||
return MockDocUpdaterServer.getDocument(
|
||||
project_id,
|
||||
doc_id,
|
||||
projectId,
|
||||
docId,
|
||||
fromVersion,
|
||||
(error, data) => {
|
||||
if (error != null) {
|
||||
|
@ -51,8 +50,8 @@ module.exports = MockDocUpdaterServer = {
|
|||
},
|
||||
|
||||
deleteProjectRequest(req, res, next) {
|
||||
const { project_id } = req.params
|
||||
return MockDocUpdaterServer.deleteProject(project_id, error => {
|
||||
const { project_id: projectId } = req.params
|
||||
return MockDocUpdaterServer.deleteProject(projectId, error => {
|
||||
if (error != null) {
|
||||
return next(error)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -18,41 +17,41 @@ module.exports = MockWebServer = {
|
|||
projects: {},
|
||||
privileges: {},
|
||||
|
||||
createMockProject(project_id, privileges, project) {
|
||||
MockWebServer.privileges[project_id] = privileges
|
||||
return (MockWebServer.projects[project_id] = project)
|
||||
createMockProject(projectId, privileges, project) {
|
||||
MockWebServer.privileges[projectId] = privileges
|
||||
return (MockWebServer.projects[projectId] = project)
|
||||
},
|
||||
|
||||
joinProject(project_id, user_id, callback) {
|
||||
joinProject(projectId, userId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
return callback(
|
||||
null,
|
||||
MockWebServer.projects[project_id],
|
||||
MockWebServer.privileges[project_id][user_id] ||
|
||||
MockWebServer.privileges[project_id]['anonymous-user']
|
||||
MockWebServer.projects[projectId],
|
||||
MockWebServer.privileges[projectId][userId] ||
|
||||
MockWebServer.privileges[projectId]['anonymous-user']
|
||||
)
|
||||
},
|
||||
|
||||
joinProjectRequest(req, res, next) {
|
||||
const { project_id } = req.params
|
||||
const { user_id } = req.query
|
||||
if (project_id === '404404404404404404404404') {
|
||||
const { project_id: projectId } = req.params
|
||||
const { user_id: userId } = req.query
|
||||
if (projectId === '404404404404404404404404') {
|
||||
// not-found
|
||||
return res.status(404).send()
|
||||
}
|
||||
if (project_id === '403403403403403403403403') {
|
||||
if (projectId === '403403403403403403403403') {
|
||||
// forbidden
|
||||
return res.status(403).send()
|
||||
}
|
||||
if (project_id === '429429429429429429429429') {
|
||||
if (projectId === '429429429429429429429429') {
|
||||
// rate-limited
|
||||
return res.status(429).send()
|
||||
} else {
|
||||
return MockWebServer.joinProject(
|
||||
project_id,
|
||||
user_id,
|
||||
projectId,
|
||||
userId,
|
||||
(error, project, privilegeLevel) => {
|
||||
if (error != null) {
|
||||
return next(error)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -87,23 +86,23 @@ module.exports = Client = {
|
|||
)
|
||||
},
|
||||
|
||||
getConnectedClient(client_id, callback) {
|
||||
getConnectedClient(clientId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
return request.get(
|
||||
{
|
||||
url: `http://localhost:3026/clients/${client_id}`,
|
||||
url: `http://localhost:3026/clients/${clientId}`,
|
||||
json: true,
|
||||
},
|
||||
(error, response, data) => callback(error, data)
|
||||
)
|
||||
},
|
||||
|
||||
disconnectClient(client_id, callback) {
|
||||
disconnectClient(clientId, callback) {
|
||||
request.post(
|
||||
{
|
||||
url: `http://localhost:3026/client/${client_id}/disconnect`,
|
||||
url: `http://localhost:3026/client/${clientId}/disconnect`,
|
||||
},
|
||||
(error, response, data) => callback(error, data)
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
|
@ -25,11 +24,11 @@ describe('ConnectedUsersManager', function () {
|
|||
redis: {
|
||||
realtime: {
|
||||
key_schema: {
|
||||
clientsInProject({ project_id }) {
|
||||
return `clients_in_project:${project_id}`
|
||||
clientsInProject({ project_id: projectId }) {
|
||||
return `clients_in_project:${projectId}`
|
||||
},
|
||||
connectedUser({ project_id, client_id }) {
|
||||
return `connected_user:${project_id}:${client_id}`
|
||||
connectedUser({ project_id: projectId, client_id: clientId }) {
|
||||
return `connected_user:${projectId}:${clientId}`
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
|
@ -32,8 +31,8 @@ describe('DocumentUpdaterController', function () {
|
|||
redis: {
|
||||
documentupdater: {
|
||||
key_schema: {
|
||||
pendingUpdates({ doc_id }) {
|
||||
return `PendingUpdates:${doc_id}`
|
||||
pendingUpdates({ doc_id: docId }) {
|
||||
return `PendingUpdates:${docId}`
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
|
@ -28,8 +27,8 @@ describe('DocumentUpdaterManager', function () {
|
|||
redis: {
|
||||
documentupdater: {
|
||||
key_schema: {
|
||||
pendingUpdates({ doc_id }) {
|
||||
return `PendingUpdates:${doc_id}`
|
||||
pendingUpdates({ doc_id: docId }) {
|
||||
return `PendingUpdates:${docId}`
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
no-useless-escape,
|
||||
*/
|
||||
|
@ -43,8 +42,8 @@ describe('SafeJsonParse', function () {
|
|||
|
||||
return it('should return an error on oversized data', function (done) {
|
||||
// we have a 2k overhead on top of max size
|
||||
const big_blob = Array(16 * 1024).join('A')
|
||||
const data = `{\"foo\": \"${big_blob}\"}`
|
||||
const bigBlob = Array(16 * 1024).join('A')
|
||||
const data = `{\"foo\": \"${bigBlob}\"}`
|
||||
this.Settings.maxUpdateSize = 2 * 1024
|
||||
return this.SafeJsonParse.parse(data, (error, parsed) => {
|
||||
this.logger.error.called.should.equal(false)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
no-return-assign,
|
||||
no-throw-literal,
|
||||
no-unused-vars,
|
||||
|
@ -317,8 +316,8 @@ describe('WebsocketController', function () {
|
|||
this.clientsInRoom = []
|
||||
this.io = {
|
||||
sockets: {
|
||||
clients: room_id => {
|
||||
if (room_id !== this.project_id) {
|
||||
clients: roomId => {
|
||||
if (roomId !== this.project_id) {
|
||||
throw 'expected room_id to be project_id'
|
||||
}
|
||||
return this.clientsInRoom
|
||||
|
@ -396,8 +395,8 @@ describe('WebsocketController', function () {
|
|||
this.clientsInRoom = ['mock-remaining-client']
|
||||
this.io = {
|
||||
sockets: {
|
||||
clients: room_id => {
|
||||
if (room_id !== this.project_id) {
|
||||
clients: roomId => {
|
||||
if (roomId !== this.project_id) {
|
||||
throw 'expected room_id to be project_id'
|
||||
}
|
||||
return this.clientsInRoom
|
||||
|
@ -600,11 +599,11 @@ describe('WebsocketController', function () {
|
|||
})
|
||||
|
||||
return it('should call the callback with the escaped lines', function () {
|
||||
const escaped_lines = this.callback.args[0][1]
|
||||
const escaped_word = escaped_lines.pop()
|
||||
escaped_word.should.equal('räksmörgås')
|
||||
const escapedLines = this.callback.args[0][1]
|
||||
const escapedWord = escapedLines.pop()
|
||||
escapedWord.should.equal('räksmörgås')
|
||||
// Check that unescaping works
|
||||
return decodeURIComponent(escape(escaped_word)).should.equal(
|
||||
return decodeURIComponent(escape(escapedWord)).should.equal(
|
||||
'räksmörgås'
|
||||
)
|
||||
})
|
||||
|
@ -623,10 +622,10 @@ describe('WebsocketController', function () {
|
|||
})
|
||||
|
||||
return it('should call the callback with the encoded comment', function () {
|
||||
const encoded_comments = this.callback.args[0][4]
|
||||
const encoded_comment = encoded_comments.comments.pop()
|
||||
const encoded_comment_text = encoded_comment.op.c
|
||||
return encoded_comment_text.should.equal('räksmörgås')
|
||||
const encodedComments = this.callback.args[0][4]
|
||||
const encodedComment = encodedComments.comments.pop()
|
||||
const encodedCommentText = encodedComment.op.c
|
||||
return encodedCommentText.should.equal('räksmörgås')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -641,10 +640,10 @@ describe('WebsocketController', function () {
|
|||
this.callback
|
||||
)
|
||||
|
||||
const encoded_changes = this.callback.args[0][4]
|
||||
const encoded_change = encoded_changes.changes.pop()
|
||||
const encoded_change_text = encoded_change.op.i
|
||||
return encoded_change_text.should.equal('räksmörgås')
|
||||
const encodedChanges = this.callback.args[0][4]
|
||||
const encodedChange = encodedChanges.changes.pop()
|
||||
const encodedChangeText = encodedChange.op.i
|
||||
return encodedChangeText.should.equal('räksmörgås')
|
||||
})
|
||||
|
||||
return it('should call the callback with the encoded delete change', function () {
|
||||
|
@ -657,10 +656,10 @@ describe('WebsocketController', function () {
|
|||
this.callback
|
||||
)
|
||||
|
||||
const encoded_changes = this.callback.args[0][4]
|
||||
const encoded_change = encoded_changes.changes.pop()
|
||||
const encoded_change_text = encoded_change.op.d
|
||||
return encoded_change_text.should.equal('räksmörgås')
|
||||
const encodedChanges = this.callback.args[0][4]
|
||||
const encodedChange = encodedChanges.changes.pop()
|
||||
const encodedChangeText = encodedChange.op.d
|
||||
return encodedChangeText.should.equal('räksmörgås')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -746,11 +745,7 @@ describe('WebsocketController', function () {
|
|||
this.AuthorizationManager.assertClientCanViewProjectAndDoc.yields(
|
||||
new Error()
|
||||
)
|
||||
this.DocumentUpdaterManager.checkDocument = (
|
||||
project_id,
|
||||
doc_id,
|
||||
cb
|
||||
) => {
|
||||
this.DocumentUpdaterManager.checkDocument = (projectId, docId, cb) => {
|
||||
this.client.disconnected = true
|
||||
cb()
|
||||
}
|
||||
|
@ -790,11 +785,7 @@ describe('WebsocketController', function () {
|
|||
this.AuthorizationManager.assertClientCanViewProjectAndDoc.yields(
|
||||
new Error()
|
||||
)
|
||||
this.DocumentUpdaterManager.checkDocument = (
|
||||
project_id,
|
||||
doc_id,
|
||||
cb
|
||||
) => {
|
||||
this.DocumentUpdaterManager.checkDocument = (projectId, docId, cb) => {
|
||||
this.DocumentUpdaterManager.checkDocument = sinon.stub().yields()
|
||||
this.WebsocketController.joinDoc(
|
||||
this.client,
|
||||
|
@ -838,11 +829,7 @@ describe('WebsocketController', function () {
|
|||
this.AuthorizationManager.assertClientCanViewProjectAndDoc.yields(
|
||||
new Error()
|
||||
)
|
||||
this.DocumentUpdaterManager.checkDocument = (
|
||||
project_id,
|
||||
doc_id,
|
||||
cb
|
||||
) => {
|
||||
this.DocumentUpdaterManager.checkDocument = (projectId, docId, cb) => {
|
||||
this.WebsocketController.leaveDoc(this.client, this.doc_id, () => {})
|
||||
cb()
|
||||
}
|
||||
|
@ -873,7 +860,7 @@ describe('WebsocketController', function () {
|
|||
|
||||
describe('when the client disconnects while RoomManager.joinDoc is running', function () {
|
||||
beforeEach(function () {
|
||||
this.RoomManager.joinDoc = (client, doc_id, cb) => {
|
||||
this.RoomManager.joinDoc = (client, docId, cb) => {
|
||||
this.client.disconnected = true
|
||||
return cb()
|
||||
}
|
||||
|
@ -909,8 +896,8 @@ describe('WebsocketController', function () {
|
|||
return describe('when the client disconnects while DocumentUpdaterManager.getDocument is running', function () {
|
||||
beforeEach(function () {
|
||||
this.DocumentUpdaterManager.getDocument = (
|
||||
project_id,
|
||||
doc_id,
|
||||
projectId,
|
||||
docId,
|
||||
fromVersion,
|
||||
callback
|
||||
) => {
|
||||
|
@ -1524,9 +1511,9 @@ describe('WebsocketController', function () {
|
|||
this.logger.warn.called.should.equal(true)
|
||||
return this.logger.warn.args[0].should.deep.equal([
|
||||
{
|
||||
user_id: this.user_id,
|
||||
project_id: this.project_id,
|
||||
doc_id: this.doc_id,
|
||||
userId: this.user_id,
|
||||
projectId: this.project_id,
|
||||
docId: this.doc_id,
|
||||
updateSize: 7372835,
|
||||
},
|
||||
'update is too large',
|
||||
|
|
Loading…
Reference in a new issue