ProjectController.coffee 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. res.render 'project/list', viewModel
  92. timer.done()
  93. archivedProjects: (req, res, next)->
  94. user_id = req.session.user._id
  95. projectDeleter.findArchivedProjects user_id, 'name lastUpdated publicAccesLevel', (error, projects) ->
  96. return next(error) if error?
  97. logger.log projects: projects, user_id:user_id, "rendering archived project list"
  98. viewModel = _buildListViewModel projects, [], [], [], {}
  99. res.render 'project/archived', viewModel
  100. loadEditor: (req, res, next)->
  101. timer = new metrics.Timer("load-editor")
  102. if !Settings.editorIsOpen
  103. return res.render("general/closed", {title:"updating site"})
  104. if req.session.user?
  105. user_id = req.session.user._id
  106. anonymous = false
  107. else
  108. anonymous = true
  109. user_id = 'openUser'
  110. project_id = req.params.Project_id
  111. async.parallel {
  112. project: (cb)->
  113. Project.findPopulatedById project_id, cb
  114. user: (cb)->
  115. if user_id == 'openUser'
  116. cb null, defaultSettingsForAnonymousUser(user_id)
  117. else
  118. User.findById user_id, cb
  119. subscription: (cb)->
  120. if user_id == 'openUser'
  121. return cb()
  122. SubscriptionLocator.getUsersSubscription user_id, cb
  123. }, (err, results)->
  124. if err?
  125. logger.err err:err, "error getting details for project page"
  126. return next err
  127. project = results.project
  128. user = results.user
  129. subscription = results.subscription
  130. SecurityManager.userCanAccessProject user, project, (canAccess, privilegeLevel)->
  131. if !canAccess
  132. return res.send 401
  133. if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt?
  134. allowedFreeTrial = !!subscription.freeTrial.allowed || true
  135. res.render 'project/editor',
  136. title: project.name
  137. priority_title: true
  138. bodyClasses: ["editor"]
  139. project : project
  140. userObject : JSON.stringify({
  141. id : user.id
  142. email : user.email
  143. first_name : user.first_name
  144. last_name : user.last_name
  145. referal_id : user.referal_id
  146. subscription :
  147. freeTrial: {allowed: allowedFreeTrial}
  148. })
  149. userSettingsObject: JSON.stringify({
  150. mode : user.ace.mode
  151. theme : user.ace.theme
  152. project_id : project._id
  153. fontSize : user.ace.fontSize
  154. autoComplete: user.ace.autoComplete
  155. spellCheckLanguage: user.ace.spellCheckLanguage
  156. pdfViewer : user.ace.pdfViewer
  157. docPositions: {}
  158. oldHistory: !!user.featureSwitches?.oldHistory
  159. })
  160. sharelatexObject : JSON.stringify({
  161. siteUrl: Settings.siteUrl,
  162. jsPath: res.locals.jsPath
  163. })
  164. privilegeLevel: privilegeLevel
  165. loadPdfjs: (user.ace.pdfViewer == "pdfjs")
  166. chatUrl: Settings.apis.chat.url
  167. anonymous: anonymous
  168. languages: Settings.languages
  169. timer.done()
  170. defaultSettingsForAnonymousUser = (user_id)->
  171. id : user_id
  172. ace:
  173. mode:'none'
  174. theme:'textmate'
  175. fontSize: '12'
  176. autoComplete: true
  177. spellCheckLanguage: ""
  178. pdfViewer: ""
  179. subscription:
  180. freeTrial:
  181. allowed: true
  182. featureSwitches:
  183. dropbox: false
  184. trackChanges: false
  185. _buildListViewModel = (projects, collabertions, readOnlyProjects, tags, tagsGroupedByProject)->
  186. for project in projects
  187. project.accessLevel = "owner"
  188. for project in collabertions
  189. project.accessLevel = "readWrite"
  190. for project in readOnlyProjects
  191. project.accessLevel = "readOnly"
  192. projects = projects.concat(collabertions).concat(readOnlyProjects)
  193. projects = projects.map (project)->
  194. project.tags = tagsGroupedByProject[project._id] || []
  195. return project
  196. tags = _.sortBy tags, (tag)->
  197. -tag.project_ids.length
  198. sortedProjects = _.sortBy projects, (project)->
  199. return - project.lastUpdated
  200. return {
  201. title:'Your Projects'
  202. priority_title: true
  203. projects: sortedProjects
  204. tags:tags
  205. projectTabActive: true
  206. }