Commit 4cb9f3d9 authored by Nicolas Giard's avatar Nicolas Giard

feat: rendering modules + admin rendering

parent db8e598e
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
.subheading.grey--text Configure how content is rendered .subheading.grey--text Configure how content is rendered
v-layout.mt-3(row wrap) v-layout.mt-3(row wrap)
v-flex(lg3 xs12) v-flex(lg3 xs12)
v-card
v-toolbar( v-toolbar(
color='primary' color='primary'
dense dense
...@@ -15,132 +14,37 @@ ...@@ -15,132 +14,37 @@
) )
v-icon.mr-2 line_weight v-icon.mr-2 line_weight
.subheading Pipeline .subheading Pipeline
v-toolbar( v-expansion-panel.adm-rendering-pipeline
color='blue' v-expansion-panel-content(
dense hide-actions
dark v-for='core in cores'
) :key='core.key'
v-icon.mr-2 arrow_downward
.body-2 Markdown
v-spacer
v-btn(
icon
@click=''
) )
v-icon add
v-list(two-line, dense)
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') crop_free
v-list-tile-content
v-list-tile-title Core
v-list-tile-sub-title Basic Markdown parser
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') tag_faces
v-list-tile-content
v-list-tile-title Emoji
v-list-tile-sub-title Convert tags to emojis
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') list
v-list-tile-content
v-list-tile-title Task Lists
v-list-tile-sub-title Parse task lists to checkboxes
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') multiline_chart
v-list-tile-content
v-list-tile-title PlantUML
v-list-tile-sub-title Generate diagrams from PlantUML syntax
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') merge_type
v-list-tile-content
v-list-tile-title Mermaid
v-list-tile-sub-title Generate flowcharts from Mermaid syntax
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') functions
v-list-tile-content
v-list-tile-title Mathjax Pre-Processor
v-list-tile-sub-title Parse Mathjax content from Markdown
v-list-tile-avatar
v-icon(color='red', small) trip_origin
v-toolbar( v-toolbar(
slot='header'
color='blue' color='blue'
dense dense
dark dark
flat
) )
v-icon.mr-2 arrow_downward .body-2 {{core.input}}
.body-2 HTML v-icon.mx-2 arrow_forward
v-spacer .caption {{core.output}}
v-btn(
icon
@click=''
)
v-icon add
v-list(two-line, dense) v-list(two-line, dense)
v-list-tile(avatar) v-list-tile(
v-list-tile-avatar avatar
v-icon(color='grey') subscriptions v-for='rdr in core.children'
v-list-tile-content :key='rdr.key'
v-list-tile-title Video Players )
v-list-tile-sub-title Embed video players such as Youtube, Vimeo, etc.
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') subtitles
v-list-tile-content
v-list-tile-title Asciinema
v-list-tile-sub-title Embed asciinema players from compatible links
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') volume_up
v-list-tile-content
v-list-tile-title Audio Players
v-list-tile-sub-title Embed audio players for audio content
v-list-tile-avatar
v-icon(color='green', small) lens
v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar v-list-tile-avatar
v-icon(color='grey') insert_comment v-icon(color='grey') {{rdr.icon}}
v-list-tile-content v-list-tile-content
v-list-tile-title Blockquotes v-list-tile-title {{rdr.title}}
v-list-tile-sub-title Process styled blockquotes v-list-tile-sub-title {{rdr.description}}
v-list-tile-avatar v-list-tile-avatar
v-icon(color='green', small) lens v-icon(color='green', small, v-if='rdr.isEnabled') lens
v-icon(color='red', small, v-else) trip_origin
v-divider.my-0 v-divider.my-0
v-list-tile(avatar)
v-list-tile-avatar
v-icon(color='grey') functions
v-list-tile-content
v-list-tile-title Mathjax Processor
v-list-tile-sub-title TeX/MathML Math Equations Parser
v-list-tile-avatar
v-icon(color='red', small) trip_origin
v-flex(lg9 xs12) v-flex(lg9 xs12)
v-card v-card
...@@ -201,16 +105,45 @@ ...@@ -201,16 +105,45 @@
</template> </template>
<script> <script>
import _ from 'lodash'
import renderersQuery from 'gql/admin/rendering/rendering-query-renderers.gql'
export default { export default {
data() { data() {
return { return {
linkify: true, linkify: true,
codeTheme: 'Light' codeTheme: 'Light',
renderers: []
}
},
computed: {
cores() {
return _.filter(this.renderers, ['dependsOn', null]).map(core => {
core.children = _.concat([_.cloneDeep(core)], _.filter(this.renderers, ['dependsOn', core.key]))
return core
})
}
},
apollo: {
renderers: {
query: renderersQuery,
fetchPolicy: 'network-only',
update: (data) => _.cloneDeep(data.rendering.renderers).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.parse(cfg.value)}))})),
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-rendering-refresh')
}
} }
} }
} }
</script> </script>
<style lang='scss'> <style lang='scss'>
.adm-rendering-pipeline {
border-top: 1px solid #FFF;
.v-expansion-panel__header {
padding: 0 0;
}
}
</style> </style>
mutation($renderers: [RendererInput]) {
rendering {
updateRenderers(renderers: $renderers) {
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
{
rendering {
renderers {
isEnabled
key
title
description
icon
dependsOn
input
output
config {
key
value
}
}
}
}
...@@ -51,6 +51,7 @@ module.exports = { ...@@ -51,6 +51,7 @@ module.exports = {
async postBootMaster() { async postBootMaster() {
await WIKI.models.authentication.refreshStrategiesFromDisk() await WIKI.models.authentication.refreshStrategiesFromDisk()
await WIKI.models.editors.refreshEditorsFromDisk() await WIKI.models.editors.refreshEditorsFromDisk()
await WIKI.models.renderers.refreshRenderersFromDisk()
await WIKI.models.storage.refreshTargetsFromDisk() await WIKI.models.storage.refreshTargetsFromDisk()
await WIKI.auth.activateStrategies() await WIKI.auth.activateStrategies()
......
...@@ -96,7 +96,7 @@ exports.up = knex => { ...@@ -96,7 +96,7 @@ exports.up = knex => {
table.string('createdAt').notNullable() table.string('createdAt').notNullable()
table.string('updatedAt').notNullable() table.string('updatedAt').notNullable()
}) })
// STORAGE ----------------------------- // RENDERERS ---------------------------
.createTable('renderers', table => { .createTable('renderers', table => {
table.increments('id').primary() table.increments('id').primary()
table.string('key').notNullable().unique() table.string('key').notNullable().unique()
...@@ -199,14 +199,19 @@ exports.up = knex => { ...@@ -199,14 +199,19 @@ exports.up = knex => {
exports.down = knex => { exports.down = knex => {
return knex.schema return knex.schema
.dropTableIfExists('userGroups') .dropTableIfExists('userGroups')
.dropTableIfExists('pageHistoryTags')
.dropTableIfExists('pageHistory')
.dropTableIfExists('pageTags') .dropTableIfExists('pageTags')
.dropTableIfExists('assets') .dropTableIfExists('assets')
.dropTableIfExists('assetFolders') .dropTableIfExists('assetFolders')
.dropTableIfExists('comments') .dropTableIfExists('comments')
.dropTableIfExists('editors')
.dropTableIfExists('groups') .dropTableIfExists('groups')
.dropTableIfExists('locales') .dropTableIfExists('locales')
.dropTableIfExists('pages') .dropTableIfExists('pages')
.dropTableIfExists('renderers')
.dropTableIfExists('settings') .dropTableIfExists('settings')
.dropTableIfExists('storage')
.dropTableIfExists('tags') .dropTableIfExists('tags')
.dropTableIfExists('users') .dropTableIfExists('users')
} }
const _ = require('lodash')
const graphHelper = require('../../helpers/graph')
/* global WIKI */
module.exports = {
Query: {
async rendering() { return {} }
},
Mutation: {
async rendering() { return {} }
},
RenderingQuery: {
async renderers(obj, args, context, info) {
let renderers = await WIKI.models.renderers.getRenderers()
renderers = renderers.map(rdr => {
const rendererInfo = _.find(WIKI.data.renderers, ['key', rdr.key]) || {}
return {
...rendererInfo,
...rdr,
config: _.sortBy(_.transform(rdr.config, (res, value, key) => {
const configData = _.get(rendererInfo.props, key, {})
res.push({
key,
value: JSON.stringify({
...configData,
value
})
})
}, []), 'key')
}
})
if (args.filter) { renderers = graphHelper.filter(renderers, args.filter) }
if (args.orderBy) { renderers = graphHelper.orderBy(renderers, args.orderBy) }
return renderers
}
},
RenderingMutation: {
async updateRenderers(obj, args, context) {
try {
for (let rdr of args.renderers) {
await WIKI.models.storage.query().patch({
isEnabled: rdr.isEnabled,
config: _.reduce(rdr.config, (result, value, key) => {
_.set(result, `${value.key}`, value.value)
return result
}, {})
}).where('key', rdr.key)
}
return {
responseResult: graphHelper.generateSuccess('Renderers updated successfully')
}
} catch (err) {
return graphHelper.generateError(err)
}
}
}
}
# ===============================================
# RENDERING
# ===============================================
extend type Query {
rendering: RenderingQuery
}
extend type Mutation {
rendering: RenderingMutation
}
# -----------------------------------------------
# QUERIES
# -----------------------------------------------
type RenderingQuery {
renderers(
filter: String
orderBy: String
): [Renderer]
}
# -----------------------------------------------
# MUTATIONS
# -----------------------------------------------
type RenderingMutation {
updateRenderers(
renderers: [RendererInput]
): DefaultResponse
}
# -----------------------------------------------
# TYPES
# -----------------------------------------------
type Renderer {
isEnabled: Boolean!
key: String!
title: String!
description: String
icon: String
dependsOn: String
input: String
output: String
config: [KeyValuePair]
}
input RendererInput {
isEnabled: Boolean!
key: String!
mode: String!
config: [KeyValuePairInput]
}
const Model = require('objection').Model
const path = require('path')
const fs = require('fs-extra')
const _ = require('lodash')
const yaml = require('js-yaml')
const commonHelper = require('../helpers/common')
/* global WIKI */
/**
* Renderer model
*/
module.exports = class Renderer extends Model {
static get tableName() { return 'renderers' }
static get jsonSchema () {
return {
type: 'object',
required: ['key', 'isEnabled'],
properties: {
id: {type: 'integer'},
key: {type: 'string'},
isEnabled: {type: 'boolean'},
config: {type: 'object'}
}
}
}
static async getRenderers() {
return WIKI.models.renderers.query()
}
static async refreshRenderersFromDisk() {
let trx
try {
const dbRenderers = await WIKI.models.renderers.query()
// -> Fetch definitions from disk
const rendererDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/renderer'))
let diskRenderers = []
for (let dir of rendererDirs) {
const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/renderer', dir, 'definition.yml'), 'utf8')
diskRenderers.push(yaml.safeLoad(def))
}
WIKI.data.renderers = diskRenderers.map(renderer => ({
...renderer,
props: commonHelper.parseModuleProps(renderer.props)
}))
// -> Insert new Renderers
let newRenderers = []
for (let renderer of WIKI.data.renderers) {
if (!_.some(dbRenderers, ['key', renderer.key])) {
newRenderers.push({
key: renderer.key,
isEnabled: _.get(renderer, 'enabledDefault', true),
config: _.transform(renderer.props, (result, value, key) => {
_.set(result, key, value.default)
return result
}, {})
})
} else {
const rendererConfig = _.get(_.find(dbRenderers, ['key', renderer.key]), 'config', {})
await WIKI.models.renderers.query().patch({
config: _.transform(renderer.props, (result, value, key) => {
if (!_.has(result, key)) {
_.set(result, key, value.default)
}
return result
}, rendererConfig)
}).where('key', renderer.key)
}
}
if (newRenderers.length > 0) {
trx = await WIKI.models.Objection.transaction.start(WIKI.models.knex)
for (let renderer of newRenderers) {
await WIKI.models.renderers.query(trx).insert(renderer)
}
await trx.commit()
WIKI.logger.info(`Loaded ${newRenderers.length} new renderers: [ OK ]`)
} else {
WIKI.logger.info(`No new renderers found: [ SKIPPED ]`)
}
} catch (err) {
WIKI.logger.error(`Failed to scan or load new renderers: [ FAILED ]`)
WIKI.logger.error(err)
if (trx) {
trx.rollback()
}
}
}
static async pageEvent({ event, page }) {
const targets = await WIKI.models.storage.query().where('isEnabled', true)
if (targets && targets.length > 0) {
_.forEach(targets, target => {
WIKI.queue.job.syncStorage.add({
event,
target,
page
}, {
removeOnComplete: true
})
})
}
}
}
key: markdownAbbr key: htmlAsciinema
title: Abbreviations title: Asciinema
description: Parse abbreviations into abbr tags description: Embed asciinema players from compatible links
author: requarks.io author: requarks.io
dependsOn: icon: subtitles
- markdownCore enabledDefault: false
dependsOn: htmlCore
props: {} props: {}
key: markdownAbbr key: htmlBlockquotes
title: Abbreviations title: Blockquotes
description: Parse abbreviations into abbr tags description: Embed audio players for audio content
author: requarks.io author: requarks.io
dependsOn: icon: insert_comment
- markdownCore enabledDefault: true
dependsOn: htmlCore
props: {} props: {}
key: htmlCore
title: Core
description: Basic HTML Parser
author: requarks.io
input: html
output: html
icon: crop_free
props: {}
key: markdownAbbr key: htmlMathjax
title: Abbreviations title: Mathjax Processor
description: Parse abbreviations into abbr tags description: TeX/MathML Math Equations Parser
author: requarks.io author: requarks.io
dependsOn: icon: functions
- markdownCore enabledDefault: false
dependsOn: htmlCore
props: {} props: {}
key: markdownAbbr key: htmlMedia
title: Abbreviations title: Media Players
description: Parse abbreviations into abbr tags description: Embed players such as Youtube, Vimeo, Soundcloud, etc.
author: requarks.io author: requarks.io
dependsOn: icon: subscriptions
- markdownCore enabledDefault: false
dependsOn: htmlCore
props: {} props: {}
key: markdownAbbr key: htmlSecurity
title: Abbreviations title: Security
description: Parse abbreviations into abbr tags description: Filter and strips potentially dangerous content
author: requarks.io author: requarks.io
dependsOn: icon: whatshot
- markdownCore enabledDefault: true
dependsOn: htmlCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownAbbr ...@@ -2,6 +2,7 @@ key: markdownAbbr
title: Abbreviations title: Abbreviations
description: Parse abbreviations into abbr tags description: Parse abbreviations into abbr tags
author: requarks.io author: requarks.io
dependsOn: icon: text_format
- markdownCore enabledDefault: true
dependsOn: markdownCore
props: {} props: {}
...@@ -2,7 +2,9 @@ key: markdownCore ...@@ -2,7 +2,9 @@ key: markdownCore
title: Core title: Core
description: Basic Markdown Parser description: Basic Markdown Parser
author: requarks.io author: requarks.io
dependsOn: [] input: markdown
output: html
icon: crop_free
props: props:
linkify: linkify:
type: Boolean type: Boolean
......
...@@ -2,6 +2,7 @@ key: markdownEmoji ...@@ -2,6 +2,7 @@ key: markdownEmoji
title: Emoji title: Emoji
description: Convert tags to emojis description: Convert tags to emojis
author: requarks.io author: requarks.io
dependsOn: icon: tag_faces
- markdownCore enabledDefault: true
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownExpandtabs ...@@ -2,6 +2,7 @@ key: markdownExpandtabs
title: Expand Tabs title: Expand Tabs
description: Replace tabs with spaces in code blocks description: Replace tabs with spaces in code blocks
author: requarks.io author: requarks.io
dependsOn: icon: space_bar
- markdownCore enabledDefault: true
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownFootnotes ...@@ -2,6 +2,7 @@ key: markdownFootnotes
title: Footnotes title: Footnotes
description: Parse footnotes references description: Parse footnotes references
author: requarks.io author: requarks.io
dependsOn: icon: low_priority
- markdownCore enabledDefault: true
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownMathjax ...@@ -2,6 +2,7 @@ key: markdownMathjax
title: Mathjax Pre-Processor title: Mathjax Pre-Processor
description: Pre-parse TeX blocks for Mathjax description: Pre-parse TeX blocks for Mathjax
author: requarks.io author: requarks.io
dependsOn: icon: functions
- markdownCore enabledDefault: false
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownMermaid ...@@ -2,6 +2,7 @@ key: markdownMermaid
title: Mermaid title: Mermaid
description: Generate flowcharts from Mermaid syntax description: Generate flowcharts from Mermaid syntax
author: requarks.io author: requarks.io
dependsOn: icon: merge_type
- markdownCore enabledDefault: false
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownPlantuml ...@@ -2,6 +2,7 @@ key: markdownPlantuml
title: PlantUML title: PlantUML
description: Generate diagrams from PlantUML syntax description: Generate diagrams from PlantUML syntax
author: requarks.io author: requarks.io
dependsOn: icon: multiline_chart
- markdownCore enabledDefault: false
dependsOn: markdownCore
props: {} props: {}
...@@ -2,6 +2,7 @@ key: markdownTasklists ...@@ -2,6 +2,7 @@ key: markdownTasklists
title: Task Lists title: Task Lists
description: Parse task lists to checkboxes description: Parse task lists to checkboxes
author: requarks.io author: requarks.io
dependsOn: icon: list
- markdownCore enabledDefault: true
dependsOn: markdownCore
props: {} props: {}
...@@ -24,7 +24,6 @@ module.exports = () => { ...@@ -24,7 +24,6 @@ module.exports = () => {
const yaml = require('js-yaml') const yaml = require('js-yaml')
const _ = require('lodash') const _ = require('lodash')
const cfgHelper = require('./helpers/config') const cfgHelper = require('./helpers/config')
const filesize = require('filesize.js')
const crypto = Promise.promisifyAll(require('crypto')) const crypto = Promise.promisifyAll(require('crypto'))
// ---------------------------------------- // ----------------------------------------
...@@ -77,174 +76,6 @@ module.exports = () => { ...@@ -77,174 +76,6 @@ module.exports = () => {
}) })
/** /**
* Perform basic system checks
*/
app.post('/syscheck', (req, res) => {
WIKI.telemetry.enabled = (req.body.telemetry === true)
WIKI.telemetry.sendEvent('setup', 'start')
Promise.mapSeries([
() => {
const semver = require('semver')
if (!semver.satisfies(semver.clean(process.version), '>=8.9.0')) {
throw new Error('Node.js version is too old. Minimum is 8.9.0.')
}
return {
title: 'Node.js ' + process.version + ' detected.',
subtitle: ' Minimum is 8.9.0.'
}
},
() => {
return Promise.try(() => {
require('crypto')
}).catch(err => {
throw new Error('Crypto Node.js module is not available.')
}).return({
title: 'Node.js Crypto module is available.',
subtitle: 'Crypto module is required.'
})
},
() => {
const exec = require('child_process').exec
const semver = require('semver')
return new Promise((resolve, reject) => {
exec('git --version', (err, stdout, stderr) => {
if (err || stdout.length < 3) {
reject(new Error('Git is not installed or not reachable from PATH.'))
}
let gitver = _.head(stdout.match(/[\d]+\.[\d]+(\.[\d]+)?/gi))
if (!gitver || !semver.satisfies(semver.clean(gitver), '>=2.7.4')) {
reject(new Error('Git version is too old. Minimum is 2.7.4.'))
}
resolve({
title: 'Git ' + gitver + ' detected.',
subtitle: 'Minimum is 2.7.4.'
})
})
})
},
() => {
const os = require('os')
if (os.totalmem() < 1000 * 1000 * 768) {
throw new Error('Not enough memory. Minimum is 768 MB.')
}
return {
title: filesize(os.totalmem()) + ' of system memory available.',
subtitle: 'Minimum is 768 MB.'
}
},
() => {
let fs = require('fs')
return Promise.try(() => {
fs.accessSync(path.join(WIKI.ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK)
}).catch(err => {
throw new Error('config.yml file is not writable by Node.js process or was not created properly.')
}).return({
title: 'config.yml is writable by the setup process.',
subtitle: 'Setup will write to this file.'
})
}
], test => test()).then(results => {
res.json({ ok: true, results })
}).catch(err => {
res.json({ ok: false, error: err.message })
})
})
/**
* Check the Git connection
*/
app.post('/gitcheck', (req, res) => {
WIKI.telemetry.sendEvent('setup', 'gitcheck')
const exec = require('execa')
const url = require('url')
const dataDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData))
const gitDir = path.resolve(WIKI.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo))
let gitRemoteUrl = ''
if (req.body.gitUseRemote === true) {
let urlObj = url.parse(cfgHelper.parseConfigValue(req.body.gitUrl))
if (req.body.gitAuthType === 'basic') {
urlObj.auth = req.body.gitAuthUser + ':' + req.body.gitAuthPass
}
gitRemoteUrl = url.format(urlObj)
}
Promise.mapSeries([
() => {
return fs.ensureDir(dataDir).then(() => 'Data directory path is valid.')
},
() => {
return fs.ensureDir(gitDir).then(() => 'Git directory path is valid.')
},
() => {
return exec.stdout('git', ['init'], { cwd: gitDir }).then(result => {
return 'Local git repository has been initialized.'
})
},
() => {
if (req.body.gitUseRemote === false) { return false }
return exec.stdout('git', ['config', '--local', 'user.name', 'Wiki'], { cwd: gitDir }).then(result => {
return 'Git Signature Name has been set successfully.'
})
},
() => {
if (req.body.gitUseRemote === false) { return false }
return exec.stdout('git', ['config', '--local', 'user.email', req.body.gitServerEmail], { cwd: gitDir }).then(result => {
return 'Git Signature Name has been set successfully.'
})
},
() => {
if (req.body.gitUseRemote === false) { return false }
return exec.stdout('git', ['config', '--local', '--bool', 'http.sslVerify', req.body.gitAuthSSL], { cwd: gitDir }).then(result => {
return 'Git SSL Verify flag has been set successfully.'
})
},
() => {
if (req.body.gitUseRemote === false) { return false }
if (_.includes(['sshenv', 'sshdb'], req.body.gitAuthType)) {
req.body.gitAuthSSHKey = path.join(dataDir, 'ssh/key.pem')
}
if (_.startsWith(req.body.gitAuthType, 'ssh')) {
return exec.stdout('git', ['config', '--local', 'core.sshCommand', 'ssh -i "' + req.body.gitAuthSSHKey + '" -o StrictHostKeyChecking=no'], { cwd: gitDir }).then(result => {
return 'Git SSH Private Key path has been set successfully.'
})
} else {
return false
}
},
() => {
if (req.body.gitUseRemote === false) { return false }
return exec.stdout('git', ['remote', 'rm', 'origin'], { cwd: gitDir }).catch(err => {
if (_.includes(err.message, 'No such remote') || _.includes(err.message, 'Could not remove')) {
return true
} else {
throw err
}
}).then(() => {
return exec.stdout('git', ['remote', 'add', 'origin', gitRemoteUrl], { cwd: gitDir }).then(result => {
return 'Git Remote was added successfully.'
})
})
},
() => {
if (req.body.gitUseRemote === false) { return false }
return exec.stdout('git', ['pull', 'origin', req.body.gitBranch], { cwd: gitDir }).then(result => {
return 'Git Pull operation successful.'
})
}
], step => { return step() }).then(results => {
return res.json({ ok: true, results: _.without(results, false) })
}).catch(err => {
let errMsg = (err.stderr) ? err.stderr.replace(/(error:|warning:|fatal:)/gi, '').replace(/ \s+/g, ' ') : err.message
res.json({ ok: false, error: errMsg })
})
})
/**
* Finalize * Finalize
*/ */
app.post('/finalize', async (req, res) => { app.post('/finalize', async (req, res) => {
...@@ -263,13 +94,6 @@ module.exports = () => { ...@@ -263,13 +94,6 @@ module.exports = () => {
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.paths.data = req.body.pathData
conf.paths.content = req.body.pathContent
confRaw = yaml.safeDump(conf)
await fs.writeFileAsync(path.join(WIKI.ROOTPATH, 'config.yml'), confRaw)
// Create directory structure // Create directory structure
await fs.ensureDir(conf.paths.data) await fs.ensureDir(conf.paths.data)
await fs.ensureDir(path.join(conf.paths.data, 'cache')) await fs.ensureDir(path.join(conf.paths.data, 'cache'))
...@@ -283,16 +107,13 @@ module.exports = () => { ...@@ -283,16 +107,13 @@ module.exports = () => {
_.set(WIKI.config, 'lang.autoUpdate', true) _.set(WIKI.config, 'lang.autoUpdate', true)
_.set(WIKI.config, 'lang.namespacing', false) _.set(WIKI.config, 'lang.namespacing', false)
_.set(WIKI.config, 'lang.namespaces', []) _.set(WIKI.config, 'lang.namespaces', [])
_.set(WIKI.config, 'paths.content', req.body.pathContent) _.set(WIKI.config, 'public', false)
_.set(WIKI.config, 'paths.data', req.body.pathData)
_.set(WIKI.config, 'port', req.body.port)
_.set(WIKI.config, 'public', req.body.public === 'true')
_.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
_.set(WIKI.config, 'telemetry.isEnabled', req.body.telemetry === 'true') _.set(WIKI.config, 'telemetry.isEnabled', req.body.telemetry === 'true')
_.set(WIKI.config, 'telemetry.clientId', WIKI.telemetry.cid) _.set(WIKI.config, 'telemetry.clientId', WIKI.telemetry.cid)
_.set(WIKI.config, 'theming.theme', 'default') _.set(WIKI.config, 'theming.theme', 'default')
_.set(WIKI.config, 'theming.darkMode', false) _.set(WIKI.config, 'theming.darkMode', false)
_.set(WIKI.config, 'title', req.body.title) _.set(WIKI.config, 'title', 'Wiki.js')
// Save config to DB // Save config to DB
WIKI.logger.info('Persisting config to DB...') WIKI.logger.info('Persisting config to DB...')
...@@ -325,6 +146,9 @@ module.exports = () => { ...@@ -325,6 +146,9 @@ module.exports = () => {
await WIKI.models.editors.refreshEditorsFromDisk() await WIKI.models.editors.refreshEditorsFromDisk()
await WIKI.models.editors.query().patch({ isEnabled: true }).where('key', 'markdown') await WIKI.models.editors.query().patch({ isEnabled: true }).where('key', 'markdown')
// Load renderers
await WIKI.models.renderers.refreshRenderersFromDisk()
// Load storage targets // Load storage targets
await WIKI.models.storage.refreshTargetsFromDisk() await WIKI.models.storage.refreshTargetsFromDisk()
...@@ -367,7 +191,7 @@ module.exports = () => { ...@@ -367,7 +191,7 @@ module.exports = () => {
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: '/',
redirectPort: WIKI.config.port redirectPort: WIKI.config.port
}).end() }).end()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment