ProjectController.coffee 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. async = require("async")
  2. logger = require("logger-sharelatex")
  3. projectDeleter = require("./ProjectDeleter")
  4. projectDuplicator = require("./ProjectDuplicator")
  5. projectCreationHandler = require("./ProjectCreationHandler")
  6. editorController = require("../Editor/EditorController")
  7. metrics = require('../../infrastructure/Metrics')
  8. sanitize = require('sanitizer')
  9. Project = require('../../models/Project').Project
  10. User = require('../../models/User').User
  11. TagsHandler = require("../Tags/TagsHandler")
  12. SubscriptionLocator = require("../Subscription/SubscriptionLocator")
  13. _ = require("underscore")
  14. Settings = require("settings-sharelatex")
  15. SecurityManager = require("../../managers/SecurityManager")
  16. module.exports =
  17. deleteProject: (req, res) ->
  18. project_id = req.params.Project_id
  19. forever = req.query?.forever?
  20. logger.log project_id: project_id, forever: forever, "received request to delete project"
  21. if forever
  22. doDelete = projectDeleter.deleteProject
  23. else
  24. doDelete = projectDeleter.archiveProject
  25. doDelete project_id, (err)->
  26. if err?
  27. res.send 500
  28. else
  29. res.send 200
  30. restoreProject: (req, res) ->
  31. project_id = req.params.Project_id
  32. logger.log project_id:project_id, "received request to restore project"
  33. projectDeleter.restoreProject project_id, (err)->
  34. if err?
  35. res.send 500
  36. else
  37. res.send 200
  38. cloneProject: (req, res)->
  39. metrics.inc "cloned-project"
  40. project_id = req.params.Project_id
  41. projectName = req.body.projectName
  42. logger.log project_id:project_id, projectName:projectName, "cloning project"
  43. if !req.session.user?
  44. return res.send redir:"/register"
  45. projectDuplicator.duplicate req.session.user, project_id, projectName, (err, project)->
  46. if err?
  47. logger.error err:err, project_id: project_id, user_id: req.session.user._id, "error cloning project"
  48. return next(err)
  49. res.send(project_id:project._id)
  50. newProject: (req, res)->
  51. user = req.session.user
  52. projectName = sanitize.escape(req.body.projectName)
  53. template = sanitize.escape(req.body.template)
  54. logger.log user: user, type: template, name: projectName, "creating project"
  55. async.waterfall [
  56. (cb)->
  57. if template == 'example'
  58. projectCreationHandler.createExampleProject user._id, projectName, cb
  59. else
  60. projectCreationHandler.createBasicProject user._id, projectName, cb
  61. ], (err, project)->
  62. if err?
  63. logger.error err: err, project: project, user: user, name: projectName, type: template, "error creating project"
  64. res.send 500
  65. else
  66. logger.log project: project, user: user, name: projectName, type: template, "created project"
  67. res.send {project_id:project._id}
  68. renameProject: (req, res)->
  69. project_id = req.params.Project_id
  70. newName = req.body.newProjectName
  71. editorController.renameProject project_id, newName, (err)->
  72. if err?
  73. logger.err err:err, project_id:project_id, newName:newName, "problem renaming project"
  74. res.send 500
  75. else
  76. res.send 200
  77. projectListPage: (req, res, next)->
  78. timer = new metrics.Timer("project-list")
  79. user_id = req.session.user._id
  80. async.parallel {
  81. tags: (cb)->
  82. TagsHandler.getAllTags user_id, cb
  83. projects: (cb)->
  84. Project.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel', cb
  85. }, (err, results)->
  86. if err?
  87. logger.err err:err, "error getting data for project list page"
  88. return res.send 500
  89. logger.log results:results, user_id:user_id, "rendering project list"
  90. viewModel = _buildListViewModel results.projects[0], results.projects[1], results.projects[2], results.tags[0], results.tags[1]
  91. viewModel.showUserDetailsArea = Settings?.algolia?.institutions?.app_id? and Settings?.algolia?.institutions?.api_key?
  92. res.render 'project/list', viewModel
  93. timer.done()
  94. archivedProjects: (req, res, next)->
  95. user_id = req.session.user._id
  96. projectDeleter.findArchivedProjects user_id, 'name lastUpdated publicAccesLevel', (error, projects) ->
  97. return next(error) if error?
  98. logger.log projects: projects, user_id:user_id, "rendering archived project list"
  99. viewModel = _buildListViewModel projects, [], [], [], {}
  100. res.render 'project/archived', viewModel
  101. loadEditor: (req, res, next)->
  102. timer = new metrics.Timer("load-editor")
  103. if !Settings.editorIsOpen
  104. return res.render("general/closed", {title:"updating site"})
  105. if req.session.user?
  106. user_id = req.session.user._id
  107. anonymous = false
  108. else
  109. anonymous = true
  110. user_id = 'openUser'
  111. project_id = req.params.Project_id
  112. async.parallel {
  113. project: (cb)->
  114. Project.findPopulatedById project_id, cb
  115. user: (cb)->
  116. if user_id == 'openUser'
  117. cb null, defaultSettingsForAnonymousUser(user_id)
  118. else
  119. User.findById user_id, cb
  120. subscription: (cb)->
  121. if user_id == 'openUser'
  122. return cb()
  123. SubscriptionLocator.getUsersSubscription user_id, cb
  124. }, (err, results)->
  125. if err?
  126. logger.err err:err, "error getting details for project page"
  127. return next err
  128. project = results.project
  129. user = results.user
  130. subscription = results.subscription
  131. SecurityManager.userCanAccessProject user, project, (canAccess, privilegeLevel)->
  132. if !canAccess
  133. return res.send 401
  134. if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt?
  135. allowedFreeTrial = !!subscription.freeTrial.allowed || true
  136. res.render 'project/editor',
  137. title: project.name
  138. priority_title: true
  139. bodyClasses: ["editor"]
  140. project : project
  141. userObject : JSON.stringify({
  142. id : user.id
  143. email : user.email
  144. first_name : user.first_name
  145. last_name : user.last_name
  146. referal_id : user.referal_id
  147. subscription :
  148. freeTrial: {allowed: allowedFreeTrial}
  149. })
  150. userSettingsObject: JSON.stringify({
  151. mode : user.ace.mode
  152. theme : user.ace.theme
  153. project_id : project._id
  154. fontSize : user.ace.fontSize
  155. autoComplete: user.ace.autoComplete
  156. spellCheckLanguage: user.ace.spellCheckLanguage
  157. pdfViewer : user.ace.pdfViewer
  158. docPositions: {}
  159. oldHistory: !!user.featureSwitches?.oldHistory
  160. })
  161. sharelatexObject : JSON.stringify({
  162. siteUrl: Settings.siteUrl,
  163. jsPath: res.locals.jsPath
  164. })
  165. privilegeLevel: privilegeLevel
  166. loadPdfjs: (user.ace.pdfViewer == "pdfjs")
  167. chatUrl: Settings.apis.chat.url
  168. anonymous: anonymous
  169. languages: Settings.languages
  170. timer.done()
  171. defaultSettingsForAnonymousUser = (user_id)->
  172. id : user_id
  173. ace:
  174. mode:'none'
  175. theme:'textmate'
  176. fontSize: '12'
  177. autoComplete: true
  178. spellCheckLanguage: ""
  179. pdfViewer: ""
  180. subscription:
  181. freeTrial:
  182. allowed: true
  183. featureSwitches:
  184. dropbox: false
  185. trackChanges: false
  186. _buildListViewModel = (projects, collabertions, readOnlyProjects, tags, tagsGroupedByProject)->
  187. for project in projects
  188. project.accessLevel = "owner"
  189. for project in collabertions
  190. project.accessLevel = "readWrite"
  191. for project in readOnlyProjects
  192. project.accessLevel = "readOnly"
  193. projects = projects.concat(collabertions).concat(readOnlyProjects)
  194. projects = projects.map (project)->
  195. project.tags = tagsGroupedByProject[project._id] || []
  196. return project
  197. tags = _.sortBy tags, (tag)->
  198. -tag.project_ids.length
  199. sortedProjects = _.sortBy projects, (project)->
  200. return - project.lastUpdated
  201. return {
  202. title:'Your Projects'
  203. priority_title: true
  204. projects: sortedProjects
  205. tags:tags
  206. projectTabActive: true
  207. }