Files
overleaf-cep/services/web/app/src/Features/History/HistoryRouter.mjs
T
Eric Mc Sween dd526693f5 Merge pull request #24775 from overleaf/em-bypass-project-history
Call history-v1 directly for latest history and changes

GitOrigin-RevId: 39c32dd50ff7875f82bbb2716da753a9c3e6e81d
2025-04-11 08:05:56 +00:00

180 lines
5.3 KiB
JavaScript

// @ts-check
import Settings from '@overleaf/settings'
import { Joi, validate } from '../../infrastructure/Validation.js'
import { RateLimiter } from '../../infrastructure/RateLimiter.js'
import AuthenticationController from '../Authentication/AuthenticationController.js'
import AuthorizationMiddleware from '../Authorization/AuthorizationMiddleware.js'
import RateLimiterMiddleware from '../Security/RateLimiterMiddleware.js'
import HistoryController from './HistoryController.js'
const rateLimiters = {
downloadProjectRevision: new RateLimiter('download-project-revision', {
points: 30,
duration: 60 * 60,
}),
getProjectBlob: new RateLimiter('get-project-blob', {
// Download project in full once per hour
points: Settings.maxEntitiesPerProject,
duration: 60 * 60,
}),
flushHistory: new RateLimiter('flush-project-history', {
points: 30,
duration: 60,
}),
}
function apply(webRouter, privateApiRouter) {
// Blobs
webRouter.head(
'/project/:project_id/blob/:hash',
validate({
params: Joi.object({
project_id: Joi.objectId().required(),
hash: Joi.string().required().hex().length(40),
}),
query: Joi.object({
fallback: Joi.objectId().optional(),
}),
}),
RateLimiterMiddleware.rateLimit(rateLimiters.getProjectBlob),
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.headBlob
)
webRouter.get(
'/project/:project_id/blob/:hash',
validate({
params: Joi.object({
project_id: Joi.objectId().required(),
hash: Joi.string().required().hex().length(40),
}),
query: Joi.object({
fallback: Joi.objectId().optional(),
}),
}),
RateLimiterMiddleware.rateLimit(rateLimiters.getProjectBlob),
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.getBlob
)
// History diffs
webRouter.get(
'/project/:Project_id/updates',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.proxyToHistoryApiAndInjectUserDetails
)
webRouter.get(
'/project/:Project_id/doc/:doc_id/diff',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.proxyToHistoryApi
)
webRouter.get(
'/project/:Project_id/diff',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.proxyToHistoryApiAndInjectUserDetails
)
webRouter.get(
'/project/:Project_id/filetree/diff',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.proxyToHistoryApi
)
// File and project restore
webRouter.post(
'/project/:project_id/restore_file',
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
HistoryController.restoreFileFromV2
)
webRouter.post(
'/project/:project_id/revert_file',
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
HistoryController.revertFile
)
webRouter.post(
'/project/:project_id/revert-project',
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
HistoryController.revertProject
)
// History download
webRouter.get(
'/project/:project_id/version/:version/zip',
RateLimiterMiddleware.rateLimit(rateLimiters.downloadProjectRevision),
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.downloadZipOfVersion
)
// History flush and resync
webRouter.post(
'/project/:Project_id/flush',
RateLimiterMiddleware.rateLimit(rateLimiters.flushHistory),
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.proxyToHistoryApi
)
privateApiRouter.post(
'/project/:Project_id/history/resync',
AuthenticationController.requirePrivateApiAuth(),
HistoryController.resyncProjectHistory
)
// History labels
webRouter.get(
'/project/:Project_id/labels',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.getLabels
)
webRouter.post(
'/project/:Project_id/labels',
AuthorizationMiddleware.ensureUserCanWriteOrReviewProjectContent,
HistoryController.createLabel
)
webRouter.delete(
'/project/:Project_id/labels/:label_id',
AuthorizationMiddleware.ensureUserCanWriteOrReviewProjectContent,
HistoryController.deleteLabel
)
// History snapshot
webRouter.get(
'/project/:project_id/latest/history',
validate({
params: Joi.object({
project_id: Joi.objectId().required(),
}),
}),
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.getLatestHistory
)
webRouter.get(
'/project/:project_id/changes',
validate({
params: Joi.object({
project_id: Joi.objectId().required(),
}),
query: Joi.object({
since: Joi.number().integer().min(0).optional(),
}),
}),
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
HistoryController.getChanges
)
}
export default { apply }