router.coffee 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. AdminController = require('./Features/ServerAdmin/AdminController')
  2. ErrorController = require('./Features/Errors/ErrorController')
  3. ProjectController = require("./Features/Project/ProjectController")
  4. ProjectApiController = require("./Features/Project/ProjectApiController")
  5. SpellingController = require('./Features/Spelling/SpellingController')
  6. SecurityManager = require('./managers/SecurityManager')
  7. AuthorizationManager = require('./Features/Security/AuthorizationManager')
  8. EditorController = require("./Features/Editor/EditorController")
  9. EditorRouter = require("./Features/Editor/EditorRouter")
  10. EditorUpdatesController = require("./Features/Editor/EditorUpdatesController")
  11. Settings = require('settings-sharelatex')
  12. TpdsController = require('./Features/ThirdPartyDataStore/TpdsController')
  13. SubscriptionRouter = require './Features/Subscription/SubscriptionRouter'
  14. UploadsRouter = require './Features/Uploads/UploadsRouter'
  15. metrics = require('./infrastructure/Metrics')
  16. ReferalController = require('./Features/Referal/ReferalController')
  17. ReferalMiddleware = require('./Features/Referal/ReferalMiddleware')
  18. TemplatesRouter = require('./Features/Templates/TemplatesRouter')
  19. AuthenticationController = require('./Features/Authentication/AuthenticationController')
  20. TagsController = require("./Features/Tags/TagsController")
  21. CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter')
  22. UserInfoController = require('./Features/User/UserInfoController')
  23. UserController = require("./Features/User/UserController")
  24. UserPagesController = require('./Features/User/UserPagesController')
  25. DocumentController = require('./Features/Documents/DocumentController')
  26. CompileManager = require("./Features/Compile/CompileManager")
  27. CompileController = require("./Features/Compile/CompileController")
  28. HealthCheckController = require("./Features/HealthCheck/HealthCheckController")
  29. ProjectDownloadsController = require "./Features/Downloads/ProjectDownloadsController"
  30. FileStoreController = require("./Features/FileStore/FileStoreController")
  31. TrackChangesController = require("./Features/TrackChanges/TrackChangesController")
  32. PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
  33. StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter")
  34. ChatController = require("./Features/Chat/ChatController")
  35. BlogController = require("./Features/Blog/BlogController")
  36. WikiController = require("./Features/Wiki/WikiController")
  37. ConnectedUsersController = require("./Features/ConnectedUsers/ConnectedUsersController")
  38. DropboxRouter = require "./Features/Dropbox/DropboxRouter"
  39. dropboxHandler = require "./Features/Dropbox/DropboxHandler"
  40. Modules = require "./infrastructure/Modules"
  41. logger = require("logger-sharelatex")
  42. _ = require("underscore")
  43. httpAuth = require('express').basicAuth (user, pass)->
  44. isValid = Settings.httpAuthUsers[user] == pass
  45. if !isValid
  46. logger.err user:user, pass:pass, "invalid login details"
  47. return isValid
  48. module.exports = class Router
  49. constructor: (app, io, socketSessions)->
  50. app.use(app.router)
  51. app.get '/login', UserPagesController.loginPage
  52. app.post '/login', AuthenticationController.login
  53. app.get '/logout', UserController.logout
  54. app.get '/restricted', SecurityManager.restricted
  55. app.get '/register', UserPagesController.registerPage
  56. app.post '/register', UserController.register
  57. EditorRouter.apply(app, httpAuth)
  58. CollaboratorsRouter.apply(app)
  59. SubscriptionRouter.apply(app)
  60. UploadsRouter.apply(app)
  61. PasswordResetRouter.apply(app)
  62. StaticPagesRouter.apply(app)
  63. TemplatesRouter.apply(app)
  64. DropboxRouter.apply(app)
  65. Modules.applyRouter(app)
  66. app.get '/blog', BlogController.getIndexPage
  67. app.get '/blog/*', BlogController.getPage
  68. if Settings.enableSubscriptions
  69. app.get '/user/bonus', AuthenticationController.requireLogin(), ReferalMiddleware.getUserReferalId, ReferalController.bonus
  70. app.get '/user/settings', AuthenticationController.requireLogin(), UserPagesController.settingsPage
  71. app.post '/user/settings', AuthenticationController.requireLogin(), UserController.updateUserSettings
  72. app.post '/user/password/update', AuthenticationController.requireLogin(), UserController.changePassword
  73. app.del '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe
  74. app.del '/user', AuthenticationController.requireLogin(), UserController.deleteUser
  75. app.get '/user/auth_token', AuthenticationController.requireLogin(), AuthenticationController.getAuthToken
  76. app.get '/user/personal_info', AuthenticationController.requireLogin(allow_auth_token: true), UserInfoController.getLoggedInUsersPersonalInfo
  77. app.get '/user/:user_id/personal_info', httpAuth, UserInfoController.getPersonalInfo
  78. app.get '/project', AuthenticationController.requireLogin(), ProjectController.projectListPage
  79. app.post '/project/new', AuthenticationController.requireLogin(), ProjectController.newProject
  80. app.get '/Project/:Project_id', SecurityManager.requestCanAccessProject, ProjectController.loadEditor
  81. app.get '/Project/:Project_id/file/:File_id', SecurityManager.requestCanAccessProject, FileStoreController.getFile
  82. app.post '/project/:Project_id/settings', SecurityManager.requestCanModifyProject, ProjectController.updateProjectSettings
  83. app.post '/project/:Project_id/compile', SecurityManager.requestCanAccessProject, CompileController.compile
  84. app.get '/Project/:Project_id/output/output.pdf', SecurityManager.requestCanAccessProject, CompileController.downloadPdf
  85. app.get /^\/project\/([^\/]*)\/output\/(.*)$/,
  86. ((req, res, next) ->
  87. params =
  88. "Project_id": req.params[0]
  89. "file": req.params[1]
  90. req.params = params
  91. next()
  92. ), SecurityManager.requestCanAccessProject, CompileController.getFileFromClsi
  93. app.del "/project/:Project_id/output", SecurityManager.requestCanAccessProject, CompileController.deleteAuxFiles
  94. app.get "/project/:Project_id/sync/code", SecurityManager.requestCanAccessProject, CompileController.proxySync
  95. app.get "/project/:Project_id/sync/pdf", SecurityManager.requestCanAccessProject, CompileController.proxySync
  96. app.del '/Project/:Project_id', SecurityManager.requestIsOwner, ProjectController.deleteProject
  97. app.post '/Project/:Project_id/restore', SecurityManager.requestIsOwner, ProjectController.restoreProject
  98. app.post '/Project/:Project_id/clone', SecurityManager.requestCanAccessProject, ProjectController.cloneProject
  99. app.post '/project/:Project_id/rename', SecurityManager.requestIsOwner, ProjectController.renameProject
  100. app.get "/project/:Project_id/updates", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
  101. app.get "/project/:Project_id/doc/:doc_id/diff", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
  102. app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
  103. app.get '/project/:Project_id/connected_users', SecurityManager.requestCanAccessProject, ConnectedUsersController.getConnectedUsers
  104. app.get '/Project/:Project_id/download/zip', SecurityManager.requestCanAccessProject, ProjectDownloadsController.downloadProject
  105. app.get '/project/download/zip', SecurityManager.requestCanAccessMultipleProjects, ProjectDownloadsController.downloadMultipleProjects
  106. app.get '/tag', AuthenticationController.requireLogin(), TagsController.getAllTags
  107. app.post '/project/:project_id/tag', AuthenticationController.requireLogin(), TagsController.processTagsUpdate
  108. app.get '/project/:project_id/details', httpAuth, ProjectApiController.getProjectDetails
  109. app.get '/internal/project/:Project_id/zip', httpAuth, ProjectDownloadsController.downloadProject
  110. app.get '/internal/project/:project_id/compile/pdf', httpAuth, CompileController.compileAndDownloadPdf
  111. app.get '/project/:Project_id/doc/:doc_id', httpAuth, DocumentController.getDocument
  112. app.post '/project/:Project_id/doc/:doc_id', httpAuth, DocumentController.setDocument
  113. app.ignoreCsrf('post', '/project/:Project_id/doc/:doc_id')
  114. app.post '/user/:user_id/update/*', httpAuth, TpdsController.mergeUpdate
  115. app.del '/user/:user_id/update/*', httpAuth, TpdsController.deleteUpdate
  116. app.ignoreCsrf('post', '/user/:user_id/update/*')
  117. app.ignoreCsrf('delete', '/user/:user_id/update/*')
  118. app.post '/project/:project_id/contents/*', httpAuth, TpdsController.updateProjectContents
  119. app.del '/project/:project_id/contents/*', httpAuth, TpdsController.deleteProjectContents
  120. app.ignoreCsrf('post', '/project/:project_id/contents/*')
  121. app.ignoreCsrf('delete', '/project/:project_id/contents/*')
  122. app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
  123. app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
  124. app.get "/project/:Project_id/messages", SecurityManager.requestCanAccessProject, ChatController.getMessages
  125. app.post "/project/:Project_id/messages", SecurityManager.requestCanAccessProject, ChatController.sendMessage
  126. app.get /learn(\/.*)?/, WikiController.getPage
  127. #Admin Stuff
  128. app.get '/admin', SecurityManager.requestIsAdmin, AdminController.index
  129. app.post '/admin/closeEditor', SecurityManager.requestIsAdmin, AdminController.closeEditor
  130. app.post '/admin/dissconectAllUsers', SecurityManager.requestIsAdmin, AdminController.dissconectAllUsers
  131. app.post '/admin/syncUserToSubscription', SecurityManager.requestIsAdmin, AdminController.syncUserToSubscription
  132. app.post '/admin/flushProjectToTpds', SecurityManager.requestIsAdmin, AdminController.flushProjectToTpds
  133. app.post '/admin/pollDropboxForUser', SecurityManager.requestIsAdmin, AdminController.pollDropboxForUser
  134. app.post '/admin/messages', SecurityManager.requestIsAdmin, AdminController.createMessage
  135. app.post '/admin/messages/clear', SecurityManager.requestIsAdmin, AdminController.clearMessages
  136. app.get '/perfTest', (req,res)->
  137. res.send("hello")
  138. req.session.destroy()
  139. app.get '/status', (req,res)->
  140. res.send("websharelatex is up")
  141. req.session.destroy()
  142. app.get '/health_check', HealthCheckController.check
  143. app.get '/health_check/redis', HealthCheckController.checkRedis
  144. app.get "/status/compiler/:Project_id", SecurityManager.requestCanAccessProject, (req, res) ->
  145. sendRes = _.once (statusCode, message)->
  146. res.writeHead statusCode
  147. res.end message
  148. CompileManager.compile req.params.Project_id, "test-compile", {}, () ->
  149. sendRes 200, "Compiler returned in less than 10 seconds"
  150. setTimeout (() ->
  151. sendRes 500, "Compiler timed out"
  152. ), 10000
  153. req.session.destroy()
  154. app.get '/test', (req, res) ->
  155. res.render "tests",
  156. privilegeLevel: "owner"
  157. project:
  158. name: "test"
  159. date: Date.now()
  160. layout: false
  161. userCanSeeDropbox: true
  162. languages: []
  163. app.get "/ip", (req, res, next) ->
  164. res.send({
  165. ip: req.ip
  166. ips: req.ips
  167. headers: req.headers
  168. })
  169. app.get '/oops-express', (req, res, next) -> next(new Error("Test error"))
  170. app.get '/oops-internal', (req, res, next) -> throw new Error("Test error")
  171. app.get '/oops-mongo', (req, res, next) ->
  172. require("./models/Project").Project.findOne {}, () ->
  173. throw new Error("Test error")
  174. app.get '/opps-small', (req, res, next)->
  175. logger.err "test error occured"
  176. res.send()
  177. app.post '/error/client', (req, res, next) ->
  178. logger.error err: req.body.error, meta: req.body.meta, "client side error"
  179. res.send(204)
  180. app.get '*', ErrorController.notFound
  181. socketSessions.on 'connection', (err, client, session)->
  182. metrics.inc('socket-io.connection')
  183. # This is not ideal - we should come up with a better way of handling
  184. # anonymous users, but various logging lines rely on user._id
  185. if !session or !session.user?
  186. user = {_id: "anonymous-user"}
  187. else
  188. user = session.user
  189. client.on 'joinProject', (data, callback) ->
  190. EditorController.joinProject(client, user, data.project_id, callback)
  191. client.on 'disconnect', () ->
  192. metrics.inc ('socket-io.disconnect')
  193. EditorController.leaveProject client, user
  194. client.on 'applyOtUpdate', (doc_id, update) ->
  195. AuthorizationManager.ensureClientCanEditProject client, (error, project_id) =>
  196. EditorUpdatesController.applyOtUpdate(client, project_id, doc_id, update)
  197. client.on 'clientTracking.updatePosition', (cursorData) ->
  198. AuthorizationManager.ensureClientCanViewProject client, (error, project_id) =>
  199. EditorController.updateClientPosition(client, cursorData)
  200. client.on 'leaveDoc', (doc_id, callback)->
  201. AuthorizationManager.ensureClientCanViewProject client, (error, project_id) =>
  202. EditorController.leaveDoc(client, project_id, doc_id, callback)
  203. client.on 'joinDoc', (args...)->
  204. AuthorizationManager.ensureClientCanViewProject client, (error, project_id) =>
  205. EditorController.joinDoc(client, project_id, args...)
  206. # The remaining can be done via HTTP
  207. client.on 'addUserToProject', (email, newPrivalageLevel, callback)->
  208. AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) =>
  209. EditorController.addUserToProject project_id, email, newPrivalageLevel, callback
  210. client.on 'removeUserFromProject', (user_id, callback)->
  211. AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) =>
  212. EditorController.removeUserFromProject(project_id, user_id, callback)
  213. client.on 'getUserDropboxLinkStatus', (owner_id, callback)->
  214. AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) =>
  215. dropboxHandler.getUserRegistrationStatus owner_id, callback
  216. # client.on 'publishProjectAsTemplate', (user_id, callback)->
  217. # AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) =>
  218. # TemplatesController.publishProject user_id, project_id, callback
  219. #
  220. # client.on 'unPublishProjectAsTemplate', (user_id, callback)->
  221. # AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) =>
  222. # TemplatesController.unPublishProject user_id, project_id, callback
  223. #
  224. # client.on 'updateProjectDescription', (description, callback)->
  225. # AuthorizationManager.ensureClientCanEditProject client, (error, project_id) =>
  226. # EditorController.updateProjectDescription project_id, description, callback
  227. #
  228. # client.on "getPublishedDetails", (user_id, callback)->
  229. # AuthorizationManager.ensureClientCanViewProject client, (error, project_id) =>
  230. # TemplatesController.getTemplateDetails user_id, project_id, callback