refactor: global namespace + admin pages UI

This commit is contained in:
NGPixel 2018-03-05 15:49:36 -05:00
parent f203173c6c
commit 7acc4e9fed
61 changed files with 751 additions and 508 deletions

View File

@ -0,0 +1,113 @@
<template lang='pug'>
v-card(flat)
v-card(flat, color='grey lighten-5').pa-3.pt-4
.headline.blue--text.text--darken-2 API
.subheading.grey--text Manage keys to access the API
v-card
v-card-title
v-btn(color='primary', dark)
v-icon(left) add
| New API Key
v-btn(icon)
v-icon.grey--text refresh
v-spacer
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search')
v-data-table(
v-model='selected'
:items='items',
:headers='headers',
:search='search',
:pagination.sync='pagination',
:rows-per-page-items='[15]'
select-all,
hide-actions,
disable-initial-sort
)
template(slot='headers', slot-scope='props')
tr
th(width='50')
th.text-xs-right(
width='80'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]'
@click='changeSort(`id`)'
)
v-icon(small) arrow_upward
| ID
th.text-xs-left(
v-for='header in props.headers'
:key='header.text'
:width='header.width'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]'
@click='changeSort(header.value)'
)
| {{ header.text }}
v-icon(small) arrow_upward
template(slot='items', slot-scope='props')
tr(:active='props.selected')
td
v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected')
td.text-xs-right {{ props.item.id }}
td {{ props.item.name }}
td {{ props.item.key }}
td {{ props.item.createdOn }}
td {{ props.item.updatedOn }}
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
template(slot='no-data')
v-alert(icon='warning', :value='true') No users to display!
.text-xs-center.py-2
v-pagination(v-model='pagination.page', :length='pages')
</template>
<script>
export default {
data() {
return {
selected: [],
pagination: {},
items: [
{ id: 1, key: 'user@test.com' },
{ id: 2, key: 'dude@test.com' },
{ id: 3, key: 'dude@test.com' }
],
headers: [
{ text: 'Name', value: 'name' },
{ text: 'Key', value: 'key' },
{ text: 'Created On', value: 'createdOn' },
{ text: 'Updated On', value: 'updatedOn' },
{ text: '', value: 'actions', sortable: false, width: 50 }
],
search: ''
}
},
computed: {
pages () {
if (this.pagination.rowsPerPage == null || this.pagination.totalItems == null) {
return 0
}
return Math.ceil(this.pagination.totalItems / this.pagination.rowsPerPage)
}
},
methods: {
changeSort (column) {
if (this.pagination.sortBy === column) {
this.pagination.descending = !this.pagination.descending
} else {
this.pagination.sortBy = column
this.pagination.descending = false
}
},
toggleAll () {
if (this.selected.length) {
this.selected = []
} else {
this.selected = this.items.slice()
}
}
}
}
</script>
<style lang='scss'>
</style>

View File

@ -28,7 +28,9 @@
v-btn(color='primary') v-btn(color='primary')
v-icon(left) chevron_right v-icon(left) chevron_right
| Set Providers | Set Providers
v-btn(color='black', dark)
v-icon(left) layers_clear
| Flush Sessions
</template> </template>
<script> <script>

View File

@ -0,0 +1,19 @@
<template lang='pug'>
v-container(fluid, fill-height)
v-layout(row wrap)
v-flex(xs12)
.headline.primary--text Developer Tools
.subheading.grey--text ¯\_()_/¯
</template>
<script>
export default {
data() {
return {}
}
}
</script>
<style lang='scss'>
</style>

View File

@ -20,6 +20,9 @@
v-btn(color='primary') v-btn(color='primary')
v-icon(left) chevron_right v-icon(left) chevron_right
| Set Engine | Set Engine
v-btn(color='black', dark)
v-icon(left) refresh
| Rebuild Index
v-tab-item(key='db') v-tab-item(key='db')
v-card.pa-3 TODO v-card.pa-3 TODO
v-tab-item(key='algolia') v-tab-item(key='algolia')

View File

@ -0,0 +1,53 @@
<template lang='pug'>
v-card(flat)
v-card(color='grey lighten-5')
.pa-3.pt-4
.headline.primary--text Storage
.subheading.grey--text Set backup and sync targets for your content
v-tabs(color='grey lighten-4', grow, slider-color='primary', show-arrows)
v-tab(key='settings'): v-icon settings
v-tab(key='local') Local FS
v-tab(key='git') Git
v-tab(key='s3') Amazon S3
v-tab(key='azure') Azure Blob Storage
v-tab(key='digitalocean') DigitalOcean Spaces
v-tab(key='dropbox') Dropbox
v-tab(key='gdrive') Google Drive
v-tab(key='onedrive') OneDrive
v-tab(key='scp') SCP (SSH)
v-tab-item(key='settings')
v-card.pa-3
v-form
v-checkbox(v-for='(target, n) in targets', v-model='auths', :key='n', :label='target.text', :value='target.value', color='primary')
v-divider
v-btn(color='primary')
v-icon(left) chevron_right
| Set Backup Targets
</template>
<script>
export default {
data() {
return {
targets: [
{ text: 'Local FS', value: 'local' },
{ text: 'Git', value: 'auth0' },
{ text: 'Amazon S3', value: 'algolia' },
{ text: 'Azure Blob Storage', value: 'elasticsearch' },
{ text: 'DigitalOcean Spaces', value: 'solr' },
{ text: 'Dropbox', value: 'solr' },
{ text: 'Google Drive', value: 'solr' },
{ text: 'OneDrive', value: 'solr' },
{ text: 'SCP (SSH)', value: 'solr' }
],
auths: ['local']
}
}
}
</script>
<style lang='scss'>
</style>

View File

@ -1,66 +1,65 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-card(flat)
v-layout(row wrap) v-card(flat, color='grey lighten-5').pa-3.pt-4
v-flex(xs12) .headline.blue--text.text--darken-2 Users
.headline.blue--text.text--darken-2 Users .subheading.grey--text Manage users
.subheading.grey--text Manage users v-card
v-card.mt-3.elevation-1 v-card-title
v-card-title v-btn(color='primary', dark)
v-btn(color='primary', dark) v-icon(left) add
v-icon(left) add | New User
| New User v-btn(color='primary', dark)
v-btn(color='primary', dark) v-icon(left) lock_outline
v-icon(left) lock_outline | Authorize User
| Authorize User v-btn(icon)
v-btn(icon) v-icon.grey--text refresh
v-icon.grey--text refresh v-spacer
v-spacer v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search')
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search') v-data-table(
v-data-table( v-model='selected'
v-model='selected' :items='items',
:items='items', :headers='headers',
:headers='headers', :search='search',
:search='search', :pagination.sync='pagination',
:pagination.sync='pagination', :rows-per-page-items='[15]'
:rows-per-page-items='[15]' select-all,
select-all, hide-actions,
hide-actions, disable-initial-sort
disable-initial-sort )
) template(slot='headers', slot-scope='props')
template(slot='headers', slot-scope='props') tr
tr th(width='50')
th(width='50') th.text-xs-right(
th.text-xs-right( width='80'
width='80' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]' @click='changeSort(`id`)'
@click='changeSort(`id`)' )
) v-icon(small) arrow_upward
v-icon(small) arrow_upward | ID
| ID th.text-xs-left(
th.text-xs-left( v-for='header in props.headers'
v-for='header in props.headers' :key='header.text'
:key='header.text' :width='header.width'
:width='header.width' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]' @click='changeSort(header.value)'
@click='changeSort(header.value)' )
) | {{ header.text }}
| {{ header.text }} v-icon(small) arrow_upward
v-icon(small) arrow_upward template(slot='items', slot-scope='props')
template(slot='items', slot-scope='props') tr(:active='props.selected')
tr(:active='props.selected') td
td v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected')
v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected') td.text-xs-right {{ props.item.id }}
td.text-xs-right {{ props.item.id }} td {{ props.item.email }}
td {{ props.item.email }} td {{ props.item.name }}
td {{ props.item.name }} td {{ props.item.provider }}
td {{ props.item.provider }} td {{ props.item.createdOn }}
td {{ props.item.createdOn }} td {{ props.item.updatedOn }}
td {{ props.item.updatedOn }} td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz template(slot='no-data')
template(slot='no-data') v-alert(icon='warning', :value='true') No users to display!
v-alert(icon='warning', :value='true') No users to display! .text-xs-center.py-2
.text-xs-center.py-2 v-pagination(v-model='pagination.page', :length='pages')
v-pagination(v-model='pagination.page', :length='pages')
</template> </template>
<script> <script>

View File

@ -0,0 +1,19 @@
<template lang='pug'>
v-container(fluid, fill-height)
v-layout(row wrap)
v-flex(xs12)
.headline.primary--text Utilities
.subheading.grey--text Maintenance and troubleshooting tools
</template>
<script>
export default {
data() {
return {}
}
}
</script>
<style lang='scss'>
</style>

View File

@ -50,6 +50,9 @@
v-list-tile-title Storage v-list-tile-title Storage
v-divider.my-2 v-divider.my-2
v-subheader System 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(to='/system')
v-list-tile-action: v-icon tune v-list-tile-action: v-icon tune
v-list-tile-title System Info v-list-tile-title System Info
@ -83,7 +86,11 @@ const router = new VueRouter({
{ path: '/users', component: () => import(/* webpackChunkName: "admin" */ './admin-users.vue') }, { path: '/users', component: () => import(/* webpackChunkName: "admin" */ './admin-users.vue') },
{ path: '/auth', component: () => import(/* webpackChunkName: "admin" */ './admin-auth.vue') }, { path: '/auth', component: () => import(/* webpackChunkName: "admin" */ './admin-auth.vue') },
{ path: '/search', component: () => import(/* webpackChunkName: "admin" */ './admin-search.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') }
] ]
}) })

View File

@ -98,6 +98,7 @@
"mongodb": "3.0.2", "mongodb": "3.0.2",
"multer": "1.3.0", "multer": "1.3.0",
"node-2fa": "1.1.2", "node-2fa": "1.1.2",
"oauth2orize": "1.11.0",
"ora": "1.4.0", "ora": "1.4.0",
"passport": "0.4.0", "passport": "0.4.0",
"passport-auth0": "0.6.1", "passport-auth0": "0.6.1",

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
const Promise = require('bluebird') const Promise = require('bluebird')
const express = require('express') const express = require('express')
@ -12,7 +12,7 @@ const _ = require('lodash')
* Setup Express-Brute * Setup Express-Brute
*/ */
const EBstore = new ExpressBruteRedisStore({ const EBstore = new ExpressBruteRedisStore({
client: wiki.redis client: WIKI.redis
}) })
const bruteforce = new ExpressBrute(EBstore, { const bruteforce = new ExpressBrute(EBstore, {
freeRetries: 5, freeRetries: 5,
@ -22,8 +22,8 @@ const bruteforce = new ExpressBrute(EBstore, {
failCallback (req, res, next, nextValidRequestDate) { failCallback (req, res, next, nextValidRequestDate) {
req.flash('alert', { req.flash('alert', {
class: 'error', class: 'error',
title: wiki.lang.t('auth:errors.toomanyattempts'), title: WIKI.lang.t('auth:errors.toomanyattempts'),
message: wiki.lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }), message: WIKI.lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }),
iconClass: 'fa-times' iconClass: 'fa-times'
}) })
res.redirect('/login') res.redirect('/login')
@ -40,16 +40,16 @@ router.get('/login', function (req, res, next) {
router.post('/login', bruteforce.prevent, function (req, res, next) { router.post('/login', bruteforce.prevent, function (req, res, next) {
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
// [1] LOCAL AUTHENTICATION // [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 (err) { return reject(err) }
if (!user) { return reject(new Error('INVALID_LOGIN')) } if (!user) { return reject(new Error('INVALID_LOGIN')) }
resolve(user) resolve(user)
})(req, res, next) })(req, res, next)
}).catch({ message: 'INVALID_LOGIN' }, err => { }).catch({ message: 'INVALID_LOGIN' }, err => {
if (_.has(wiki.config.auth.strategy, 'ldap')) { if (_.has(WIKI.config.auth.strategy, 'ldap')) {
// [2] LDAP AUTHENTICATION // [2] LDAP AUTHENTICATION
return new Promise((resolve, reject) => { 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 (err) { return reject(err) }
if (info && info.message) { return reject(new Error(info.message)) } if (info && info.message) { return reject(new Error(info.message)) }
if (!user) { return reject(new Error('INVALID_LOGIN')) } if (!user) { return reject(new Error('INVALID_LOGIN')) }
@ -71,13 +71,13 @@ router.post('/login', bruteforce.prevent, function (req, res, next) {
// LOGIN FAIL // LOGIN FAIL
if (err.message === 'INVALID_LOGIN') { if (err.message === 'INVALID_LOGIN') {
req.flash('alert', { req.flash('alert', {
title: wiki.lang.t('auth:errors.invalidlogin'), title: WIKI.lang.t('auth:errors.invalidlogin'),
message: wiki.lang.t('auth:errors.invalidloginmsg') message: WIKI.lang.t('auth:errors.invalidloginmsg')
}) })
return res.redirect('/login') return res.redirect('/login')
} else { } else {
req.flash('alert', { req.flash('alert', {
title: wiki.lang.t('auth:errors.loginerror'), title: WIKI.lang.t('auth:errors.loginerror'),
message: err.message message: err.message
}) })
return res.redirect('/login') return res.redirect('/login')
@ -89,19 +89,19 @@ router.post('/login', bruteforce.prevent, function (req, res, next) {
* Social Login * Social Login
*/ */
router.get('/login/ms', wiki.auth.passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] })) 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/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/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/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/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/azure', WIKI.auth.passport.authenticate('azure_ad_oauth2'))
router.get('/login/ms/callback', wiki.auth.passport.authenticate('windowslive', { 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/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/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/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/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/azure/callback', WIKI.auth.passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' }))
/** /**
* Logout * Logout

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
const _ = require('lodash') const _ = require('lodash')
const passport = require('passport') const passport = require('passport')
@ -17,11 +17,11 @@ module.exports = {
}) })
passport.deserializeUser(function (id, done) { passport.deserializeUser(function (id, done) {
wiki.db.User.findById(id).then((user) => { WIKI.db.User.findById(id).then((user) => {
if (user) { if (user) {
done(null, user) done(null, user)
} else { } else {
done(new Error(wiki.lang.t('auth:errors:usernotfound')), null) done(new Error(WIKI.lang.t('auth:errors:usernotfound')), null)
} }
return true return true
}).catch((err) => { }).catch((err) => {
@ -31,49 +31,49 @@ module.exports = {
// Load authentication strategies // Load authentication strategies
_.forOwn(_.omitBy(wiki.config.auth.strategies, s => s.enabled === false), (strategyConfig, strategyKey) => { _.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` strategyConfig.callbackURL = `${WIKI.config.site.host}${WIKI.config.site.path}login/${strategyKey}/callback`
let strategy = require(`../modules/authentication/${strategyKey}`) let strategy = require(`../modules/authentication/${strategyKey}`)
try { try {
strategy.init(passport, strategyConfig) strategy.init(passport, strategyConfig)
} catch (err) { } catch (err) {
wiki.logger.error(`Authentication Provider ${strategyKey}: [ FAILED ]`) WIKI.logger.error(`Authentication Provider ${strategyKey}: [ FAILED ]`)
wiki.logger.error(err) 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 strategy.icon = iconData
}).catch(err => { }).catch(err => {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
strategy.icon = '[missing icon]' strategy.icon = '[missing icon]'
} else { } else {
wiki.logger.error(err) WIKI.logger.error(err)
} }
}) })
this.strategies[strategy.key] = strategy 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 // Create Guest account for first-time
wiki.db.User.findOne({ WIKI.db.User.findOne({
where: { where: {
provider: 'local', provider: 'local',
email: 'guest@example.com' email: 'guest@example.com'
} }
}).then((c) => { }).then((c) => {
if (c < 1) { if (c < 1) {
return wiki.db.User.create({ return WIKI.db.User.create({
provider: 'local', provider: 'local',
email: 'guest@example.com', email: 'guest@example.com',
name: 'Guest', name: 'Guest',
password: '', password: '',
role: 'guest' role: 'guest'
}).then(() => { }).then(() => {
wiki.logger.info('[AUTH] Guest account created successfully!') WIKI.logger.info('[AUTH] Guest account created successfully!')
return true return true
}).catch((err) => { }).catch((err) => {
wiki.logger.error('[AUTH] An error occured while creating guest account:') WIKI.logger.error('[AUTH] An error occured while creating guest account:')
wiki.logger.error(err) WIKI.logger.error(err)
return err return err
}) })
} }
@ -81,22 +81,22 @@ module.exports = {
// .then(() => { // .then(() => {
// if (process.env.WIKI_JS_HEROKU) { // 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) { // if (c < 1) {
// // Create root admin account (HEROKU ONLY) // // Create root admin account (HEROKU ONLY)
// return wiki.db.User.create({ // return WIKI.db.User.create({
// provider: 'local', // provider: 'local',
// email: process.env.WIKI_ADMIN_EMAIL, // email: process.env.WIKI_ADMIN_EMAIL,
// name: 'Administrator', // name: 'Administrator',
// password: '$2a$04$MAHRw785Xe/Jd5kcKzr3D.VRZDeomFZu2lius4gGpZZ9cJw7B7Mna', // admin123 (default) // password: '$2a$04$MAHRw785Xe/Jd5kcKzr3D.VRZDeomFZu2lius4gGpZZ9cJw7B7Mna', // admin123 (default)
// role: 'admin' // role: 'admin'
// }).then(() => { // }).then(() => {
// wiki.logger.info('[AUTH] Root admin account created successfully!') // WIKI.logger.info('[AUTH] Root admin account created successfully!')
// return true // return true
// }).catch((err) => { // }).catch((err) => {
// wiki.logger.error('[AUTH] An error occured while creating root admin account:') // WIKI.logger.error('[AUTH] An error occured while creating root admin account:')
// wiki.logger.error(err) // WIKI.logger.error(err)
// return err // return err
// }) // })
// } else { return true } // } else { return true }

View File

@ -4,7 +4,7 @@ const fs = require('fs')
const path = require('path') const path = require('path')
const yaml = require('js-yaml') const yaml = require('js-yaml')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
/** /**
@ -12,9 +12,9 @@ module.exports = {
*/ */
init() { init() {
let confPaths = { let confPaths = {
config: path.join(wiki.ROOTPATH, 'config.yml'), config: path.join(WIKI.ROOTPATH, 'config.yml'),
data: path.join(wiki.SERVERPATH, 'app/data.yml'), data: path.join(WIKI.SERVERPATH, 'app/data.yml'),
dataRegex: path.join(wiki.SERVERPATH, 'app/regex.js') dataRegex: path.join(WIKI.SERVERPATH, 'app/regex.js')
} }
let appconfig = {} let appconfig = {}
@ -43,9 +43,9 @@ module.exports = {
appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true')
wiki.config = appconfig WIKI.config = appconfig
wiki.data = appdata WIKI.data = appdata
wiki.version = require(path.join(wiki.ROOTPATH, 'package.json')).version WIKI.version = require(path.join(WIKI.ROOTPATH, 'package.json')).version
}, },
/** /**
@ -56,10 +56,10 @@ module.exports = {
*/ */
async loadFromDb(subsets) { async loadFromDb(subsets) {
if (!_.isArray(subsets) || subsets.length === 0) { 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'], attributes: ['key', 'config'],
where: { where: {
key: { key: {
@ -69,11 +69,11 @@ module.exports = {
}) })
if (_.isArray(results) && results.length === subsets.length) { if (_.isArray(results) && results.length === subsets.length) {
results.forEach(result => { results.forEach(result => {
wiki.config[result.key] = result.config WIKI.config[result.key] = result.config
}) })
return true return true
} else { } else {
wiki.logger.warn('DB Configuration is empty or incomplete.') WIKI.logger.warn('DB Configuration is empty or incomplete.')
return false return false
} }
}, },
@ -85,18 +85,18 @@ module.exports = {
*/ */
async saveToDb(subsets) { async saveToDb(subsets) {
if (!_.isArray(subsets) || subsets.length === 0) { if (!_.isArray(subsets) || subsets.length === 0) {
subsets = wiki.data.configNamespaces subsets = WIKI.data.configNamespaces
} }
try { try {
for (let set of subsets) { for (let set of subsets) {
await wiki.db.Setting.upsert({ await WIKI.db.Setting.upsert({
key: set, key: set,
config: _.get(wiki.config, set, {}) config: _.get(WIKI.config, set, {})
}) })
} }
} catch (err) { } 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 return false
} }

View File

@ -4,7 +4,7 @@ const path = require('path')
const Promise = require('bluebird') const Promise = require('bluebird')
const Sequelize = require('sequelize') const Sequelize = require('sequelize')
/* global wiki */ /* global WIKI */
const operatorsAliases = { const operatorsAliases = {
$eq: Sequelize.Op.eq, $eq: Sequelize.Op.eq,
@ -57,30 +57,30 @@ module.exports = {
*/ */
init() { init() {
let self = this let self = this
let dbModelsPath = path.join(wiki.SERVERPATH, 'models') let dbModelsPath = path.join(WIKI.SERVERPATH, 'models')
// Define Sequelize instance // Define Sequelize instance
this.inst = new this.Sequelize(wiki.config.db.db, wiki.config.db.user, wiki.config.db.pass, { this.inst = new this.Sequelize(WIKI.config.db.db, WIKI.config.db.user, WIKI.config.db.pass, {
host: wiki.config.db.host, host: WIKI.config.db.host,
port: wiki.config.db.port, port: WIKI.config.db.port,
dialect: 'postgres', dialect: 'postgres',
pool: { pool: {
max: 10, max: 10,
min: 0, min: 0,
idle: 10000 idle: 10000
}, },
logging: log => { wiki.logger.log('debug', log) }, logging: log => { WIKI.logger.log('debug', log) },
operatorsAliases operatorsAliases
}) })
// Attempt to connect and authenticate to DB // Attempt to connect and authenticate to DB
this.inst.authenticate().then(() => { this.inst.authenticate().then(() => {
wiki.logger.info('Database (PostgreSQL) connection: [ OK ]') WIKI.logger.info('Database (PostgreSQL) connection: [ OK ]')
}).catch(err => { }).catch(err => {
wiki.logger.error('Failed to connect to PostgreSQL instance.') WIKI.logger.error('Failed to connect to PostgreSQL instance.')
wiki.logger.error(err) WIKI.logger.error(err)
process.exit(1) process.exit(1)
}) })
@ -107,16 +107,16 @@ module.exports = {
syncSchemas() { syncSchemas() {
return self.inst.sync({ return self.inst.sync({
force: false, force: false,
logging: log => { wiki.logger.log('debug', log) } logging: log => { WIKI.logger.log('debug', log) }
}) })
}, },
// -> Set Connection App Name // -> Set Connection App Name
setAppName() { 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.syncSchemas,
initTasks.setAppName initTasks.setAppName
] : [ ] : [

View File

@ -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

View File

@ -2,19 +2,19 @@ const _ = require('lodash')
const cluster = require('cluster') const cluster = require('cluster')
const Promise = require('bluebird') const Promise = require('bluebird')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
numWorkers: 1, numWorkers: 1,
workers: [], workers: [],
init() { init() {
if (cluster.isMaster) { if (cluster.isMaster) {
wiki.logger.info('=======================================') WIKI.logger.info('=======================================')
wiki.logger.info('= Wiki.js =============================') WIKI.logger.info('= WIKI.js =============================')
wiki.logger.info('=======================================') WIKI.logger.info('=======================================')
wiki.redis = require('./redis').init() WIKI.redis = require('./redis').init()
wiki.queue = require('./queue').init() WIKI.queue = require('./queue').init()
this.setWorkerLimit() this.setWorkerLimit()
this.bootMaster() this.bootMaster()
@ -27,9 +27,9 @@ module.exports = {
*/ */
preBootMaster() { preBootMaster() {
return Promise.mapSeries([ return Promise.mapSeries([
() => { return wiki.db.onReady }, () => { return WIKI.db.onReady },
() => { return wiki.configSvc.loadFromDb() }, () => { return WIKI.configSvc.loadFromDb() },
() => { return wiki.queue.clean() } () => { return WIKI.queue.clean() }
], fn => { return fn() }) ], fn => { return fn() })
}, },
/** /**
@ -37,15 +37,15 @@ module.exports = {
*/ */
bootMaster() { bootMaster() {
this.preBootMaster().then(sequenceResults => { 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() this.postBootMaster()
} else { } else {
wiki.logger.info('Starting configuration manager...') WIKI.logger.info('Starting configuration manager...')
require('../setup')() require('../setup')()
} }
return true return true
}).catch(err => { }).catch(err => {
wiki.logger.error(err) WIKI.logger.error(err)
process.exit(1) process.exit(1)
}) })
}, },
@ -59,13 +59,13 @@ module.exports = {
this.spawnWorker() this.spawnWorker()
}) })
wiki.queue.uplClearTemp.add({}, { WIKI.queue.uplClearTemp.add({}, {
repeat: { cron: '*/15 * * * *' } repeat: { cron: '*/15 * * * *' }
}) })
cluster.on('exit', (worker, code, signal) => { cluster.on('exit', (worker, code, signal) => {
if (!global.DEV) { 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 * Boot Worker Process
*/ */
bootWorker() { bootWorker() {
wiki.logger.info(`Background Worker #${cluster.worker.id} is initializing...`) WIKI.logger.info(`Background Worker #${cluster.worker.id} is initializing...`)
require('../worker') require('../worker')
}, },
/** /**
@ -87,7 +87,7 @@ module.exports = {
*/ */
setWorkerLimit() { setWorkerLimit() {
const numCPUs = require('os').cpus().length 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) { if (this.numWorkers > numCPUs) {
this.numWorkers = numCPUs this.numWorkers = numCPUs
} }

View File

@ -6,24 +6,24 @@ const i18next = require('i18next')
const path = require('path') const path = require('path')
const Promise = require('bluebird') const Promise = require('bluebird')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
engine: null, engine: null,
namespaces: [], namespaces: [],
init() { init() {
this.namespaces = wiki.data.localeNamespaces this.namespaces = WIKI.data.localeNamespaces
this.engine = i18next this.engine = i18next
this.engine.use(i18nBackend).init({ this.engine.use(i18nBackend).init({
load: 'languageOnly', load: 'languageOnly',
ns: this.namespaces, ns: this.namespaces,
defaultNS: 'common', defaultNS: 'common',
saveMissing: false, saveMissing: false,
preload: [wiki.config.site.lang], preload: [WIKI.config.site.lang],
lng: wiki.config.site.lang, lng: WIKI.config.site.lang,
fallbackLng: 'en', fallbackLng: 'en',
backend: { backend: {
loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml') loadPath: path.join(WIKI.SERVERPATH, 'locales/{{lng}}/{{ns}}.yml')
} }
}) })
return this return this

View File

@ -3,7 +3,7 @@ const cluster = require('cluster')
const fs = require('fs-extra') const fs = require('fs-extra')
const path = require('path') const path = require('path')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
loggers: {}, loggers: {},
@ -11,7 +11,7 @@ module.exports = {
let winston = require('winston') let winston = require('winston')
let logger = new (winston.Logger)({ let logger = new (winston.Logger)({
level: wiki.config.logLevel, level: WIKI.config.logLevel,
transports: [] transports: []
}) })
@ -20,10 +20,10 @@ module.exports = {
return '[' + processName + '] ' + msg 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}`) let loggerModule = require(`../modules/logging/${loggerKey}`)
loggerModule.init(logger, loggerConfig) 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 logger.icon = iconData
}).catch(err => { }).catch(err => {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {

View File

@ -1,35 +1,35 @@
const Bull = require('bull') const Bull = require('bull')
const Promise = require('bluebird') const Promise = require('bluebird')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
init() { init() {
wiki.data.queues.forEach(queueName => { WIKI.data.queues.forEach(queueName => {
this[queueName] = new Bull(queueName, { this[queueName] = new Bull(queueName, {
prefix: `q-${wiki.config.ha.nodeuid}`, prefix: `q-${WIKI.config.ha.nodeuid}`,
redis: wiki.config.redis redis: WIKI.config.redis
}) })
}) })
return this return this
}, },
clean() { clean() {
return Promise.each(wiki.data.queues, queueName => { return Promise.each(WIKI.data.queues, queueName => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let keyStream = wiki.redis.scanStream({ let keyStream = WIKI.redis.scanStream({
match: `q-${wiki.config.ha.nodeuid}:${queueName}:*` match: `q-${WIKI.config.ha.nodeuid}:${queueName}:*`
}) })
keyStream.on('data', resultKeys => { keyStream.on('data', resultKeys => {
if (resultKeys.length > 0) { if (resultKeys.length > 0) {
wiki.redis.del(resultKeys) WIKI.redis.del(resultKeys)
} }
}) })
keyStream.on('end', resolve) keyStream.on('end', resolve)
}) })
}).then(() => { }).then(() => {
wiki.logger.info('Purging old queue jobs: [ OK ]') WIKI.logger.info('Purging old queue jobs: [ OK ]')
}).return(true).catch(err => { }).return(true).catch(err => {
wiki.logger.error(err) WIKI.logger.error(err)
}) })
} }
} }

View File

@ -1,22 +1,22 @@
const Redis = require('ioredis') const Redis = require('ioredis')
const { isPlainObject } = require('lodash') const { isPlainObject } = require('lodash')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
init() { init() {
if (isPlainObject(wiki.config.redis)) { if (isPlainObject(WIKI.config.redis)) {
let red = new Redis(wiki.config.redis) let red = new Redis(WIKI.config.redis)
red.on('ready', () => { red.on('ready', () => {
wiki.logger.info('Redis connection: [ OK ]') WIKI.logger.info('Redis connection: [ OK ]')
}) })
red.on('error', () => { red.on('error', () => {
wiki.logger.error('Failed to connect to Redis instance!') WIKI.logger.error('Failed to connect to Redis instance!')
process.exit(1) process.exit(1)
}) })
return red return red
} else { } else {
wiki.logger.error('Invalid Redis configuration!') WIKI.logger.error('Invalid Redis configuration!')
process.exit(1) process.exit(1)
} }
} }

View File

@ -2,18 +2,18 @@ const _ = require('lodash')
const cfgHelper = require('../helpers/config') const cfgHelper = require('../helpers/config')
const Promise = require('bluebird') const Promise = require('bluebird')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
/** /**
* Upgrade from Wiki.js 1.x - MongoDB database * Upgrade from WIKI.js 1.x - MongoDB database
* *
* @param {Object} opts Options object * @param {Object} opts Options object
*/ */
async upgradeFromMongo (opts) { 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 mongo = require('mongodb').MongoClient
let parsedMongoConStr = cfgHelper.parseConfigValue(opts.mongoCnStr) let parsedMongoConStr = cfgHelper.parseConfigValue(opts.mongoCnStr)
@ -45,7 +45,7 @@ module.exports = {
$not: 'guest' $not: 'guest'
} }
}).toArray() }).toArray()
await wiki.db.User.bulkCreate(_.map(userData, usr => { await WIKI.db.User.bulkCreate(_.map(userData, usr => {
return { return {
email: usr.email, email: usr.email,
name: usr.name || 'Imported User', name: usr.name || 'Imported User',

View File

@ -4,27 +4,27 @@ const bugsnag = require('bugsnag')
const path = require('path') const path = require('path')
const uuid = require('uuid/v4') const uuid = require('uuid/v4')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
cid: '', cid: '',
enabled: false, enabled: false,
init() { init() {
this.cid = uuid() this.cid = uuid()
bugsnag.register(wiki.data.telemetry.BUGSNAG_ID, { bugsnag.register(WIKI.data.telemetry.BUGSNAG_ID, {
appVersion: wiki.version, appVersion: WIKI.version,
autoNotify: false, autoNotify: false,
hostname: this.cid, hostname: this.cid,
notifyReleaseStages: ['production'], notifyReleaseStages: ['production'],
packageJSON: path.join(wiki.ROOTPATH, 'package.json'), packageJSON: path.join(WIKI.ROOTPATH, 'package.json'),
projectRoot: wiki.ROOTPATH, projectRoot: WIKI.ROOTPATH,
useSSL: true useSSL: true
}) })
bugsnag.onBeforeNotify((notification, originalError) => { bugsnag.onBeforeNotify((notification, originalError) => {
if (!this.enabled) { return false } if (!this.enabled) { return false }
}) })
if (_.get(wiki.config, 'logging.telemetry', false) === true) { if (_.get(WIKI.config, 'logging.telemetry', false) === true) {
this.enabled = true this.enabled = true
} }
@ -37,13 +37,13 @@ module.exports = {
if (!this.enabled) { return false } if (!this.enabled) { return false }
axios({ axios({
method: 'post', method: 'post',
url: wiki.data.telemetry.GA_REMOTE, url: WIKI.data.telemetry.GA_REMOTE,
headers: { headers: {
'Content-type': 'application/x-www-form-urlencoded' 'Content-type': 'application/x-www-form-urlencoded'
}, },
params: { params: {
v: 1, // API version v: 1, // API version
tid: wiki.data.telemetry.GA_ID, // Tracking ID tid: WIKI.data.telemetry.GA_ID, // Tracking ID
aip: 1, // Anonymize IP aip: 1, // Anonymize IP
ds: 'server', // Data source ds: 'server', // Data source
cid: this.cid, // Client ID cid: this.cid, // Client ID
@ -54,10 +54,10 @@ module.exports = {
} }
}).then(resp => { }).then(resp => {
if (resp.status !== 200) { if (resp.status !== 200) {
wiki.logger.warn('Unable to send analytics telemetry request.') WIKI.logger.warn('Unable to send analytics telemetry request.')
} }
}, err => { }, err => {
wiki.logger.warn('Unable to send analytics telemetry request.') WIKI.logger.warn('Unable to send analytics telemetry request.')
}) })
} }
} }

34
server/graph/index.js Normal file
View File

@ -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

View File

@ -2,14 +2,20 @@ const _ = require('lodash')
const fs = require('fs-extra') const fs = require('fs-extra')
const path = require('path') const path = require('path')
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
authentication(obj, args, context, info) { async authentication() { return {} }
},
Mutation: {
async authentication() { return {} }
},
AuthenticationQuery: {
providers(obj, args, context, info) {
switch (args.mode) { switch (args.mode) {
case 'active': case 'active':
let strategies = _.chain(wiki.auth.strategies).map(str => { let strategies = _.chain(WIKI.auth.strategies).map(str => {
return { return {
key: str.key, key: str.key,
title: str.title, title: str.title,
@ -26,10 +32,9 @@ module.exports = {
} }
} }
}, },
Mutation: {},
AuthenticationProvider: { AuthenticationProvider: {
icon (ap, args) { 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') { if (err.code === 'ENOENT') {
return null return null
} }

View File

@ -1,22 +1,22 @@
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
comments(obj, args, context, info) { comments(obj, args, context, info) {
return wiki.db.Comment.findAll({ where: args }) return WIKI.db.Comment.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
createComment(obj, args) { createComment(obj, args) {
return wiki.db.Comment.create({ return WIKI.db.Comment.create({
content: args.content, content: args.content,
author: args.userId, author: args.userId,
document: args.documentId document: args.documentId
}) })
}, },
deleteComment(obj, args) { deleteComment(obj, args) {
return wiki.db.Comment.destroy({ return WIKI.db.Comment.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -24,7 +24,7 @@ module.exports = {
}) })
}, },
modifyComment(obj, args) { modifyComment(obj, args) {
return wiki.db.Comment.update({ return WIKI.db.Comment.update({
content: args.content content: args.content
}, { }, {
where: { id: args.id } where: { id: args.id }

View File

@ -1,18 +1,18 @@
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
documents(obj, args, context, info) { documents(obj, args, context, info) {
return wiki.db.Document.findAll({ where: args }) return WIKI.db.Document.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
createDocument(obj, args) { createDocument(obj, args) {
return wiki.db.Document.create(args) return WIKI.db.Document.create(args)
}, },
deleteDocument(obj, args) { deleteDocument(obj, args) {
return wiki.db.Document.destroy({ return WIKI.db.Document.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -20,7 +20,7 @@ module.exports = {
}) })
}, },
modifyDocument(obj, args) { modifyDocument(obj, args) {
return wiki.db.Document.update({ return WIKI.db.Document.update({
title: args.title, title: args.title,
subtitle: args.subtitle subtitle: args.subtitle
}, { }, {
@ -28,7 +28,7 @@ module.exports = {
}) })
}, },
moveDocument(obj, args) { moveDocument(obj, args) {
return wiki.db.Document.update({ return WIKI.db.Document.update({
path: args.path path: args.path
}, { }, {
where: { id: args.id } where: { id: args.id }

View File

@ -1,21 +1,21 @@
/* global wiki */ /* global WIKI */
const gql = require('graphql') const gql = require('graphql')
module.exports = { module.exports = {
Query: { Query: {
files(obj, args, context, info) { files(obj, args, context, info) {
return wiki.db.File.findAll({ where: args }) return WIKI.db.File.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
uploadFile(obj, args) { uploadFile(obj, args) {
// todo // todo
return wiki.db.File.create(args) return WIKI.db.File.create(args)
}, },
deleteFile(obj, args) { deleteFile(obj, args) {
return wiki.db.File.destroy({ return WIKI.db.File.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -23,18 +23,18 @@ module.exports = {
}) })
}, },
renameFile(obj, args) { renameFile(obj, args) {
return wiki.db.File.update({ return WIKI.db.File.update({
filename: args.filename filename: args.filename
}, { }, {
where: { id: args.id } where: { id: args.id }
}) })
}, },
moveFile(obj, args) { moveFile(obj, args) {
return wiki.db.File.findById(args.fileId).then(fl => { return WIKI.db.File.findById(args.fileId).then(fl => {
if (!fl) { if (!fl) {
throw new gql.GraphQLError('Invalid File ID') 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) { if (!fld) {
throw new gql.GraphQLError('Invalid Folder ID') throw new gql.GraphQLError('Invalid Folder ID')
} }

View File

@ -1,18 +1,18 @@
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
folders(obj, args, context, info) { folders(obj, args, context, info) {
return wiki.db.Folder.findAll({ where: args }) return WIKI.db.Folder.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
createFolder(obj, args) { createFolder(obj, args) {
return wiki.db.Folder.create(args) return WIKI.db.Folder.create(args)
}, },
deleteGroup(obj, args) { deleteGroup(obj, args) {
return wiki.db.Folder.destroy({ return WIKI.db.Folder.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -20,7 +20,7 @@ module.exports = {
}) })
}, },
renameFolder(obj, args) { renameFolder(obj, args) {
return wiki.db.Folder.update({ return WIKI.db.Folder.update({
name: args.name name: args.name
}, { }, {
where: { id: args.id } where: { id: args.id }

View File

@ -1,21 +1,21 @@
/* global wiki */ /* global WIKI */
const gql = require('graphql') const gql = require('graphql')
module.exports = { module.exports = {
Query: { Query: {
groups(obj, args, context, info) { groups(obj, args, context, info) {
return wiki.db.Group.findAll({ where: args }) return WIKI.db.Group.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
assignUserToGroup(obj, args) { assignUserToGroup(obj, args) {
return wiki.db.Group.findById(args.groupId).then(grp => { return WIKI.db.Group.findById(args.groupId).then(grp => {
if (!grp) { if (!grp) {
throw new gql.GraphQLError('Invalid Group ID') 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) { if (!usr) {
throw new gql.GraphQLError('Invalid User ID') throw new gql.GraphQLError('Invalid User ID')
} }
@ -24,10 +24,10 @@ module.exports = {
}) })
}, },
createGroup(obj, args) { createGroup(obj, args) {
return wiki.db.Group.create(args) return WIKI.db.Group.create(args)
}, },
deleteGroup(obj, args) { deleteGroup(obj, args) {
return wiki.db.Group.destroy({ return WIKI.db.Group.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -35,11 +35,11 @@ module.exports = {
}) })
}, },
removeUserFromGroup(obj, args) { removeUserFromGroup(obj, args) {
return wiki.db.Group.findById(args.groupId).then(grp => { return WIKI.db.Group.findById(args.groupId).then(grp => {
if (!grp) { if (!grp) {
throw new gql.GraphQLError('Invalid Group ID') 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) { if (!usr) {
throw new gql.GraphQLError('Invalid User ID') throw new gql.GraphQLError('Invalid User ID')
} }
@ -48,7 +48,7 @@ module.exports = {
}) })
}, },
renameGroup(obj, args) { renameGroup(obj, args) {
return wiki.db.Group.update({ return WIKI.db.Group.update({
name: args.name name: args.name
}, { }, {
where: { id: args.id } where: { id: args.id }

View File

@ -1,21 +1,21 @@
/* global wiki */ /* global WIKI */
const gql = require('graphql') const gql = require('graphql')
module.exports = { module.exports = {
Query: { Query: {
rights(obj, args, context, info) { rights(obj, args, context, info) {
return wiki.db.Right.findAll({ where: args }) return WIKI.db.Right.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
addRightToGroup(obj, args) { addRightToGroup(obj, args) {
return wiki.db.Group.findById(args.groupId).then(grp => { return WIKI.db.Group.findById(args.groupId).then(grp => {
if (!grp) { if (!grp) {
throw new gql.GraphQLError('Invalid Group ID') throw new gql.GraphQLError('Invalid Group ID')
} }
return wiki.db.Right.create({ return WIKI.db.Right.create({
path: args.path, path: args.path,
role: args.role, role: args.role,
exact: args.exact, exact: args.exact,
@ -25,7 +25,7 @@ module.exports = {
}) })
}, },
removeRightFromGroup(obj, args) { removeRightFromGroup(obj, args) {
return wiki.db.Right.destroy({ return WIKI.db.Right.destroy({
where: { where: {
id: args.rightId id: args.rightId
}, },
@ -33,7 +33,7 @@ module.exports = {
}) })
}, },
modifyRight(obj, args) { modifyRight(obj, args) {
return wiki.db.Right.update({ return WIKI.db.Right.update({
path: args.path, path: args.path,
role: args.role, role: args.role,
exact: args.exact, exact: args.exact,

View File

@ -1,12 +1,12 @@
/* global wiki */ /* global WIKI */
const _ = require('lodash') const _ = require('lodash')
module.exports = { module.exports = {
Query: { Query: {
settings(obj, args, context, info) { 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 => { return _.map(entries, entry => {
entry.config = JSON.stringify(entry.config) entry.config = JSON.stringify(entry.config)
return entry return entry
@ -16,7 +16,7 @@ module.exports = {
}, },
Mutation: { Mutation: {
setConfigEntry(obj, args) { setConfigEntry(obj, args) {
return wiki.db.Setting.update({ return WIKI.db.Setting.update({
value: args.value value: args.value
}, { where: { key: args.key } }) }, { where: { key: args.key } })
} }

View File

@ -1,21 +1,21 @@
/* global wiki */ /* global WIKI */
const gql = require('graphql') const gql = require('graphql')
module.exports = { module.exports = {
Query: { Query: {
tags(obj, args, context, info) { tags(obj, args, context, info) {
return wiki.db.Tag.findAll({ where: args }) return WIKI.db.Tag.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
assignTagToDocument(obj, args) { assignTagToDocument(obj, args) {
return wiki.db.Tag.findById(args.tagId).then(tag => { return WIKI.db.Tag.findById(args.tagId).then(tag => {
if (!tag) { if (!tag) {
throw new gql.GraphQLError('Invalid Tag ID') 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) { if (!doc) {
throw new gql.GraphQLError('Invalid Document ID') throw new gql.GraphQLError('Invalid Document ID')
} }
@ -24,10 +24,10 @@ module.exports = {
}) })
}, },
createTag(obj, args) { createTag(obj, args) {
return wiki.db.Tag.create(args) return WIKI.db.Tag.create(args)
}, },
deleteTag(obj, args) { deleteTag(obj, args) {
return wiki.db.Tag.destroy({ return WIKI.db.Tag.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -35,11 +35,11 @@ module.exports = {
}) })
}, },
removeTagFromDocument(obj, args) { removeTagFromDocument(obj, args) {
return wiki.db.Tag.findById(args.tagId).then(tag => { return WIKI.db.Tag.findById(args.tagId).then(tag => {
if (!tag) { if (!tag) {
throw new gql.GraphQLError('Invalid Tag ID') 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) { if (!doc) {
throw new gql.GraphQLError('Invalid Document ID') throw new gql.GraphQLError('Invalid Document ID')
} }
@ -48,7 +48,7 @@ module.exports = {
}) })
}, },
renameTag(obj, args) { renameTag(obj, args) {
return wiki.db.Group.update({ return WIKI.db.Group.update({
key: args.key key: args.key
}, { }, {
where: { id: args.id } where: { id: args.id }

View File

@ -1,10 +1,10 @@
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
translations (obj, args, context, info) { translations (obj, args, context, info) {
return wiki.lang.getByNamespace(args.locale, args.namespace) return WIKI.lang.getByNamespace(args.locale, args.namespace)
} }
}, },
Mutation: {}, Mutation: {},

View File

@ -1,18 +1,18 @@
/* global wiki */ /* global WIKI */
module.exports = { module.exports = {
Query: { Query: {
users(obj, args, context, info) { users(obj, args, context, info) {
return wiki.db.User.findAll({ where: args }) return WIKI.db.User.findAll({ where: args })
} }
}, },
Mutation: { Mutation: {
createUser(obj, args) { createUser(obj, args) {
return wiki.db.User.create(args) return WIKI.db.User.create(args)
}, },
deleteUser(obj, args) { deleteUser(obj, args) {
return wiki.db.User.destroy({ return WIKI.db.User.destroy({
where: { where: {
id: args.id id: args.id
}, },
@ -20,7 +20,7 @@ module.exports = {
}) })
}, },
login(obj, args, context) { login(obj, args, context) {
return wiki.db.User.login(args, context).catch(err => { return WIKI.db.User.login(args, context).catch(err => {
return { return {
succeeded: false, succeeded: false,
message: err.message message: err.message
@ -28,7 +28,7 @@ module.exports = {
}) })
}, },
loginTFA(obj, args, context) { loginTFA(obj, args, context) {
return wiki.db.User.loginTFA(args, context).catch(err => { return WIKI.db.User.loginTFA(args, context).catch(err => {
return { return {
succeeded: false, succeeded: false,
message: err.message message: err.message
@ -36,7 +36,7 @@ module.exports = {
}) })
}, },
modifyUser(obj, args) { modifyUser(obj, args) {
return wiki.db.User.update({ return WIKI.db.User.update({
email: args.email, email: args.email,
name: args.name, name: args.name,
provider: args.provider, provider: args.provider,

View File

@ -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
}

View File

@ -1,6 +1,4 @@
# SCALARS
scalar Date
# ENUMS # ENUMS
@ -31,15 +29,6 @@ interface Base {
# TYPES # TYPES
type AuthenticationProvider {
key: String!
useForm: Boolean!
title: String!
props: [String]
icon: String
config: String
}
type Comment implements Base { type Comment implements Base {
id: Int! id: Int!
createdAt: Date createdAt: Date
@ -162,7 +151,6 @@ type LoginResult {
# Query (Read) # Query (Read)
type Query { type Query {
authentication(mode: String!): [AuthenticationProvider]
comments(id: Int): [Comment] comments(id: Int): [Comment]
documents(id: Int, path: String): [Document] documents(id: Int, path: String): [Document]
files(id: Int): [File] files(id: Int): [File]

View File

@ -0,0 +1,3 @@
# SCALARS
scalar Date

View File

@ -6,7 +6,7 @@
const path = require('path') const path = require('path')
const cluster = require('cluster') const cluster = require('cluster')
let wiki = { let WIKI = {
IS_DEBUG: process.env.NODE_ENV === 'development', IS_DEBUG: process.env.NODE_ENV === 'development',
IS_MASTER: cluster.isMaster, IS_MASTER: cluster.isMaster,
ROOTPATH: process.cwd(), ROOTPATH: process.cwd(),
@ -15,41 +15,41 @@ let wiki = {
configSvc: require('./core/config'), configSvc: require('./core/config'),
kernel: require('./core/kernel') kernel: require('./core/kernel')
} }
global.wiki = wiki global.WIKI = WIKI
// if (wiki.IS_DEBUG) { // if (WIKI.IS_DEBUG) {
// require('@glimpse/glimpse').init() // require('@glimpse/glimpse').init()
// } // }
wiki.configSvc.init() WIKI.configSvc.init()
// ---------------------------------------- // ----------------------------------------
// Init Logger // Init Logger
// ---------------------------------------- // ----------------------------------------
wiki.logger = require('./core/logger').init() WIKI.logger = require('./core/logger').init()
// ---------------------------------------- // ----------------------------------------
// Init Telemetry // Init Telemetry
// ---------------------------------------- // ----------------------------------------
wiki.telemetry = require('./core/telemetry').init() WIKI.telemetry = require('./core/telemetry').init()
process.on('unhandledRejection', (err) => { process.on('unhandledRejection', (err) => {
wiki.telemetry.sendError(err) WIKI.telemetry.sendError(err)
}) })
process.on('uncaughtException', (err) => { process.on('uncaughtException', (err) => {
wiki.telemetry.sendError(err) WIKI.telemetry.sendError(err)
}) })
// ---------------------------------------- // ----------------------------------------
// Init DB // Init DB
// ---------------------------------------- // ----------------------------------------
wiki.db = require('./core/db').init() WIKI.db = require('./core/db').init()
// ---------------------------------------- // ----------------------------------------
// Start Kernel // Start Kernel
// ---------------------------------------- // ----------------------------------------
wiki.kernel.init() WIKI.kernel.init()

View File

@ -10,31 +10,32 @@ const path = require('path')
const session = require('express-session') const session = require('express-session')
const SessionRedisStore = require('connect-redis')(session) const SessionRedisStore = require('connect-redis')(session)
const graphqlApollo = require('apollo-server-express') 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 () => { module.exports = async () => {
// ---------------------------------------- // ----------------------------------------
// Load core modules // Load core modules
// ---------------------------------------- // ----------------------------------------
wiki.auth = require('./core/auth').init() WIKI.auth = require('./core/auth').init()
wiki.lang = require('./core/localization').init() WIKI.lang = require('./core/localization').init()
// ---------------------------------------- // ----------------------------------------
// Load middlewares // Load middlewares
// ---------------------------------------- // ----------------------------------------
var mw = autoload(path.join(wiki.SERVERPATH, '/middlewares')) var mw = autoload(path.join(WIKI.SERVERPATH, '/middlewares'))
var ctrl = autoload(path.join(wiki.SERVERPATH, '/controllers')) var ctrl = autoload(path.join(WIKI.SERVERPATH, '/controllers'))
// ---------------------------------------- // ----------------------------------------
// Define Express App // Define Express App
// ---------------------------------------- // ----------------------------------------
const app = express() const app = express()
wiki.app = app WIKI.app = app
app.use(compression()) app.use(compression())
// ---------------------------------------- // ----------------------------------------
@ -42,38 +43,44 @@ module.exports = async () => {
// ---------------------------------------- // ----------------------------------------
app.use(mw.security) app.use(mw.security)
app.use(cors(wiki.config.cors)) app.use(cors(WIKI.config.cors))
app.options('*', cors(wiki.config.cors)) app.options('*', cors(WIKI.config.cors))
app.enable('trust proxy') app.enable('trust proxy')
// ---------------------------------------- // ----------------------------------------
// Public Assets // Public Assets
// ---------------------------------------- // ----------------------------------------
app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico')))
app.use(express.static(path.join(wiki.ROOTPATH, 'assets'), { app.use(express.static(path.join(WIKI.ROOTPATH, 'assets'), {
index: false, index: false,
maxAge: '7d' maxAge: '7d'
})) }))
// ----------------------------------------
// OAuth2 Server
// ----------------------------------------
const OAuth2Server = oauth2orize.createServer()
// ---------------------------------------- // ----------------------------------------
// Passport Authentication // Passport Authentication
// ---------------------------------------- // ----------------------------------------
let sessionStore = new SessionRedisStore({ let sessionStore = new SessionRedisStore({
client: wiki.redis client: WIKI.redis
}) })
app.use(cookieParser()) app.use(cookieParser())
app.use(session({ app.use(session({
name: 'wikijs.sid', name: 'wikijs.sid',
store: sessionStore, store: sessionStore,
secret: wiki.config.site.sessionSecret, secret: WIKI.config.site.sessionSecret,
resave: false, resave: false,
saveUninitialized: false saveUninitialized: false
})) }))
app.use(wiki.auth.passport.initialize()) app.use(WIKI.auth.passport.initialize())
app.use(wiki.auth.passport.session()) app.use(WIKI.auth.passport.session())
// ---------------------------------------- // ----------------------------------------
// SEO // SEO
@ -85,7 +92,7 @@ module.exports = async () => {
// View Engine Setup // 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.set('view engine', 'pug')
app.use(bodyParser.json({ limit: '1mb' })) app.use(bodyParser.json({ limit: '1mb' }))
@ -95,17 +102,17 @@ module.exports = async () => {
// Localization // Localization
// ---------------------------------------- // ----------------------------------------
wiki.lang.attachMiddleware(app) WIKI.lang.attachMiddleware(app)
// ---------------------------------------- // ----------------------------------------
// View accessible data // View accessible data
// ---------------------------------------- // ----------------------------------------
app.locals.basedir = wiki.ROOTPATH app.locals.basedir = WIKI.ROOTPATH
app.locals._ = require('lodash') app.locals._ = require('lodash')
app.locals.moment = require('moment') app.locals.moment = require('moment')
app.locals.moment.locale(wiki.config.site.lang) app.locals.moment.locale(WIKI.config.site.lang)
app.locals.config = wiki.config app.locals.config = WIKI.config
// ---------------------------------------- // ----------------------------------------
// HMR (Dev Mode Only) // HMR (Dev Mode Only)
@ -151,7 +158,7 @@ module.exports = async () => {
res.status(err.status || 500) res.status(err.status || 500)
res.render('error', { res.render('error', {
message: err.message, message: err.message,
error: wiki.IS_DEBUG ? err : {} error: WIKI.IS_DEBUG ? err : {}
}) })
}) })
@ -161,13 +168,13 @@ module.exports = async () => {
let srvConnections = {} 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) app.set('port', WIKI.config.port)
wiki.server = http.createServer(app) WIKI.server = http.createServer(app)
wiki.server.listen(wiki.config.port) WIKI.server.listen(WIKI.config.port)
wiki.server.on('error', (error) => { WIKI.server.on('error', (error) => {
if (error.syscall !== 'listen') { if (error.syscall !== 'listen') {
throw error throw error
} }
@ -175,17 +182,17 @@ module.exports = async () => {
// handle specific listen errors with friendly messages // handle specific listen errors with friendly messages
switch (error.code) { switch (error.code) {
case 'EACCES': 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) return process.exit(1)
case 'EADDRINUSE': 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) return process.exit(1)
default: default:
throw error throw error
} }
}) })
wiki.server.on('connection', conn => { WIKI.server.on('connection', conn => {
let key = `${conn.remoteAddress}:${conn.remotePort}` let key = `${conn.remoteAddress}:${conn.remotePort}`
srvConnections[key] = conn srvConnections[key] = conn
conn.on('close', function() { conn.on('close', function() {
@ -193,12 +200,12 @@ module.exports = async () => {
}) })
}) })
wiki.server.on('listening', () => { WIKI.server.on('listening', () => {
wiki.logger.info('HTTP Server: [ RUNNING ]') WIKI.logger.info('HTTP Server: [ RUNNING ]')
}) })
wiki.server.destroy = (cb) => { WIKI.server.destroy = (cb) => {
wiki.server.close(cb) WIKI.server.close(cb)
for (let key in srvConnections) { for (let key in srvConnections) {
srvConnections[key].destroy() srvConnections[key].destroy()
} }

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
/** /**
* Authentication middleware * Authentication middleware
@ -7,7 +7,7 @@ module.exports = (req, res, next) => {
// Is user authenticated ? // Is user authenticated ?
if (!req.isAuthenticated()) { if (!req.isAuthenticated()) {
if (wiki.config.auth.public !== true) { if (WIKI.config.auth.public !== true) {
return res.redirect('/login') return res.redirect('/login')
} else { } else {
// req.user = rights.guest // req.user = rights.guest

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
const Promise = require('bluebird') const Promise = require('bluebird')
const bcrypt = require('bcryptjs-then') const bcrypt = require('bcryptjs-then')
@ -62,13 +62,13 @@ module.exports = (sequelize, DataTypes) => {
if (await bcrypt.compare(rawPwd, this.password) === true) { if (await bcrypt.compare(rawPwd, this.password) === true) {
return true return true
} else { } else {
throw new wiki.Error.AuthLoginFailed() throw new WIKI.Error.AuthLoginFailed()
} }
} }
userSchema.prototype.enableTFA = async function () { userSchema.prototype.enableTFA = async function () {
let tfaInfo = tfa.generateSecret({ let tfaInfo = tfa.generateSecret({
name: wiki.config.site.title name: WIKI.config.site.title
}) })
this.tfaIsActive = true this.tfaIsActive = true
this.tfaSecret = tfaInfo.secret this.tfaSecret = tfaInfo.secret
@ -87,21 +87,21 @@ module.exports = (sequelize, DataTypes) => {
} }
userSchema.login = async (opts, context) => { 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.email', opts.username)
_.set(context.req, 'body.password', opts.password) _.set(context.req, 'body.password', opts.password)
// Authenticate // Authenticate
return new Promise((resolve, reject) => { 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 (err) { return reject(err) }
if (!user) { return reject(new wiki.Error.AuthLoginFailed()) } if (!user) { return reject(new WIKI.Error.AuthLoginFailed()) }
// Is 2FA required? // Is 2FA required?
if (user.tfaIsActive) { if (user.tfaIsActive) {
try { try {
let loginToken = await securityHelper.generateToken(32) 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({ return resolve({
succeeded: true, succeeded: true,
message: 'Login Successful. Awaiting 2FA security code.', message: 'Login Successful. Awaiting 2FA security code.',
@ -109,8 +109,8 @@ module.exports = (sequelize, DataTypes) => {
tfaLoginToken: loginToken tfaLoginToken: loginToken
}) })
} catch (err) { } catch (err) {
wiki.logger.warn(err) WIKI.logger.warn(err)
return reject(new wiki.Error.AuthGenericError()) return reject(new WIKI.Error.AuthGenericError())
} }
} else { } else {
// No 2FA, log in user // No 2FA, log in user
@ -126,17 +126,17 @@ module.exports = (sequelize, DataTypes) => {
})(context.req, context.res, () => {}) })(context.req, context.res, () => {})
}) })
} else { } else {
throw new wiki.Error.AuthProviderInvalid() throw new WIKI.Error.AuthProviderInvalid()
} }
} }
userSchema.loginTFA = async (opts, context) => { userSchema.loginTFA = async (opts, context) => {
if (opts.securityCode.length === 6 && opts.loginToken.length === 64) { 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) { if (result) {
let userId = _.toSafeInteger(result) let userId = _.toSafeInteger(result)
if (userId && userId > 0) { 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)) { if (user && user.verifyTFA(opts.securityCode)) {
return Promise.fromCallback(clb => { return Promise.fromCallback(clb => {
context.req.logIn(user, clb) context.req.logIn(user, clb)
@ -144,16 +144,16 @@ module.exports = (sequelize, DataTypes) => {
succeeded: true, succeeded: true,
message: 'Login Successful' message: 'Login Successful'
}).catch(err => { }).catch(err => {
wiki.logger.warn(err) WIKI.logger.warn(err)
throw new wiki.Error.AuthGenericError() throw new WIKI.Error.AuthGenericError()
}) })
} else { } else {
throw new wiki.Error.AuthTFAFailed() throw new WIKI.Error.AuthTFAFailed()
} }
} }
} }
} }
throw new wiki.Error.AuthTFAInvalid() throw new WIKI.Error.AuthTFAInvalid()
} }
userSchema.processProfile = (profile) => { userSchema.processProfile = (profile) => {
@ -168,13 +168,13 @@ module.exports = (sequelize, DataTypes) => {
} else if (profile.user && profile.user.email && profile.user.email.length > 5) { } else if (profile.user && profile.user.email && profile.user.email.length > 5) {
primaryEmail = profile.user.email primaryEmail = profile.user.email
} else { } 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) profile.provider = _.lowerCase(profile.provider)
primaryEmail = _.toLower(primaryEmail) primaryEmail = _.toLower(primaryEmail)
return wiki.db.User.findOneAndUpdate({ return WIKI.db.User.findOneAndUpdate({
email: primaryEmail, email: primaryEmail,
provider: profile.provider provider: profile.provider
}, { }, {
@ -186,7 +186,7 @@ module.exports = (sequelize, DataTypes) => {
new: true new: true
}).then((user) => { }).then((user) => {
// Handle unregistered accounts // 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 = { let nUsr = {
email: primaryEmail, email: primaryEmail,
provider: profile.provider, provider: profile.provider,
@ -200,9 +200,9 @@ module.exports = (sequelize, DataTypes) => {
deny: false 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')))
}) })
} }

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Auth0 Account // Auth0 Account
@ -19,7 +19,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, function (accessToken, refreshToken, profile, cb) { }, function (accessToken, refreshToken, profile, cb) {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Azure AD Account // Azure AD Account
@ -24,7 +24,7 @@ module.exports = {
let waadProfile = jwt.decode(params.id_token) let waadProfile = jwt.decode(params.id_token)
waadProfile.id = waadProfile.oid waadProfile.id = waadProfile.oid
waadProfile.provider = 'azure' waadProfile.provider = 'azure'
wiki.db.User.processProfile(waadProfile).then((user) => { WIKI.db.User.processProfile(waadProfile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Discord Account // Discord Account
@ -19,7 +19,7 @@ module.exports = {
callbackURL: conf.callbackURL, callbackURL: conf.callbackURL,
scope: 'identify email' scope: 'identify email'
}, function (accessToken, refreshToken, profile, cb) { }, function (accessToken, refreshToken, profile, cb) {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Dropbox Account // Dropbox Account
@ -19,7 +19,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => { }, (accessToken, refreshToken, profile, cb) => {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Facebook Account // Facebook Account
@ -19,7 +19,7 @@ module.exports = {
callbackURL: conf.callbackURL, callbackURL: conf.callbackURL,
profileFields: ['id', 'displayName', 'email'] profileFields: ['id', 'displayName', 'email']
}, function (accessToken, refreshToken, profile, cb) { }, function (accessToken, refreshToken, profile, cb) {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// GitHub Account // GitHub Account
@ -19,7 +19,7 @@ module.exports = {
callbackURL: conf.callbackURL, callbackURL: conf.callbackURL,
scope: ['user:email'] scope: ['user:email']
}, (accessToken, refreshToken, profile, cb) => { }, (accessToken, refreshToken, profile, cb) => {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Google ID Account // Google ID Account
@ -18,7 +18,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => { }, (accessToken, refreshToken, profile, cb) => {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// LDAP Account // LDAP Account
@ -33,7 +33,7 @@ module.exports = {
}, (profile, cb) => { }, (profile, cb) => {
profile.provider = 'ldap' profile.provider = 'ldap'
profile.id = profile.dn profile.id = profile.dn
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Local Account // Local Account
@ -17,7 +17,7 @@ module.exports = {
usernameField: 'email', usernameField: 'email',
passwordField: 'password' passwordField: 'password'
}, (uEmail, uPassword, done) => { }, (uEmail, uPassword, done) => {
wiki.db.User.findOne({ WIKI.db.User.findOne({
where: { where: {
email: uEmail, email: uEmail,
provider: 'local' provider: 'local'
@ -30,7 +30,7 @@ module.exports = {
return done(err, null) return done(err, null)
}) })
} else { } else {
return done(new wiki.Error.AuthLoginFailed(), null) return done(new WIKI.Error.AuthLoginFailed(), null)
} }
}).catch((err) => { }).catch((err) => {
done(err, null) done(err, null)

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Microsoft Account // Microsoft Account
@ -18,7 +18,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, function (accessToken, refreshToken, profile, cb) { }, function (accessToken, refreshToken, profile, cb) {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// OAuth2 Account // OAuth2 Account
@ -20,7 +20,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => { }, (accessToken, refreshToken, profile, cb) => {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Slack Account // Slack Account
@ -18,7 +18,7 @@ module.exports = {
clientSecret: conf.clientSecret, clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => { }, (accessToken, refreshToken, profile, cb) => {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,4 +1,4 @@
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Twitch Account // Twitch Account
@ -19,7 +19,7 @@ module.exports = {
callbackURL: conf.callbackURL, callbackURL: conf.callbackURL,
scope: 'user_read' scope: 'user_read'
}, function (accessToken, refreshToken, profile, cb) { }, function (accessToken, refreshToken, profile, cb) {
wiki.db.User.processProfile(profile).then((user) => { WIKI.db.User.processProfile(profile).then((user) => {
return cb(null, user) || true return cb(null, user) || true
}).catch((err) => { }).catch((err) => {
return cb(err, null) || true return cb(err, null) || true

View File

@ -1,6 +1,6 @@
const winston = require('winston') const winston = require('winston')
/* global wiki */ /* global WIKI */
// ------------------------------------ // ------------------------------------
// Console // Console
@ -12,7 +12,7 @@ module.exports = {
props: [], props: [],
init (logger, conf) { init (logger, conf) {
logger.add(winston.transports.Console, { logger.add(winston.transports.Console, {
level: wiki.config.logLevel, level: WIKI.config.logLevel,
prettyPrint: true, prettyPrint: true,
colorize: true, colorize: true,
silent: false, silent: false,

View File

@ -5,7 +5,7 @@ const _ = require('lodash')
// Mathjax // Mathjax
// ------------------------------------ // ------------------------------------
/* global wiki */ /* global WIKI */
const mathRegex = [ const mathRegex = [
{ {
@ -67,7 +67,7 @@ module.exports = {
resolve(result.svg) resolve(result.svg)
} else { } else {
resolve(currentMatch[0]) resolve(currentMatch[0])
wiki.logger.warn(result.errors.join(', ')) WIKI.logger.warn(result.errors.join(', '))
} }
}) })
}) })

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
/* global wiki */ /* global WIKI */
const Promise = require('bluebird') const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs-extra')) const fs = Promise.promisifyAll(require('fs-extra'))
@ -10,7 +10,7 @@ const path = require('path')
const entryHelper = require('../helpers/entry') const entryHelper = require('../helpers/entry')
module.exports = (job) => { module.exports = (job) => {
return wiki.git.resync().then(() => { return WIKI.git.resync().then(() => {
// -> Stream all documents // -> Stream all documents
let cacheJobs = [] let cacheJobs = []
@ -19,7 +19,7 @@ module.exports = (job) => {
jobCbStreamDocsResolve = resolve 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') { if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') {
let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path)) let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path))
let cachePath = entryHelper.getCachePath(entryPath) let cachePath = entryHelper.getCachePath(entryPath)
@ -62,7 +62,7 @@ module.exports = (job) => {
return jobCbStreamDocs return jobCbStreamDocs
}).then(() => { }).then(() => {
wiki.logger.info('Git remote repository sync: DONE') WIKI.logger.info('Git remote repository sync: DONE')
return true return true
}) })
} }

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
/* global wiki */ /* global WIKI */
const Promise = require('bluebird') const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs-extra')) const fs = Promise.promisifyAll(require('fs-extra'))
@ -8,22 +8,22 @@ const moment = require('moment')
const path = require('path') const path = require('path')
module.exports = (job) => { module.exports = (job) => {
return fs.readdirAsync(wiki.UPLTEMPPATH).then((ls) => { return fs.readdirAsync(WIKI.UPLTEMPPATH).then((ls) => {
let fifteenAgo = moment().subtract(15, 'minutes') let fifteenAgo = moment().subtract(15, 'minutes')
return Promise.map(ls, (f) => { 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) => { }).filter((s) => { return s.stat.isFile() }).then((arrFiles) => {
return Promise.map(arrFiles, (f) => { return Promise.map(arrFiles, (f) => {
if (moment(f.stat.ctime).isBefore(fifteenAgo, 'minute')) { 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 { } else {
return true return true
} }
}) })
}) })
}).then(() => { }).then(() => {
wiki.logger.info('Purging temporary upload files: DONE') WIKI.logger.info('Purging temporary upload files: DONE')
return true return true
}) })
} }

View File

@ -1,14 +1,14 @@
const path = require('path') const path = require('path')
/* global wiki */ /* global WIKI */
module.exports = () => { module.exports = () => {
wiki.config.site = { WIKI.config.site = {
path: '', path: '',
title: 'Wiki.js' title: 'WIKI.js'
} }
wiki.system = require('./core/system') WIKI.system = require('./core/system')
// ---------------------------------------- // ----------------------------------------
// Load modules // Load modules
@ -40,21 +40,21 @@ module.exports = () => {
// Public Assets // Public Assets
// ---------------------------------------- // ----------------------------------------
app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico')))
app.use(express.static(path.join(wiki.ROOTPATH, 'assets'))) app.use(express.static(path.join(WIKI.ROOTPATH, 'assets')))
// ---------------------------------------- // ----------------------------------------
// View Engine Setup // 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.set('view engine', 'pug')
app.use(bodyParser.json()) app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.urlencoded({ extended: false }))
app.locals.config = wiki.config app.locals.config = WIKI.config
app.locals.data = wiki.data app.locals.data = WIKI.data
app.locals._ = require('lodash') app.locals._ = require('lodash')
// ---------------------------------------- // ----------------------------------------
@ -71,10 +71,10 @@ module.exports = () => {
// ---------------------------------------- // ----------------------------------------
app.get('*', async (req, res) => { 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', { res.render('main/setup', {
packageObj, packageObj,
telemetryClientID: wiki.telemetry.cid telemetryClientID: WIKI.telemetry.cid
}) })
}) })
@ -82,8 +82,8 @@ module.exports = () => {
* Perform basic system checks * Perform basic system checks
*/ */
app.post('/syscheck', (req, res) => { app.post('/syscheck', (req, res) => {
wiki.telemetry.enabled = (req.body.telemetry === true) WIKI.telemetry.enabled = (req.body.telemetry === true)
wiki.telemetry.sendEvent('setup', 'start') WIKI.telemetry.sendEvent('setup', 'start')
Promise.mapSeries([ Promise.mapSeries([
() => { () => {
@ -126,7 +126,7 @@ module.exports = () => {
() => { () => {
let fs = require('fs') let fs = require('fs')
return Promise.try(() => { 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 => { }).catch(err => {
throw new Error('config.yml file is not writable by Node.js process or was not created properly.') 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.') }).return('config.yml is writable by the setup process.')
@ -142,13 +142,13 @@ module.exports = () => {
* Check the Git connection * Check the Git connection
*/ */
app.post('/gitcheck', (req, res) => { app.post('/gitcheck', (req, res) => {
wiki.telemetry.sendEvent('setup', 'gitcheck') WIKI.telemetry.sendEvent('setup', 'gitcheck')
const exec = require('execa') const exec = require('execa')
const url = require('url') const url = require('url')
const dataDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) const dataDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData))
const gitDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) const gitDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo))
let gitRemoteUrl = '' let gitRemoteUrl = ''
@ -235,107 +235,107 @@ module.exports = () => {
* Finalize * Finalize
*/ */
app.post('/finalize', async (req, res) => { app.post('/finalize', async (req, res) => {
wiki.telemetry.sendEvent('setup', 'finalize') WIKI.telemetry.sendEvent('setup', 'finalize')
try { try {
// Upgrade from Wiki.js 1.x? // Upgrade from WIKI.js 1.x?
if (req.body.upgrade) { if (req.body.upgrade) {
await wiki.system.upgradeFromMongo({ await WIKI.system.upgradeFromMongo({
mongoCnStr: cfgHelper.parseConfigValue(req.body.upgMongo) mongoCnStr: cfgHelper.parseConfigValue(req.body.upgMongo)
}) })
} }
// Update config file // Update config file
wiki.logger.info('Writing config file to disk...') WIKI.logger.info('Writing config file to disk...')
let confRaw = await fs.readFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), 'utf8') let confRaw = await fs.readFileAsync(path.join(WIKI.ROOTPATH, 'config.yml'), 'utf8')
let conf = yaml.safeLoad(confRaw) let conf = yaml.safeLoad(confRaw)
conf.port = req.body.port conf.port = req.body.port
conf.paths.repo = req.body.pathRepo conf.paths.repo = req.body.pathRepo
confRaw = yaml.safeDump(conf) 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, 'port', req.body.port)
_.set(wiki.config, 'paths.repo', req.body.pathRepo) _.set(WIKI.config, 'paths.repo', req.body.pathRepo)
// Populate config namespaces // Populate config namespaces
wiki.config.auth = wiki.config.auth || {} WIKI.config.auth = WIKI.config.auth || {}
wiki.config.features = wiki.config.features || {} WIKI.config.features = WIKI.config.features || {}
wiki.config.git = wiki.config.git || {} WIKI.config.git = WIKI.config.git || {}
wiki.config.logging = wiki.config.logging || {} WIKI.config.logging = WIKI.config.logging || {}
wiki.config.site = wiki.config.site || {} WIKI.config.site = WIKI.config.site || {}
wiki.config.theme = wiki.config.theme || {} WIKI.config.theme = WIKI.config.theme || {}
wiki.config.uploads = wiki.config.uploads || {} WIKI.config.uploads = WIKI.config.uploads || {}
// Site namespace // Site namespace
_.set(wiki.config.site, 'title', req.body.title) _.set(WIKI.config.site, 'title', req.body.title)
_.set(wiki.config.site, 'path', req.body.path) _.set(WIKI.config.site, 'path', req.body.path)
_.set(wiki.config.site, 'lang', req.body.lang) _.set(WIKI.config.site, 'lang', req.body.lang)
_.set(wiki.config.site, 'rtl', _.includes(wiki.data.rtlLangs, 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, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
// Auth namespace // Auth namespace
_.set(wiki.config.auth, 'public', req.body.public === 'true') _.set(WIKI.config.auth, 'public', req.body.public === 'true')
_.set(wiki.config.auth, 'strategies.local.enabled', true) _.set(WIKI.config.auth, 'strategies.local.enabled', true)
_.set(wiki.config.auth, 'strategies.local.allowSelfRegister', req.body.selfRegister === 'true') _.set(WIKI.config.auth, 'strategies.local.allowSelfRegister', req.body.selfRegister === 'true')
// Git namespace // Git namespace
_.set(wiki.config.git, 'enabled', req.body.gitUseRemote === 'true') _.set(WIKI.config.git, 'enabled', req.body.gitUseRemote === 'true')
if (wiki.config.git.enabled) { if (WIKI.config.git.enabled) {
_.set(wiki.config.git, 'url', req.body.gitUrl) _.set(WIKI.config.git, 'url', req.body.gitUrl)
_.set(wiki.config.git, 'branch', req.body.gitBranch) _.set(WIKI.config.git, 'branch', req.body.gitBranch)
_.set(wiki.config.git, 'author.defaultEmail', req.body.gitServerEmail) _.set(WIKI.config.git, 'author.defaultEmail', req.body.gitServerEmail)
_.set(wiki.config.git, 'author.useUserEmail', req.body.gitShowUserEmail) _.set(WIKI.config.git, 'author.useUserEmail', req.body.gitShowUserEmail)
_.set(wiki.config.git, 'sslVerify', req.body.gitAuthSSL === 'true') _.set(WIKI.config.git, 'sslVerify', req.body.gitAuthSSL === 'true')
_.set(wiki.config.git, 'auth.type', req.body.gitAuthType) _.set(WIKI.config.git, 'auth.type', req.body.gitAuthType)
switch (wiki.config.git.auth.type) { switch (WIKI.config.git.auth.type) {
case 'basic': case 'basic':
_.set(wiki.config.git, 'auth.user', req.body.gitAuthUser) _.set(WIKI.config.git, 'auth.user', req.body.gitAuthUser)
_.set(wiki.config.git, 'auth.pass', req.body.gitAuthPass) _.set(WIKI.config.git, 'auth.pass', req.body.gitAuthPass)
break break
case 'ssh': case 'ssh':
_.set(wiki.config.git, 'auth.keyPath', req.body.gitAuthSSHKey) _.set(WIKI.config.git, 'auth.keyPath', req.body.gitAuthSSHKey)
break break
case 'sshenv': case 'sshenv':
_.set(wiki.config.git, 'auth.keyEnv', req.body.gitAuthSSHKeyEnv) _.set(WIKI.config.git, 'auth.keyEnv', req.body.gitAuthSSHKeyEnv)
break break
case 'sshdb': case 'sshdb':
_.set(wiki.config.git, 'auth.keyContents', req.body.gitAuthSSHKeyDB) _.set(WIKI.config.git, 'auth.keyContents', req.body.gitAuthSSHKeyDB)
break break
} }
} }
// Logging namespace // Logging namespace
wiki.config.logging.telemetry = (req.body.telemetry === 'true') WIKI.config.logging.telemetry = (req.body.telemetry === 'true')
// Save config to DB // Save config to DB
wiki.logger.info('Persisting config to DB...') WIKI.logger.info('Persisting config to DB...')
await wiki.configSvc.saveToDb() await WIKI.configSvc.saveToDb()
// Create root administrator // Create root administrator
wiki.logger.info('Creating root administrator...') WIKI.logger.info('Creating root administrator...')
await wiki.db.User.upsert({ await WIKI.db.User.upsert({
email: req.body.adminEmail, email: req.body.adminEmail,
provider: 'local', provider: 'local',
password: await wiki.db.User.hashPassword(req.body.adminPassword), password: await WIKI.db.User.hashPassword(req.body.adminPassword),
name: 'Administrator', name: 'Administrator',
role: 'admin', role: 'admin',
tfaIsActive: false tfaIsActive: false
}) })
wiki.logger.info('Setup is complete!') WIKI.logger.info('Setup is complete!')
res.json({ res.json({
ok: true, ok: true,
redirectPath: wiki.config.site.path, redirectPath: WIKI.config.site.path,
redirectPort: wiki.config.port redirectPort: WIKI.config.port
}).end() }).end()
wiki.logger.info('Stopping Setup...') WIKI.logger.info('Stopping Setup...')
server.destroy(() => { server.destroy(() => {
wiki.logger.info('Setup stopped. Starting Wiki.js...') WIKI.logger.info('Setup stopped. Starting WIKI.js...')
_.delay(() => { _.delay(() => {
wiki.kernel.bootMaster() WIKI.kernel.bootMaster()
}, 1000) }, 1000)
}) })
} catch (err) { } catch (err) {
@ -357,25 +357,25 @@ module.exports = () => {
res.status(err.status || 500) res.status(err.status || 500)
res.send({ res.send({
message: err.message, message: err.message,
error: wiki.IS_DEBUG ? err : {} error: WIKI.IS_DEBUG ? err : {}
}) })
wiki.logger.error(err.message) WIKI.logger.error(err.message)
wiki.telemetry.sendError(err) WIKI.telemetry.sendError(err)
}) })
// ---------------------------------------- // ----------------------------------------
// Start HTTP server // 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) app.set('port', WIKI.config.port)
wiki.server = http.createServer(app) WIKI.server = http.createServer(app)
wiki.server.listen(wiki.config.port) WIKI.server.listen(WIKI.config.port)
var openConnections = [] var openConnections = []
wiki.server.on('connection', (conn) => { WIKI.server.on('connection', (conn) => {
let key = conn.remoteAddress + ':' + conn.remotePort let key = conn.remoteAddress + ':' + conn.remotePort
openConnections[key] = conn openConnections[key] = conn
conn.on('close', () => { conn.on('close', () => {
@ -383,31 +383,31 @@ module.exports = () => {
}) })
}) })
wiki.server.destroy = (cb) => { WIKI.server.destroy = (cb) => {
wiki.server.close(cb) WIKI.server.close(cb)
for (let key in openConnections) { for (let key in openConnections) {
openConnections[key].destroy() openConnections[key].destroy()
} }
} }
wiki.server.on('error', (error) => { WIKI.server.on('error', (error) => {
if (error.syscall !== 'listen') { if (error.syscall !== 'listen') {
throw error throw error
} }
switch (error.code) { switch (error.code) {
case 'EACCES': 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) return process.exit(1)
case 'EADDRINUSE': 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) return process.exit(1)
default: default:
throw error throw error
} }
}) })
wiki.server.on('listening', () => { WIKI.server.on('listening', () => {
wiki.logger.info('HTTP Server: RUNNING') WIKI.logger.info('HTTP Server: RUNNING')
}) })
} }

View File

@ -1,38 +1,38 @@
const Promise = require('bluebird') const Promise = require('bluebird')
/* global wiki */ /* global WIKI */
module.exports = Promise.join( module.exports = Promise.join(
wiki.db.onReady, WIKI.db.onReady,
wiki.configSvc.loadFromDb(['features', 'git', 'logging', 'site', 'uploads']) WIKI.configSvc.loadFromDb(['features', 'git', 'logging', 'site', 'uploads'])
).then(() => { ).then(() => {
const path = require('path') const path = require('path')
wiki.REPOPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo) WIKI.REPOPATH = path.resolve(WIKI.ROOTPATH, WIKI.config.paths.repo)
wiki.DATAPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.data) WIKI.DATAPATH = path.resolve(WIKI.ROOTPATH, WIKI.config.paths.data)
wiki.UPLTEMPPATH = path.join(wiki.DATAPATH, 'temp-upload') WIKI.UPLTEMPPATH = path.join(WIKI.DATAPATH, 'temp-upload')
// ---------------------------------------- // ----------------------------------------
// Load global modules // Load global modules
// ---------------------------------------- // ----------------------------------------
wiki.lang = require('i18next') WIKI.lang = require('i18next')
// ---------------------------------------- // ----------------------------------------
// Localization Engine // Localization Engine
// ---------------------------------------- // ----------------------------------------
const i18nBackend = require('i18next-node-fs-backend') const i18nBackend = require('i18next-node-fs-backend')
wiki.lang.use(i18nBackend).init({ WIKI.lang.use(i18nBackend).init({
load: 'languageOnly', load: 'languageOnly',
ns: ['common', 'admin', 'auth', 'errors', 'git'], ns: ['common', 'admin', 'auth', 'errors', 'git'],
defaultNS: 'common', defaultNS: 'common',
saveMissing: false, saveMissing: false,
preload: [wiki.config.lang], preload: [WIKI.config.lang],
lng: wiki.config.lang, lng: WIKI.config.lang,
fallbackLng: 'en', fallbackLng: 'en',
backend: { 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 Bull = require('bull')
const autoload = require('auto-load') 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) { for (let queueName in queues) {
new Bull(queueName, { new Bull(queueName, {
prefix: `q-${wiki.config.ha.nodeuid}`, prefix: `q-${WIKI.config.ha.nodeuid}`,
redis: wiki.config.redis redis: WIKI.config.redis
}).process(queues[queueName]) }).process(queues[queueName])
} }

View File

@ -2999,7 +2999,7 @@ debug@2.6.7:
dependencies: dependencies:
ms "2.0.0" 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" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies: dependencies:
@ -6988,6 +6988,14 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2" version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" 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: oauth@0.9.x:
version "0.9.15" version "0.9.15"
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"