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