[filestore] remove user files endpoints (#28125)

* [filestore] remove user files endpoints

* [web] remove user files integration for filestore

GitOrigin-RevId: 565fa68a659c07420ee6141d0f276b4e4d2972e0
This commit is contained in:
Jakob Ackermann
2025-09-02 08:04:52 +00:00
committed by Copybot
parent 2036947981
commit bd4130c147
73 changed files with 1481 additions and 3587 deletions
@@ -10,10 +10,6 @@ module.exports = {
getFile,
getFileHead,
insertFile,
copyFile,
deleteFile,
deleteProject,
directorySize,
}
function getFile(req, res, next) {
@@ -125,85 +121,6 @@ function insertFile(req, res, next) {
})
}
function copyFile(req, res, next) {
metrics.inc('copyFile')
const { key, bucket } = req
const oldProjectId = req.body.source.project_id
const oldFileId = req.body.source.file_id
req.requestLogger.addFields({
key,
bucket,
oldProject_id: oldProjectId,
oldFile_id: oldFileId,
})
req.requestLogger.setMessage('copying file')
FileHandler.copyObject(bucket, `${oldProjectId}/${oldFileId}`, key, err => {
if (err) {
if (err instanceof Errors.NotFoundError) {
res.sendStatus(404)
} else {
next(err)
}
} else {
res.sendStatus(200)
}
})
}
function deleteFile(req, res, next) {
metrics.inc('deleteFile')
const { key, bucket } = req
req.requestLogger.addFields({ key, bucket })
req.requestLogger.setMessage('deleting file')
FileHandler.deleteFile(bucket, key, function (err) {
if (err) {
next(err)
} else {
res.sendStatus(204)
}
})
}
function deleteProject(req, res, next) {
metrics.inc('deleteProject')
const { key, bucket } = req
req.requestLogger.setMessage('deleting project')
req.requestLogger.addFields({ key, bucket })
FileHandler.deleteProject(bucket, key, function (err) {
if (err) {
if (err instanceof Errors.InvalidParametersError) {
return res.sendStatus(400)
}
next(err)
} else {
res.sendStatus(204)
}
})
}
function directorySize(req, res, next) {
metrics.inc('projectSize')
const { project_id: projectId, bucket } = req
req.requestLogger.setMessage('getting project size')
req.requestLogger.addFields({ projectId, bucket })
FileHandler.getDirectorySize(bucket, projectId, function (err, size) {
if (err) {
return next(err)
}
res.json({ 'total bytes': size })
req.requestLogger.addFields({ size })
})
}
function _getRange(header) {
const parsed = parseRange(maxSizeInBytes, header)
if (parsed === -1 || parsed === -2 || parsed.type !== 'bytes') {
+3 -46
View File
@@ -10,23 +10,15 @@ const { ConversionError, InvalidParametersError } = require('./Errors')
const metrics = require('@overleaf/metrics')
module.exports = {
copyObject: callbackify(copyObject),
insertFile: callbackify(insertFile),
deleteFile: callbackify(deleteFile),
deleteProject: callbackify(deleteProject),
getFile: callbackify(getFile),
getRedirectUrl: callbackify(getRedirectUrl),
getFileSize: callbackify(getFileSize),
getDirectorySize: callbackify(getDirectorySize),
promises: {
copyObject,
getFile,
getRedirectUrl,
insertFile,
deleteFile,
deleteProject,
getFileSize,
getDirectorySize,
},
}
@@ -36,13 +28,11 @@ if (process.env.NODE_ENV === 'test') {
}
}
async function copyObject(bucket, sourceKey, destinationKey) {
await PersistorManager.copyObject(bucket, sourceKey, destinationKey)
}
async function insertFile(bucket, key, stream) {
const convertedKey = KeyBuilder.getConvertedFolderKey(key)
if (!convertedKey.match(/^[0-9a-f]{24}\/([0-9a-f]{24}|v\/[0-9]+\/[a-z]+)/i)) {
if (
!convertedKey.match(/^[0-9a-f]{24}\/([0-9a-f]{24}|v\/[0-9]+\/[a-z0-9]+)/i)
) {
throw new InvalidParametersError('key does not match validation regex', {
bucket,
key,
@@ -52,35 +42,6 @@ async function insertFile(bucket, key, stream) {
await PersistorManager.sendStream(bucket, key, stream)
}
async function deleteFile(bucket, key) {
const convertedKey = KeyBuilder.getConvertedFolderKey(key)
if (!convertedKey.match(/^[0-9a-f]{24}\/([0-9a-f]{24}|v\/[0-9]+\/[a-z]+)/i)) {
throw new InvalidParametersError('key does not match validation regex', {
bucket,
key,
convertedKey,
})
}
const jobs = [PersistorManager.deleteObject(bucket, key)]
if (
Settings.enableConversions &&
bucket === Settings.filestore.stores.template_files
) {
jobs.push(PersistorManager.deleteDirectory(bucket, convertedKey))
}
await Promise.all(jobs)
}
async function deleteProject(bucket, key) {
if (!key.match(/^[0-9a-f]{24}\//i)) {
throw new InvalidParametersError('key does not match validation regex', {
bucket,
key,
})
}
await PersistorManager.deleteDirectory(bucket, key)
}
async function getFile(bucket, key, opts) {
opts = opts || {}
if (!opts.format && !opts.style) {
@@ -129,10 +90,6 @@ async function getFileSize(bucket, key) {
return await PersistorManager.getObjectSize(bucket, key)
}
async function getDirectorySize(bucket, projectId) {
return await PersistorManager.directorySize(bucket, projectId)
}
async function _getConvertedFile(bucket, key, opts) {
const convertedKey = KeyBuilder.addCachingToKey(key, opts)
const exists = await PersistorManager.checkIfObjectExists(
@@ -1,67 +0,0 @@
const fs = require('node:fs')
const path = require('node:path')
const Settings = require('@overleaf/settings')
const { WritableBuffer } = require('@overleaf/stream-utils')
const { promisify } = require('node:util')
const Stream = require('node:stream')
const pipeline = promisify(Stream.pipeline)
const fsCopy = promisify(fs.copyFile)
const fsUnlink = promisify(fs.unlink)
const { HealthCheckError } = require('./Errors')
const FileConverter = require('./FileConverter').promises
const FileHandler = require('./FileHandler').promises
async function checkCanGetFiles() {
if (!Settings.health_check) {
return
}
const projectId = Settings.health_check.project_id
const fileId = Settings.health_check.file_id
const key = `${projectId}/${fileId}`
const bucket = Settings.filestore.stores.user_files
const buffer = new WritableBuffer({ initialSize: 100 })
const sourceStream = await FileHandler.getFile(bucket, key, {})
try {
await pipeline(sourceStream, buffer)
} catch (err) {
throw new HealthCheckError('failed to get health-check file', {}, err)
}
if (!buffer.size()) {
throw new HealthCheckError('no bytes written to download stream')
}
}
async function checkFileConvert() {
if (!Settings.enableConversions) {
return
}
const imgPath = path.join(Settings.path.uploadFolder, '/tiny.pdf')
let resultPath
try {
await fsCopy('./tiny.pdf', imgPath)
resultPath = await FileConverter.thumbnail(imgPath)
} finally {
if (resultPath) {
await fsUnlink(resultPath)
}
await fsUnlink(imgPath)
}
}
module.exports = {
check(req, res, next) {
Promise.all([checkCanGetFiles(), checkFileConvert()])
.then(() => res.sendStatus(200))
.catch(err => {
next(err)
})
},
}
-17
View File
@@ -4,8 +4,6 @@ const projectKey = require('./project_key')
module.exports = {
getConvertedFolderKey,
addCachingToKey,
userFileKeyMiddleware,
userProjectKeyMiddleware,
bucketFileKeyMiddleware,
globalBlobFileKeyMiddleware,
projectBlobFileKeyMiddleware,
@@ -32,21 +30,6 @@ function addCachingToKey(key, opts) {
return key
}
function userFileKeyMiddleware(req, res, next) {
const { project_id: projectId, file_id: fileId } = req.params
req.key = `${projectId}/${fileId}`
req.bucket = settings.filestore.stores.user_files
next()
}
function userProjectKeyMiddleware(req, res, next) {
const { project_id: projectId } = req.params
req.project_id = projectId
req.key = `${projectId}/`
req.bucket = settings.filestore.stores.user_files
next()
}
function bucketFileKeyMiddleware(req, res, next) {
req.bucket = req.params.bucket
req.key = req.params[0]