|
@@ -8,13 +8,17 @@ const WebsocketAddressManager = require('./WebsocketAddressManager')
|
|
|
const bodyParser = require('body-parser')
|
|
const bodyParser = require('body-parser')
|
|
|
const base64id = require('base64id')
|
|
const base64id = require('base64id')
|
|
|
const { UnexpectedArgumentsError } = require('./Errors')
|
|
const { UnexpectedArgumentsError } = require('./Errors')
|
|
|
-const { z, zz } = require('@overleaf/validation-tools')
|
|
|
|
|
-const { isZodErrorLike } = require('zod-validation-error')
|
|
|
|
|
|
|
+const Joi = require('joi')
|
|
|
|
|
|
|
|
const HOSTNAME = require('node:os').hostname()
|
|
const HOSTNAME = require('node:os').hostname()
|
|
|
const SERVER_PING_INTERVAL = 15000
|
|
const SERVER_PING_INTERVAL = 15000
|
|
|
const SERVER_PING_LATENCY_THRESHOLD = 5000
|
|
const SERVER_PING_LATENCY_THRESHOLD = 5000
|
|
|
|
|
|
|
|
|
|
+const JOI_OBJECT_ID = Joi.string()
|
|
|
|
|
+ .required()
|
|
|
|
|
+ .regex(/^[0-9a-f]{24}$/)
|
|
|
|
|
+ .message('invalid id')
|
|
|
|
|
+
|
|
|
let Router
|
|
let Router
|
|
|
module.exports = Router = {
|
|
module.exports = Router = {
|
|
|
_handleError(callback, error, client, method, attrs) {
|
|
_handleError(callback, error, client, method, attrs) {
|
|
@@ -25,11 +29,11 @@ module.exports = Router = {
|
|
|
attrs.client_id = client.id
|
|
attrs.client_id = client.id
|
|
|
attrs.err = error
|
|
attrs.err = error
|
|
|
attrs.method = method
|
|
attrs.method = method
|
|
|
- if (isZodErrorLike(error)) {
|
|
|
|
|
|
|
+ if (Joi.isError(error)) {
|
|
|
logger.info(attrs, 'validation error')
|
|
logger.info(attrs, 'validation error')
|
|
|
let message = 'invalid'
|
|
let message = 'invalid'
|
|
|
try {
|
|
try {
|
|
|
- message = error.issues[0].message
|
|
|
|
|
|
|
+ message = error.details[0].message
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
// ignore unexpected errors
|
|
// ignore unexpected errors
|
|
|
logger.warn({ error, e }, 'unexpected validation error')
|
|
logger.warn({ error, e }, 'unexpected validation error')
|
|
@@ -189,7 +193,7 @@ module.exports = Router = {
|
|
|
|
|
|
|
|
if (!isDebugging) {
|
|
if (!isDebugging) {
|
|
|
try {
|
|
try {
|
|
|
- zz.objectId().parse(projectId)
|
|
|
|
|
|
|
+ Joi.assert(projectId, JOI_OBJECT_ID)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
metrics.inc('socket-io.connection', 1, {
|
|
metrics.inc('socket-io.connection', 1, {
|
|
|
status: client.transport,
|
|
status: client.transport,
|
|
@@ -405,11 +409,6 @@ module.exports = Router = {
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- const joinDocSchema = z.object({
|
|
|
|
|
- doc_id: zz.objectId(),
|
|
|
|
|
- fromVersion: z.number().int().optional(),
|
|
|
|
|
- options: z.object(),
|
|
|
|
|
- })
|
|
|
|
|
// Variadic. The possible arguments:
|
|
// Variadic. The possible arguments:
|
|
|
// doc_id, callback
|
|
// doc_id, callback
|
|
|
// doc_id, fromVersion, callback
|
|
// doc_id, fromVersion, callback
|
|
@@ -443,7 +442,14 @@ module.exports = Router = {
|
|
|
return Router._handleInvalidArguments(client, 'joinDoc', arguments)
|
|
return Router._handleInvalidArguments(client, 'joinDoc', arguments)
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- joinDocSchema.parse({ doc_id: docId, fromVersion, options })
|
|
|
|
|
|
|
+ Joi.assert(
|
|
|
|
|
+ { doc_id: docId, fromVersion, options },
|
|
|
|
|
+ Joi.object({
|
|
|
|
|
+ doc_id: JOI_OBJECT_ID,
|
|
|
|
|
+ fromVersion: Joi.number().integer(),
|
|
|
|
|
+ options: Joi.object().required(),
|
|
|
|
|
+ })
|
|
|
|
|
+ )
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
return Router._handleError(callback, error, client, 'joinDoc', {
|
|
return Router._handleError(callback, error, client, 'joinDoc', {
|
|
|
disconnect: 1,
|
|
disconnect: 1,
|
|
@@ -472,7 +478,7 @@ module.exports = Router = {
|
|
|
return Router._handleInvalidArguments(client, 'leaveDoc', arguments)
|
|
return Router._handleInvalidArguments(client, 'leaveDoc', arguments)
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- zz.objectId().parse(docId)
|
|
|
|
|
|
|
+ Joi.assert(docId, JOI_OBJECT_ID)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
return Router._handleError(callback, error, client, 'joinDoc', {
|
|
return Router._handleError(callback, error, client, 'joinDoc', {
|
|
|
disconnect: 1,
|
|
disconnect: 1,
|
|
@@ -548,10 +554,6 @@ module.exports = Router = {
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- const applyOtUpdateSchema = z.object({
|
|
|
|
|
- doc_id: zz.objectId(),
|
|
|
|
|
- update: z.object(),
|
|
|
|
|
- })
|
|
|
|
|
client.on('applyOtUpdate', function (docId, update, callback) {
|
|
client.on('applyOtUpdate', function (docId, update, callback) {
|
|
|
if (typeof callback !== 'function') {
|
|
if (typeof callback !== 'function') {
|
|
|
return Router._handleInvalidArguments(
|
|
return Router._handleInvalidArguments(
|
|
@@ -561,7 +563,13 @@ module.exports = Router = {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- applyOtUpdateSchema.parse({ doc_id: docId, update })
|
|
|
|
|
|
|
+ Joi.assert(
|
|
|
|
|
+ { doc_id: docId, update },
|
|
|
|
|
+ Joi.object({
|
|
|
|
|
+ doc_id: JOI_OBJECT_ID,
|
|
|
|
|
+ update: Joi.object().required(),
|
|
|
|
|
+ })
|
|
|
|
|
+ )
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
return Router._handleError(callback, error, client, 'applyOtUpdate', {
|
|
return Router._handleError(callback, error, client, 'applyOtUpdate', {
|
|
|
disconnect: 1,
|
|
disconnect: 1,
|