ProjectController.coffee 6.8 KB

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