Merge pull request #28670 from overleaf/td-rename-validate-req

Rename validateReq to parseReq

GitOrigin-RevId: a935aaa3f89495e164ce5d10b0bd80436571440f
This commit is contained in:
Tim Down
2026-01-14 10:53:20 +00:00
committed by Copybot
parent 6e5e53f4e6
commit 64da16f0d1
23 changed files with 99 additions and 102 deletions

View File

@@ -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,

View File

@@ -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<T>} 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 }

View File

@@ -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({

View File

@@ -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({

View File

@@ -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()

View File

@@ -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 => {

View File

@@ -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

View File

@@ -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 =

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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

View File

@@ -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') {

View File

@@ -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

View File

@@ -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)

View File

@@ -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') {

View File

@@ -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')) {

View File

@@ -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 => {

View File

@@ -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) {

View File

@@ -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<void>}
*/
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)

View File

@@ -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

View File

@@ -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 })

View File

@@ -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,

View File

@@ -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,
}