|
|
@@ -8,16 +8,23 @@ 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')
|
|
|
+const joinDocSchema = z.object({
|
|
|
+ doc_id: zz.objectId(),
|
|
|
+ fromVersion: z.number().int().optional(),
|
|
|
+ options: z.object(),
|
|
|
+})
|
|
|
+
|
|
|
+const applyOtUpdateSchema = z.object({
|
|
|
+ doc_id: zz.objectId(),
|
|
|
+ update: z.object(),
|
|
|
+})
|
|
|
|
|
|
let Router
|
|
|
module.exports = Router = {
|
|
|
@@ -29,11 +36,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 +200,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,
|
|
|
@@ -442,14 +449,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 +478,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,
|
|
|
@@ -563,13 +563,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,
|