diff --git a/libraries/validation-tools/index.js b/libraries/validation-tools/index.js index c41b37d0b5..c456a3a7bf 100644 --- a/libraries/validation-tools/index.js +++ b/libraries/validation-tools/index.js @@ -1,7 +1,7 @@ const { ParamsError } = require('./Errors') const { z } = require('zod') const { zz } = require('./zodHelpers') -const { validateReq } = require('./validateReq') +const { parseReq } = require('./parseReq') const { validateSchema } = require('./validateSchema') const { handleValidationError, @@ -12,7 +12,7 @@ module.exports = { z, zz, validateSchema, - validateReq, + parseReq, handleValidationError, createHandleValidationError, ParamsError, diff --git a/libraries/validation-tools/validateReq.js b/libraries/validation-tools/parseReq.js similarity index 86% rename from libraries/validation-tools/validateReq.js rename to libraries/validation-tools/parseReq.js index 36c6a5a36f..cb3c87c659 100644 --- a/libraries/validation-tools/validateReq.js +++ b/libraries/validation-tools/parseReq.js @@ -12,14 +12,14 @@ const { ParamsError } = require('./Errors') */ /** - * Validate a request against a zod schema + * Parse and validate a request against a Zod schema * * @template {ZodType} T * @param {Request} req - The Express request object * @param {T} schema - The Zod schema to validate against * @returns {output} The validated request object */ -function validateReq(req, schema) { +function parseReq(req, schema) { const parsed = schema.safeParse(req) if (parsed.success) { return parsed.data @@ -31,4 +31,4 @@ function validateReq(req, schema) { } } -module.exports = { validateReq } +module.exports = { parseReq } diff --git a/libraries/validation-tools/test/unit/src/validateReq.test.ts b/libraries/validation-tools/test/unit/src/validateReq.test.ts index 4a716d7a69..a30e14c299 100644 --- a/libraries/validation-tools/test/unit/src/validateReq.test.ts +++ b/libraries/validation-tools/test/unit/src/validateReq.test.ts @@ -1,10 +1,10 @@ -import { validateReq } from '../../../validateReq' +import { parseReq } from '../../../parseReq' import { describe, expect, it } from 'vitest' import { z } from 'zod' import type { Request } from 'express' import { zz } from '../../../zodHelpers' -describe('validateReq', () => { +describe('parseReq', () => { describe('with a request that is valid for the schema', () => { it('should return the parsed request', () => { const req = { @@ -25,7 +25,7 @@ describe('validateReq', () => { }), }) - const result = validateReq(req, schema) + const result = parseReq(req, schema) expect(result).toEqual({ params: { @@ -46,7 +46,7 @@ describe('validateReq', () => { } as Request<{ id: string }> expect(() => - validateReq( + parseReq( req, z.object({ params: z.object({ @@ -65,7 +65,7 @@ describe('validateReq', () => { } as Request expect(() => - validateReq( + parseReq( req, z.object({ body: z.object({ diff --git a/server-ce/test/host-admin.js b/server-ce/test/host-admin.js index 9b1c9ae856..c76151745c 100644 --- a/server-ce/test/host-admin.js +++ b/server-ce/test/host-admin.js @@ -6,7 +6,7 @@ import bodyParser from 'body-parser' import express from 'express' import YAML from 'js-yaml' import { isZodErrorLike } from 'zod-validation-error' -import { ParamsError, validateReq, z } from '@overleaf/validation-tools' +import { ParamsError, parseReq, z } from '@overleaf/validation-tools' import { expressify } from '@overleaf/promise-utils' const execFile = promisify(execFileCb) @@ -114,7 +114,7 @@ app.post( expressify(async (req, res) => { const { body: { cwd, script, args, user, hasOverleafEnv }, - } = validateReq( + } = parseReq( req, z.object({ body: z.object({ @@ -154,7 +154,7 @@ app.post( expressify(async (req, res) => { const { body: { task, args }, - } = validateReq( + } = parseReq( req, z.object({ body: z.object({ @@ -297,7 +297,7 @@ app.post( const { params: { cmd }, body: { args }, - } = validateReq( + } = parseReq( req, z.object({ params: z.object({ @@ -348,7 +348,7 @@ app.post( expressify(async (req, res) => { const { body: { pro, version, vars, withDataDir, resetData, mongoVersion }, - } = validateReq( + } = parseReq( req, z.object({ body: z.object({ @@ -402,7 +402,7 @@ app.post( expressify(async (req, res) => { const { body: { mongoVersion }, - } = validateReq( + } = parseReq( req, z.object({ body: z.object({ diff --git a/services/history-v1/api/controllers/project_import.js b/services/history-v1/api/controllers/project_import.js index d4cb94886b..dfc0c40159 100644 --- a/services/history-v1/api/controllers/project_import.js +++ b/services/history-v1/api/controllers/project_import.js @@ -27,7 +27,7 @@ const persistBuffer = storage.persistBuffer const InvalidChangeError = storage.InvalidChangeError const render = require('./render') -const { validateReq } = require('@overleaf/validation-tools') +const { parseReq } = require('@overleaf/validation-tools') const schemas = require('../schema') const Rollout = require('../app/rollout') const redisBackend = require('../../storage/lib/chunk_store/redis') @@ -54,7 +54,7 @@ function getParam(req, name, location = 'path') { } } async function importSnapshot(req, res) { - const { params, body } = validateReq(req, schemas.importSnapshot) + const { params, body } = parseReq(req, schemas.importSnapshot) const projectId = params.project_id const rawSnapshot = getParam({ body }, 'snapshot', 'body') ?? body let snapshot @@ -82,7 +82,7 @@ async function importSnapshot(req, res) { } async function importChanges(req, res, next) { - const { params, query, body } = validateReq(req, schemas.importChanges) + const { params, query, body } = parseReq(req, schemas.importChanges) const projectId = params.project_id const rawChanges = getParam({ body }, 'changes', 'body') ?? body const endVersion = query.end_version @@ -177,7 +177,7 @@ async function importChanges(req, res, next) { } async function flushChanges(req, res, next) { - const { params } = validateReq(req, schemas.flushChanges) + const { params } = parseReq(req, schemas.flushChanges) const projectId = params.project_id // Use the same limits importChanges, since these are passed to persistChanges const farFuture = new Date() @@ -201,7 +201,7 @@ async function flushChanges(req, res, next) { } async function expireProject(req, res, next) { - const { params } = validateReq(req, schemas.expireProject) + const { params } = parseReq(req, schemas.expireProject) const projectId = params.project_id await redisBackend.expireProject(projectId) res.status(HTTPStatus.OK).end() diff --git a/services/history-v1/api/controllers/projects.js b/services/history-v1/api/controllers/projects.js index b8d567c6af..5d6eb5b5aa 100644 --- a/services/history-v1/api/controllers/projects.js +++ b/services/history-v1/api/controllers/projects.js @@ -9,7 +9,7 @@ const { promisify } = require('node:util') const config = require('config') const OError = require('@overleaf/o-error') const { expressify } = require('@overleaf/promise-utils') -const { validateReq } = require('@overleaf/validation-tools') +const { parseReq } = require('@overleaf/validation-tools') const logger = require('@overleaf/logger') const { Chunk, ChunkResponse, Blob } = require('overleaf-editor-core') @@ -35,7 +35,7 @@ const { getChunkMetadataForVersion } = require('../../storage/lib/chunk_store') const pipeline = promisify(Stream.pipeline) async function initializeProject(req, res, next) { - const { body } = validateReq(req, schemas.initializeProject) + const { body } = parseReq(req, schemas.initializeProject) let projectId = body?.projectId try { projectId = await chunkStore.initializeProject(projectId) @@ -51,7 +51,7 @@ async function initializeProject(req, res, next) { } async function getLatestContent(req, res, next) { - const { params } = validateReq(req, schemas.getLatestContent) + const { params } = parseReq(req, schemas.getLatestContent) const projectId = params.project_id const blobStore = new BlobStore(projectId) const chunk = await chunkStore.loadLatest(projectId) @@ -62,7 +62,7 @@ async function getLatestContent(req, res, next) { } async function getContentAtVersion(req, res, next) { - const { params } = validateReq(req, schemas.getContentAtVersion) + const { params } = parseReq(req, schemas.getContentAtVersion) const projectId = params.project_id const version = params.version const blobStore = new BlobStore(projectId) @@ -72,7 +72,7 @@ async function getContentAtVersion(req, res, next) { } async function getLatestHashedContent(req, res, next) { - const { params } = validateReq(req, schemas.getLatestHashedContent) + const { params } = parseReq(req, schemas.getLatestHashedContent) const projectId = params.project_id const blobStore = new HashCheckBlobStore(new BlobStore(projectId)) const chunk = await chunkStore.loadLatest(projectId) @@ -84,7 +84,7 @@ async function getLatestHashedContent(req, res, next) { } async function getLatestHistory(req, res, next) { - const { params } = validateReq(req, schemas.getLatestHistory) + const { params } = parseReq(req, schemas.getLatestHistory) const projectId = params.project_id try { const chunk = await chunkStore.loadLatest(projectId) @@ -100,7 +100,7 @@ async function getLatestHistory(req, res, next) { } async function getLatestHistoryRaw(req, res, next) { - const { params, query } = validateReq(req, schemas.getLatestHistoryRaw) + const { params, query } = parseReq(req, schemas.getLatestHistoryRaw) const projectId = params.project_id const readOnly = query.readOnly try { @@ -121,7 +121,7 @@ async function getLatestHistoryRaw(req, res, next) { } async function getHistory(req, res, next) { - const { params } = validateReq(req, schemas.getHistory) + const { params } = parseReq(req, schemas.getHistory) const projectId = params.project_id const version = params.version try { @@ -138,7 +138,7 @@ async function getHistory(req, res, next) { } async function getHistoryBefore(req, res, next) { - const { params } = validateReq(req, schemas.getHistoryBefore) + const { params } = parseReq(req, schemas.getHistoryBefore) const projectId = params.project_id const timestamp = params.timestamp try { @@ -158,7 +158,7 @@ async function getHistoryBefore(req, res, next) { * Get all changes since the beginning of history or since a given version */ async function getChanges(req, res, next) { - const { params, query } = validateReq(req, schemas.getChanges) + const { params, query } = parseReq(req, schemas.getChanges) const projectId = params.project_id const sinceParam = query.since const since = sinceParam == null ? 0 : sinceParam @@ -187,7 +187,7 @@ async function getChanges(req, res, next) { } async function getZip(req, res, next) { - const { params } = validateReq(req, schemas.getZip) + const { params } = parseReq(req, schemas.getZip) const projectId = params.project_id const version = params.version const blobStore = new BlobStore(projectId) @@ -215,7 +215,7 @@ async function getZip(req, res, next) { } async function createZip(req, res, next) { - const { params } = validateReq(req, schemas.createZip) + const { params } = parseReq(req, schemas.createZip) const projectId = params.project_id const version = params.version try { @@ -236,7 +236,7 @@ async function createZip(req, res, next) { } async function deleteProject(req, res, next) { - const { params } = validateReq(req, schemas.deleteProject) + const { params } = parseReq(req, schemas.deleteProject) const projectId = params.project_id const blobStore = new BlobStore(projectId) @@ -249,7 +249,7 @@ async function deleteProject(req, res, next) { } async function createProjectBlob(req, res, next) { - const { params } = validateReq(req, schemas.createProjectBlob) + const { params } = parseReq(req, schemas.createProjectBlob) const projectId = params.project_id const expectedHash = params.hash const maxUploadSize = parseInt(config.get('maxFileUploadSize'), 10) @@ -287,7 +287,7 @@ async function createProjectBlob(req, res, next) { } async function headProjectBlob(req, res) { - const { params } = validateReq(req, schemas.headProjectBlob) + const { params } = parseReq(req, schemas.headProjectBlob) const projectId = params.project_id const hash = params.hash @@ -320,7 +320,7 @@ function _getRangeOpts(header) { } async function getProjectBlob(req, res, next) { - const { params, headers } = validateReq(req, schemas.getProjectBlob) + const { params, headers } = parseReq(req, schemas.getProjectBlob) const projectId = params.project_id const hash = params.hash const rangeHeader = headers.range || '' @@ -385,7 +385,7 @@ async function getProjectBlob(req, res, next) { } async function copyProjectBlob(req, res, next) { - const { params, query } = validateReq(req, schemas.copyProjectBlob) + const { params, query } = parseReq(req, schemas.copyProjectBlob) const sourceProjectId = query.copyFrom const targetProjectId = params.project_id const blobHash = params.hash @@ -450,7 +450,7 @@ function sumUpByteLength(blobs) { } async function getBlobStats(req, res) { - const { params, body } = validateReq(req, schemas.getBlobStats) + const { params, body } = parseReq(req, schemas.getBlobStats) const projectId = params.project_id const blobHashes = body.blobHashes || [] for (const hash of blobHashes) { @@ -475,7 +475,7 @@ async function getBlobStats(req, res) { } async function getProjectBlobsStats(req, res) { - const { body } = validateReq(req, schemas.getProjectBlobsStats) + const { body } = parseReq(req, schemas.getProjectBlobsStats) const projectIds = body.projectIds const { blobs } = await getProjectBlobsBatch( projectIds.map(id => { diff --git a/services/history-v1/api/middleware/security.js b/services/history-v1/api/middleware/security.js index 0f9568c088..4835e455a0 100644 --- a/services/history-v1/api/middleware/security.js +++ b/services/history-v1/api/middleware/security.js @@ -5,7 +5,7 @@ const config = require('config') const HTTPStatus = require('http-status') const jwt = require('jsonwebtoken') const tsscmp = require('tsscmp') -const { validateReq } = require('@overleaf/validation-tools') +const { parseReq } = require('@overleaf/validation-tools') const schemas = require('../schema') function hasValidBasicAuthCredentials(req) { @@ -103,7 +103,7 @@ function configureJWTAuth(mode = 'jwt') { throw error } - const { params } = validateReq(req, schemas.projectId) + const { params } = parseReq(req, schemas.projectId) if (decoded.project_id.toString() !== params.project_id.toString()) { const err = new Error('Wrong project_id') err.statusCode = HTTPStatus.FORBIDDEN diff --git a/services/notifications/app/js/NotificationsController.ts b/services/notifications/app/js/NotificationsController.ts index 1109ec8164..08e36acbcc 100644 --- a/services/notifications/app/js/NotificationsController.ts +++ b/services/notifications/app/js/NotificationsController.ts @@ -2,7 +2,7 @@ import logger from '@overleaf/logger' import metrics from '@overleaf/metrics' import Notifications from './Notifications.js' import { expressify } from '@overleaf/promise-utils' -import { validateReq, z, zz } from '@overleaf/validation-tools' +import { parseReq, z, zz } from '@overleaf/validation-tools' import type { Request, Response } from 'express' const getUserNotificationsSchema = z.object({ @@ -12,7 +12,7 @@ const getUserNotificationsSchema = z.object({ }) async function getUserNotifications(req: Request, res: Response) { - const { params } = validateReq(req, getUserNotificationsSchema) + const { params } = parseReq(req, getUserNotificationsSchema) logger.debug({ userId: params.user_id }, 'getting user unread notifications') metrics.inc('getUserNotifications') const notifications = await Notifications.getUserNotifications(params.user_id) @@ -27,7 +27,7 @@ const addNotificationSchema = z.object({ }) async function addNotification(req: Request, res: Response) { - const { params, body } = validateReq(req, addNotificationSchema) + const { params, body } = parseReq(req, addNotificationSchema) logger.debug( { userId: params.user_id, notification: body }, 'adding notification' @@ -49,7 +49,7 @@ const removeNotificationIdSchema = z.object({ }) async function removeNotificationId(req: Request, res: Response) { - const { params } = validateReq(req, removeNotificationIdSchema) + const { params } = parseReq(req, removeNotificationIdSchema) logger.debug( { userId: req.params.user_id, @@ -75,7 +75,7 @@ const removeNotificationKeySchema = z.object({ }) async function removeNotificationKey(req: Request, res: Response) { - const { params, body } = validateReq(req, removeNotificationKeySchema) + const { params, body } = parseReq(req, removeNotificationKeySchema) logger.debug( { userId: req.params.user_id, notificationKey: body.key }, 'mark key notification as read' @@ -93,7 +93,7 @@ const removeNotificationByKeyOnlySchema = z.object({ }) async function removeNotificationByKeyOnly(req: Request, res: Response) { - const { params } = validateReq(req, removeNotificationByKeyOnlySchema) + const { params } = parseReq(req, removeNotificationByKeyOnlySchema) const notificationKey = params.key logger.debug({ notificationKey }, 'mark notification as read by key only') metrics.inc('removeNotificationKey') @@ -108,7 +108,7 @@ const countNotificationsByKeyOnlySchema = z.object({ }) async function countNotificationsByKeyOnly(req: Request, res: Response) { - const { params } = validateReq(req, countNotificationsByKeyOnlySchema) + const { params } = parseReq(req, countNotificationsByKeyOnlySchema) const notificationKey = params.key try { const count = @@ -130,10 +130,7 @@ async function deleteUnreadNotificationsByKeyOnlyBulk( req: Request, res: Response ) { - const { params } = validateReq( - req, - deleteUnreadNotificationsByKeyOnlyBulkSchema - ) + const { params } = parseReq(req, deleteUnreadNotificationsByKeyOnlyBulkSchema) const notificationKey = params.key try { const count = diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs index cf31f5804e..6441a4b8b9 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs @@ -15,7 +15,7 @@ import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs' import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs' import LimitationsManager from '../Subscription/LimitationsManager.mjs' import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import Features from '../../infrastructure/Features.mjs' const { hasAdminAccess } = AdminAuthorizationHelper @@ -93,7 +93,7 @@ const setCollaboratorInfoSchema = z.object({ async function setCollaboratorInfo(req, res, next) { try { - const { params, body } = validateReq(req, setCollaboratorInfoSchema) + const { params, body } = parseReq(req, setCollaboratorInfoSchema) const projectId = params.Project_id const userId = params.user_id const { privilegeLevel } = body @@ -143,7 +143,7 @@ const transferOwnershipSchema = z.object({ async function transferOwnership(req, res, next) { const sessionUser = SessionManager.getSessionUser(req.session) - const { params, body } = validateReq(req, transferOwnershipSchema) + const { params, body } = parseReq(req, transferOwnershipSchema) const projectId = params.Project_id const toUserId = body.user_id try { diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs index 06e4e3a55e..28cd74e343 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs @@ -11,7 +11,7 @@ import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs' import AnalyticsManager from '../Analytics/AnalyticsManager.mjs' import SessionManager from '../Authentication/SessionManager.mjs' import { RateLimiter } from '../../infrastructure/RateLimiter.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import { expressify } from '@overleaf/promise-utils' import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs' import Errors from '../Errors/Errors.js' @@ -96,7 +96,7 @@ const inviteToProjectSchema = z.object({ }) async function inviteToProject(req, res) { - const { params, body } = validateReq(req, inviteToProjectSchema) + const { params, body } = parseReq(req, inviteToProjectSchema) const projectId = params.Project_id let { email, privileges } = body const sendingUser = SessionManager.getSessionUser(req.session) diff --git a/services/web/app/src/Features/Compile/CompileController.mjs b/services/web/app/src/Features/Compile/CompileController.mjs index 0f23c340fb..0da893013f 100644 --- a/services/web/app/src/Features/Compile/CompileController.mjs +++ b/services/web/app/src/Features/Compile/CompileController.mjs @@ -23,7 +23,7 @@ import { } from '@overleaf/fetch-utils' import Features from '../../infrastructure/Features.mjs' -const { z, zz, validateReq } = Validation +const { z, zz, parseReq } = Validation const ClsiCookieManager = ClsiCookieManagerFactory( Settings.apis.clsi?.backendGroupName ) @@ -358,7 +358,7 @@ const _CompileController = { }, async deleteAuxFiles(req, res) { - const { params, query } = validateReq(req, deleteAuxFilesSchema) + const { params, query } = parseReq(req, deleteAuxFilesSchema) const projectId = params.Project_id const { clsiserverid } = query const userId = await CompileController._getUserIdForCompile(req) @@ -625,7 +625,7 @@ const _CompileController = { }, async wordCount(req, res) { - const { params, query } = validateReq(req, wordCountSchema) + const { params, query } = parseReq(req, wordCountSchema) const projectId = params.Project_id const file = query.file || false const { clsiserverid } = query diff --git a/services/web/app/src/Features/Editor/EditorHttpController.mjs b/services/web/app/src/Features/Editor/EditorHttpController.mjs index aefe529e05..95eec08588 100644 --- a/services/web/app/src/Features/Editor/EditorHttpController.mjs +++ b/services/web/app/src/Features/Editor/EditorHttpController.mjs @@ -11,7 +11,7 @@ import Errors from '../Errors/Errors.js' import { expressify } from '@overleaf/promise-utils' import Settings from '@overleaf/settings' import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' const ProjectAccess = CollaboratorsGetter.ProjectAccess @@ -39,7 +39,7 @@ const joinProjectSchema = z.object({ }) async function joinProject(req, res, next) { - const { params, body } = validateReq(req, joinProjectSchema) + const { params, body } = parseReq(req, joinProjectSchema) const projectId = params.Project_id let userId = body.userId if (userId === 'anonymous-user') { diff --git a/services/web/app/src/Features/History/HistoryController.mjs b/services/web/app/src/Features/History/HistoryController.mjs index 71fd824cdd..7d8c8a03aa 100644 --- a/services/web/app/src/Features/History/HistoryController.mjs +++ b/services/web/app/src/Features/History/HistoryController.mjs @@ -25,7 +25,7 @@ import ProjectEntityUpdateHandler from '../Project/ProjectEntityUpdateHandler.mj import RestoreManager from './RestoreManager.mjs' import { prepareZipAttachment } from '../../infrastructure/Response.mjs' import Features from '../../infrastructure/Features.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs' // Number of seconds after which the browser should send a request to revalidate @@ -57,7 +57,7 @@ const requestBlobSchema = z.object({ }) async function requestBlob(method, req, res) { - const { params } = validateReq(req, requestBlobSchema) + const { params } = parseReq(req, requestBlobSchema) const { project_id: projectId, hash } = params // Handle conditional GET request @@ -535,7 +535,7 @@ const getLatestHistorySchema = z.object({ }) async function getLatestHistory(req, res, next) { - const { params } = validateReq(req, getLatestHistorySchema) + const { params } = parseReq(req, getLatestHistorySchema) const projectId = params.project_id const history = await HistoryManager.promises.getLatestHistory(projectId) res.json(history) @@ -552,7 +552,7 @@ const getChangesSchema = z.object({ }) async function getChanges(req, res, next) { - const { params, query } = validateReq(req, getChangesSchema) + const { params, query } = parseReq(req, getChangesSchema) const projectId = params.project_id let since = query.since // TODO: Transition flag; remove after a while diff --git a/services/web/app/src/Features/LinkedFiles/LinkedFilesController.mjs b/services/web/app/src/Features/LinkedFiles/LinkedFilesController.mjs index 696cbc7db5..8a0a465a9d 100644 --- a/services/web/app/src/Features/LinkedFiles/LinkedFilesController.mjs +++ b/services/web/app/src/Features/LinkedFiles/LinkedFilesController.mjs @@ -22,7 +22,7 @@ import { } from '../Errors/Errors.js' import Modules from '../../infrastructure/Modules.mjs' import { plainTextResponse } from '../../infrastructure/Response.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs' import { expressify } from '@overleaf/promise-utils' import ProjectOutputFileAgent from './ProjectOutputFileAgent.mjs' @@ -60,7 +60,7 @@ const createLinkedFileSchema = z.object({ }) async function createLinkedFile(req, res, next) { - const { params, body } = validateReq(req, createLinkedFileSchema) + const { params, body } = parseReq(req, createLinkedFileSchema) const { project_id: projectId } = params const { name, provider, data, parent_folder_id: parentFolderId } = body const userId = SessionManager.getLoggedInUserId(req.session) diff --git a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs index 57a1e3874e..24d00c78a3 100644 --- a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs +++ b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs @@ -8,7 +8,7 @@ import UserSessionsManager from '../User/UserSessionsManager.mjs' import OError from '@overleaf/o-error' import EmailsHelper from '../Helpers/EmailHelper.mjs' import { expressify } from '@overleaf/promise-utils' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs' const setNewUserPasswordSchema = z.object({ @@ -21,7 +21,7 @@ const setNewUserPasswordSchema = z.object({ async function setNewUserPassword(req, res, next) { let user - const { body } = validateReq(req, setNewUserPasswordSchema) + const { body } = parseReq(req, setNewUserPasswordSchema) let { passwordResetToken, password, email } = body if (!passwordResetToken || !password) { return res.status(400).json({ @@ -120,7 +120,7 @@ const requestResetSchema = z.object({ }) async function requestReset(req, res, next) { - const { body } = validateReq(req, requestResetSchema) + const { body } = parseReq(req, requestResetSchema) const email = EmailsHelper.parseEmail(body.email) if (!email) { return res.status(400).json({ @@ -173,7 +173,7 @@ const renderSetPasswordFormSchema = z.object({ }) async function renderSetPasswordForm(req, res, next) { - const { query } = validateReq(req, renderSetPasswordFormSchema) + const { query } = parseReq(req, renderSetPasswordFormSchema) if (query.passwordResetToken != null) { try { @@ -244,7 +244,7 @@ const renderRequestResetFormSchema = z.object({ }) async function renderRequestResetForm(req, res) { - const { query } = validateReq(req, renderRequestResetFormSchema) + const { query } = parseReq(req, renderRequestResetFormSchema) const errorQuery = query.error let error = null if (errorQuery === 'token_expired') { diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs index 2c1eb2c255..ecbc0136c8 100644 --- a/services/web/app/src/Features/Project/ProjectController.mjs +++ b/services/web/app/src/Features/Project/ProjectController.mjs @@ -46,7 +46,7 @@ import TagsHandler from '../Tags/TagsHandler.mjs' import TutorialHandler from '../Tutorial/TutorialHandler.mjs' import UserUpdater from '../User/UserUpdater.mjs' import Modules from '../../infrastructure/Modules.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import UserGetter from '../User/UserGetter.mjs' import { isStandaloneAiAddOnPlanCode } from '../Subscription/AiHelper.mjs' import SubscriptionController from '../Subscription/SubscriptionController.mjs' @@ -100,7 +100,7 @@ const _ProjectController = { }, async updateProjectSettings(req, res) { - const { params, body } = validateReq(req, updateProjectSettingsSchema) + const { params, body } = parseReq(req, updateProjectSettingsSchema) const projectId = params.Project_id if (body.compiler != null) { @@ -137,7 +137,7 @@ const _ProjectController = { }, async updateProjectAdminSettings(req, res) { - const { params, body } = validateReq(req, updateProjectAdminSettingsSchema) + const { params, body } = parseReq(req, updateProjectAdminSettingsSchema) const projectId = params.Project_id const user = SessionManager.getSessionUser(req.session) if (!Features.hasFeature('link-sharing')) { diff --git a/services/web/app/src/Features/Spelling/SpellingController.mjs b/services/web/app/src/Features/Spelling/SpellingController.mjs index 2e55ad5691..1ad42655f3 100644 --- a/services/web/app/src/Features/Spelling/SpellingController.mjs +++ b/services/web/app/src/Features/Spelling/SpellingController.mjs @@ -2,7 +2,7 @@ import SessionManager from '../Authentication/SessionManager.mjs' import LearnedWordsManager from './LearnedWordsManager.mjs' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' const learnSchema = z.object({ body: z.object({ @@ -18,7 +18,7 @@ const unlearnSchema = z.object({ export default { learn(req, res, next) { - const { body } = validateReq(req, learnSchema) + const { body } = parseReq(req, learnSchema) const { word } = body const userId = SessionManager.getLoggedInUserId(req.session) LearnedWordsManager.learnWord(userId, word, err => { @@ -28,7 +28,7 @@ export default { }, unlearn(req, res, next) { - const { body } = validateReq(req, unlearnSchema) + const { body } = parseReq(req, unlearnSchema) const { word } = body const userId = SessionManager.getLoggedInUserId(req.session) LearnedWordsManager.unlearnWord(userId, word, err => { diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.mjs b/services/web/app/src/Features/Subscription/SubscriptionController.mjs index 02038a3a51..42a7ab9cf1 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionController.mjs @@ -32,7 +32,7 @@ import { User } from '../../models/User.mjs' import UserGetter from '../User/UserGetter.mjs' import PermissionsManager from '../Authorization/PermissionsManager.mjs' import { sanitizeSessionUserForFrontEnd } from '../../infrastructure/FrontEndUser.mjs' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' import { IndeterminateInvoiceError } from '../Errors/Errors.js' import SubscriptionLocator from './SubscriptionLocator.mjs' @@ -407,7 +407,7 @@ const pauseSubscriptionSchema = z.object({ async function pauseSubscription(req, res, next) { const user = SessionManager.getSessionUser(req.session) - const { params } = validateReq(req, pauseSubscriptionSchema) + const { params } = parseReq(req, pauseSubscriptionSchema) const pauseCycles = params.pauseCycles if (pauseCycles < 0) { return HttpErrorHandler.badRequest( @@ -631,7 +631,7 @@ const purchaseAddonSchema = z.object({ async function purchaseAddon(req, res, next) { const user = SessionManager.getSessionUser(req.session) - const { params } = validateReq(req, purchaseAddonSchema) + const { params } = parseReq(req, purchaseAddonSchema) const addOnCode = params.addOnCode // currently we only support having a quantity of 1 const quantity = 1 @@ -716,7 +716,7 @@ const removeAddonSchema = z.object({ async function removeAddon(req, res, next) { const user = SessionManager.getSessionUser(req.session) - const { params } = validateReq(req, removeAddonSchema) + const { params } = parseReq(req, removeAddonSchema) const addOnCode = params.addOnCode if (addOnCode !== AI_ADD_ON_CODE) { @@ -761,7 +761,7 @@ const reactivateAddonSchema = z.object({ */ async function reactivateAddon(req, res) { const user = SessionManager.getSessionUser(req.session) - const { params } = validateReq(req, reactivateAddonSchema) + const { params } = parseReq(req, reactivateAddonSchema) const addOnCode = params.addOnCode if (addOnCode !== AI_ADD_ON_CODE) { diff --git a/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs b/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs index 208c12f72f..9b67a0ad38 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs @@ -9,7 +9,7 @@ import { expressify } from '@overleaf/promise-utils' import Modules from '../../infrastructure/Modules.mjs' import UserGetter from '../User/UserGetter.mjs' import { Subscription } from '../../models/Subscription.mjs' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' import { isProfessionalGroupPlan } from './PlansHelper.mjs' import { MissingBillingInfoError, @@ -215,7 +215,7 @@ const previewAddSeatsSubscriptionChangeSchema = z.object({ * @returns {Promise} */ async function previewAddSeatsSubscriptionChange(req, res) { - const { body } = validateReq(req, previewAddSeatsSubscriptionChangeSchema) + const { body } = parseReq(req, previewAddSeatsSubscriptionChangeSchema) try { const userId = SessionManager.getLoggedInUserId(req.session) const preview = @@ -311,7 +311,7 @@ const submitFormSchema = z.object({ }) async function submitForm(req, res) { - const { body } = validateReq(req, submitFormSchema) + const { body } = parseReq(req, submitFormSchema) const { adding, poNumber } = body const userId = SessionManager.getLoggedInUserId(req.session) diff --git a/services/web/app/src/Features/Tags/TagsController.mjs b/services/web/app/src/Features/Tags/TagsController.mjs index 873f7ea0e5..9c6ac6b368 100644 --- a/services/web/app/src/Features/Tags/TagsController.mjs +++ b/services/web/app/src/Features/Tags/TagsController.mjs @@ -1,7 +1,7 @@ import TagsHandler from './TagsHandler.mjs' import SessionManager from '../Authentication/SessionManager.mjs' import Errors from '../Errors/Errors.js' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' import { expressify } from '@overleaf/promise-utils' async function _getTags(userId, _req, res) { @@ -30,7 +30,7 @@ const createTagSchema = z.object({ }) async function createTag(req, res) { - const { body } = validateReq(req, createTagSchema) + const { body } = parseReq(req, createTagSchema) const { name, color } = body const userId = SessionManager.getLoggedInUserId(req.session) const tag = await TagsHandler.promises.createTag(userId, name, color) @@ -54,7 +54,7 @@ const addProjectsToTagSchema = z.object({ }) async function addProjectsToTag(req, res) { - const { params, body } = validateReq(req, addProjectsToTagSchema) + const { params, body } = parseReq(req, addProjectsToTagSchema) const { tagId } = params const { projectIds } = body const userId = SessionManager.getLoggedInUserId(req.session) @@ -79,7 +79,7 @@ const removeProjectsFromTagSchema = z.object({ }) async function removeProjectsFromTag(req, res, next) { - const { params, body } = validateReq(req, removeProjectsFromTagSchema) + const { params, body } = parseReq(req, removeProjectsFromTagSchema) const { tagId } = params const { projectIds } = body const userId = SessionManager.getLoggedInUserId(req.session) @@ -104,7 +104,7 @@ const renameTagSchema = z.object({ }) async function renameTag(req, res) { - const { params, body } = validateReq(req, renameTagSchema) + const { params, body } = parseReq(req, renameTagSchema) const userId = SessionManager.getLoggedInUserId(req.session) const { tagId } = params const name = body.name @@ -126,7 +126,7 @@ const editTagSchema = z.object({ }) async function editTag(req, res) { - const { params, body } = validateReq(req, editTagSchema) + const { params, body } = parseReq(req, editTagSchema) const { tagId } = params const name = body.name const color = body.color diff --git a/services/web/app/src/Features/User/UserController.mjs b/services/web/app/src/Features/User/UserController.mjs index 8967fe075e..ac1ca8870b 100644 --- a/services/web/app/src/Features/User/UserController.mjs +++ b/services/web/app/src/Features/User/UserController.mjs @@ -8,7 +8,7 @@ import metrics from '@overleaf/metrics' import AuthenticationManager from '../Authentication/AuthenticationManager.mjs' import SessionManager from '../Authentication/SessionManager.mjs' import Features from '../../infrastructure/Features.mjs' -import { z, validateReq } from '../../infrastructure/Validation.mjs' +import { z, parseReq } from '../../infrastructure/Validation.mjs' import UserAuditLogHandler from './UserAuditLogHandler.mjs' import UserSessionsManager from './UserSessionsManager.mjs' import UserUpdater from './UserUpdater.mjs' @@ -340,7 +340,7 @@ const updateUserSettingsSchema = z.object({ }) async function updateUserSettings(req, res, next) { - const { body } = validateReq(req, updateUserSettingsSchema) + const { body } = parseReq(req, updateUserSettingsSchema) const userId = SessionManager.getLoggedInUserId(req.session) req.logger.addFields({ userId }) diff --git a/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs b/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs index 13289c0096..06d9e79068 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs +++ b/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs @@ -10,7 +10,7 @@ import EntityConfigs from './UserMembershipEntityConfigs.mjs' import Errors from '../Errors/Errors.js' import HttpErrorHandler from '../Errors/HttpErrorHandler.mjs' import TemplatesManager from '../Templates/TemplatesManager.mjs' -import { z, zz, validateReq } from '../../infrastructure/Validation.mjs' +import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs' const { useAdminCapabilities } = AdminAuthorizationHelper @@ -283,7 +283,7 @@ const fetchEntitySchema = z.discriminatedUnion('entityName', [ // fetch the entity with id and config, and set it in the request function fetchEntity() { return expressify(async (req, res, next) => { - const { params } = validateReq(req, fetchEntitySchema) + const { params } = parseReq(req, fetchEntitySchema) req.entity = await UserMembershipHandler.promises.getEntityWithoutAuthorizationCheck( params.id, diff --git a/services/web/app/src/infrastructure/Validation.mjs b/services/web/app/src/infrastructure/Validation.mjs index 930eb21aa3..c0bd79e28d 100644 --- a/services/web/app/src/infrastructure/Validation.mjs +++ b/services/web/app/src/infrastructure/Validation.mjs @@ -3,7 +3,7 @@ import { NotFoundError } from '../Features/Errors/Errors.js' import { - validateReq as validateReqBase, + parseReq as parseReqBase, z, zz, ParamsError, @@ -11,9 +11,9 @@ import { export { z, zz } from '@overleaf/validation-tools' -export const validateReq = (req, schema) => { +export const parseReq = (req, schema) => { try { - return validateReqBase(req, schema) + return parseReqBase(req, schema) } catch (err) { if (err instanceof ParamsError) { // convert into a NotFoundError that web understands @@ -24,7 +24,7 @@ export const validateReq = (req, schema) => { } export default { - validateReq, + parseReq, z, zz, }