Server.coffee 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. Path = require "path"
  2. express = require('express')
  3. Settings = require('settings-sharelatex')
  4. logger = require 'logger-sharelatex'
  5. metrics = require('metrics-sharelatex')
  6. crawlerLogger = require('./CrawlerLogger')
  7. expressLocals = require('./ExpressLocals')
  8. Router = require('../router')
  9. metrics.inc("startup")
  10. UserSessionsRedis = require('../Features/User/UserSessionsRedis')
  11. sessionsRedisClient = UserSessionsRedis.client()
  12. session = require("express-session")
  13. RedisStore = require('connect-redis')(session)
  14. bodyParser = require('body-parser')
  15. multer = require('multer')
  16. methodOverride = require('method-override')
  17. csrf = require('csurf')
  18. csrfProtection = csrf()
  19. cookieParser = require('cookie-parser')
  20. # Init the session store
  21. sessionStore = new RedisStore(client:sessionsRedisClient)
  22. passport = require('passport')
  23. LocalStrategy = require('passport-local').Strategy
  24. Mongoose = require("./Mongoose")
  25. oneDayInMilliseconds = 86400000
  26. ReferalConnect = require('../Features/Referal/ReferalConnect')
  27. RedirectManager = require("./RedirectManager")
  28. OldAssetProxy = require("./OldAssetProxy")
  29. translations = require("translations-sharelatex").setup(Settings.i18n)
  30. Modules = require "./Modules"
  31. ErrorController = require "../Features/Errors/ErrorController"
  32. UserSessionsManager = require "../Features/User/UserSessionsManager"
  33. AuthenticationController = require "../Features/Authentication/AuthenticationController"
  34. metrics.event_loop?.monitor(logger)
  35. Settings.editorIsOpen ||= true
  36. if Settings.cacheStaticAssets
  37. staticCacheAge = (oneDayInMilliseconds * 365)
  38. else
  39. staticCacheAge = 0
  40. app = express()
  41. webRouter = express.Router()
  42. apiRouter = express.Router()
  43. if Settings.behindProxy
  44. app.enable('trust proxy')
  45. webRouter.use express.static(__dirname + '/../../../public', {maxAge: staticCacheAge })
  46. app.set 'views', __dirname + '/../../views'
  47. app.set 'view engine', 'pug'
  48. Modules.loadViewIncludes app
  49. app.use bodyParser.urlencoded({ extended: true, limit: "2mb"})
  50. # Make sure we can process the max doc length plus some overhead for JSON encoding
  51. app.use bodyParser.json({limit: Settings.max_doc_length + 16 * 1024}) # 16kb overhead
  52. app.use multer(dest: Settings.path.uploadFolder)
  53. app.use methodOverride()
  54. app.use metrics.http.monitor(logger)
  55. app.use RedirectManager
  56. app.use OldAssetProxy
  57. webRouter.use cookieParser(Settings.security.sessionSecret)
  58. webRouter.use session
  59. resave: false
  60. saveUninitialized:false
  61. secret:Settings.security.sessionSecret
  62. proxy: Settings.behindProxy
  63. cookie:
  64. domain: Settings.cookieDomain
  65. maxAge: Settings.cookieSessionLength
  66. secure: Settings.secureCookie
  67. store: sessionStore
  68. key: Settings.cookieName
  69. rolling: true
  70. # passport
  71. webRouter.use passport.initialize()
  72. webRouter.use passport.session()
  73. passport.use(new LocalStrategy(
  74. {
  75. passReqToCallback: true,
  76. usernameField: 'email',
  77. passwordField: 'password'
  78. },
  79. AuthenticationController.doPassportLogin
  80. ))
  81. passport.serializeUser(AuthenticationController.serializeUser)
  82. passport.deserializeUser(AuthenticationController.deserializeUser)
  83. Modules.hooks.fire 'passportSetup', passport, (err) ->
  84. if err?
  85. logger.err {err}, "error setting up passport in modules"
  86. Modules.applyNonCsrfRouter(webRouter, apiRouter)
  87. webRouter.use csrfProtection
  88. webRouter.use translations.expressMiddlewear
  89. webRouter.use translations.setLangBasedOnDomainMiddlewear
  90. # Measure expiry from last request, not last login
  91. webRouter.use (req, res, next) ->
  92. req.session.touch()
  93. if AuthenticationController.isUserLoggedIn(req)
  94. UserSessionsManager.touch(AuthenticationController.getSessionUser(req), (err)->)
  95. next()
  96. webRouter.use ReferalConnect.use
  97. expressLocals(app, webRouter, apiRouter)
  98. if app.get('env') == 'production'
  99. logger.info "Production Enviroment"
  100. app.enable('view cache')
  101. app.use (req, res, next)->
  102. metrics.inc "http-request"
  103. crawlerLogger.log(req)
  104. next()
  105. webRouter.use (req, res, next) ->
  106. if Settings.editorIsOpen
  107. next()
  108. else if req.url.indexOf("/admin") == 0
  109. next()
  110. else
  111. res.status(503)
  112. res.render("general/closed", {title:"maintenance"})
  113. apiRouter.get "/status", (req, res)->
  114. res.send("web sharelatex is alive")
  115. profiler = require "v8-profiler"
  116. apiRouter.get "/profile", (req, res) ->
  117. time = parseInt(req.query.time || "1000")
  118. profiler.startProfiling("test")
  119. setTimeout () ->
  120. profile = profiler.stopProfiling("test")
  121. res.json(profile)
  122. , time
  123. app.get "/heapdump", (req, res)->
  124. require('heapdump').writeSnapshot '/tmp/' + Date.now() + '.web.heapsnapshot', (err, filename)->
  125. res.send filename
  126. logger.info ("creating HTTP server").yellow
  127. server = require('http').createServer(app)
  128. # process api routes first, if nothing matched fall though and use
  129. # web middlewear + routes
  130. app.use(apiRouter)
  131. app.use(webRouter)
  132. router = new Router(webRouter, apiRouter)
  133. app.use ErrorController.handleError
  134. module.exports =
  135. app: app
  136. server: server