master.js 5.33 KB
Newer Older
NGPixel's avatar
NGPixel committed
1 2
/* global wiki */

NGPixel's avatar
NGPixel committed
3
module.exports = () => {
4 5 6 7
  // ----------------------------------------
  // Load global modules
  // ----------------------------------------

8
  wiki.auth = require('./modules/auth').init()
9
  wiki.disk = require('./modules/disk').init()
NGPixel's avatar
NGPixel committed
10
  wiki.docs = require('./modules/documents').init()
11
  wiki.git = require('./modules/git').init(false)
12
  wiki.lang = require('./modules/localization').init()
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
  wiki.mark = require('./modules/markdown')
  wiki.search = require('./modules/search').init()
  wiki.upl = require('./modules/uploads').init()

  // ----------------------------------------
  // Load modules
  // ----------------------------------------

  const autoload = require('auto-load')
  const bodyParser = require('body-parser')
  const compression = require('compression')
  const cookieParser = require('cookie-parser')
  const express = require('express')
  const favicon = require('serve-favicon')
  const flash = require('connect-flash')
  const http = require('http')
  const path = require('path')
  const session = require('express-session')
  const SessionRedisStore = require('connect-redis')(session)
  const graceful = require('node-graceful')
  const graphqlApollo = require('apollo-server-express')
  const graphqlSchema = require('./modules/graphql')

  var mw = autoload(path.join(wiki.SERVERPATH, '/middlewares'))
  var ctrl = autoload(path.join(wiki.SERVERPATH, '/controllers'))

  // ----------------------------------------
  // Define Express App
  // ----------------------------------------

  const app = express()
  wiki.app = app
  app.use(compression())

  // ----------------------------------------
  // Security
  // ----------------------------------------

  app.use(mw.security)

  // ----------------------------------------
  // Public Assets
  // ----------------------------------------

  app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico')))
  app.use(express.static(path.join(wiki.ROOTPATH, 'assets'), {
    index: false,
    maxAge: '7d'
  }))

  // ----------------------------------------
  // Passport Authentication
  // ----------------------------------------

  let sessionStore = new SessionRedisStore({
    client: wiki.redis
  })
NGPixel's avatar
NGPixel committed
70

71 72 73 74 75 76 77 78 79
  app.use(cookieParser())
  app.use(session({
    name: 'wikijs.sid',
    store: sessionStore,
    secret: wiki.config.site.sessionSecret,
    resave: false,
    saveUninitialized: false
  }))
  app.use(flash())
80 81
  app.use(wiki.auth.passport.initialize())
  app.use(wiki.auth.passport.session())
82 83 84 85 86 87 88 89 90 91

  // ----------------------------------------
  // SEO
  // ----------------------------------------

  app.use(mw.seo)

  // ----------------------------------------
  // View Engine Setup
  // ----------------------------------------
NGPixel's avatar
NGPixel committed
92

93 94
  app.set('views', path.join(wiki.SERVERPATH, 'views'))
  app.set('view engine', 'pug')
NGPixel's avatar
NGPixel committed
95

96 97
  app.use(bodyParser.json({ limit: '1mb' }))
  app.use(bodyParser.urlencoded({ extended: false, limit: '1mb' }))
NGPixel's avatar
NGPixel committed
98

99 100 101
  // ----------------------------------------
  // View accessible data
  // ----------------------------------------
NGPixel's avatar
NGPixel committed
102

103
  app.locals.basedir = wiki.ROOTPATH
104
  app.locals._ = require('lodash')
105
  app.locals.t = wiki.lang.engine.t.bind(wiki.lang)
106 107
  app.locals.moment = require('moment')
  app.locals.moment.locale(wiki.config.site.lang)
NGPixel's avatar
NGPixel committed
108
  app.locals.config = wiki.config
109
  app.use(mw.flash)
NGPixel's avatar
NGPixel committed
110

111 112 113
  // ----------------------------------------
  // Controllers
  // ----------------------------------------
NGPixel's avatar
NGPixel committed
114

115
  app.use('/', ctrl.auth)
NGPixel's avatar
NGPixel committed
116

117 118
  app.use('/graphql', graphqlApollo.graphqlExpress({ schema: graphqlSchema }))
  app.use('/graphiql', graphqlApollo.graphiqlExpress({ endpointURL: '/graphql' }))
119
  // app.use('/uploads', mw.auth, ctrl.uploads)
120 121
  app.use('/admin', mw.auth, ctrl.admin)
  app.use('/', mw.auth, ctrl.pages)
NGPixel's avatar
NGPixel committed
122

123 124 125
  // ----------------------------------------
  // Error handling
  // ----------------------------------------
NGPixel's avatar
NGPixel committed
126

127 128 129 130 131
  app.use(function (req, res, next) {
    var err = new Error('Not Found')
    err.status = 404
    next(err)
  })
NGPixel's avatar
NGPixel committed
132

133 134 135 136 137 138
  app.use(function (err, req, res, next) {
    res.status(err.status || 500)
    res.render('error', {
      message: err.message,
      error: wiki.IS_DEBUG ? err : {}
    })
NGPixel's avatar
NGPixel committed
139 140
  })

141 142 143 144
  // ----------------------------------------
  // Start HTTP server
  // ----------------------------------------

145
  wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`)
146 147

  app.set('port', wiki.config.port)
148
  let server = http.createServer(app)
149 150 151 152

  server.listen(wiki.config.port)
  server.on('error', (error) => {
    if (error.syscall !== 'listen') {
NGPixel's avatar
NGPixel committed
153
      throw error
154 155 156 157 158 159 160 161 162 163 164 165 166 167
    }

    // handle specific listen errors with friendly messages
    switch (error.code) {
      case 'EACCES':
        wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!')
        return process.exit(1)
      case 'EADDRINUSE':
        wiki.logger.error('Port ' + wiki.config.port + ' is already in use!')
        return process.exit(1)
      default:
        throw error
    }
  })
NGPixel's avatar
NGPixel committed
168

169
  server.on('listening', () => {
170
    wiki.logger.info('HTTP Server: RUNNING')
171
  })
NGPixel's avatar
NGPixel committed
172

173 174 175 176 177 178 179 180 181 182
  // ----------------------------------------
  // Graceful shutdown
  // ----------------------------------------

  graceful.on('exit', () => {
    wiki.logger.info('- SHUTTING DOWN - Performing git sync...')
    return global.git.resync().then(() => {
      wiki.logger.info('- SHUTTING DOWN - Git sync successful. Now safe to exit.')
      process.exit()
    })
NGPixel's avatar
NGPixel committed
183
  })
184 185

  return true
NGPixel's avatar
NGPixel committed
186
}