Explorar o código

Allow all files to be in zip (in same directory)

GitOrigin-RevId: 14645a0c3db88faf00e2718b9574b5892ac3efcb
andrew rumble %!s(int64=2) %!d(string=hai) anos
pai
achega
c764566148

+ 1 - 8
services/clsi/app/js/OutputController.js

@@ -2,20 +2,13 @@ const logger = require('@overleaf/logger')
 const OutputFileArchiveManager = require('./OutputFileArchiveManager')
 const OutputFileArchiveManager = require('./OutputFileArchiveManager')
 const { expressify } = require('@overleaf/promise-utils')
 const { expressify } = require('@overleaf/promise-utils')
 
 
-function cleanFiles(files) {
-  if (!Array.isArray(files)) {
-    return []
-  }
-  return files.filter(file => /^output\./g.test(file))
-}
-
 async function createOutputZip(req, res) {
 async function createOutputZip(req, res) {
   const {
   const {
     project_id: projectId,
     project_id: projectId,
     user_id: userId,
     user_id: userId,
     build_id: buildId,
     build_id: buildId,
   } = req.params
   } = req.params
-  const files = cleanFiles(req.query.files)
+  const files = Array.isArray(req.query.files) ? req.query.files : []
   logger.debug({ projectId, userId, buildId, files }, 'Will create zip file')
   logger.debug({ projectId, userId, buildId, files }, 'Will create zip file')
 
 
   const archive = await OutputFileArchiveManager.archiveFilesForBuild(
   const archive = await OutputFileArchiveManager.archiveFilesForBuild(

+ 13 - 15
services/clsi/app/js/OutputFileArchiveManager.js

@@ -4,7 +4,7 @@ const OutputCacheManager = require('./OutputCacheManager')
 const OutputFileFinder = require('./OutputFileFinder')
 const OutputFileFinder = require('./OutputFileFinder')
 const Settings = require('@overleaf/settings')
 const Settings = require('@overleaf/settings')
 const { open } = require('node:fs/promises')
 const { open } = require('node:fs/promises')
-const path = require('node:path')
+const path = require('path')
 const { NotFoundError } = require('./Errors')
 const { NotFoundError } = require('./Errors')
 
 
 function getContentDir(projectId, userId) {
 function getContentDir(projectId, userId) {
@@ -19,8 +19,6 @@ function getContentDir(projectId, userId) {
 
 
 module.exports = OutputFileArchiveManager = {
 module.exports = OutputFileArchiveManager = {
   async archiveFilesForBuild(projectId, userId, build, files = []) {
   async archiveFilesForBuild(projectId, userId, build, files = []) {
-    const contentDir = getContentDir(projectId, userId)
-
     const validFiles = await (files.length > 0
     const validFiles = await (files.length > 0
       ? this._getRequestedOutputFiles(projectId, userId, build, files)
       ? this._getRequestedOutputFiles(projectId, userId, build, files)
       : this._getAllOutputFiles(projectId, userId, build))
       : this._getAllOutputFiles(projectId, userId, build))
@@ -33,11 +31,9 @@ module.exports = OutputFileArchiveManager = {
 
 
     for (const file of validFiles) {
     for (const file of validFiles) {
       try {
       try {
-        const fileHandle = await open(
-          `${contentDir}${OutputCacheManager.path(build, file)}`
-        )
+        const fileHandle = await open(file, 'r')
         const fileStream = fileHandle.createReadStream()
         const fileStream = fileHandle.createReadStream()
-        archive.append(fileStream, { name: file })
+        archive.append(fileStream, { name: path.basename(file) })
       } catch (error) {
       } catch (error) {
         missingFiles.push(file)
         missingFiles.push(file)
       }
       }
@@ -63,7 +59,9 @@ module.exports = OutputFileArchiveManager = {
         `${contentDir}${OutputCacheManager.path(build, '.')}`
         `${contentDir}${OutputCacheManager.path(build, '.')}`
       )
       )
 
 
-      return outputFiles.map(({ path }) => path)
+      return outputFiles.map(
+        ({ path }) => `${contentDir}${OutputCacheManager.path(build, path)}`
+      )
     } catch (error) {
     } catch (error) {
       if (
       if (
         error.code === 'ENOENT' ||
         error.code === 'ENOENT' ||
@@ -77,14 +75,14 @@ module.exports = OutputFileArchiveManager = {
   },
   },
 
 
   async _getRequestedOutputFiles(projectId, userId, build, files) {
   async _getRequestedOutputFiles(projectId, userId, build, files) {
-    const outputFiles = new Set(
-      await OutputFileArchiveManager._getAllOutputFiles(
-        projectId,
-        userId,
-        build
-      )
+    const outputFiles = await OutputFileArchiveManager._getAllOutputFiles(
+      projectId,
+      userId,
+      build
     )
     )
 
 
-    return files.filter(file => outputFiles.has(file))
+    return files.filter(file =>
+      outputFiles.some(outputFile => file === path.basename(outputFile))
+    )
   },
   },
 }
 }

+ 1 - 11
services/clsi/test/unit/js/OutputControllerTests.js

@@ -37,23 +37,13 @@ describe('OutputController', function () {
             build_id: 'build-id-123',
             build_id: 'build-id-123',
           },
           },
           query: {
           query: {
-            files: ['output.tex', 'not-output.tex'],
+            files: ['output.tex'],
           },
           },
         }
         }
         this.archive.pipe.callsFake(() => done())
         this.archive.pipe.callsFake(() => done())
         this.OutputController.createOutputZip(this.req, this.res)
         this.OutputController.createOutputZip(this.req, this.res)
       })
       })
 
 
-      it('does not pass files that do not start with "output" to OutputFileArchiveManager', function () {
-        sinon.assert.calledWith(
-          this.archiveFilesForBuild,
-          'project-id-123',
-          'user-id-123',
-          'build-id-123',
-          ['output.tex']
-        )
-      })
-
       it('pipes the archive to the response', function () {
       it('pipes the archive to the response', function () {
         sinon.assert.calledWith(this.archive.pipe, this.res)
         sinon.assert.calledWith(this.archive.pipe, this.res)
       })
       })

+ 3 - 6
services/clsi/test/unit/js/OutputFileArchiveManagerTests.js

@@ -50,9 +50,6 @@ describe('OutputFileArchiveManager', function () {
         './OutputCacheManager': this.OutputCacheManger,
         './OutputCacheManager': this.OutputCacheManger,
         archiver: this.archiver,
         archiver: this.archiver,
         'node:fs/promises': this.fs,
         'node:fs/promises': this.fs,
-        'node:path': {
-          basename: sinon.stub().callsFake(path => path.split('/').pop()),
-        },
         '@overleaf/settings': {
         '@overleaf/settings': {
           path: {
           path: {
             outputDir: this.outputDir,
             outputDir: this.outputDir,
@@ -140,14 +137,14 @@ describe('OutputFileArchiveManager', function () {
       expect(this.archive.append.callCount).to.equal(2)
       expect(this.archive.append.callCount).to.equal(2)
       sinon.assert.calledWith(
       sinon.assert.calledWith(
         this.archive.append,
         this.archive.append,
-        `handle: ${this.outputDir}/${projectId}-${userId}/${buildId}/file_1`,
+        `handle: file_1`,
         sinon.match({
         sinon.match({
           name: 'file_1',
           name: 'file_1',
         })
         })
       )
       )
       sinon.assert.calledWith(
       sinon.assert.calledWith(
         this.archive.append,
         this.archive.append,
-        `handle: ${this.outputDir}/${projectId}-${userId}/${buildId}/file_4`,
+        `handle: file_4`,
         sinon.match({
         sinon.match({
           name: 'file_4',
           name: 'file_4',
         })
         })
@@ -185,7 +182,7 @@ describe('OutputFileArchiveManager', function () {
     it('adds the files that were found to the archive', function () {
     it('adds the files that were found to the archive', function () {
       sinon.assert.calledWith(
       sinon.assert.calledWith(
         this.archive.append,
         this.archive.append,
-        `handle: ${this.outputDir}/${projectId}-${userId}/${buildId}/file_1`,
+        `handle: file_1`,
         sinon.match({ name: 'file_1' })
         sinon.match({ name: 'file_1' })
       )
       )
     })
     })