EditorHttpController.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. max-len,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * DS207: Consider shorter variations of null checks
  13. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  14. */
  15. let EditorHttpController
  16. const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
  17. const ProjectDeleter = require('../Project/ProjectDeleter')
  18. const logger = require('logger-sharelatex')
  19. const EditorRealTimeController = require('./EditorRealTimeController')
  20. const EditorController = require('./EditorController')
  21. const ProjectGetter = require('../Project/ProjectGetter')
  22. const UserGetter = require('../User/UserGetter')
  23. const AuthorizationManager = require('../Authorization/AuthorizationManager')
  24. const ProjectEditorHandler = require('../Project/ProjectEditorHandler')
  25. const Metrics = require('metrics-sharelatex')
  26. const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
  27. const CollaboratorsInviteHandler = require('../Collaborators/CollaboratorsInviteHandler')
  28. const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
  29. const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
  30. const AuthenticationController = require('../Authentication/AuthenticationController')
  31. const Errors = require('../Errors/Errors')
  32. module.exports = EditorHttpController = {
  33. joinProject(req, res, next) {
  34. const project_id = req.params.Project_id
  35. let { user_id } = req.query
  36. if (user_id === 'anonymous-user') {
  37. user_id = null
  38. }
  39. logger.log({ user_id, project_id }, 'join project request')
  40. Metrics.inc('editor.join-project')
  41. return EditorHttpController._buildJoinProjectView(
  42. req,
  43. project_id,
  44. user_id,
  45. function(error, project, privilegeLevel) {
  46. if (error != null) {
  47. return next(error)
  48. }
  49. // Hide access tokens if this is not the project owner
  50. TokenAccessHandler.protectTokens(project, privilegeLevel)
  51. res.json({
  52. project,
  53. privilegeLevel
  54. })
  55. // Only show the 'renamed or deleted' message once
  56. if (project != null ? project.deletedByExternalDataSource : undefined) {
  57. return ProjectDeleter.unmarkAsDeletedByExternalSource(project_id)
  58. }
  59. }
  60. )
  61. },
  62. _buildJoinProjectView(req, project_id, user_id, callback) {
  63. if (callback == null) {
  64. callback = function(error, project, privilegeLevel) {}
  65. }
  66. logger.log({ project_id, user_id }, 'building the joinProject view')
  67. return ProjectGetter.getProjectWithoutDocLines(project_id, function(
  68. error,
  69. project
  70. ) {
  71. if (error != null) {
  72. return callback(error)
  73. }
  74. if (project == null) {
  75. return callback(new Errors.NotFoundError('project not found'))
  76. }
  77. return CollaboratorsHandler.getInvitedMembersWithPrivilegeLevels(
  78. project_id,
  79. function(error, members) {
  80. if (error != null) {
  81. return callback(error)
  82. }
  83. const token = TokenAccessHandler.getRequestToken(req, project_id)
  84. return AuthorizationManager.getPrivilegeLevelForProject(
  85. user_id,
  86. project_id,
  87. token,
  88. function(error, privilegeLevel) {
  89. if (error != null) {
  90. return callback(error)
  91. }
  92. if (
  93. privilegeLevel == null ||
  94. privilegeLevel === PrivilegeLevels.NONE
  95. ) {
  96. logger.log(
  97. { project_id, user_id, privilegeLevel },
  98. 'not an acceptable privilege level, returning null'
  99. )
  100. return callback(null, null, false)
  101. }
  102. return CollaboratorsInviteHandler.getAllInvites(
  103. project_id,
  104. function(error, invites) {
  105. if (error != null) {
  106. return callback(error)
  107. }
  108. logger.log(
  109. {
  110. project_id,
  111. user_id,
  112. memberCount: members.length,
  113. inviteCount: invites.length,
  114. privilegeLevel
  115. },
  116. 'returning project model view'
  117. )
  118. return callback(
  119. null,
  120. ProjectEditorHandler.buildProjectModelView(
  121. project,
  122. members,
  123. invites
  124. ),
  125. privilegeLevel
  126. )
  127. }
  128. )
  129. }
  130. )
  131. }
  132. )
  133. })
  134. },
  135. _nameIsAcceptableLength(name) {
  136. return name != null && name.length < 150 && name.length !== 0
  137. },
  138. addDoc(req, res, next) {
  139. const project_id = req.params.Project_id
  140. const { name } = req.body
  141. const { parent_folder_id } = req.body
  142. const user_id = AuthenticationController.getLoggedInUserId(req)
  143. logger.log(
  144. { project_id, name, parent_folder_id },
  145. 'getting request to add doc to project'
  146. )
  147. if (!EditorHttpController._nameIsAcceptableLength(name)) {
  148. return res.sendStatus(400)
  149. }
  150. return EditorController.addDoc(
  151. project_id,
  152. parent_folder_id,
  153. name,
  154. [],
  155. 'editor',
  156. user_id,
  157. function(error, doc) {
  158. if (error && error.message === 'project_has_to_many_files') {
  159. return res
  160. .status(400)
  161. .json(req.i18n.translate('project_has_to_many_files'))
  162. } else if (error) {
  163. return next(error)
  164. } else {
  165. return res.json(doc)
  166. }
  167. }
  168. )
  169. },
  170. addFolder(req, res, next) {
  171. const project_id = req.params.Project_id
  172. const { name } = req.body
  173. const { parent_folder_id } = req.body
  174. if (!EditorHttpController._nameIsAcceptableLength(name)) {
  175. return res.sendStatus(400)
  176. }
  177. return EditorController.addFolder(
  178. project_id,
  179. parent_folder_id,
  180. name,
  181. 'editor',
  182. function(error, doc) {
  183. if (error && error.message === 'project_has_to_many_files') {
  184. return res
  185. .status(400)
  186. .json(req.i18n.translate('project_has_to_many_files'))
  187. } else if (error && error.message === 'invalid element name') {
  188. return res.status(400).json(req.i18n.translate('invalid_file_name'))
  189. } else if (error) {
  190. return next(error)
  191. } else {
  192. return res.json(doc)
  193. }
  194. }
  195. )
  196. },
  197. renameEntity(req, res, next) {
  198. const project_id = req.params.Project_id
  199. const { entity_id } = req.params
  200. const { entity_type } = req.params
  201. const { name } = req.body
  202. if (!EditorHttpController._nameIsAcceptableLength(name)) {
  203. return res.sendStatus(400)
  204. }
  205. const user_id = AuthenticationController.getLoggedInUserId(req)
  206. return EditorController.renameEntity(
  207. project_id,
  208. entity_id,
  209. entity_type,
  210. name,
  211. user_id,
  212. function(error) {
  213. if (error != null) {
  214. return next(error)
  215. }
  216. return res.sendStatus(204)
  217. }
  218. )
  219. },
  220. moveEntity(req, res, next) {
  221. const project_id = req.params.Project_id
  222. const { entity_id } = req.params
  223. const { entity_type } = req.params
  224. const { folder_id } = req.body
  225. const user_id = AuthenticationController.getLoggedInUserId(req)
  226. return EditorController.moveEntity(
  227. project_id,
  228. entity_id,
  229. folder_id,
  230. entity_type,
  231. user_id,
  232. function(error) {
  233. if (error != null) {
  234. return next(error)
  235. }
  236. return res.sendStatus(204)
  237. }
  238. )
  239. },
  240. deleteDoc(req, res, next) {
  241. req.params.entity_type = 'doc'
  242. return EditorHttpController.deleteEntity(req, res, next)
  243. },
  244. deleteFile(req, res, next) {
  245. req.params.entity_type = 'file'
  246. return EditorHttpController.deleteEntity(req, res, next)
  247. },
  248. deleteFolder(req, res, next) {
  249. req.params.entity_type = 'folder'
  250. return EditorHttpController.deleteEntity(req, res, next)
  251. },
  252. deleteEntity(req, res, next) {
  253. const project_id = req.params.Project_id
  254. const { entity_id } = req.params
  255. const { entity_type } = req.params
  256. const user_id = AuthenticationController.getLoggedInUserId(req)
  257. return EditorController.deleteEntity(
  258. project_id,
  259. entity_id,
  260. entity_type,
  261. 'editor',
  262. user_id,
  263. function(error) {
  264. if (error != null) {
  265. return next(error)
  266. }
  267. return res.sendStatus(204)
  268. }
  269. )
  270. }
  271. }