feat: config wizard save

This commit is contained in:
NGPixel 2017-12-16 23:41:16 -05:00
parent 1f350172b9
commit 18dee58a06
12 changed files with 669 additions and 440 deletions

View File

@ -47,7 +47,7 @@ export default {
pathRepo: './repo', pathRepo: './repo',
port: siteConfig.port || 80, port: siteConfig.port || 80,
public: (siteConfig.public === true), public: (siteConfig.public === true),
selfregister: (siteConfig.selfregister === true), selfRegister: (siteConfig.selfRegister === true),
telemetry: true, telemetry: true,
title: siteConfig.title || 'Wiki', title: siteConfig.title || 'Wiki',
upgrade: false, upgrade: false,

View File

@ -1,7 +1,7 @@
####################################################################### #######################################################################
# Wiki.js - CONFIGURATION # # Wiki.js - CONFIGURATION #
####################################################################### #######################################################################
# Full explanation + examples in the documentation: # Full documentation + examples:
# https://docs.requarks.io/wiki/install # https://docs.requarks.io/wiki/install
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -39,11 +39,18 @@ redis:
db: 0 db: 0
password: null password: null
# ---------------------------------------------------------------------
# Log Level
# ---------------------------------------------------------------------
# Possible values: error, warn, info (default), verbose, debug, silly
logLevel: info
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
# Configuration Mode # Configuration Mode
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
# Possible values: # Possible values:
# - interactive (default) # - interactive (recommended)
# - file # - file
configMode: interactive configMode: interactive

View File

@ -33,17 +33,17 @@
}, },
"homepage": "https://github.com/Requarks/wiki#readme", "homepage": "https://github.com/Requarks/wiki#readme",
"engines": { "engines": {
"node": ">=8.8.1" "node": ">=8.9.3"
}, },
"dependencies": { "dependencies": {
"apollo-server-express": "1.2.0", "apollo-server-express": "1.3.0",
"auto-load": "3.0.0", "auto-load": "3.0.0",
"axios": "0.17.1", "axios": "0.17.1",
"bcryptjs-then": "1.0.1", "bcryptjs-then": "1.0.1",
"bluebird": "3.5.1", "bluebird": "3.5.1",
"body-parser": "1.18.2", "body-parser": "1.18.2",
"bugsnag": "2.0.1", "bugsnag": "2.0.1",
"bull": "3.3.6", "bull": "3.3.7",
"bunyan": "1.8.12", "bunyan": "1.8.12",
"cheerio": "1.0.0-rc.2", "cheerio": "1.0.0-rc.2",
"child-process-promise": "2.2.1", "child-process-promise": "2.2.1",
@ -59,24 +59,24 @@
"express-brute": "1.0.1", "express-brute": "1.0.1",
"express-brute-redis": "0.0.1", "express-brute-redis": "0.0.1",
"express-session": "1.15.6", "express-session": "1.15.6",
"file-type": "7.2.0", "file-type": "7.4.0",
"filesize.js": "1.0.2", "filesize.js": "1.0.2",
"follow-redirects": "1.2.5", "follow-redirects": "1.2.6",
"fs-extra": "4.0.2", "fs-extra": "5.0.0",
"git-wrapper2-promise": "0.2.9", "git-wrapper2-promise": "0.2.9",
"graphql": "0.11.7", "graphql": "0.12.1",
"graphql-tools": "2.7.2", "graphql-tools": "2.13.0",
"highlight.js": "9.12.0", "highlight.js": "9.12.0",
"i18next": "10.0.7", "i18next": "10.2.1",
"i18next-express-middleware": "1.0.7", "i18next-express-middleware": "1.0.9",
"i18next-localstorage-cache": "1.1.1", "i18next-localstorage-cache": "1.1.1",
"i18next-node-fs-backend": "1.0.0", "i18next-node-fs-backend": "1.0.0",
"image-size": "0.6.1", "image-size": "0.6.2",
"ioredis": "3.2.1", "ioredis": "3.2.2",
"jimp": "0.2.28", "jimp": "0.2.28",
"js-yaml": "3.10.0", "js-yaml": "3.10.0",
"jsonwebtoken": "8.1.0", "jsonwebtoken": "8.1.0",
"klaw": "2.1.0", "klaw": "2.1.1",
"lodash": "4.17.4", "lodash": "4.17.4",
"markdown-it": "8.4.0", "markdown-it": "8.4.0",
"markdown-it-abbr": "1.0.4", "markdown-it-abbr": "1.0.4",
@ -90,9 +90,9 @@
"markdown-it-task-lists": "2.1.0", "markdown-it-task-lists": "2.1.0",
"mathjax-node": "1.2.1", "mathjax-node": "1.2.1",
"mime-types": "2.1.17", "mime-types": "2.1.17",
"moment": "2.19.2", "moment": "2.20.0",
"moment-timezone": "0.5.14", "moment-timezone": "0.5.14",
"mongodb": "2.2.33", "mongodb": "3.0.0-rc0",
"multer": "1.3.0", "multer": "1.3.0",
"node-2fa": "1.1.2", "node-2fa": "1.1.2",
"node-graceful": "0.2.3", "node-graceful": "0.2.3",
@ -106,10 +106,10 @@
"passport-local": "1.0.0", "passport-local": "1.0.0",
"passport-slack": "0.0.7", "passport-slack": "0.0.7",
"passport-windowslive": "1.0.2", "passport-windowslive": "1.0.2",
"pg": "7.4.0", "pg": "6.4.2",
"pg-hstore": "2.3.2", "pg-hstore": "2.3.2",
"pg-promise": "7.3.1", "pg-promise": "7.3.2",
"pm2": "2.7.2", "pm2": "2.9.1",
"pug": "2.0.0-rc.4", "pug": "2.0.0-rc.4",
"qr-image": "3.2.0", "qr-image": "3.2.0",
"read-chunk": "2.1.0", "read-chunk": "2.1.0",
@ -117,65 +117,65 @@
"request": "2.83.0", "request": "2.83.0",
"request-promise": "4.2.2", "request-promise": "4.2.2",
"semver": "5.4.1", "semver": "5.4.1",
"sequelize": "4.22.6", "sequelize": "4.28.5",
"serve-favicon": "2.4.5", "serve-favicon": "2.4.5",
"simplemde": "1.11.2", "simplemde": "1.11.2",
"stream-to-promise": "2.2.0", "stream-to-promise": "2.2.0",
"tar": "4.0.2", "tar": "4.1.1",
"through2": "2.0.3", "through2": "2.0.3",
"uuid": "3.1.0", "uuid": "3.1.0",
"validator": "9.1.1", "validator": "9.2.0",
"validator-as-promised": "1.0.2", "validator-as-promised": "1.0.2",
"winston": "2.4.0", "winston": "2.4.0",
"yargs": "10.0.3" "yargs": "10.0.3"
}, },
"devDependencies": { "devDependencies": {
"@glimpse/glimpse": "0.22.15", "@glimpse/glimpse": "0.22.15",
"@panter/vue-i18next": "0.8.1", "@panter/vue-i18next": "0.9.1",
"apollo-client-preset": "1.0.2", "apollo-client-preset": "1.0.5",
"autoprefixer": "7.1.6", "autoprefixer": "7.2.3",
"babel-cli": "6.26.0", "babel-cli": "6.26.0",
"babel-core": "6.26.0", "babel-core": "6.26.0",
"babel-jest": "21.2.0", "babel-jest": "21.2.0",
"babel-preset-env": "1.6.1", "babel-preset-env": "1.6.1",
"babel-preset-es2015": "6.24.1", "babel-preset-es2015": "6.24.1",
"babel-preset-stage-2": "6.24.1", "babel-preset-stage-2": "6.24.1",
"brace": "0.10.0", "brace": "0.11.0",
"colors": "1.1.2", "colors": "1.1.2",
"consolidate": "0.15.0", "consolidate": "0.15.0",
"eslint": "4.11.0", "eslint": "4.13.1",
"eslint-config-requarks": "1.0.7", "eslint-config-requarks": "1.0.7",
"eslint-config-standard": "10.2.1", "eslint-config-standard": "11.0.0-beta.0",
"eslint-plugin-import": "2.8.0", "eslint-plugin-import": "2.8.0",
"eslint-plugin-node": "5.2.1", "eslint-plugin-node": "5.2.1",
"eslint-plugin-promise": "3.6.0", "eslint-plugin-promise": "3.6.0",
"eslint-plugin-standard": "3.0.1", "eslint-plugin-standard": "3.0.1",
"eslint-plugin-vue": "3.13.1", "eslint-plugin-vue": "3.13.1",
"fuse-box": "2.5.0-beta.1", "fuse-box": "2.5.0-beta.1",
"graphql-tag": "^2.5.0", "graphql-tag": "^2.6.0",
"i18next-xhr-backend": "1.5.0", "i18next-xhr-backend": "1.5.0",
"jest": "21.2.1", "jest": "21.2.1",
"jest-junit": "3.1.0", "jest-junit": "3.4.0",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
"node-sass": "4.6.1", "node-sass": "4.7.2",
"nodemon": "1.12.1", "nodemon": "1.13.3",
"postcss-selector-parser": "3.1.1", "postcss-selector-parser": "3.1.1",
"pug-lint": "2.5.0", "pug-lint": "2.5.0",
"twemoji-awesome": "1.0.6", "twemoji-awesome": "1.0.6",
"typescript": "2.6.1", "typescript": "2.6.2",
"uglify-es": "3.1.9", "uglify-es": "3.2.2",
"vee-validate": "2.0.0-rc.21", "vee-validate": "2.0.0-rc.27",
"vue": "2.5.3", "vue": "2.5.11",
"vue-clipboards": "1.1.0", "vue-clipboards": "1.2.0",
"vue-hot-reload-api": "2.2.3", "vue-hot-reload-api": "2.2.4",
"vue-lodash": "1.0.4", "vue-lodash": "1.0.4",
"vue-material": "^0.8.1", "vue-material": "^0.8.1",
"vue-resource": "1.3.4", "vue-resource": "1.3.4",
"vue-simple-breakpoints": "1.0.3", "vue-simple-breakpoints": "1.0.3",
"vue-template-compiler": "2.5.3", "vue-template-compiler": "2.5.11",
"vue-template-es2015-compiler": "1.6.0", "vue-template-es2015-compiler": "1.6.0",
"vuex": "3.0.1", "vuex": "3.0.1",
"vuex-persistedstate": "2.3.2" "vuex-persistedstate": "2.4.2"
}, },
"jest": { "jest": {
"testResultsProcessor": "./node_modules/jest-junit", "testResultsProcessor": "./node_modules/jest-junit",

View File

@ -237,6 +237,7 @@ module.exports = () => {
} }
// Update config file // Update config file
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)
@ -256,18 +257,60 @@ module.exports = () => {
wiki.config.uploads = wiki.config.uploads || {} wiki.config.uploads = wiki.config.uploads || {}
// Site namespace // Site namespace
wiki.config.site.title = req.body.title _.set(wiki.config.site, 'title', req.body.title)
wiki.config.site.path = req.body.path _.set(wiki.config.site, 'path', req.body.path)
wiki.config.site.lang = req.body.lang _.set(wiki.config.site, 'lang', req.body.lang)
wiki.config.site.rtl = _.includes(wiki.data.rtlLangs, req.body.lang) _.set(wiki.config.site, 'rtl', _.includes(wiki.data.rtlLangs, req.body.lang))
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
wiki.config.auth.public = (req.body.public === 'true') _.set(wiki.config.auth, 'public', req.body.public === 'true')
_.set(wiki.config.auth, 'strategies.local.allowSelfRegister', req.body.selfRegister === 'true')
// Git namespace
_.set(wiki.config.git, 'enabled', req.body.gitUseRemote === 'true')
if (wiki.config.git.enabled) {
_.set(wiki.config.git, 'url', req.body.gitUrl)
_.set(wiki.config.git, 'branch', req.body.gitBranch)
_.set(wiki.config.git, 'author.defaultEmail', req.body.gitServerEmail)
_.set(wiki.config.git, 'author.useUserEmail', req.body.gitShowUserEmail)
_.set(wiki.config.git, 'sslVerify', req.body.gitAuthSSL === 'true')
_.set(wiki.config.git, 'auth.type', req.body.gitAuthType)
switch (wiki.config.git.auth.type) {
case 'basic':
_.set(wiki.config.git, 'auth.user', req.body.gitAuthUser)
_.set(wiki.config.git, 'auth.pass', req.body.gitAuthPass)
break
case 'ssh':
_.set(wiki.config.git, 'auth.keyPath', req.body.gitAuthSSHKey)
break
case 'sshenv':
_.set(wiki.config.git, 'auth.keyEnv', req.body.gitAuthSSHKeyEnv)
break
case 'sshdb':
_.set(wiki.config.git, 'auth.keyContents', req.body.gitAuthSSHKeyDB)
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
wiki.logger.info('Persisting config to DB...')
await wiki.configSvc.saveToDb()
// Create root administrator
wiki.logger.info('Creating root administrator...')
await wiki.db.User.upsert({
email: req.body.adminEmail,
provider: 'local',
password: await wiki.db.User.hashPassword(req.body.adminPassword),
name: 'Administrator',
role: 'admin',
tfaIsActive: false
})
res.json({ ok: true }) res.json({ ok: true })
} catch (err) { } catch (err) {
res.json({ ok: false, error: err.message }) res.json({ ok: false, error: err.message })

View File

@ -37,126 +37,126 @@ router.get('/t/*', (req, res, next) => {
}) })
}) })
router.post('/img', wiki.disk.uploadImgHandler, (req, res, next) => { // router.post('/img', wiki.disk.uploadImgHandler, (req, res, next) => {
let destFolder = _.chain(req.body.folder).trim().toLower().value() // let destFolder = _.chain(req.body.folder).trim().toLower().value()
wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => { // wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
if (!destFolderPath) { // if (!destFolderPath) {
res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') }) // res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') })
return true // return true
} // }
Promise.map(req.files, (f) => { // Promise.map(req.files, (f) => {
let destFilename = '' // let destFilename = ''
let destFilePath = '' // let destFilePath = ''
return wiki.disk.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => { // return wiki.disk.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => {
destFilename = fname // destFilename = fname
destFilePath = path.resolve(destFolderPath, destFilename) // destFilePath = path.resolve(destFolderPath, destFilename)
return readChunk(f.path, 0, 262) // return readChunk(f.path, 0, 262)
}).then((buf) => { // }).then((buf) => {
// -> Check MIME type by magic number // // -> Check MIME type by magic number
let mimeInfo = fileType(buf) // let mimeInfo = fileType(buf)
if (!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) { // if (!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
return Promise.reject(new Error(wiki.lang.t('errors:invalidfiletype'))) // return Promise.reject(new Error(wiki.lang.t('errors:invalidfiletype')))
} // }
return true // return true
}).then(() => { // }).then(() => {
// -> Move file to final destination // // -> Move file to final destination
return fs.moveAsync(f.path, destFilePath, { clobber: false }) // return fs.moveAsync(f.path, destFilePath, { clobber: false })
}).then(() => { // }).then(() => {
return { // return {
ok: true, // ok: true,
filename: destFilename, // filename: destFilename,
filesize: f.size // filesize: f.size
} // }
}).reflect() // }).reflect()
}, {concurrency: 3}).then((results) => { // }, {concurrency: 3}).then((results) => {
let uplResults = _.map(results, (r) => { // let uplResults = _.map(results, (r) => {
if (r.isFulfilled()) { // if (r.isFulfilled()) {
return r.value() // return r.value()
} else { // } else {
return { // return {
ok: false, // ok: false,
msg: r.reason().message // msg: r.reason().message
} // }
} // }
}) // })
res.json({ ok: true, results: uplResults }) // res.json({ ok: true, results: uplResults })
return true // return true
}).catch((err) => { // }).catch((err) => {
res.json({ ok: false, msg: err.message }) // res.json({ ok: false, msg: err.message })
return true // return true
}) // })
}) // })
}) // })
router.post('/file', wiki.disk.uploadFileHandler, (req, res, next) => { // router.post('/file', wiki.disk.uploadFileHandler, (req, res, next) => {
let destFolder = _.chain(req.body.folder).trim().toLower().value() // let destFolder = _.chain(req.body.folder).trim().toLower().value()
wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => { // wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
if (!destFolderPath) { // if (!destFolderPath) {
res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') }) // res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') })
return true // return true
} // }
Promise.map(req.files, (f) => { // Promise.map(req.files, (f) => {
let destFilename = '' // let destFilename = ''
let destFilePath = '' // let destFilePath = ''
return wiki.disk.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => { // return wiki.disk.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => {
destFilename = fname // destFilename = fname
destFilePath = path.resolve(destFolderPath, destFilename) // destFilePath = path.resolve(destFolderPath, destFilename)
// -> Move file to final destination // // -> Move file to final destination
return fs.moveAsync(f.path, destFilePath, { clobber: false }) // return fs.moveAsync(f.path, destFilePath, { clobber: false })
}).then(() => { // }).then(() => {
return { // return {
ok: true, // ok: true,
filename: destFilename, // filename: destFilename,
filesize: f.size // filesize: f.size
} // }
}).reflect() // }).reflect()
}, {concurrency: 3}).then((results) => { // }, {concurrency: 3}).then((results) => {
let uplResults = _.map(results, (r) => { // let uplResults = _.map(results, (r) => {
if (r.isFulfilled()) { // if (r.isFulfilled()) {
return r.value() // return r.value()
} else { // } else {
return { // return {
ok: false, // ok: false,
msg: r.reason().message // msg: r.reason().message
} // }
} // }
}) // })
res.json({ ok: true, results: uplResults }) // res.json({ ok: true, results: uplResults })
return true // return true
}).catch((err) => { // }).catch((err) => {
res.json({ ok: false, msg: err.message }) // res.json({ ok: false, msg: err.message })
return true // return true
}) // })
}) // })
}) // })
router.get('/*', (req, res, next) => { // router.get('/*', (req, res, next) => {
let fileName = req.params[0] // let fileName = req.params[0]
if (!validPathRe.test(fileName)) { // if (!validPathRe.test(fileName)) {
return res.sendStatus(404).end() // return res.sendStatus(404).end()
} // }
// todo: Authentication-based access // // todo: Authentication-based access
res.sendFile(fileName, { // res.sendFile(fileName, {
root: wiki.git.getRepoPath() + '/uploads/', // root: wiki.git.getRepoPath() + '/uploads/',
dotfiles: 'deny' // dotfiles: 'deny'
}, (err) => { // }, (err) => {
if (err) { // if (err) {
res.status(err.status).end() // res.status(err.status).end()
} // }
}) // })
}) // })
module.exports = router module.exports = router

View File

@ -1,6 +1,6 @@
/* global wiki */ /* global wiki */
module.exports = () => { module.exports = async () => {
// ---------------------------------------- // ----------------------------------------
// Load global modules // Load global modules
// ---------------------------------------- // ----------------------------------------

View File

@ -54,28 +54,52 @@ module.exports = {
* @param {Array} subsets Array of subsets to load * @param {Array} subsets Array of subsets to load
* @returns Promise * @returns Promise
*/ */
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
} }
return wiki.db.Setting.findAll({ let results = await wiki.db.Setting.findAll({
attributes: ['key', 'config'], attributes: ['key', 'config'],
where: { where: {
key: { key: {
$in: subsets $in: subsets
} }
} }
}).then(results => {
if (_.isArray(results) && results.length === subsets.length) {
results.forEach(result => {
wiki.config[result.key] = result.config
})
return true
} else {
wiki.logger.warn('DB Configuration is empty or incomplete.')
return false
}
}) })
if (_.isArray(results) && results.length === subsets.length) {
results.forEach(result => {
wiki.config[result.key] = result.config
})
return true
} else {
wiki.logger.warn('DB Configuration is empty or incomplete.')
return false
}
},
/**
* Save config to DB
*
* @param {Array} subsets Array of subsets to save
* @returns Promise
*/
async saveToDb(subsets) {
if (!_.isArray(subsets) || subsets.length === 0) {
subsets = wiki.data.configNamespaces
}
try {
for (let set of subsets) {
await wiki.db.Setting.upsert({
key: set,
config: _.get(wiki.config, set, {})
})
}
} catch (err) {
wiki.logger.error(`Failed to save configuration to DB: ${err.message}`)
return false
}
return true
} }
} }

View File

@ -73,7 +73,7 @@ module.exports = {
min: 0, min: 0,
idle: 10000 idle: 10000
}, },
logging: log => { wiki.logger.log('verbose', log) }, logging: log => { wiki.logger.log('debug', log) },
operatorsAliases operatorsAliases
}) })
@ -110,7 +110,7 @@ module.exports = {
syncSchemas() { syncSchemas() {
return self.inst.sync({ return self.inst.sync({
force: false, force: false,
logging: log => { wiki.logger.log('verbose', log) } logging: log => { wiki.logger.log('debug', log) }
}) })
}, },
// -> Set Connection App Name // -> Set Connection App Name

View File

@ -11,10 +11,10 @@ module.exports = {
// Console // Console
let logger = new (winston.Logger)({ let logger = new (winston.Logger)({
level: (wiki.IS_DEBUG) ? 'debug' : 'info', level: wiki.config.logLevel,
transports: [ transports: [
new (winston.transports.Console)({ new (winston.transports.Console)({
level: (wiki.IS_DEBUG) ? 'debug' : 'info', level: wiki.config.logLevel,
prettyPrint: true, prettyPrint: true,
colorize: true, colorize: true,
silent: false, silent: false,

View File

@ -14,6 +14,8 @@ module.exports = {
async upgradeFromMongo (opts) { async upgradeFromMongo (opts) {
wiki.telemetry.sendEvent('setup', 'upgradeFromMongo') wiki.telemetry.sendEvent('setup', 'upgradeFromMongo')
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)

View File

@ -112,7 +112,7 @@ block body
label.label(for='ipt-public') Public Access label.label(for='ipt-public') Public Access
span.desc Should the site be accessible (read only) without login. span.desc Should the site be accessible (read only) without login.
p.control.is-fullwidth p.control.is-fullwidth
input#ipt-selfregister(type='checkbox', v-model='conf.selfregister', data-vv-scope='general', name='ipt-selfregister') input#ipt-selfregister(type='checkbox', v-model='conf.selfRegister', data-vv-scope='general', name='ipt-selfregister')
label.label(for='ipt-selfregister') Allow Self-Registration label.label(for='ipt-selfregister') Allow Self-Registration
span.desc Can users create their own account to gain access? span.desc Can users create their own account to gain access?
section section
@ -208,7 +208,7 @@ block body
p.control.is-fullwidth p.control.is-fullwidth
label.label Private Key location label.label Private Key location
input(type='text', placeholder='e.g. /etc/wiki/keys/git.pem', v-model='conf.gitAuthSSHKey') input(type='text', placeholder='e.g. /etc/wiki/keys/git.pem', v-model='conf.gitAuthSSHKey')
span.desc The full path to the private key on disk. span.desc The full path to the #[strong unencrypted] private key on disk.
.column(v-show='conf.gitAuthType === "sshenv"') .column(v-show='conf.gitAuthType === "sshenv"')
p.control.is-fullwidth p.control.is-fullwidth
label.label Private Key Environment Variable label.label Private Key Environment Variable

687
yarn.lock

File diff suppressed because it is too large Load Diff