ProjectUploadController.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* eslint-disable
  2. max-len,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS207: Consider shorter variations of null checks
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. let ProjectUploadController
  14. const logger = require('@overleaf/logger')
  15. const metrics = require('@overleaf/metrics')
  16. const fs = require('fs')
  17. const Path = require('path')
  18. const FileSystemImportManager = require('./FileSystemImportManager')
  19. const ProjectUploadManager = require('./ProjectUploadManager')
  20. const SessionManager = require('../Authentication/SessionManager')
  21. const Settings = require('@overleaf/settings')
  22. const { InvalidZipFileError } = require('./ArchiveErrors')
  23. const multer = require('multer')
  24. const _ = require('lodash')
  25. const upload = multer(
  26. _.defaultsDeep(
  27. {
  28. dest: Settings.path.uploadFolder,
  29. limits: {
  30. fileSize: Settings.maxUploadSize,
  31. },
  32. },
  33. Settings.multerOptions
  34. )
  35. )
  36. module.exports = ProjectUploadController = {
  37. uploadProject(req, res, next) {
  38. const timer = new metrics.Timer('project-upload')
  39. const userId = SessionManager.getLoggedInUserId(req.session)
  40. const { originalname, path } = req.file
  41. const name = Path.basename(originalname, '.zip')
  42. return ProjectUploadManager.createProjectFromZipArchive(
  43. userId,
  44. name,
  45. path,
  46. function (error, project) {
  47. fs.unlink(path, function () {})
  48. timer.done()
  49. if (error != null) {
  50. logger.error(
  51. { err: error, filePath: path, fileName: name },
  52. 'error uploading project'
  53. )
  54. if (error instanceof InvalidZipFileError) {
  55. return res.status(422).json({
  56. success: false,
  57. error: req.i18n.translate(error.message),
  58. })
  59. } else {
  60. return res.status(500).json({
  61. success: false,
  62. error: req.i18n.translate('upload_failed'),
  63. })
  64. }
  65. } else {
  66. return res.json({ success: true, project_id: project._id })
  67. }
  68. }
  69. )
  70. },
  71. uploadFile(req, res, next) {
  72. const timer = new metrics.Timer('file-upload')
  73. const name = req.file != null ? req.file.originalname : undefined
  74. const path = req.file != null ? req.file.path : undefined
  75. const projectId = req.params.Project_id
  76. const { folder_id: folderId } = req.query
  77. if (name == null || name.length === 0 || name.length > 150) {
  78. logger.err(
  79. { projectId, fileName: name },
  80. 'bad name when trying to upload file'
  81. )
  82. return res.status(422).json({
  83. success: false,
  84. error: 'invalid_filename',
  85. })
  86. }
  87. const userId = SessionManager.getLoggedInUserId(req.session)
  88. return FileSystemImportManager.addEntity(
  89. userId,
  90. projectId,
  91. folderId,
  92. name,
  93. path,
  94. true,
  95. function (error, entity) {
  96. fs.unlink(path, function () {})
  97. timer.done()
  98. if (error != null) {
  99. logger.error(
  100. {
  101. err: error,
  102. projectId,
  103. filePath: path,
  104. fileName: name,
  105. folderId,
  106. },
  107. 'error uploading file'
  108. )
  109. if (error.name === 'InvalidNameError') {
  110. return res.status(422).json({
  111. success: false,
  112. error: 'invalid_filename',
  113. })
  114. } else if (error.message === 'project_has_too_many_files') {
  115. return res.status(422).json({
  116. success: false,
  117. error: 'project_has_too_many_files',
  118. })
  119. } else {
  120. return res.status(422).json({ success: false })
  121. }
  122. } else {
  123. return res.json({
  124. success: true,
  125. entity_id: entity != null ? entity._id : undefined,
  126. entity_type: entity != null ? entity.type : undefined,
  127. })
  128. }
  129. }
  130. )
  131. },
  132. multerMiddleware(req, res, next) {
  133. if (upload == null) {
  134. return res
  135. .status(500)
  136. .json({ success: false, error: req.i18n.translate('upload_failed') })
  137. }
  138. return upload.single('qqfile')(req, res, function (err) {
  139. if (err instanceof multer.MulterError && err.code === 'LIMIT_FILE_SIZE') {
  140. return res
  141. .status(422)
  142. .json({ success: false, error: req.i18n.translate('file_too_large') })
  143. }
  144. return next(err)
  145. })
  146. },
  147. }