From 7acc4e9fed23ff5da3873635f735aac1f0906387 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Mon, 5 Mar 2018 15:49:36 -0500 Subject: [PATCH] refactor: global namespace + admin pages UI --- client/components/admin-api.vue | 113 ++++++++++++ client/components/admin-auth.vue | 4 +- client/components/admin-dev.vue | 19 ++ client/components/admin-search.vue | 3 + client/components/admin-storage.vue | 53 ++++++ client/components/admin-users.vue | 123 +++++++------ client/components/admin-utilities.vue | 19 ++ client/components/admin.vue | 9 +- package.json | 1 + server/controllers/auth.js | 44 ++--- server/core/auth.js | 40 ++--- server/core/config.js | 30 ++-- server/core/db.js | 24 +-- server/core/graphql.js | 41 ----- server/core/kernel.js | 32 ++-- server/core/localization.js | 10 +- server/core/logger.js | 8 +- server/core/queue.js | 20 +-- server/core/redis.js | 12 +- server/core/system.js | 10 +- server/core/telemetry.js | 20 +-- server/graph/index.js | 34 ++++ .../resolvers/authentication.js} | 15 +- .../resolvers/comment.js} | 10 +- .../resolvers/document.js} | 12 +- .../resolvers/file.js} | 14 +- .../resolvers/folder.js} | 10 +- .../resolvers/group.js} | 18 +- .../resolvers/right.js} | 12 +- .../resolvers/setting.js} | 6 +- .../resolvers/tag.js} | 18 +- .../resolvers/translation.js} | 4 +- .../resolvers/user.js} | 14 +- .../scalar-date.js => graph/scalars/date.js} | 0 server/graph/schemas/authentication.graphql | 23 +++ .../schemas/common.graphql} | 12 -- server/graph/schemas/scalars.graphql | 3 + server/index.js | 20 +-- server/master.js | 73 ++++---- server/middlewares/auth.js | 4 +- server/models/user.js | 42 ++--- server/modules/authentication/auth0.js | 4 +- server/modules/authentication/azure.js | 4 +- server/modules/authentication/discord.js | 4 +- server/modules/authentication/dropbox.js | 4 +- server/modules/authentication/facebook.js | 4 +- server/modules/authentication/github.js | 4 +- server/modules/authentication/google.js | 4 +- server/modules/authentication/ldap.js | 4 +- server/modules/authentication/local.js | 6 +- server/modules/authentication/microsoft.js | 4 +- server/modules/authentication/oauth2.js | 4 +- server/modules/authentication/slack.js | 4 +- server/modules/authentication/twitch.js | 4 +- server/modules/logging/console.js | 4 +- server/modules/renderer/common/mathjax.js | 4 +- server/queues/git-sync.js | 8 +- server/queues/upl-clear-temp.js | 10 +- server/setup.js | 162 +++++++++--------- server/worker.js | 28 +-- yarn.lock | 10 +- 61 files changed, 751 insertions(+), 508 deletions(-) create mode 100644 client/components/admin-api.vue create mode 100644 client/components/admin-dev.vue create mode 100644 client/components/admin-storage.vue create mode 100644 client/components/admin-utilities.vue delete mode 100644 server/core/graphql.js create mode 100644 server/graph/index.js rename server/{schemas/resolvers-authentication.js => graph/resolvers/authentication.js} (71%) rename server/{schemas/resolvers-comment.js => graph/resolvers/comment.js} (76%) rename server/{schemas/resolvers-document.js => graph/resolvers/document.js} (73%) rename server/{schemas/resolvers-file.js => graph/resolvers/file.js} (71%) rename server/{schemas/resolvers-folder.js => graph/resolvers/folder.js} (69%) rename server/{schemas/resolvers-group.js => graph/resolvers/group.js} (69%) rename server/{schemas/resolvers-right.js => graph/resolvers/right.js} (76%) rename server/{schemas/resolvers-setting.js => graph/resolvers/setting.js} (76%) rename server/{schemas/resolvers-tag.js => graph/resolvers/tag.js} (71%) rename server/{schemas/resolvers-translation.js => graph/resolvers/translation.js} (60%) rename server/{schemas/resolvers-user.js => graph/resolvers/user.js} (75%) rename server/{schemas/scalar-date.js => graph/scalars/date.js} (100%) create mode 100644 server/graph/schemas/authentication.graphql rename server/{schemas/types.graphql => graph/schemas/common.graphql} (96%) create mode 100644 server/graph/schemas/scalars.graphql diff --git a/client/components/admin-api.vue b/client/components/admin-api.vue new file mode 100644 index 00000000..9b2e03b0 --- /dev/null +++ b/client/components/admin-api.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/client/components/admin-auth.vue b/client/components/admin-auth.vue index 3eed7281..25b56f7d 100644 --- a/client/components/admin-auth.vue +++ b/client/components/admin-auth.vue @@ -28,7 +28,9 @@ v-btn(color='primary') v-icon(left) chevron_right | Set Providers - + v-btn(color='black', dark) + v-icon(left) layers_clear + | Flush Sessions + + diff --git a/client/components/admin-search.vue b/client/components/admin-search.vue index 990e2f87..1b384198 100644 --- a/client/components/admin-search.vue +++ b/client/components/admin-search.vue @@ -20,6 +20,9 @@ v-btn(color='primary') v-icon(left) chevron_right | Set Engine + v-btn(color='black', dark) + v-icon(left) refresh + | Rebuild Index v-tab-item(key='db') v-card.pa-3 TODO v-tab-item(key='algolia') diff --git a/client/components/admin-storage.vue b/client/components/admin-storage.vue new file mode 100644 index 00000000..e47e3ae2 --- /dev/null +++ b/client/components/admin-storage.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/client/components/admin-users.vue b/client/components/admin-users.vue index b5b1c23c..61f03723 100644 --- a/client/components/admin-users.vue +++ b/client/components/admin-users.vue @@ -1,66 +1,65 @@ + + diff --git a/client/components/admin.vue b/client/components/admin.vue index 1efd31da..74019937 100644 --- a/client/components/admin.vue +++ b/client/components/admin.vue @@ -50,6 +50,9 @@ v-list-tile-title Storage v-divider.my-2 v-subheader System + v-list-tile(to='/api') + v-list-tile-action: v-icon call_split + v-list-tile-title API Access v-list-tile(to='/system') v-list-tile-action: v-icon tune v-list-tile-title System Info @@ -83,7 +86,11 @@ const router = new VueRouter({ { path: '/users', component: () => import(/* webpackChunkName: "admin" */ './admin-users.vue') }, { path: '/auth', component: () => import(/* webpackChunkName: "admin" */ './admin-auth.vue') }, { path: '/search', component: () => import(/* webpackChunkName: "admin" */ './admin-search.vue') }, - { path: '/system', component: () => import(/* webpackChunkName: "admin" */ './admin-system.vue') } + { path: '/storage', component: () => import(/* webpackChunkName: "admin" */ './admin-storage.vue') }, + { path: '/api', component: () => import(/* webpackChunkName: "admin" */ './admin-api.vue') }, + { path: '/system', component: () => import(/* webpackChunkName: "admin" */ './admin-system.vue') }, + { path: '/utilities', component: () => import(/* webpackChunkName: "admin" */ './admin-utilities.vue') }, + { path: '/dev', component: () => import(/* webpackChunkName: "admin" */ './admin-dev.vue') } ] }) diff --git a/package.json b/package.json index c5021e41..94781a3f 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "mongodb": "3.0.2", "multer": "1.3.0", "node-2fa": "1.1.2", + "oauth2orize": "1.11.0", "ora": "1.4.0", "passport": "0.4.0", "passport-auth0": "0.6.1", diff --git a/server/controllers/auth.js b/server/controllers/auth.js index dae3a6e8..0b7de5df 100644 --- a/server/controllers/auth.js +++ b/server/controllers/auth.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ const Promise = require('bluebird') const express = require('express') @@ -12,7 +12,7 @@ const _ = require('lodash') * Setup Express-Brute */ const EBstore = new ExpressBruteRedisStore({ - client: wiki.redis + client: WIKI.redis }) const bruteforce = new ExpressBrute(EBstore, { freeRetries: 5, @@ -22,8 +22,8 @@ const bruteforce = new ExpressBrute(EBstore, { failCallback (req, res, next, nextValidRequestDate) { req.flash('alert', { class: 'error', - title: wiki.lang.t('auth:errors.toomanyattempts'), - message: wiki.lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }), + title: WIKI.lang.t('auth:errors.toomanyattempts'), + message: WIKI.lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }), iconClass: 'fa-times' }) res.redirect('/login') @@ -40,16 +40,16 @@ router.get('/login', function (req, res, next) { router.post('/login', bruteforce.prevent, function (req, res, next) { new Promise((resolve, reject) => { // [1] LOCAL AUTHENTICATION - wiki.auth.passport.authenticate('local', function (err, user, info) { + WIKI.auth.passport.authenticate('local', function (err, user, info) { if (err) { return reject(err) } if (!user) { return reject(new Error('INVALID_LOGIN')) } resolve(user) })(req, res, next) }).catch({ message: 'INVALID_LOGIN' }, err => { - if (_.has(wiki.config.auth.strategy, 'ldap')) { + if (_.has(WIKI.config.auth.strategy, 'ldap')) { // [2] LDAP AUTHENTICATION return new Promise((resolve, reject) => { - wiki.auth.passport.authenticate('ldapauth', function (err, user, info) { + WIKI.auth.passport.authenticate('ldapauth', function (err, user, info) { if (err) { return reject(err) } if (info && info.message) { return reject(new Error(info.message)) } if (!user) { return reject(new Error('INVALID_LOGIN')) } @@ -71,13 +71,13 @@ router.post('/login', bruteforce.prevent, function (req, res, next) { // LOGIN FAIL if (err.message === 'INVALID_LOGIN') { req.flash('alert', { - title: wiki.lang.t('auth:errors.invalidlogin'), - message: wiki.lang.t('auth:errors.invalidloginmsg') + title: WIKI.lang.t('auth:errors.invalidlogin'), + message: WIKI.lang.t('auth:errors.invalidloginmsg') }) return res.redirect('/login') } else { req.flash('alert', { - title: wiki.lang.t('auth:errors.loginerror'), + title: WIKI.lang.t('auth:errors.loginerror'), message: err.message }) return res.redirect('/login') @@ -89,19 +89,19 @@ router.post('/login', bruteforce.prevent, function (req, res, next) { * Social Login */ -router.get('/login/ms', wiki.auth.passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] })) -router.get('/login/google', wiki.auth.passport.authenticate('google', { scope: ['profile', 'email'] })) -router.get('/login/facebook', wiki.auth.passport.authenticate('facebook', { scope: ['public_profile', 'email'] })) -router.get('/login/github', wiki.auth.passport.authenticate('github', { scope: ['user:email'] })) -router.get('/login/slack', wiki.auth.passport.authenticate('slack', { scope: ['identity.basic', 'identity.email'] })) -router.get('/login/azure', wiki.auth.passport.authenticate('azure_ad_oauth2')) +router.get('/login/ms', WIKI.auth.passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] })) +router.get('/login/google', WIKI.auth.passport.authenticate('google', { scope: ['profile', 'email'] })) +router.get('/login/facebook', WIKI.auth.passport.authenticate('facebook', { scope: ['public_profile', 'email'] })) +router.get('/login/github', WIKI.auth.passport.authenticate('github', { scope: ['user:email'] })) +router.get('/login/slack', WIKI.auth.passport.authenticate('slack', { scope: ['identity.basic', 'identity.email'] })) +router.get('/login/azure', WIKI.auth.passport.authenticate('azure_ad_oauth2')) -router.get('/login/ms/callback', wiki.auth.passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/google/callback', wiki.auth.passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/facebook/callback', wiki.auth.passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/github/callback', wiki.auth.passport.authenticate('github', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/slack/callback', wiki.auth.passport.authenticate('slack', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/azure/callback', wiki.auth.passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/ms/callback', WIKI.auth.passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/google/callback', WIKI.auth.passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/facebook/callback', WIKI.auth.passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/github/callback', WIKI.auth.passport.authenticate('github', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/slack/callback', WIKI.auth.passport.authenticate('slack', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/azure/callback', WIKI.auth.passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' })) /** * Logout diff --git a/server/core/auth.js b/server/core/auth.js index a2892ee5..16ebb471 100644 --- a/server/core/auth.js +++ b/server/core/auth.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ const _ = require('lodash') const passport = require('passport') @@ -17,11 +17,11 @@ module.exports = { }) passport.deserializeUser(function (id, done) { - wiki.db.User.findById(id).then((user) => { + WIKI.db.User.findById(id).then((user) => { if (user) { done(null, user) } else { - done(new Error(wiki.lang.t('auth:errors:usernotfound')), null) + done(new Error(WIKI.lang.t('auth:errors:usernotfound')), null) } return true }).catch((err) => { @@ -31,49 +31,49 @@ module.exports = { // Load authentication strategies - _.forOwn(_.omitBy(wiki.config.auth.strategies, s => s.enabled === false), (strategyConfig, strategyKey) => { - strategyConfig.callbackURL = `${wiki.config.site.host}${wiki.config.site.path}login/${strategyKey}/callback` + _.forOwn(_.omitBy(WIKI.config.auth.strategies, s => s.enabled === false), (strategyConfig, strategyKey) => { + strategyConfig.callbackURL = `${WIKI.config.site.host}${WIKI.config.site.path}login/${strategyKey}/callback` let strategy = require(`../modules/authentication/${strategyKey}`) try { strategy.init(passport, strategyConfig) } catch (err) { - wiki.logger.error(`Authentication Provider ${strategyKey}: [ FAILED ]`) - wiki.logger.error(err) + WIKI.logger.error(`Authentication Provider ${strategyKey}: [ FAILED ]`) + WIKI.logger.error(err) } - fs.readFile(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${strategyKey}.svg`), 'utf8').then(iconData => { + fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${strategyKey}.svg`), 'utf8').then(iconData => { strategy.icon = iconData }).catch(err => { if (err.code === 'ENOENT') { strategy.icon = '[missing icon]' } else { - wiki.logger.error(err) + WIKI.logger.error(err) } }) this.strategies[strategy.key] = strategy - wiki.logger.info(`Authentication Provider ${strategyKey}: [ OK ]`) + WIKI.logger.info(`Authentication Provider ${strategyKey}: [ OK ]`) }) // Create Guest account for first-time - wiki.db.User.findOne({ + WIKI.db.User.findOne({ where: { provider: 'local', email: 'guest@example.com' } }).then((c) => { if (c < 1) { - return wiki.db.User.create({ + return WIKI.db.User.create({ provider: 'local', email: 'guest@example.com', name: 'Guest', password: '', role: 'guest' }).then(() => { - wiki.logger.info('[AUTH] Guest account created successfully!') + WIKI.logger.info('[AUTH] Guest account created successfully!') return true }).catch((err) => { - wiki.logger.error('[AUTH] An error occured while creating guest account:') - wiki.logger.error(err) + WIKI.logger.error('[AUTH] An error occured while creating guest account:') + WIKI.logger.error(err) return err }) } @@ -81,22 +81,22 @@ module.exports = { // .then(() => { // if (process.env.WIKI_JS_HEROKU) { - // return wiki.db.User.findOne({ provider: 'local', email: process.env.WIKI_ADMIN_EMAIL }).then((c) => { + // return WIKI.db.User.findOne({ provider: 'local', email: process.env.WIKI_ADMIN_EMAIL }).then((c) => { // if (c < 1) { // // Create root admin account (HEROKU ONLY) - // return wiki.db.User.create({ + // return WIKI.db.User.create({ // provider: 'local', // email: process.env.WIKI_ADMIN_EMAIL, // name: 'Administrator', // password: '$2a$04$MAHRw785Xe/Jd5kcKzr3D.VRZDeomFZu2lius4gGpZZ9cJw7B7Mna', // admin123 (default) // role: 'admin' // }).then(() => { - // wiki.logger.info('[AUTH] Root admin account created successfully!') + // WIKI.logger.info('[AUTH] Root admin account created successfully!') // return true // }).catch((err) => { - // wiki.logger.error('[AUTH] An error occured while creating root admin account:') - // wiki.logger.error(err) + // WIKI.logger.error('[AUTH] An error occured while creating root admin account:') + // WIKI.logger.error(err) // return err // }) // } else { return true } diff --git a/server/core/config.js b/server/core/config.js index f78259b3..377dd3b1 100644 --- a/server/core/config.js +++ b/server/core/config.js @@ -4,7 +4,7 @@ const fs = require('fs') const path = require('path') const yaml = require('js-yaml') -/* global wiki */ +/* global WIKI */ module.exports = { /** @@ -12,9 +12,9 @@ module.exports = { */ init() { let confPaths = { - config: path.join(wiki.ROOTPATH, 'config.yml'), - data: path.join(wiki.SERVERPATH, 'app/data.yml'), - dataRegex: path.join(wiki.SERVERPATH, 'app/regex.js') + config: path.join(WIKI.ROOTPATH, 'config.yml'), + data: path.join(WIKI.SERVERPATH, 'app/data.yml'), + dataRegex: path.join(WIKI.SERVERPATH, 'app/regex.js') } let appconfig = {} @@ -43,9 +43,9 @@ module.exports = { appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') - wiki.config = appconfig - wiki.data = appdata - wiki.version = require(path.join(wiki.ROOTPATH, 'package.json')).version + WIKI.config = appconfig + WIKI.data = appdata + WIKI.version = require(path.join(WIKI.ROOTPATH, 'package.json')).version }, /** @@ -56,10 +56,10 @@ module.exports = { */ async loadFromDb(subsets) { if (!_.isArray(subsets) || subsets.length === 0) { - subsets = wiki.data.configNamespaces + subsets = WIKI.data.configNamespaces } - let results = await wiki.db.Setting.findAll({ + let results = await WIKI.db.Setting.findAll({ attributes: ['key', 'config'], where: { key: { @@ -69,11 +69,11 @@ module.exports = { }) if (_.isArray(results) && results.length === subsets.length) { results.forEach(result => { - wiki.config[result.key] = result.config + WIKI.config[result.key] = result.config }) return true } else { - wiki.logger.warn('DB Configuration is empty or incomplete.') + WIKI.logger.warn('DB Configuration is empty or incomplete.') return false } }, @@ -85,18 +85,18 @@ module.exports = { */ async saveToDb(subsets) { if (!_.isArray(subsets) || subsets.length === 0) { - subsets = wiki.data.configNamespaces + subsets = WIKI.data.configNamespaces } try { for (let set of subsets) { - await wiki.db.Setting.upsert({ + await WIKI.db.Setting.upsert({ key: set, - config: _.get(wiki.config, set, {}) + config: _.get(WIKI.config, set, {}) }) } } catch (err) { - wiki.logger.error(`Failed to save configuration to DB: ${err.message}`) + WIKI.logger.error(`Failed to save configuration to DB: ${err.message}`) return false } diff --git a/server/core/db.js b/server/core/db.js index 4f19b5b5..2771908a 100644 --- a/server/core/db.js +++ b/server/core/db.js @@ -4,7 +4,7 @@ const path = require('path') const Promise = require('bluebird') const Sequelize = require('sequelize') -/* global wiki */ +/* global WIKI */ const operatorsAliases = { $eq: Sequelize.Op.eq, @@ -57,30 +57,30 @@ module.exports = { */ init() { let self = this - let dbModelsPath = path.join(wiki.SERVERPATH, 'models') + let dbModelsPath = path.join(WIKI.SERVERPATH, 'models') // Define Sequelize instance - this.inst = new this.Sequelize(wiki.config.db.db, wiki.config.db.user, wiki.config.db.pass, { - host: wiki.config.db.host, - port: wiki.config.db.port, + this.inst = new this.Sequelize(WIKI.config.db.db, WIKI.config.db.user, WIKI.config.db.pass, { + host: WIKI.config.db.host, + port: WIKI.config.db.port, dialect: 'postgres', pool: { max: 10, min: 0, idle: 10000 }, - logging: log => { wiki.logger.log('debug', log) }, + logging: log => { WIKI.logger.log('debug', log) }, operatorsAliases }) // Attempt to connect and authenticate to DB this.inst.authenticate().then(() => { - wiki.logger.info('Database (PostgreSQL) connection: [ OK ]') + WIKI.logger.info('Database (PostgreSQL) connection: [ OK ]') }).catch(err => { - wiki.logger.error('Failed to connect to PostgreSQL instance.') - wiki.logger.error(err) + WIKI.logger.error('Failed to connect to PostgreSQL instance.') + WIKI.logger.error(err) process.exit(1) }) @@ -107,16 +107,16 @@ module.exports = { syncSchemas() { return self.inst.sync({ force: false, - logging: log => { wiki.logger.log('debug', log) } + logging: log => { WIKI.logger.log('debug', log) } }) }, // -> Set Connection App Name setAppName() { - return self.inst.query(`set application_name = 'Wiki.js'`, { raw: true }) + return self.inst.query(`set application_name = 'WIKI.js'`, { raw: true }) } } - let initTasksQueue = (wiki.IS_MASTER) ? [ + let initTasksQueue = (WIKI.IS_MASTER) ? [ initTasks.syncSchemas, initTasks.setAppName ] : [ diff --git a/server/core/graphql.js b/server/core/graphql.js deleted file mode 100644 index 33c032cd..00000000 --- a/server/core/graphql.js +++ /dev/null @@ -1,41 +0,0 @@ -const _ = require('lodash') -const fs = require('fs') -const gqlTools = require('graphql-tools') -const path = require('path') - -/* global wiki */ - -const typeDefs = fs.readFileSync(path.join(wiki.SERVERPATH, 'schemas/types.graphql'), 'utf8') - -const DateScalar = require('../schemas/scalar-date') -const AuthenticationResolvers = require('../schemas/resolvers-authentication') -const CommentResolvers = require('../schemas/resolvers-comment') -const DocumentResolvers = require('../schemas/resolvers-document') -const FileResolvers = require('../schemas/resolvers-file') -const FolderResolvers = require('../schemas/resolvers-folder') -const GroupResolvers = require('../schemas/resolvers-group') -const SettingResolvers = require('../schemas/resolvers-setting') -const TagResolvers = require('../schemas/resolvers-tag') -const TranslationResolvers = require('../schemas/resolvers-translation') -const UserResolvers = require('../schemas/resolvers-user') - -const resolvers = _.merge( - AuthenticationResolvers, - CommentResolvers, - DocumentResolvers, - FileResolvers, - FolderResolvers, - GroupResolvers, - SettingResolvers, - TagResolvers, - TranslationResolvers, - UserResolvers, - DateScalar -) - -const Schema = gqlTools.makeExecutableSchema({ - typeDefs, - resolvers -}) - -module.exports = Schema diff --git a/server/core/kernel.js b/server/core/kernel.js index f697c47e..f74d2c2c 100644 --- a/server/core/kernel.js +++ b/server/core/kernel.js @@ -2,19 +2,19 @@ const _ = require('lodash') const cluster = require('cluster') const Promise = require('bluebird') -/* global wiki */ +/* global WIKI */ module.exports = { numWorkers: 1, workers: [], init() { if (cluster.isMaster) { - wiki.logger.info('=======================================') - wiki.logger.info('= Wiki.js =============================') - wiki.logger.info('=======================================') + WIKI.logger.info('=======================================') + WIKI.logger.info('= WIKI.js =============================') + WIKI.logger.info('=======================================') - wiki.redis = require('./redis').init() - wiki.queue = require('./queue').init() + WIKI.redis = require('./redis').init() + WIKI.queue = require('./queue').init() this.setWorkerLimit() this.bootMaster() @@ -27,9 +27,9 @@ module.exports = { */ preBootMaster() { return Promise.mapSeries([ - () => { return wiki.db.onReady }, - () => { return wiki.configSvc.loadFromDb() }, - () => { return wiki.queue.clean() } + () => { return WIKI.db.onReady }, + () => { return WIKI.configSvc.loadFromDb() }, + () => { return WIKI.queue.clean() } ], fn => { return fn() }) }, /** @@ -37,15 +37,15 @@ module.exports = { */ bootMaster() { this.preBootMaster().then(sequenceResults => { - if (_.every(sequenceResults, rs => rs === true) && wiki.config.configMode !== 'setup') { + if (_.every(sequenceResults, rs => rs === true) && WIKI.config.configMode !== 'setup') { this.postBootMaster() } else { - wiki.logger.info('Starting configuration manager...') + WIKI.logger.info('Starting configuration manager...') require('../setup')() } return true }).catch(err => { - wiki.logger.error(err) + WIKI.logger.error(err) process.exit(1) }) }, @@ -59,13 +59,13 @@ module.exports = { this.spawnWorker() }) - wiki.queue.uplClearTemp.add({}, { + WIKI.queue.uplClearTemp.add({}, { repeat: { cron: '*/15 * * * *' } }) cluster.on('exit', (worker, code, signal) => { if (!global.DEV) { - wiki.logger.info(`Background Worker #${worker.id} was terminated.`) + WIKI.logger.info(`Background Worker #${worker.id} was terminated.`) } }) }, @@ -73,7 +73,7 @@ module.exports = { * Boot Worker Process */ bootWorker() { - wiki.logger.info(`Background Worker #${cluster.worker.id} is initializing...`) + WIKI.logger.info(`Background Worker #${cluster.worker.id} is initializing...`) require('../worker') }, /** @@ -87,7 +87,7 @@ module.exports = { */ setWorkerLimit() { const numCPUs = require('os').cpus().length - this.numWorkers = (wiki.config.workers > 0) ? wiki.config.workers : numCPUs + this.numWorkers = (WIKI.config.workers > 0) ? WIKI.config.workers : numCPUs if (this.numWorkers > numCPUs) { this.numWorkers = numCPUs } diff --git a/server/core/localization.js b/server/core/localization.js index c178cb4c..348fb745 100644 --- a/server/core/localization.js +++ b/server/core/localization.js @@ -6,24 +6,24 @@ const i18next = require('i18next') const path = require('path') const Promise = require('bluebird') -/* global wiki */ +/* global WIKI */ module.exports = { engine: null, namespaces: [], init() { - this.namespaces = wiki.data.localeNamespaces + this.namespaces = WIKI.data.localeNamespaces this.engine = i18next this.engine.use(i18nBackend).init({ load: 'languageOnly', ns: this.namespaces, defaultNS: 'common', saveMissing: false, - preload: [wiki.config.site.lang], - lng: wiki.config.site.lang, + preload: [WIKI.config.site.lang], + lng: WIKI.config.site.lang, fallbackLng: 'en', backend: { - loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml') + loadPath: path.join(WIKI.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml') } }) return this diff --git a/server/core/logger.js b/server/core/logger.js index a3bc3b1c..1b6b1dbe 100644 --- a/server/core/logger.js +++ b/server/core/logger.js @@ -3,7 +3,7 @@ const cluster = require('cluster') const fs = require('fs-extra') const path = require('path') -/* global wiki */ +/* global WIKI */ module.exports = { loggers: {}, @@ -11,7 +11,7 @@ module.exports = { let winston = require('winston') let logger = new (winston.Logger)({ - level: wiki.config.logLevel, + level: WIKI.config.logLevel, transports: [] }) @@ -20,10 +20,10 @@ module.exports = { return '[' + processName + '] ' + msg }) - _.forOwn(_.omitBy(wiki.config.logging.loggers, s => s.enabled === false), (loggerConfig, loggerKey) => { + _.forOwn(_.omitBy(WIKI.config.logging.loggers, s => s.enabled === false), (loggerConfig, loggerKey) => { let loggerModule = require(`../modules/logging/${loggerKey}`) loggerModule.init(logger, loggerConfig) - fs.readFile(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${loggerKey}.svg`), 'utf8').then(iconData => { + fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${loggerKey}.svg`), 'utf8').then(iconData => { logger.icon = iconData }).catch(err => { if (err.code === 'ENOENT') { diff --git a/server/core/queue.js b/server/core/queue.js index 158081fd..dfce3afb 100644 --- a/server/core/queue.js +++ b/server/core/queue.js @@ -1,35 +1,35 @@ const Bull = require('bull') const Promise = require('bluebird') -/* global wiki */ +/* global WIKI */ module.exports = { init() { - wiki.data.queues.forEach(queueName => { + WIKI.data.queues.forEach(queueName => { this[queueName] = new Bull(queueName, { - prefix: `q-${wiki.config.ha.nodeuid}`, - redis: wiki.config.redis + prefix: `q-${WIKI.config.ha.nodeuid}`, + redis: WIKI.config.redis }) }) return this }, clean() { - return Promise.each(wiki.data.queues, queueName => { + return Promise.each(WIKI.data.queues, queueName => { return new Promise((resolve, reject) => { - let keyStream = wiki.redis.scanStream({ - match: `q-${wiki.config.ha.nodeuid}:${queueName}:*` + let keyStream = WIKI.redis.scanStream({ + match: `q-${WIKI.config.ha.nodeuid}:${queueName}:*` }) keyStream.on('data', resultKeys => { if (resultKeys.length > 0) { - wiki.redis.del(resultKeys) + WIKI.redis.del(resultKeys) } }) keyStream.on('end', resolve) }) }).then(() => { - wiki.logger.info('Purging old queue jobs: [ OK ]') + WIKI.logger.info('Purging old queue jobs: [ OK ]') }).return(true).catch(err => { - wiki.logger.error(err) + WIKI.logger.error(err) }) } } diff --git a/server/core/redis.js b/server/core/redis.js index 4cd7cfd3..06594b18 100644 --- a/server/core/redis.js +++ b/server/core/redis.js @@ -1,22 +1,22 @@ const Redis = require('ioredis') const { isPlainObject } = require('lodash') -/* global wiki */ +/* global WIKI */ module.exports = { init() { - if (isPlainObject(wiki.config.redis)) { - let red = new Redis(wiki.config.redis) + if (isPlainObject(WIKI.config.redis)) { + let red = new Redis(WIKI.config.redis) red.on('ready', () => { - wiki.logger.info('Redis connection: [ OK ]') + WIKI.logger.info('Redis connection: [ OK ]') }) red.on('error', () => { - wiki.logger.error('Failed to connect to Redis instance!') + WIKI.logger.error('Failed to connect to Redis instance!') process.exit(1) }) return red } else { - wiki.logger.error('Invalid Redis configuration!') + WIKI.logger.error('Invalid Redis configuration!') process.exit(1) } } diff --git a/server/core/system.js b/server/core/system.js index 9c181f5c..c59b3e9b 100644 --- a/server/core/system.js +++ b/server/core/system.js @@ -2,18 +2,18 @@ const _ = require('lodash') const cfgHelper = require('../helpers/config') const Promise = require('bluebird') -/* global wiki */ +/* global WIKI */ module.exports = { /** - * Upgrade from Wiki.js 1.x - MongoDB database + * Upgrade from WIKI.js 1.x - MongoDB database * * @param {Object} opts Options object */ async upgradeFromMongo (opts) { - wiki.telemetry.sendEvent('setup', 'upgradeFromMongo') + WIKI.telemetry.sendEvent('setup', 'upgradeFromMongo') - wiki.logger.info('Upgrading from MongoDB...') + WIKI.logger.info('Upgrading from MongoDB...') let mongo = require('mongodb').MongoClient let parsedMongoConStr = cfgHelper.parseConfigValue(opts.mongoCnStr) @@ -45,7 +45,7 @@ module.exports = { $not: 'guest' } }).toArray() - await wiki.db.User.bulkCreate(_.map(userData, usr => { + await WIKI.db.User.bulkCreate(_.map(userData, usr => { return { email: usr.email, name: usr.name || 'Imported User', diff --git a/server/core/telemetry.js b/server/core/telemetry.js index b7dc6ff5..a926c3f9 100644 --- a/server/core/telemetry.js +++ b/server/core/telemetry.js @@ -4,27 +4,27 @@ const bugsnag = require('bugsnag') const path = require('path') const uuid = require('uuid/v4') -/* global wiki */ +/* global WIKI */ module.exports = { cid: '', enabled: false, init() { this.cid = uuid() - bugsnag.register(wiki.data.telemetry.BUGSNAG_ID, { - appVersion: wiki.version, + bugsnag.register(WIKI.data.telemetry.BUGSNAG_ID, { + appVersion: WIKI.version, autoNotify: false, hostname: this.cid, notifyReleaseStages: ['production'], - packageJSON: path.join(wiki.ROOTPATH, 'package.json'), - projectRoot: wiki.ROOTPATH, + packageJSON: path.join(WIKI.ROOTPATH, 'package.json'), + projectRoot: WIKI.ROOTPATH, useSSL: true }) bugsnag.onBeforeNotify((notification, originalError) => { if (!this.enabled) { return false } }) - if (_.get(wiki.config, 'logging.telemetry', false) === true) { + if (_.get(WIKI.config, 'logging.telemetry', false) === true) { this.enabled = true } @@ -37,13 +37,13 @@ module.exports = { if (!this.enabled) { return false } axios({ method: 'post', - url: wiki.data.telemetry.GA_REMOTE, + url: WIKI.data.telemetry.GA_REMOTE, headers: { 'Content-type': 'application/x-www-form-urlencoded' }, params: { v: 1, // API version - tid: wiki.data.telemetry.GA_ID, // Tracking ID + tid: WIKI.data.telemetry.GA_ID, // Tracking ID aip: 1, // Anonymize IP ds: 'server', // Data source cid: this.cid, // Client ID @@ -54,10 +54,10 @@ module.exports = { } }).then(resp => { if (resp.status !== 200) { - wiki.logger.warn('Unable to send analytics telemetry request.') + WIKI.logger.warn('Unable to send analytics telemetry request.') } }, err => { - wiki.logger.warn('Unable to send analytics telemetry request.') + WIKI.logger.warn('Unable to send analytics telemetry request.') }) } } diff --git a/server/graph/index.js b/server/graph/index.js new file mode 100644 index 00000000..5ca53a9f --- /dev/null +++ b/server/graph/index.js @@ -0,0 +1,34 @@ +const _ = require('lodash') +const fs = require('fs') +const gqlTools = require('graphql-tools') +const path = require('path') +const autoload = require('auto-load') + +/* global WIKI */ + +WIKI.logger.info(`Loading GraphQL Schema...`) + +// Schemas + +let typeDefs = [] +let schemas = fs.readdirSync(path.join(WIKI.SERVERPATH, 'graph/schemas')) +schemas.forEach(schema => { + typeDefs.push(fs.readFileSync(path.join(WIKI.SERVERPATH, `graph/schemas/${schema}`), 'utf8')) +}) + +// Resolvers + +let resolvers = {} +const resolversObj = _.values(autoload(path.join(WIKI.SERVERPATH, 'graph/resolvers'))) +resolversObj.forEach(resolver => { + _.merge(resolvers, resolver) +}) + +const Schema = gqlTools.makeExecutableSchema({ + typeDefs, + resolvers +}) + +WIKI.logger.info(`GraphQL Schema: [ OK ]`) + +module.exports = Schema diff --git a/server/schemas/resolvers-authentication.js b/server/graph/resolvers/authentication.js similarity index 71% rename from server/schemas/resolvers-authentication.js rename to server/graph/resolvers/authentication.js index 572c9d37..0145845f 100644 --- a/server/schemas/resolvers-authentication.js +++ b/server/graph/resolvers/authentication.js @@ -2,14 +2,20 @@ const _ = require('lodash') const fs = require('fs-extra') const path = require('path') -/* global wiki */ +/* global WIKI */ module.exports = { Query: { - authentication(obj, args, context, info) { + async authentication() { return {} } + }, + Mutation: { + async authentication() { return {} } + }, + AuthenticationQuery: { + providers(obj, args, context, info) { switch (args.mode) { case 'active': - let strategies = _.chain(wiki.auth.strategies).map(str => { + let strategies = _.chain(WIKI.auth.strategies).map(str => { return { key: str.key, title: str.title, @@ -26,10 +32,9 @@ module.exports = { } } }, - Mutation: {}, AuthenticationProvider: { icon (ap, args) { - return fs.readFileAsync(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${ap.key}.svg`), 'utf8').catch(err => { + return fs.readFileAsync(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${ap.key}.svg`), 'utf8').catch(err => { if (err.code === 'ENOENT') { return null } diff --git a/server/schemas/resolvers-comment.js b/server/graph/resolvers/comment.js similarity index 76% rename from server/schemas/resolvers-comment.js rename to server/graph/resolvers/comment.js index fec565b3..7ed2f0e6 100644 --- a/server/schemas/resolvers-comment.js +++ b/server/graph/resolvers/comment.js @@ -1,22 +1,22 @@ -/* global wiki */ +/* global WIKI */ module.exports = { Query: { comments(obj, args, context, info) { - return wiki.db.Comment.findAll({ where: args }) + return WIKI.db.Comment.findAll({ where: args }) } }, Mutation: { createComment(obj, args) { - return wiki.db.Comment.create({ + return WIKI.db.Comment.create({ content: args.content, author: args.userId, document: args.documentId }) }, deleteComment(obj, args) { - return wiki.db.Comment.destroy({ + return WIKI.db.Comment.destroy({ where: { id: args.id }, @@ -24,7 +24,7 @@ module.exports = { }) }, modifyComment(obj, args) { - return wiki.db.Comment.update({ + return WIKI.db.Comment.update({ content: args.content }, { where: { id: args.id } diff --git a/server/schemas/resolvers-document.js b/server/graph/resolvers/document.js similarity index 73% rename from server/schemas/resolvers-document.js rename to server/graph/resolvers/document.js index 41dc9160..b8fa486a 100644 --- a/server/schemas/resolvers-document.js +++ b/server/graph/resolvers/document.js @@ -1,18 +1,18 @@ -/* global wiki */ +/* global WIKI */ module.exports = { Query: { documents(obj, args, context, info) { - return wiki.db.Document.findAll({ where: args }) + return WIKI.db.Document.findAll({ where: args }) } }, Mutation: { createDocument(obj, args) { - return wiki.db.Document.create(args) + return WIKI.db.Document.create(args) }, deleteDocument(obj, args) { - return wiki.db.Document.destroy({ + return WIKI.db.Document.destroy({ where: { id: args.id }, @@ -20,7 +20,7 @@ module.exports = { }) }, modifyDocument(obj, args) { - return wiki.db.Document.update({ + return WIKI.db.Document.update({ title: args.title, subtitle: args.subtitle }, { @@ -28,7 +28,7 @@ module.exports = { }) }, moveDocument(obj, args) { - return wiki.db.Document.update({ + return WIKI.db.Document.update({ path: args.path }, { where: { id: args.id } diff --git a/server/schemas/resolvers-file.js b/server/graph/resolvers/file.js similarity index 71% rename from server/schemas/resolvers-file.js rename to server/graph/resolvers/file.js index c8913413..60802701 100644 --- a/server/schemas/resolvers-file.js +++ b/server/graph/resolvers/file.js @@ -1,21 +1,21 @@ -/* global wiki */ +/* global WIKI */ const gql = require('graphql') module.exports = { Query: { files(obj, args, context, info) { - return wiki.db.File.findAll({ where: args }) + return WIKI.db.File.findAll({ where: args }) } }, Mutation: { uploadFile(obj, args) { // todo - return wiki.db.File.create(args) + return WIKI.db.File.create(args) }, deleteFile(obj, args) { - return wiki.db.File.destroy({ + return WIKI.db.File.destroy({ where: { id: args.id }, @@ -23,18 +23,18 @@ module.exports = { }) }, renameFile(obj, args) { - return wiki.db.File.update({ + return WIKI.db.File.update({ filename: args.filename }, { where: { id: args.id } }) }, moveFile(obj, args) { - return wiki.db.File.findById(args.fileId).then(fl => { + return WIKI.db.File.findById(args.fileId).then(fl => { if (!fl) { throw new gql.GraphQLError('Invalid File ID') } - return wiki.db.Folder.findById(args.folderId).then(fld => { + return WIKI.db.Folder.findById(args.folderId).then(fld => { if (!fld) { throw new gql.GraphQLError('Invalid Folder ID') } diff --git a/server/schemas/resolvers-folder.js b/server/graph/resolvers/folder.js similarity index 69% rename from server/schemas/resolvers-folder.js rename to server/graph/resolvers/folder.js index b7fc9a2b..f1e341dd 100644 --- a/server/schemas/resolvers-folder.js +++ b/server/graph/resolvers/folder.js @@ -1,18 +1,18 @@ -/* global wiki */ +/* global WIKI */ module.exports = { Query: { folders(obj, args, context, info) { - return wiki.db.Folder.findAll({ where: args }) + return WIKI.db.Folder.findAll({ where: args }) } }, Mutation: { createFolder(obj, args) { - return wiki.db.Folder.create(args) + return WIKI.db.Folder.create(args) }, deleteGroup(obj, args) { - return wiki.db.Folder.destroy({ + return WIKI.db.Folder.destroy({ where: { id: args.id }, @@ -20,7 +20,7 @@ module.exports = { }) }, renameFolder(obj, args) { - return wiki.db.Folder.update({ + return WIKI.db.Folder.update({ name: args.name }, { where: { id: args.id } diff --git a/server/schemas/resolvers-group.js b/server/graph/resolvers/group.js similarity index 69% rename from server/schemas/resolvers-group.js rename to server/graph/resolvers/group.js index cc9b10b7..ee4852de 100644 --- a/server/schemas/resolvers-group.js +++ b/server/graph/resolvers/group.js @@ -1,21 +1,21 @@ -/* global wiki */ +/* global WIKI */ const gql = require('graphql') module.exports = { Query: { groups(obj, args, context, info) { - return wiki.db.Group.findAll({ where: args }) + return WIKI.db.Group.findAll({ where: args }) } }, Mutation: { assignUserToGroup(obj, args) { - return wiki.db.Group.findById(args.groupId).then(grp => { + return WIKI.db.Group.findById(args.groupId).then(grp => { if (!grp) { throw new gql.GraphQLError('Invalid Group ID') } - return wiki.db.User.findById(args.userId).then(usr => { + return WIKI.db.User.findById(args.userId).then(usr => { if (!usr) { throw new gql.GraphQLError('Invalid User ID') } @@ -24,10 +24,10 @@ module.exports = { }) }, createGroup(obj, args) { - return wiki.db.Group.create(args) + return WIKI.db.Group.create(args) }, deleteGroup(obj, args) { - return wiki.db.Group.destroy({ + return WIKI.db.Group.destroy({ where: { id: args.id }, @@ -35,11 +35,11 @@ module.exports = { }) }, removeUserFromGroup(obj, args) { - return wiki.db.Group.findById(args.groupId).then(grp => { + return WIKI.db.Group.findById(args.groupId).then(grp => { if (!grp) { throw new gql.GraphQLError('Invalid Group ID') } - return wiki.db.User.findById(args.userId).then(usr => { + return WIKI.db.User.findById(args.userId).then(usr => { if (!usr) { throw new gql.GraphQLError('Invalid User ID') } @@ -48,7 +48,7 @@ module.exports = { }) }, renameGroup(obj, args) { - return wiki.db.Group.update({ + return WIKI.db.Group.update({ name: args.name }, { where: { id: args.id } diff --git a/server/schemas/resolvers-right.js b/server/graph/resolvers/right.js similarity index 76% rename from server/schemas/resolvers-right.js rename to server/graph/resolvers/right.js index 3b286deb..4da3ef6a 100644 --- a/server/schemas/resolvers-right.js +++ b/server/graph/resolvers/right.js @@ -1,21 +1,21 @@ -/* global wiki */ +/* global WIKI */ const gql = require('graphql') module.exports = { Query: { rights(obj, args, context, info) { - return wiki.db.Right.findAll({ where: args }) + return WIKI.db.Right.findAll({ where: args }) } }, Mutation: { addRightToGroup(obj, args) { - return wiki.db.Group.findById(args.groupId).then(grp => { + return WIKI.db.Group.findById(args.groupId).then(grp => { if (!grp) { throw new gql.GraphQLError('Invalid Group ID') } - return wiki.db.Right.create({ + return WIKI.db.Right.create({ path: args.path, role: args.role, exact: args.exact, @@ -25,7 +25,7 @@ module.exports = { }) }, removeRightFromGroup(obj, args) { - return wiki.db.Right.destroy({ + return WIKI.db.Right.destroy({ where: { id: args.rightId }, @@ -33,7 +33,7 @@ module.exports = { }) }, modifyRight(obj, args) { - return wiki.db.Right.update({ + return WIKI.db.Right.update({ path: args.path, role: args.role, exact: args.exact, diff --git a/server/schemas/resolvers-setting.js b/server/graph/resolvers/setting.js similarity index 76% rename from server/schemas/resolvers-setting.js rename to server/graph/resolvers/setting.js index dc0c4f9e..077b6376 100644 --- a/server/schemas/resolvers-setting.js +++ b/server/graph/resolvers/setting.js @@ -1,12 +1,12 @@ -/* global wiki */ +/* global WIKI */ const _ = require('lodash') module.exports = { Query: { settings(obj, args, context, info) { - return wiki.db.Setting.findAll({ where: args, raw: true }).then(entries => { + return WIKI.db.Setting.findAll({ where: args, raw: true }).then(entries => { return _.map(entries, entry => { entry.config = JSON.stringify(entry.config) return entry @@ -16,7 +16,7 @@ module.exports = { }, Mutation: { setConfigEntry(obj, args) { - return wiki.db.Setting.update({ + return WIKI.db.Setting.update({ value: args.value }, { where: { key: args.key } }) } diff --git a/server/schemas/resolvers-tag.js b/server/graph/resolvers/tag.js similarity index 71% rename from server/schemas/resolvers-tag.js rename to server/graph/resolvers/tag.js index 0aa3e89e..699af3e8 100644 --- a/server/schemas/resolvers-tag.js +++ b/server/graph/resolvers/tag.js @@ -1,21 +1,21 @@ -/* global wiki */ +/* global WIKI */ const gql = require('graphql') module.exports = { Query: { tags(obj, args, context, info) { - return wiki.db.Tag.findAll({ where: args }) + return WIKI.db.Tag.findAll({ where: args }) } }, Mutation: { assignTagToDocument(obj, args) { - return wiki.db.Tag.findById(args.tagId).then(tag => { + return WIKI.db.Tag.findById(args.tagId).then(tag => { if (!tag) { throw new gql.GraphQLError('Invalid Tag ID') } - return wiki.db.Document.findById(args.documentId).then(doc => { + return WIKI.db.Document.findById(args.documentId).then(doc => { if (!doc) { throw new gql.GraphQLError('Invalid Document ID') } @@ -24,10 +24,10 @@ module.exports = { }) }, createTag(obj, args) { - return wiki.db.Tag.create(args) + return WIKI.db.Tag.create(args) }, deleteTag(obj, args) { - return wiki.db.Tag.destroy({ + return WIKI.db.Tag.destroy({ where: { id: args.id }, @@ -35,11 +35,11 @@ module.exports = { }) }, removeTagFromDocument(obj, args) { - return wiki.db.Tag.findById(args.tagId).then(tag => { + return WIKI.db.Tag.findById(args.tagId).then(tag => { if (!tag) { throw new gql.GraphQLError('Invalid Tag ID') } - return wiki.db.Document.findById(args.documentId).then(doc => { + return WIKI.db.Document.findById(args.documentId).then(doc => { if (!doc) { throw new gql.GraphQLError('Invalid Document ID') } @@ -48,7 +48,7 @@ module.exports = { }) }, renameTag(obj, args) { - return wiki.db.Group.update({ + return WIKI.db.Group.update({ key: args.key }, { where: { id: args.id } diff --git a/server/schemas/resolvers-translation.js b/server/graph/resolvers/translation.js similarity index 60% rename from server/schemas/resolvers-translation.js rename to server/graph/resolvers/translation.js index aed8d57d..ca45bd14 100644 --- a/server/schemas/resolvers-translation.js +++ b/server/graph/resolvers/translation.js @@ -1,10 +1,10 @@ -/* global wiki */ +/* global WIKI */ module.exports = { Query: { translations (obj, args, context, info) { - return wiki.lang.getByNamespace(args.locale, args.namespace) + return WIKI.lang.getByNamespace(args.locale, args.namespace) } }, Mutation: {}, diff --git a/server/schemas/resolvers-user.js b/server/graph/resolvers/user.js similarity index 75% rename from server/schemas/resolvers-user.js rename to server/graph/resolvers/user.js index f02ddc34..b5137b31 100644 --- a/server/schemas/resolvers-user.js +++ b/server/graph/resolvers/user.js @@ -1,18 +1,18 @@ -/* global wiki */ +/* global WIKI */ module.exports = { Query: { users(obj, args, context, info) { - return wiki.db.User.findAll({ where: args }) + return WIKI.db.User.findAll({ where: args }) } }, Mutation: { createUser(obj, args) { - return wiki.db.User.create(args) + return WIKI.db.User.create(args) }, deleteUser(obj, args) { - return wiki.db.User.destroy({ + return WIKI.db.User.destroy({ where: { id: args.id }, @@ -20,7 +20,7 @@ module.exports = { }) }, login(obj, args, context) { - return wiki.db.User.login(args, context).catch(err => { + return WIKI.db.User.login(args, context).catch(err => { return { succeeded: false, message: err.message @@ -28,7 +28,7 @@ module.exports = { }) }, loginTFA(obj, args, context) { - return wiki.db.User.loginTFA(args, context).catch(err => { + return WIKI.db.User.loginTFA(args, context).catch(err => { return { succeeded: false, message: err.message @@ -36,7 +36,7 @@ module.exports = { }) }, modifyUser(obj, args) { - return wiki.db.User.update({ + return WIKI.db.User.update({ email: args.email, name: args.name, provider: args.provider, diff --git a/server/schemas/scalar-date.js b/server/graph/scalars/date.js similarity index 100% rename from server/schemas/scalar-date.js rename to server/graph/scalars/date.js diff --git a/server/graph/schemas/authentication.graphql b/server/graph/schemas/authentication.graphql new file mode 100644 index 00000000..b808f26a --- /dev/null +++ b/server/graph/schemas/authentication.graphql @@ -0,0 +1,23 @@ +extend type Query { + authentication: AuthenticationQuery +} + +extend type Mutation { + authentication: AuthenticationMutation +} + +type AuthenticationQuery { + providers: [AuthenticationProvider] +} + +type AuthenticationMutation + +type AuthenticationProvider { + isEnabled: Boolean! + key: String! + props: [String] + title: String! + useForm: Boolean! + icon: String + config: String +} diff --git a/server/schemas/types.graphql b/server/graph/schemas/common.graphql similarity index 96% rename from server/schemas/types.graphql rename to server/graph/schemas/common.graphql index ce39caa4..6e3b12a3 100644 --- a/server/schemas/types.graphql +++ b/server/graph/schemas/common.graphql @@ -1,6 +1,4 @@ -# SCALARS -scalar Date # ENUMS @@ -31,15 +29,6 @@ interface Base { # TYPES -type AuthenticationProvider { - key: String! - useForm: Boolean! - title: String! - props: [String] - icon: String - config: String -} - type Comment implements Base { id: Int! createdAt: Date @@ -162,7 +151,6 @@ type LoginResult { # Query (Read) type Query { - authentication(mode: String!): [AuthenticationProvider] comments(id: Int): [Comment] documents(id: Int, path: String): [Document] files(id: Int): [File] diff --git a/server/graph/schemas/scalars.graphql b/server/graph/schemas/scalars.graphql new file mode 100644 index 00000000..d8d6cfbd --- /dev/null +++ b/server/graph/schemas/scalars.graphql @@ -0,0 +1,3 @@ +# SCALARS + +scalar Date diff --git a/server/index.js b/server/index.js index 35229613..de96485a 100644 --- a/server/index.js +++ b/server/index.js @@ -6,7 +6,7 @@ const path = require('path') const cluster = require('cluster') -let wiki = { +let WIKI = { IS_DEBUG: process.env.NODE_ENV === 'development', IS_MASTER: cluster.isMaster, ROOTPATH: process.cwd(), @@ -15,41 +15,41 @@ let wiki = { configSvc: require('./core/config'), kernel: require('./core/kernel') } -global.wiki = wiki +global.WIKI = WIKI -// if (wiki.IS_DEBUG) { +// if (WIKI.IS_DEBUG) { // require('@glimpse/glimpse').init() // } -wiki.configSvc.init() +WIKI.configSvc.init() // ---------------------------------------- // Init Logger // ---------------------------------------- -wiki.logger = require('./core/logger').init() +WIKI.logger = require('./core/logger').init() // ---------------------------------------- // Init Telemetry // ---------------------------------------- -wiki.telemetry = require('./core/telemetry').init() +WIKI.telemetry = require('./core/telemetry').init() process.on('unhandledRejection', (err) => { - wiki.telemetry.sendError(err) + WIKI.telemetry.sendError(err) }) process.on('uncaughtException', (err) => { - wiki.telemetry.sendError(err) + WIKI.telemetry.sendError(err) }) // ---------------------------------------- // Init DB // ---------------------------------------- -wiki.db = require('./core/db').init() +WIKI.db = require('./core/db').init() // ---------------------------------------- // Start Kernel // ---------------------------------------- -wiki.kernel.init() +WIKI.kernel.init() diff --git a/server/master.js b/server/master.js index 7edd4168..c36dcb3b 100644 --- a/server/master.js +++ b/server/master.js @@ -10,31 +10,32 @@ const path = require('path') const session = require('express-session') const SessionRedisStore = require('connect-redis')(session) const graphqlApollo = require('apollo-server-express') -const graphqlSchema = require('./core/graphql') +const graphqlSchema = require('./graph') +const oauth2orize = require('oauth2orize') -/* global wiki */ +/* global WIKI */ module.exports = async () => { // ---------------------------------------- // Load core modules // ---------------------------------------- - wiki.auth = require('./core/auth').init() - wiki.lang = require('./core/localization').init() + WIKI.auth = require('./core/auth').init() + WIKI.lang = require('./core/localization').init() // ---------------------------------------- // Load middlewares // ---------------------------------------- - var mw = autoload(path.join(wiki.SERVERPATH, '/middlewares')) - var ctrl = autoload(path.join(wiki.SERVERPATH, '/controllers')) + 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 + WIKI.app = app app.use(compression()) // ---------------------------------------- @@ -42,38 +43,44 @@ module.exports = async () => { // ---------------------------------------- app.use(mw.security) - app.use(cors(wiki.config.cors)) - app.options('*', cors(wiki.config.cors)) + app.use(cors(WIKI.config.cors)) + app.options('*', cors(WIKI.config.cors)) app.enable('trust proxy') // ---------------------------------------- // Public Assets // ---------------------------------------- - app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) - app.use(express.static(path.join(wiki.ROOTPATH, 'assets'), { + app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico'))) + app.use(express.static(path.join(WIKI.ROOTPATH, 'assets'), { index: false, maxAge: '7d' })) + // ---------------------------------------- + // OAuth2 Server + // ---------------------------------------- + + const OAuth2Server = oauth2orize.createServer() + // ---------------------------------------- // Passport Authentication // ---------------------------------------- let sessionStore = new SessionRedisStore({ - client: wiki.redis + client: WIKI.redis }) app.use(cookieParser()) app.use(session({ name: 'wikijs.sid', store: sessionStore, - secret: wiki.config.site.sessionSecret, + secret: WIKI.config.site.sessionSecret, resave: false, saveUninitialized: false })) - app.use(wiki.auth.passport.initialize()) - app.use(wiki.auth.passport.session()) + app.use(WIKI.auth.passport.initialize()) + app.use(WIKI.auth.passport.session()) // ---------------------------------------- // SEO @@ -85,7 +92,7 @@ module.exports = async () => { // View Engine Setup // ---------------------------------------- - app.set('views', path.join(wiki.SERVERPATH, 'views')) + app.set('views', path.join(WIKI.SERVERPATH, 'views')) app.set('view engine', 'pug') app.use(bodyParser.json({ limit: '1mb' })) @@ -95,17 +102,17 @@ module.exports = async () => { // Localization // ---------------------------------------- - wiki.lang.attachMiddleware(app) + WIKI.lang.attachMiddleware(app) // ---------------------------------------- // View accessible data // ---------------------------------------- - app.locals.basedir = wiki.ROOTPATH + app.locals.basedir = WIKI.ROOTPATH app.locals._ = require('lodash') app.locals.moment = require('moment') - app.locals.moment.locale(wiki.config.site.lang) - app.locals.config = wiki.config + app.locals.moment.locale(WIKI.config.site.lang) + app.locals.config = WIKI.config // ---------------------------------------- // HMR (Dev Mode Only) @@ -151,7 +158,7 @@ module.exports = async () => { res.status(err.status || 500) res.render('error', { message: err.message, - error: wiki.IS_DEBUG ? err : {} + error: WIKI.IS_DEBUG ? err : {} }) }) @@ -161,13 +168,13 @@ module.exports = async () => { let srvConnections = {} - wiki.logger.info(`HTTP Server on port: [ ${wiki.config.port} ]`) + WIKI.logger.info(`HTTP Server on port: [ ${WIKI.config.port} ]`) - app.set('port', wiki.config.port) - wiki.server = http.createServer(app) + app.set('port', WIKI.config.port) + WIKI.server = http.createServer(app) - wiki.server.listen(wiki.config.port) - wiki.server.on('error', (error) => { + WIKI.server.listen(WIKI.config.port) + WIKI.server.on('error', (error) => { if (error.syscall !== 'listen') { throw error } @@ -175,17 +182,17 @@ module.exports = async () => { // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!') + 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!') + WIKI.logger.error('Port ' + WIKI.config.port + ' is already in use!') return process.exit(1) default: throw error } }) - wiki.server.on('connection', conn => { + WIKI.server.on('connection', conn => { let key = `${conn.remoteAddress}:${conn.remotePort}` srvConnections[key] = conn conn.on('close', function() { @@ -193,12 +200,12 @@ module.exports = async () => { }) }) - wiki.server.on('listening', () => { - wiki.logger.info('HTTP Server: [ RUNNING ]') + WIKI.server.on('listening', () => { + WIKI.logger.info('HTTP Server: [ RUNNING ]') }) - wiki.server.destroy = (cb) => { - wiki.server.close(cb) + WIKI.server.destroy = (cb) => { + WIKI.server.close(cb) for (let key in srvConnections) { srvConnections[key].destroy() } diff --git a/server/middlewares/auth.js b/server/middlewares/auth.js index 0e71911f..866f76e4 100644 --- a/server/middlewares/auth.js +++ b/server/middlewares/auth.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ /** * Authentication middleware @@ -7,7 +7,7 @@ module.exports = (req, res, next) => { // Is user authenticated ? if (!req.isAuthenticated()) { - if (wiki.config.auth.public !== true) { + if (WIKI.config.auth.public !== true) { return res.redirect('/login') } else { // req.user = rights.guest diff --git a/server/models/user.js b/server/models/user.js index d4c4ef5c..90405846 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ const Promise = require('bluebird') const bcrypt = require('bcryptjs-then') @@ -62,13 +62,13 @@ module.exports = (sequelize, DataTypes) => { if (await bcrypt.compare(rawPwd, this.password) === true) { return true } else { - throw new wiki.Error.AuthLoginFailed() + throw new WIKI.Error.AuthLoginFailed() } } userSchema.prototype.enableTFA = async function () { let tfaInfo = tfa.generateSecret({ - name: wiki.config.site.title + name: WIKI.config.site.title }) this.tfaIsActive = true this.tfaSecret = tfaInfo.secret @@ -87,21 +87,21 @@ module.exports = (sequelize, DataTypes) => { } userSchema.login = async (opts, context) => { - if (_.has(wiki.config.auth.strategies, opts.provider)) { + if (_.has(WIKI.config.auth.strategies, opts.provider)) { _.set(context.req, 'body.email', opts.username) _.set(context.req, 'body.password', opts.password) // Authenticate return new Promise((resolve, reject) => { - wiki.auth.passport.authenticate(opts.provider, async (err, user, info) => { + WIKI.auth.passport.authenticate(opts.provider, async (err, user, info) => { if (err) { return reject(err) } - if (!user) { return reject(new wiki.Error.AuthLoginFailed()) } + if (!user) { return reject(new WIKI.Error.AuthLoginFailed()) } // Is 2FA required? if (user.tfaIsActive) { try { let loginToken = await securityHelper.generateToken(32) - await wiki.redis.set(`tfa:${loginToken}`, user.id, 'EX', 600) + await WIKI.redis.set(`tfa:${loginToken}`, user.id, 'EX', 600) return resolve({ succeeded: true, message: 'Login Successful. Awaiting 2FA security code.', @@ -109,8 +109,8 @@ module.exports = (sequelize, DataTypes) => { tfaLoginToken: loginToken }) } catch (err) { - wiki.logger.warn(err) - return reject(new wiki.Error.AuthGenericError()) + WIKI.logger.warn(err) + return reject(new WIKI.Error.AuthGenericError()) } } else { // No 2FA, log in user @@ -126,17 +126,17 @@ module.exports = (sequelize, DataTypes) => { })(context.req, context.res, () => {}) }) } else { - throw new wiki.Error.AuthProviderInvalid() + throw new WIKI.Error.AuthProviderInvalid() } } userSchema.loginTFA = async (opts, context) => { if (opts.securityCode.length === 6 && opts.loginToken.length === 64) { - let result = await wiki.redis.get(`tfa:${opts.loginToken}`) + let result = await WIKI.redis.get(`tfa:${opts.loginToken}`) if (result) { let userId = _.toSafeInteger(result) if (userId && userId > 0) { - let user = await wiki.db.User.findById(userId) + let user = await WIKI.db.User.findById(userId) if (user && user.verifyTFA(opts.securityCode)) { return Promise.fromCallback(clb => { context.req.logIn(user, clb) @@ -144,16 +144,16 @@ module.exports = (sequelize, DataTypes) => { succeeded: true, message: 'Login Successful' }).catch(err => { - wiki.logger.warn(err) - throw new wiki.Error.AuthGenericError() + WIKI.logger.warn(err) + throw new WIKI.Error.AuthGenericError() }) } else { - throw new wiki.Error.AuthTFAFailed() + throw new WIKI.Error.AuthTFAFailed() } } } } - throw new wiki.Error.AuthTFAInvalid() + throw new WIKI.Error.AuthTFAInvalid() } userSchema.processProfile = (profile) => { @@ -168,13 +168,13 @@ module.exports = (sequelize, DataTypes) => { } else if (profile.user && profile.user.email && profile.user.email.length > 5) { primaryEmail = profile.user.email } else { - return Promise.reject(new Error(wiki.lang.t('auth:errors.invaliduseremail'))) + return Promise.reject(new Error(WIKI.lang.t('auth:errors.invaliduseremail'))) } profile.provider = _.lowerCase(profile.provider) primaryEmail = _.toLower(primaryEmail) - return wiki.db.User.findOneAndUpdate({ + return WIKI.db.User.findOneAndUpdate({ email: primaryEmail, provider: profile.provider }, { @@ -186,7 +186,7 @@ module.exports = (sequelize, DataTypes) => { new: true }).then((user) => { // Handle unregistered accounts - if (!user && profile.provider !== 'local' && (wiki.config.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) { + if (!user && profile.provider !== 'local' && (WIKI.config.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) { let nUsr = { email: primaryEmail, provider: profile.provider, @@ -200,9 +200,9 @@ module.exports = (sequelize, DataTypes) => { deny: false }] } - return wiki.db.User.create(nUsr) + return WIKI.db.User.create(nUsr) } - return user || Promise.reject(new Error(wiki.lang.t('auth:errors:notyetauthorized'))) + return user || Promise.reject(new Error(WIKI.lang.t('auth:errors:notyetauthorized'))) }) } diff --git a/server/modules/authentication/auth0.js b/server/modules/authentication/auth0.js index 63146980..453c0dab 100644 --- a/server/modules/authentication/auth0.js +++ b/server/modules/authentication/auth0.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Auth0 Account @@ -19,7 +19,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, function (accessToken, refreshToken, profile, cb) { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/azure.js b/server/modules/authentication/azure.js index 5d75bd4f..ad191a3c 100644 --- a/server/modules/authentication/azure.js +++ b/server/modules/authentication/azure.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Azure AD Account @@ -24,7 +24,7 @@ module.exports = { let waadProfile = jwt.decode(params.id_token) waadProfile.id = waadProfile.oid waadProfile.provider = 'azure' - wiki.db.User.processProfile(waadProfile).then((user) => { + WIKI.db.User.processProfile(waadProfile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/discord.js b/server/modules/authentication/discord.js index eb2676c2..2e22b1b7 100644 --- a/server/modules/authentication/discord.js +++ b/server/modules/authentication/discord.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Discord Account @@ -19,7 +19,7 @@ module.exports = { callbackURL: conf.callbackURL, scope: 'identify email' }, function (accessToken, refreshToken, profile, cb) { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/dropbox.js b/server/modules/authentication/dropbox.js index 5367e892..b20050a3 100644 --- a/server/modules/authentication/dropbox.js +++ b/server/modules/authentication/dropbox.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Dropbox Account @@ -19,7 +19,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, (accessToken, refreshToken, profile, cb) => { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/facebook.js b/server/modules/authentication/facebook.js index f0e33da5..374e7dd8 100644 --- a/server/modules/authentication/facebook.js +++ b/server/modules/authentication/facebook.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Facebook Account @@ -19,7 +19,7 @@ module.exports = { callbackURL: conf.callbackURL, profileFields: ['id', 'displayName', 'email'] }, function (accessToken, refreshToken, profile, cb) { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/github.js b/server/modules/authentication/github.js index 941ced15..aaf92e7c 100644 --- a/server/modules/authentication/github.js +++ b/server/modules/authentication/github.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // GitHub Account @@ -19,7 +19,7 @@ module.exports = { callbackURL: conf.callbackURL, scope: ['user:email'] }, (accessToken, refreshToken, profile, cb) => { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/google.js b/server/modules/authentication/google.js index e2fb4824..0298058f 100644 --- a/server/modules/authentication/google.js +++ b/server/modules/authentication/google.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Google ID Account @@ -18,7 +18,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, (accessToken, refreshToken, profile, cb) => { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/ldap.js b/server/modules/authentication/ldap.js index d2e39a8b..1991b019 100644 --- a/server/modules/authentication/ldap.js +++ b/server/modules/authentication/ldap.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // LDAP Account @@ -33,7 +33,7 @@ module.exports = { }, (profile, cb) => { profile.provider = 'ldap' profile.id = profile.dn - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/local.js b/server/modules/authentication/local.js index f712d3ae..db96f8d8 100644 --- a/server/modules/authentication/local.js +++ b/server/modules/authentication/local.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Local Account @@ -17,7 +17,7 @@ module.exports = { usernameField: 'email', passwordField: 'password' }, (uEmail, uPassword, done) => { - wiki.db.User.findOne({ + WIKI.db.User.findOne({ where: { email: uEmail, provider: 'local' @@ -30,7 +30,7 @@ module.exports = { return done(err, null) }) } else { - return done(new wiki.Error.AuthLoginFailed(), null) + return done(new WIKI.Error.AuthLoginFailed(), null) } }).catch((err) => { done(err, null) diff --git a/server/modules/authentication/microsoft.js b/server/modules/authentication/microsoft.js index 1f61dbbb..989373c3 100644 --- a/server/modules/authentication/microsoft.js +++ b/server/modules/authentication/microsoft.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Microsoft Account @@ -18,7 +18,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, function (accessToken, refreshToken, profile, cb) { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/oauth2.js b/server/modules/authentication/oauth2.js index f2e9f12e..6f930efe 100644 --- a/server/modules/authentication/oauth2.js +++ b/server/modules/authentication/oauth2.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // OAuth2 Account @@ -20,7 +20,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, (accessToken, refreshToken, profile, cb) => { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/slack.js b/server/modules/authentication/slack.js index 04d49c1d..aa0a7e61 100644 --- a/server/modules/authentication/slack.js +++ b/server/modules/authentication/slack.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Slack Account @@ -18,7 +18,7 @@ module.exports = { clientSecret: conf.clientSecret, callbackURL: conf.callbackURL }, (accessToken, refreshToken, profile, cb) => { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/authentication/twitch.js b/server/modules/authentication/twitch.js index 0dae0c1d..10266ac6 100644 --- a/server/modules/authentication/twitch.js +++ b/server/modules/authentication/twitch.js @@ -1,4 +1,4 @@ -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Twitch Account @@ -19,7 +19,7 @@ module.exports = { callbackURL: conf.callbackURL, scope: 'user_read' }, function (accessToken, refreshToken, profile, cb) { - wiki.db.User.processProfile(profile).then((user) => { + WIKI.db.User.processProfile(profile).then((user) => { return cb(null, user) || true }).catch((err) => { return cb(err, null) || true diff --git a/server/modules/logging/console.js b/server/modules/logging/console.js index 13c2b3c5..bb69154b 100644 --- a/server/modules/logging/console.js +++ b/server/modules/logging/console.js @@ -1,6 +1,6 @@ const winston = require('winston') -/* global wiki */ +/* global WIKI */ // ------------------------------------ // Console @@ -12,7 +12,7 @@ module.exports = { props: [], init (logger, conf) { logger.add(winston.transports.Console, { - level: wiki.config.logLevel, + level: WIKI.config.logLevel, prettyPrint: true, colorize: true, silent: false, diff --git a/server/modules/renderer/common/mathjax.js b/server/modules/renderer/common/mathjax.js index ffa8cf2b..8cea97f3 100644 --- a/server/modules/renderer/common/mathjax.js +++ b/server/modules/renderer/common/mathjax.js @@ -5,7 +5,7 @@ const _ = require('lodash') // Mathjax // ------------------------------------ -/* global wiki */ +/* global WIKI */ const mathRegex = [ { @@ -67,7 +67,7 @@ module.exports = { resolve(result.svg) } else { resolve(currentMatch[0]) - wiki.logger.warn(result.errors.join(', ')) + WIKI.logger.warn(result.errors.join(', ')) } }) }) diff --git a/server/queues/git-sync.js b/server/queues/git-sync.js index 6c46e8ef..b19de79f 100644 --- a/server/queues/git-sync.js +++ b/server/queues/git-sync.js @@ -1,6 +1,6 @@ 'use strict' -/* global wiki */ +/* global WIKI */ const Promise = require('bluebird') const fs = Promise.promisifyAll(require('fs-extra')) @@ -10,7 +10,7 @@ const path = require('path') const entryHelper = require('../helpers/entry') module.exports = (job) => { - return wiki.git.resync().then(() => { + return WIKI.git.resync().then(() => { // -> Stream all documents let cacheJobs = [] @@ -19,7 +19,7 @@ module.exports = (job) => { jobCbStreamDocsResolve = resolve }) - klaw(wiki.REPOPATH).on('data', function (item) { + klaw(WIKI.REPOPATH).on('data', function (item) { if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') { let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path)) let cachePath = entryHelper.getCachePath(entryPath) @@ -62,7 +62,7 @@ module.exports = (job) => { return jobCbStreamDocs }).then(() => { - wiki.logger.info('Git remote repository sync: DONE') + WIKI.logger.info('Git remote repository sync: DONE') return true }) } diff --git a/server/queues/upl-clear-temp.js b/server/queues/upl-clear-temp.js index 9c3a1b5b..feb043b8 100644 --- a/server/queues/upl-clear-temp.js +++ b/server/queues/upl-clear-temp.js @@ -1,6 +1,6 @@ 'use strict' -/* global wiki */ +/* global WIKI */ const Promise = require('bluebird') const fs = Promise.promisifyAll(require('fs-extra')) @@ -8,22 +8,22 @@ const moment = require('moment') const path = require('path') module.exports = (job) => { - return fs.readdirAsync(wiki.UPLTEMPPATH).then((ls) => { + return fs.readdirAsync(WIKI.UPLTEMPPATH).then((ls) => { let fifteenAgo = moment().subtract(15, 'minutes') return Promise.map(ls, (f) => { - return fs.statAsync(path.join(wiki.UPLTEMPPATH, f)).then((s) => { return { filename: f, stat: s } }) + return fs.statAsync(path.join(WIKI.UPLTEMPPATH, f)).then((s) => { return { filename: f, stat: s } }) }).filter((s) => { return s.stat.isFile() }).then((arrFiles) => { return Promise.map(arrFiles, (f) => { if (moment(f.stat.ctime).isBefore(fifteenAgo, 'minute')) { - return fs.unlinkAsync(path.join(wiki.UPLTEMPPATH, f.filename)) + return fs.unlinkAsync(path.join(WIKI.UPLTEMPPATH, f.filename)) } else { return true } }) }) }).then(() => { - wiki.logger.info('Purging temporary upload files: DONE') + WIKI.logger.info('Purging temporary upload files: DONE') return true }) } diff --git a/server/setup.js b/server/setup.js index e022cad7..4a6e26b3 100644 --- a/server/setup.js +++ b/server/setup.js @@ -1,14 +1,14 @@ const path = require('path') -/* global wiki */ +/* global WIKI */ module.exports = () => { - wiki.config.site = { + WIKI.config.site = { path: '', - title: 'Wiki.js' + title: 'WIKI.js' } - wiki.system = require('./core/system') + WIKI.system = require('./core/system') // ---------------------------------------- // Load modules @@ -40,21 +40,21 @@ module.exports = () => { // Public Assets // ---------------------------------------- - app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) - app.use(express.static(path.join(wiki.ROOTPATH, 'assets'))) + app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico'))) + app.use(express.static(path.join(WIKI.ROOTPATH, 'assets'))) // ---------------------------------------- // View Engine Setup // ---------------------------------------- - app.set('views', path.join(wiki.SERVERPATH, 'views')) + app.set('views', path.join(WIKI.SERVERPATH, 'views')) app.set('view engine', 'pug') app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) - app.locals.config = wiki.config - app.locals.data = wiki.data + app.locals.config = WIKI.config + app.locals.data = WIKI.data app.locals._ = require('lodash') // ---------------------------------------- @@ -71,10 +71,10 @@ module.exports = () => { // ---------------------------------------- app.get('*', async (req, res) => { - let packageObj = await fs.readJson(path.join(wiki.ROOTPATH, 'package.json')) + let packageObj = await fs.readJson(path.join(WIKI.ROOTPATH, 'package.json')) res.render('main/setup', { packageObj, - telemetryClientID: wiki.telemetry.cid + telemetryClientID: WIKI.telemetry.cid }) }) @@ -82,8 +82,8 @@ module.exports = () => { * Perform basic system checks */ app.post('/syscheck', (req, res) => { - wiki.telemetry.enabled = (req.body.telemetry === true) - wiki.telemetry.sendEvent('setup', 'start') + WIKI.telemetry.enabled = (req.body.telemetry === true) + WIKI.telemetry.sendEvent('setup', 'start') Promise.mapSeries([ () => { @@ -126,7 +126,7 @@ module.exports = () => { () => { let fs = require('fs') return Promise.try(() => { - fs.accessSync(path.join(wiki.ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK) + fs.accessSync(path.join(WIKI.ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK) }).catch(err => { throw new Error('config.yml file is not writable by Node.js process or was not created properly.') }).return('config.yml is writable by the setup process.') @@ -142,13 +142,13 @@ module.exports = () => { * Check the Git connection */ app.post('/gitcheck', (req, res) => { - wiki.telemetry.sendEvent('setup', 'gitcheck') + WIKI.telemetry.sendEvent('setup', 'gitcheck') const exec = require('execa') const url = require('url') - const dataDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) - const gitDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) + const dataDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) + const gitDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) let gitRemoteUrl = '' @@ -235,107 +235,107 @@ module.exports = () => { * Finalize */ app.post('/finalize', async (req, res) => { - wiki.telemetry.sendEvent('setup', 'finalize') + WIKI.telemetry.sendEvent('setup', 'finalize') try { - // Upgrade from Wiki.js 1.x? + // Upgrade from WIKI.js 1.x? if (req.body.upgrade) { - await wiki.system.upgradeFromMongo({ + await WIKI.system.upgradeFromMongo({ mongoCnStr: cfgHelper.parseConfigValue(req.body.upgMongo) }) } // Update config file - wiki.logger.info('Writing config file to disk...') - let confRaw = await fs.readFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), 'utf8') + WIKI.logger.info('Writing config file to disk...') + let confRaw = await fs.readFileAsync(path.join(WIKI.ROOTPATH, 'config.yml'), 'utf8') let conf = yaml.safeLoad(confRaw) conf.port = req.body.port conf.paths.repo = req.body.pathRepo confRaw = yaml.safeDump(conf) - await fs.writeFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), confRaw) + await fs.writeFileAsync(path.join(WIKI.ROOTPATH, 'config.yml'), confRaw) - _.set(wiki.config, 'port', req.body.port) - _.set(wiki.config, 'paths.repo', req.body.pathRepo) + _.set(WIKI.config, 'port', req.body.port) + _.set(WIKI.config, 'paths.repo', req.body.pathRepo) // Populate config namespaces - wiki.config.auth = wiki.config.auth || {} - wiki.config.features = wiki.config.features || {} - wiki.config.git = wiki.config.git || {} - wiki.config.logging = wiki.config.logging || {} - wiki.config.site = wiki.config.site || {} - wiki.config.theme = wiki.config.theme || {} - wiki.config.uploads = wiki.config.uploads || {} + WIKI.config.auth = WIKI.config.auth || {} + WIKI.config.features = WIKI.config.features || {} + WIKI.config.git = WIKI.config.git || {} + WIKI.config.logging = WIKI.config.logging || {} + WIKI.config.site = WIKI.config.site || {} + WIKI.config.theme = WIKI.config.theme || {} + WIKI.config.uploads = WIKI.config.uploads || {} // Site namespace - _.set(wiki.config.site, 'title', req.body.title) - _.set(wiki.config.site, 'path', req.body.path) - _.set(wiki.config.site, 'lang', req.body.lang) - _.set(wiki.config.site, 'rtl', _.includes(wiki.data.rtlLangs, req.body.lang)) - _.set(wiki.config.site, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) + _.set(WIKI.config.site, 'title', req.body.title) + _.set(WIKI.config.site, 'path', req.body.path) + _.set(WIKI.config.site, 'lang', req.body.lang) + _.set(WIKI.config.site, 'rtl', _.includes(WIKI.data.rtlLangs, req.body.lang)) + _.set(WIKI.config.site, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) // Auth namespace - _.set(wiki.config.auth, 'public', req.body.public === 'true') - _.set(wiki.config.auth, 'strategies.local.enabled', true) - _.set(wiki.config.auth, 'strategies.local.allowSelfRegister', req.body.selfRegister === 'true') + _.set(WIKI.config.auth, 'public', req.body.public === 'true') + _.set(WIKI.config.auth, 'strategies.local.enabled', true) + _.set(WIKI.config.auth, 'strategies.local.allowSelfRegister', req.body.selfRegister === 'true') // Git namespace - _.set(wiki.config.git, 'enabled', req.body.gitUseRemote === 'true') - if (wiki.config.git.enabled) { - _.set(wiki.config.git, 'url', req.body.gitUrl) - _.set(wiki.config.git, 'branch', req.body.gitBranch) - _.set(wiki.config.git, 'author.defaultEmail', req.body.gitServerEmail) - _.set(wiki.config.git, 'author.useUserEmail', req.body.gitShowUserEmail) - _.set(wiki.config.git, 'sslVerify', req.body.gitAuthSSL === 'true') - _.set(wiki.config.git, 'auth.type', req.body.gitAuthType) - switch (wiki.config.git.auth.type) { + _.set(WIKI.config.git, 'enabled', req.body.gitUseRemote === 'true') + if (WIKI.config.git.enabled) { + _.set(WIKI.config.git, 'url', req.body.gitUrl) + _.set(WIKI.config.git, 'branch', req.body.gitBranch) + _.set(WIKI.config.git, 'author.defaultEmail', req.body.gitServerEmail) + _.set(WIKI.config.git, 'author.useUserEmail', req.body.gitShowUserEmail) + _.set(WIKI.config.git, 'sslVerify', req.body.gitAuthSSL === 'true') + _.set(WIKI.config.git, 'auth.type', req.body.gitAuthType) + switch (WIKI.config.git.auth.type) { case 'basic': - _.set(wiki.config.git, 'auth.user', req.body.gitAuthUser) - _.set(wiki.config.git, 'auth.pass', req.body.gitAuthPass) + _.set(WIKI.config.git, 'auth.user', req.body.gitAuthUser) + _.set(WIKI.config.git, 'auth.pass', req.body.gitAuthPass) break case 'ssh': - _.set(wiki.config.git, 'auth.keyPath', req.body.gitAuthSSHKey) + _.set(WIKI.config.git, 'auth.keyPath', req.body.gitAuthSSHKey) break case 'sshenv': - _.set(wiki.config.git, 'auth.keyEnv', req.body.gitAuthSSHKeyEnv) + _.set(WIKI.config.git, 'auth.keyEnv', req.body.gitAuthSSHKeyEnv) break case 'sshdb': - _.set(wiki.config.git, 'auth.keyContents', req.body.gitAuthSSHKeyDB) + _.set(WIKI.config.git, 'auth.keyContents', req.body.gitAuthSSHKeyDB) break } } // Logging namespace - wiki.config.logging.telemetry = (req.body.telemetry === 'true') + WIKI.config.logging.telemetry = (req.body.telemetry === 'true') // Save config to DB - wiki.logger.info('Persisting config to DB...') - await wiki.configSvc.saveToDb() + WIKI.logger.info('Persisting config to DB...') + await WIKI.configSvc.saveToDb() // Create root administrator - wiki.logger.info('Creating root administrator...') - await wiki.db.User.upsert({ + WIKI.logger.info('Creating root administrator...') + await WIKI.db.User.upsert({ email: req.body.adminEmail, provider: 'local', - password: await wiki.db.User.hashPassword(req.body.adminPassword), + password: await WIKI.db.User.hashPassword(req.body.adminPassword), name: 'Administrator', role: 'admin', tfaIsActive: false }) - wiki.logger.info('Setup is complete!') + WIKI.logger.info('Setup is complete!') res.json({ ok: true, - redirectPath: wiki.config.site.path, - redirectPort: wiki.config.port + redirectPath: WIKI.config.site.path, + redirectPort: WIKI.config.port }).end() - wiki.logger.info('Stopping Setup...') + WIKI.logger.info('Stopping Setup...') server.destroy(() => { - wiki.logger.info('Setup stopped. Starting Wiki.js...') + WIKI.logger.info('Setup stopped. Starting WIKI.js...') _.delay(() => { - wiki.kernel.bootMaster() + WIKI.kernel.bootMaster() }, 1000) }) } catch (err) { @@ -357,25 +357,25 @@ module.exports = () => { res.status(err.status || 500) res.send({ message: err.message, - error: wiki.IS_DEBUG ? err : {} + error: WIKI.IS_DEBUG ? err : {} }) - wiki.logger.error(err.message) - wiki.telemetry.sendError(err) + WIKI.logger.error(err.message) + WIKI.telemetry.sendError(err) }) // ---------------------------------------- // Start HTTP server // ---------------------------------------- - wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`) + WIKI.logger.info(`HTTP Server on port: ${WIKI.config.port}`) - app.set('port', wiki.config.port) - wiki.server = http.createServer(app) - wiki.server.listen(wiki.config.port) + app.set('port', WIKI.config.port) + WIKI.server = http.createServer(app) + WIKI.server.listen(WIKI.config.port) var openConnections = [] - wiki.server.on('connection', (conn) => { + WIKI.server.on('connection', (conn) => { let key = conn.remoteAddress + ':' + conn.remotePort openConnections[key] = conn conn.on('close', () => { @@ -383,31 +383,31 @@ module.exports = () => { }) }) - wiki.server.destroy = (cb) => { - wiki.server.close(cb) + WIKI.server.destroy = (cb) => { + WIKI.server.close(cb) for (let key in openConnections) { openConnections[key].destroy() } } - wiki.server.on('error', (error) => { + WIKI.server.on('error', (error) => { if (error.syscall !== 'listen') { throw error } switch (error.code) { case 'EACCES': - wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!') + 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!') + WIKI.logger.error('Port ' + WIKI.config.port + ' is already in use!') return process.exit(1) default: throw error } }) - wiki.server.on('listening', () => { - wiki.logger.info('HTTP Server: RUNNING') + WIKI.server.on('listening', () => { + WIKI.logger.info('HTTP Server: RUNNING') }) } diff --git a/server/worker.js b/server/worker.js index 42c8b24f..d72b7cb5 100644 --- a/server/worker.js +++ b/server/worker.js @@ -1,38 +1,38 @@ const Promise = require('bluebird') -/* global wiki */ +/* global WIKI */ module.exports = Promise.join( - wiki.db.onReady, - wiki.configSvc.loadFromDb(['features', 'git', 'logging', 'site', 'uploads']) + WIKI.db.onReady, + WIKI.configSvc.loadFromDb(['features', 'git', 'logging', 'site', 'uploads']) ).then(() => { const path = require('path') - wiki.REPOPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo) - wiki.DATAPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.data) - wiki.UPLTEMPPATH = path.join(wiki.DATAPATH, 'temp-upload') + WIKI.REPOPATH = path.resolve(WIKI.ROOTPATH, WIKI.config.paths.repo) + WIKI.DATAPATH = path.resolve(WIKI.ROOTPATH, WIKI.config.paths.data) + WIKI.UPLTEMPPATH = path.join(WIKI.DATAPATH, 'temp-upload') // ---------------------------------------- // Load global modules // ---------------------------------------- - wiki.lang = require('i18next') + WIKI.lang = require('i18next') // ---------------------------------------- // Localization Engine // ---------------------------------------- const i18nBackend = require('i18next-node-fs-backend') - wiki.lang.use(i18nBackend).init({ + WIKI.lang.use(i18nBackend).init({ load: 'languageOnly', ns: ['common', 'admin', 'auth', 'errors', 'git'], defaultNS: 'common', saveMissing: false, - preload: [wiki.config.lang], - lng: wiki.config.lang, + preload: [WIKI.config.lang], + lng: WIKI.config.lang, fallbackLng: 'en', backend: { - loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml') + loadPath: path.join(WIKI.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml') } }) @@ -43,12 +43,12 @@ module.exports = Promise.join( const Bull = require('bull') const autoload = require('auto-load') - let queues = autoload(path.join(wiki.SERVERPATH, 'queues')) + let queues = autoload(path.join(WIKI.SERVERPATH, 'queues')) for (let queueName in queues) { new Bull(queueName, { - prefix: `q-${wiki.config.ha.nodeuid}`, - redis: wiki.config.redis + prefix: `q-${WIKI.config.ha.nodeuid}`, + redis: WIKI.config.redis }).process(queues[queueName]) } diff --git a/yarn.lock b/yarn.lock index 9d1879ee..e8d5f8a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2999,7 +2999,7 @@ debug@2.6.7: dependencies: ms "2.0.0" -debug@2.6.9, debug@^2.3.3, debug@^2.6.9: +debug@2.6.9, debug@2.x.x, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -6988,6 +6988,14 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +oauth2orize@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/oauth2orize/-/oauth2orize-1.11.0.tgz#793cef251d45ebdeac32ae40a8b6814faab1d483" + dependencies: + debug "2.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + oauth@0.9.x: version "0.9.15" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"