ProjectController.coffee 6.8 KB

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