mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
[web] enforce size limit on individual files when cloning project (#35211)
* [web] enforce size limit on individual files when cloning project Co-authored-by: Brian Gough <brian.gough@overleaf.com> * [web] improve test coverage * [agents] speed up running frontend tests * [web] gracefully handle project too large error --------- Co-authored-by: Brian Gough <brian.gough@overleaf.com> GitOrigin-RevId: c7b35a3a9688e15a9bb51c61816da82d39e0d29d
This commit is contained in:
committed by
Copybot
co-authored by
Brian Gough
parent
f62bd990d4
commit
84c6a68eae
@@ -14,7 +14,11 @@ import ProjectGetter from '../Project/ProjectGetter.mjs'
|
||||
import HistoryBackupDeletionHandler from './HistoryBackupDeletionHandler.mjs'
|
||||
import { db, waitForDb } from '../../infrastructure/mongodb.mjs'
|
||||
import Metrics from '@overleaf/metrics'
|
||||
import { NotFoundError, HistoryResyncPendingError } from '../Errors/Errors.js'
|
||||
import {
|
||||
NotFoundError,
|
||||
HistoryResyncPendingError,
|
||||
FileTooLargeError,
|
||||
} from '../Errors/Errors.js'
|
||||
|
||||
const HISTORY_V1_URL = settings.apis.v1_history.url
|
||||
const HISTORY_V1_BASIC_AUTH = {
|
||||
@@ -173,15 +177,27 @@ async function uploadBlobFromDisk(historyId, hash, byteLength, fsPath) {
|
||||
})
|
||||
}
|
||||
|
||||
async function copyBlob(sourceHistoryId, targetHistoryId, hash) {
|
||||
const url = `${HISTORY_V1_URL}/projects/${targetHistoryId}/blobs/${hash}`
|
||||
await fetchNothing(
|
||||
`${url}?${new URLSearchParams({ copyFrom: sourceHistoryId })}`,
|
||||
{
|
||||
async function copyBlob(sourceHistoryId, targetHistoryId, hash, sizeLimit) {
|
||||
const url = new URL(
|
||||
`${HISTORY_V1_URL}/projects/${targetHistoryId}/blobs/${hash}`
|
||||
)
|
||||
url.searchParams.set('copyFrom', sourceHistoryId)
|
||||
if (sizeLimit) url.searchParams.set('sizeLimit', sizeLimit)
|
||||
try {
|
||||
await fetchNothing(url, {
|
||||
method: 'POST',
|
||||
basicAuth: HISTORY_V1_BASIC_AUTH,
|
||||
})
|
||||
} catch (err) {
|
||||
if (err instanceof RequestFailedError && err.response.status === 413) {
|
||||
let size
|
||||
try {
|
||||
;({ size } = JSON.parse(err.body))
|
||||
} catch {}
|
||||
throw new FileTooLargeError('file too large', { size })
|
||||
}
|
||||
)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async function requestBlobWithProjectId(
|
||||
|
||||
@@ -57,6 +57,7 @@ import UserSettingsHelper from './UserSettingsHelper.mjs'
|
||||
import AiFeatureUsageRateLimiter from '../../infrastructure/rate-limiters/AiFeatureUsageRateLimiter.mjs'
|
||||
import WorkbenchRateLimiter from '../../infrastructure/rate-limiters/WorkbenchRateLimiter.mjs'
|
||||
import PermissionsManager from '../Authorization/PermissionsManager.mjs'
|
||||
import { FileTooLargeError } from '../Errors/Errors.js'
|
||||
|
||||
const { checkUserPermissions } = PermissionsManager.promises
|
||||
const { isPaidSubscription } = SubscriptionHelper
|
||||
@@ -309,6 +310,17 @@ const _ProjectController = {
|
||||
projectId,
|
||||
userId: currentUser._id,
|
||||
})
|
||||
const { path, size } = OError.getFullInfo(err)
|
||||
if (err instanceof FileTooLargeError && path) {
|
||||
res.status(413).json({
|
||||
message: {
|
||||
text: 'file too large to copy',
|
||||
key: 'file_too_large_to_copy',
|
||||
info: { path, size },
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
return next(err)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { callbackify } from 'node:util'
|
||||
import Path from 'node:path'
|
||||
import logger from '@overleaf/logger'
|
||||
import Settings from '@overleaf/settings'
|
||||
import OError from '@overleaf/o-error'
|
||||
import { promiseMapWithLimit } from '@overleaf/promise-utils'
|
||||
import { Doc } from '../../models/Doc.mjs'
|
||||
@@ -332,11 +333,13 @@ async function _copyFiles(
|
||||
await HistoryManager.promises.copyBlob(
|
||||
sourceHistoryId,
|
||||
targetHistoryId,
|
||||
file.hash
|
||||
file.hash,
|
||||
Settings.maxUploadSize
|
||||
)
|
||||
return { createdBlob: true, file, path }
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'unexpected error copying blob', {
|
||||
path: path.replace(/^\//, ''),
|
||||
sourceProjectId: sourceProject._id,
|
||||
targetProjectId: targetProject._id,
|
||||
sourceFile,
|
||||
|
||||
Reference in New Issue
Block a user