setup.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. const path = require('path')
  2. /* global WIKI */
  3. module.exports = () => {
  4. WIKI.config.site = {
  5. path: '',
  6. title: 'Wiki.js'
  7. }
  8. WIKI.system = require('./core/system')
  9. // ----------------------------------------
  10. // Load modules
  11. // ----------------------------------------
  12. const bodyParser = require('body-parser')
  13. const compression = require('compression')
  14. const express = require('express')
  15. const favicon = require('serve-favicon')
  16. const http = require('http')
  17. const Promise = require('bluebird')
  18. const fs = require('fs-extra')
  19. const _ = require('lodash')
  20. const cfgHelper = require('./helpers/config')
  21. const crypto = Promise.promisifyAll(require('crypto'))
  22. // ----------------------------------------
  23. // Define Express App
  24. // ----------------------------------------
  25. let app = express()
  26. app.use(compression())
  27. // ----------------------------------------
  28. // Public Assets
  29. // ----------------------------------------
  30. app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico')))
  31. app.use(express.static(path.join(WIKI.ROOTPATH, 'assets')))
  32. // ----------------------------------------
  33. // View Engine Setup
  34. // ----------------------------------------
  35. app.set('views', path.join(WIKI.SERVERPATH, 'views'))
  36. app.set('view engine', 'pug')
  37. app.use(bodyParser.json())
  38. app.use(bodyParser.urlencoded({ extended: false }))
  39. app.locals.config = WIKI.config
  40. app.locals.data = WIKI.data
  41. app.locals._ = require('lodash')
  42. // ----------------------------------------
  43. // HMR (Dev Mode Only)
  44. // ----------------------------------------
  45. if (global.DEV) {
  46. app.use(global.WP_DEV.devMiddleware)
  47. app.use(global.WP_DEV.hotMiddleware)
  48. }
  49. // ----------------------------------------
  50. // Controllers
  51. // ----------------------------------------
  52. app.get('*', async (req, res) => {
  53. let packageObj = await fs.readJson(path.join(WIKI.ROOTPATH, 'package.json'))
  54. res.render('setup', {
  55. packageObj,
  56. telemetryClientID: WIKI.telemetry.cid
  57. })
  58. })
  59. /**
  60. * Finalize
  61. */
  62. app.post('/finalize', async (req, res) => {
  63. WIKI.telemetry.sendEvent('setup', 'finalize')
  64. try {
  65. // Upgrade from WIKI.js 1.x?
  66. if (req.body.upgrade) {
  67. await WIKI.system.upgradeFromMongo({
  68. mongoCnStr: cfgHelper.parseConfigValue(req.body.upgMongo)
  69. })
  70. }
  71. // Create directory structure
  72. const dataPath = path.join(process.cwd(), 'data')
  73. await fs.ensureDir(dataPath)
  74. await fs.ensureDir(path.join(dataPath, 'cache'))
  75. await fs.ensureDir(path.join(dataPath, 'uploads'))
  76. // Set config
  77. _.set(WIKI.config, 'defaultEditor', 'markdown')
  78. _.set(WIKI.config, 'graphEndpoint', 'https://graph.requarks.io')
  79. _.set(WIKI.config, 'lang.code', 'en')
  80. _.set(WIKI.config, 'lang.autoUpdate', true)
  81. _.set(WIKI.config, 'lang.namespacing', false)
  82. _.set(WIKI.config, 'lang.namespaces', [])
  83. _.set(WIKI.config, 'public', false)
  84. _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
  85. _.set(WIKI.config, 'telemetry.isEnabled', req.body.telemetry === 'true')
  86. _.set(WIKI.config, 'telemetry.clientId', WIKI.telemetry.cid)
  87. _.set(WIKI.config, 'theming.theme', 'default')
  88. _.set(WIKI.config, 'theming.darkMode', false)
  89. _.set(WIKI.config, 'title', 'Wiki.js')
  90. // Save config to DB
  91. WIKI.logger.info('Persisting config to DB...')
  92. await WIKI.configSvc.saveToDb([
  93. 'defaultEditor',
  94. 'graphEndpoint',
  95. 'lang',
  96. 'public',
  97. 'sessionSecret',
  98. 'telemetry',
  99. 'theming',
  100. 'title'
  101. ])
  102. // Create default locale
  103. WIKI.logger.info('Installing default locale...')
  104. await WIKI.models.locales.query().insert({
  105. code: 'en',
  106. strings: require('./locales/default.json'),
  107. isRTL: false,
  108. name: 'English',
  109. nativeName: 'English'
  110. })
  111. // Create default locale
  112. WIKI.logger.info('Creating default groups...')
  113. const adminGroup = await WIKI.models.groups.query().insert({
  114. name: 'Administrators',
  115. permissions: JSON.stringify(['manage:system']),
  116. isSystem: true
  117. })
  118. const guestGroup = await WIKI.models.groups.query().insert({
  119. name: 'Guests',
  120. permissions: JSON.stringify(['read:pages']),
  121. isSystem: true
  122. })
  123. // Load authentication strategies + enable local
  124. await WIKI.models.authentication.refreshStrategiesFromDisk()
  125. await WIKI.models.authentication.query().patch({ isEnabled: true }).where('key', 'local')
  126. // Load editors + enable default
  127. await WIKI.models.editors.refreshEditorsFromDisk()
  128. await WIKI.models.editors.query().patch({ isEnabled: true }).where('key', 'markdown')
  129. // Load loggers
  130. await WIKI.models.loggers.refreshLoggersFromDisk()
  131. // Load renderers
  132. await WIKI.models.renderers.refreshRenderersFromDisk()
  133. // Load search engines + enable default
  134. await WIKI.models.searchEngines.refreshSearchEnginesFromDisk()
  135. await WIKI.models.searchEngines.query().patch({ isEnabled: true }).where('key', 'db')
  136. // Load storage targets
  137. await WIKI.models.storage.refreshTargetsFromDisk()
  138. // Create root administrator
  139. WIKI.logger.info('Creating root administrator...')
  140. await WIKI.models.users.query().delete().where({
  141. providerKey: 'local',
  142. email: req.body.adminEmail
  143. })
  144. const adminUser = await WIKI.models.users.query().insert({
  145. email: req.body.adminEmail,
  146. provider: 'local',
  147. password: req.body.adminPassword,
  148. name: 'Administrator',
  149. locale: 'en',
  150. defaultEditor: 'markdown',
  151. tfaIsActive: false
  152. })
  153. await adminUser.$relatedQuery('groups').relate(adminGroup.id)
  154. // Create Guest account
  155. WIKI.logger.info('Creating guest account...')
  156. await WIKI.models.users.query().delete().where({
  157. providerKey: 'local',
  158. email: 'guest@example.com'
  159. })
  160. const guestUser = await WIKI.models.users.query().insert({
  161. provider: 'local',
  162. email: 'guest@example.com',
  163. name: 'Guest',
  164. password: '',
  165. locale: 'en',
  166. defaultEditor: 'markdown',
  167. tfaIsActive: false
  168. })
  169. await guestUser.$relatedQuery('groups').relate(guestGroup.id)
  170. // Create site nav
  171. WIKI.logger.info('Creating default site navigation')
  172. await WIKI.models.navigation.query().delete().where({ key: 'site' })
  173. await WIKI.models.navigation.query().insert({
  174. key: 'site',
  175. config: [
  176. {
  177. icon: 'home',
  178. kind: 'link',
  179. label: 'Home',
  180. target: '/',
  181. targetType: 'home'
  182. }
  183. ]
  184. })
  185. WIKI.logger.info('Setup is complete!')
  186. res.json({
  187. ok: true,
  188. redirectPath: '/',
  189. redirectPort: WIKI.config.port
  190. }).end()
  191. WIKI.config.setup = false
  192. WIKI.logger.info('Stopping Setup...')
  193. WIKI.server.destroy(() => {
  194. WIKI.logger.info('Setup stopped. Starting Wiki.js...')
  195. _.delay(() => {
  196. WIKI.kernel.bootMaster()
  197. }, 1000)
  198. })
  199. } catch (err) {
  200. res.json({ ok: false, error: err.message })
  201. }
  202. })
  203. // ----------------------------------------
  204. // Error handling
  205. // ----------------------------------------
  206. app.use(function (req, res, next) {
  207. var err = new Error('Not Found')
  208. err.status = 404
  209. next(err)
  210. })
  211. app.use(function (err, req, res, next) {
  212. res.status(err.status || 500)
  213. res.send({
  214. message: err.message,
  215. error: WIKI.IS_DEBUG ? err : {}
  216. })
  217. WIKI.logger.error(err.message)
  218. WIKI.telemetry.sendError(err)
  219. })
  220. // ----------------------------------------
  221. // Start HTTP server
  222. // ----------------------------------------
  223. WIKI.logger.info(`HTTP Server on port: [ ${WIKI.config.port} ]`)
  224. app.set('port', WIKI.config.port)
  225. WIKI.server = http.createServer(app)
  226. WIKI.server.listen(WIKI.config.port, WIKI.config.bindIP)
  227. var openConnections = []
  228. WIKI.server.on('connection', (conn) => {
  229. let key = conn.remoteAddress + ':' + conn.remotePort
  230. openConnections[key] = conn
  231. conn.on('close', () => {
  232. delete openConnections[key]
  233. })
  234. })
  235. WIKI.server.destroy = (cb) => {
  236. WIKI.server.close(cb)
  237. for (let key in openConnections) {
  238. openConnections[key].destroy()
  239. }
  240. }
  241. WIKI.server.on('error', (error) => {
  242. if (error.syscall !== 'listen') {
  243. throw error
  244. }
  245. switch (error.code) {
  246. case 'EACCES':
  247. WIKI.logger.error('Listening on port ' + WIKI.config.port + ' requires elevated privileges!')
  248. return process.exit(1)
  249. case 'EADDRINUSE':
  250. WIKI.logger.error('Port ' + WIKI.config.port + ' is already in use!')
  251. return process.exit(1)
  252. default:
  253. throw error
  254. }
  255. })
  256. WIKI.server.on('listening', () => {
  257. WIKI.logger.info('HTTP Server: [ RUNNING ]')
  258. WIKI.logger.info('========================================')
  259. WIKI.logger.info(`Browse to http://localhost:${WIKI.config.port}/`)
  260. WIKI.logger.info('========================================')
  261. })
  262. }