Merge remote-tracking branch 'upstream/dev' into dev

pull/2754/head
Bharat Rajagopalan 3 years ago
commit 2b527daa06

@ -14,13 +14,14 @@
[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
[![Chat on Slack](https://img.shields.io/badge/slack-requarks-CC2B5E.svg?style=flat&logo=slack)](https://wiki.requarks.io/slack) [![Chat on Slack](https://img.shields.io/badge/slack-requarks-CC2B5E.svg?style=flat&logo=slack)](https://wiki.requarks.io/slack)
[![Twitter Follow](https://img.shields.io/badge/follow-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks) [![Twitter Follow](https://img.shields.io/badge/follow-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks)
[![Reddit](https://img.shields.io/badge/reddit-%2Fr%2Fwikijs-orange?logo=reddit&logoColor=white)](https://www.reddit.com/r/wikijs/)
[![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp)](https://blog.js.wiki/subscribe) [![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp)](https://blog.js.wiki/subscribe)
##### A modern, lightweight and powerful wiki app built on NodeJS ##### A modern, lightweight and powerful wiki app built on NodeJS
</div> </div>
- **[Official Website](https://wiki.js.org/)** - **[Official Website](https://js.wiki/)**
- **[Documentation](https://docs.requarks.io/)** - **[Documentation](https://docs.requarks.io/)**
- [Requirements](https://docs.requarks.io/install/requirements) - [Requirements](https://docs.requarks.io/install/requirements)
- [Installation](https://docs.requarks.io/install) - [Installation](https://docs.requarks.io/install)
@ -107,6 +108,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri
- Jay Lee ([@polyglotm](https://github.com/polyglotm)) - Jay Lee ([@polyglotm](https://github.com/polyglotm))
- Kelly Wardrop ([@dropcoded](https://github.com/dropcoded)) - Kelly Wardrop ([@dropcoded](https://github.com/dropcoded))
- Loki ([@binaryloki](https://github.com/binaryloki)) - Loki ([@binaryloki](https://github.com/binaryloki))
- Marcilio Leite Neto ([@marclneto](https://github.com/marclneto))
- Mattias Johnson ([@mattiasJohnson](https://github.com/mattiasJohnson)) - Mattias Johnson ([@mattiasJohnson](https://github.com/mattiasJohnson))
- Mitchell Rowton ([@mrowton](https://github.com/mrowton)) - Mitchell Rowton ([@mrowton](https://github.com/mrowton))
- M. Scott Ford ([@mscottford](https://github.com/mscottford)) - M. Scott Ford ([@mscottford](https://github.com/mscottford))
@ -230,6 +232,7 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re
- Alex Zen - Alex Zen
- Arti Zirk - Arti Zirk
- Brandon Curtis - Brandon Curtis
- Dave 'Sri' Seah
- djagoo - djagoo
- Douglas Lassance - Douglas Lassance
- Ernie Reid - Ernie Reid
@ -248,6 +251,7 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re
- Matt Gedigian - Matt Gedigian
- Patryk - Patryk
- Philipp Schürch - Philipp Schürch
- Tracey Duffy
- Richeir - Richeir
- SmartNET.works - SmartNET.works
- Stepan Sokolovskyi - Stepan Sokolovskyi

@ -107,6 +107,8 @@ The following table lists the configurable parameters of the Wiki.js chart and t
| `postgresql.postgresqlUser` | Postgres username | `postgres` | | `postgresql.postgresqlUser` | Postgres username | `postgres` |
| `postgresql.postgresqlHost` | External postgres host | `nil` | | `postgresql.postgresqlHost` | External postgres host | `nil` |
| `postgresql.postgresqlPassword` | External postgres password | `nil` | | `postgresql.postgresqlPassword` | External postgres password | `nil` |
| `postgresql.existingSecret` | Provide an existing `Secret` for postgres | `nil` |
| `postgresql.existingSecretKey` | The postgres password key in the existing `Secret` | `postgresql-password` |
| `postgresql.postgresqlPort` | External postgres port | `5432` | | `postgresql.postgresqlPort` | External postgres port | `5432` |
| `postgresql.ssl` | Enable external postgres SSL connection | `false` | | `postgresql.ssl` | Enable external postgres SSL connection | `false` |
| `postgresql.ca` | Certificate of Authority path for postgres | `nil` | | `postgresql.ca` | Certificate of Authority path for postgres | `nil` |
@ -137,11 +139,11 @@ By default, PostgreSQL is installed as part of the chart.
### Using an external PostgreSQL server ### Using an external PostgreSQL server
To use an external PostgreSQL server, set `postgresql.enabled` to `false` and then set `postgresql.postgresqlHost` and `postgresql.postgresqlPassword`. The other options (`postgresql.postgresqlDatabase`, `postgresql.postgresqlUser` and `postgresql.postgresqlPort`) may also want changing from their default values. To use an external PostgreSQL server, set `postgresql.enabled` to `false` and then set `postgresql.postgresqlHost` and `postgresql.postgresqlPassword`. To use an existing `Secret`, set `postgresql.existingSecret`. The other options (`postgresql.postgresqlDatabase`, `postgresql.postgresqlUser`, `postgresql.postgresqlPort` and `postgresql.existingSecretKey`) may also want changing from their default values.
To use an SSL connection you can set `postgresql.ssl` to `true` and if needed the path to a Certificate of Authority can be set using `postgresql.ca` to `/path/to/ca`. Default `postgresql.ssl` value is `false`. To use an SSL connection you can set `postgresql.ssl` to `true` and if needed the path to a Certificate of Authority can be set using `postgresql.ca` to `/path/to/ca`. Default `postgresql.ssl` value is `false`.
You also need to add the follow Helm template to your deployment: If `postgresql.existingSecret` is not specified, you also need to add the following Helm template to your deployment in order to create the postgresql `Secret`:
```yaml ```yaml
kind: Secret kind: Secret

@ -76,7 +76,7 @@ router.post('/u', (req, res, next) => {
} }
// Sanitize filename // Sanitize filename
fileMeta.originalname = sanitize(fileMeta.originalname.toLowerCase().replace(/[\s,;]+/g, '_')) fileMeta.originalname = sanitize(fileMeta.originalname.toLowerCase().replace(/[\s,;#]+/g, '_'))
// Check if user can upload at path // Check if user can upload at path
const assetPath = (folderId) ? hierarchy.map(h => h.slug).join('/') + `/${fileMeta.originalname}` : fileMeta.originalname const assetPath = (folderId) ? hierarchy.map(h => h.slug).join('/') + `/${fileMeta.originalname}` : fileMeta.originalname

@ -40,11 +40,11 @@ module.exports = {
} }
}, },
async unload () { async unload () {
if (this.fdCache) { const fds = Object.values(this.fdCache)
if (fds.length > 0) {
WIKI.logger.info('Closing ASAR file descriptors...') WIKI.logger.info('Closing ASAR file descriptors...')
for (const fdItem in this.fdCache) { const closeAsync = require('util').promisify(fs.close)
fs.closeSync(this.fdCache[fdItem].fd) await Promise.all(fds.map(x => closeAsync(x.fd)))
}
this.fdCache = {} this.fdCache = {}
} }
}, },

@ -107,19 +107,21 @@ module.exports = {
* Graceful shutdown * Graceful shutdown
*/ */
async shutdown () { async shutdown () {
if (WIKI.models) { if (WIKI.servers) {
await WIKI.models.unsubscribeToNotifications() await WIKI.servers.stopServers()
await WIKI.models.knex.client.pool.destroy()
await WIKI.models.knex.destroy()
} }
if (WIKI.scheduler) { if (WIKI.scheduler) {
WIKI.scheduler.stop() await WIKI.scheduler.stop()
}
if (WIKI.models) {
await WIKI.models.unsubscribeToNotifications()
if (WIKI.models.knex) {
await WIKI.models.knex.destroy()
}
} }
if (WIKI.asar) { if (WIKI.asar) {
await WIKI.asar.unload() await WIKI.asar.unload()
} }
if (WIKI.servers) { process.exit(0)
await WIKI.servers.stopServers()
}
} }
} }

@ -12,7 +12,8 @@ class Job {
schedule = 'P1D', schedule = 'P1D',
repeat = false, repeat = false,
worker = false worker = false
}) { }, queue) {
this.queue = queue
this.finished = Promise.resolve() this.finished = Promise.resolve()
this.name = name this.name = name
this.immediate = immediate this.immediate = immediate
@ -27,6 +28,7 @@ class Job {
* @param {Object} data Job Data * @param {Object} data Job Data
*/ */
start(data) { start(data) {
this.queue.jobs.push(this)
if (this.immediate) { if (this.immediate) {
this.invoke(data) this.invoke(data)
} else { } else {
@ -55,14 +57,22 @@ class Job {
`--job=${this.name}`, `--job=${this.name}`,
`--data=${data}` `--data=${data}`
], { ], {
cwd: WIKI.ROOTPATH cwd: WIKI.ROOTPATH,
stdio: ['inherit', 'inherit', 'pipe', 'ipc']
}) })
const stderr = [];
proc.stderr.on('data', chunk => stderr.push(chunk))
this.finished = new Promise((resolve, reject) => { this.finished = new Promise((resolve, reject) => {
proc.on('exit', (code, signal) => { proc.on('exit', (code, signal) => {
const data = Buffer.concat(stderr).toString()
if (code === 0) { if (code === 0) {
resolve() resolve(data)
} else { } else {
reject(signal) const err = new Error(`Error when running job ${this.name}: ${data}`)
err.exitSignal = signal
err.exitCode = code
err.stderr = data
reject(err)
} }
proc.kill() proc.kill()
}) })
@ -74,16 +84,20 @@ class Job {
} catch (err) { } catch (err) {
WIKI.logger.warn(err) WIKI.logger.warn(err)
} }
if (this.repeat) { if (this.repeat && this.queue.jobs.includes(this)) {
this.queue(data) this.queue(data)
} else {
this.stop().catch(() => {})
} }
} }
/** /**
* Stop any future job invocation from occuring * Stop any future job invocation from occuring
*/ */
stop() { async stop() {
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.queue.jobs = this.queue.jobs.filter(x => x !== this)
return this.finished
} }
} }
@ -110,16 +124,11 @@ module.exports = {
}) })
}, },
registerJob(opts, data) { registerJob(opts, data) {
const job = new Job(opts) const job = new Job(opts, this)
job.start(data) job.start(data)
if (job.repeat) {
this.jobs.push(job)
}
return job return job
}, },
stop() { async stop() {
this.jobs.forEach(job => { return Promise.all(this.jobs.map(job => job.stop()))
job.stop()
})
} }
} }

@ -14,6 +14,11 @@ WIKI.logger = require('./logger').init('JOB')
const args = require('yargs').argv const args = require('yargs').argv
;(async () => { ;(async () => {
await require(`../jobs/${args.job}`)(args.data) try {
process.exit(0) await require(`../jobs/${args.job}`)(args.data)
process.exit(0)
} catch (e) {
await new Promise(resolve => process.stderr.write(e.message, resolve))
process.exit(1)
}
})() })()

@ -33,3 +33,16 @@ WIKI.logger = require('./core/logger').init('MASTER')
// ---------------------------------------- // ----------------------------------------
WIKI.kernel.init() WIKI.kernel.init()
// ----------------------------------------
// Register exit handler
// ----------------------------------------
process.on('SIGINT', () => {
WIKI.kernel.shutdown()
})
process.on('message', (msg) => {
if (msg === 'shutdown') {
WIKI.kernel.shutdown()
}
})

@ -74,5 +74,7 @@ module.exports = async (pageId) => {
} catch (err) { } catch (err) {
WIKI.logger.error(`Rebuilding page tree: [ FAILED ]`) WIKI.logger.error(`Rebuilding page tree: [ FAILED ]`)
WIKI.logger.error(err.message) WIKI.logger.error(err.message)
// exit process with error code
throw err
} }
} }

@ -90,5 +90,7 @@ module.exports = async (pageId) => {
} catch (err) { } catch (err) {
WIKI.logger.error(`Rendering page ID ${pageId}: [ FAILED ]`) WIKI.logger.error(`Rendering page ID ${pageId}: [ FAILED ]`)
WIKI.logger.error(err.message) WIKI.logger.error(err.message)
// exit process with error code
throw err
} }
} }

@ -9,27 +9,38 @@ const _ = require('lodash')
module.exports = { module.exports = {
init (passport, conf) { init (passport, conf) {
passport.use('google', const strategy = new GoogleStrategy({
new GoogleStrategy({ clientID: conf.clientId,
clientID: conf.clientId, clientSecret: conf.clientSecret,
clientSecret: conf.clientSecret, callbackURL: conf.callbackURL,
callbackURL: conf.callbackURL, passReqToCallback: true
passReqToCallback: true }, async (req, accessToken, refreshToken, profile, cb) => {
}, async (req, accessToken, refreshToken, profile, cb) => { try {
try { if (conf.hostedDomain && conf.hostedDomain != profile._json.hd) {
const user = await WIKI.models.users.processProfile({ throw new Error('Google authentication should have been performed with domain ' + conf.hostedDomain)
providerKey: req.params.strategy,
profile: {
...profile,
picture: _.get(profile, 'photos[0].value', '')
}
})
cb(null, user)
} catch (err) {
cb(err, null)
} }
}) const user = await WIKI.models.users.processProfile({
) providerKey: req.params.strategy,
profile: {
...profile,
picture: _.get(profile, 'photos[0].value', '')
}
})
cb(null, user)
} catch (err) {
cb(err, null)
}
})
if (conf.hostedDomain) {
strategy.authorizationParams = function(options) {
return {
hd: conf.hostedDomain
}
}
}
passport.use('google', strategy)
}, },
logout (conf) { logout (conf) {
return '/' return '/'

@ -22,3 +22,8 @@ props:
title: Client Secret title: Client Secret
hint: Application Client Secret hint: Application Client Secret
order: 2 order: 2
hostedDomain:
type: String
title: Hosted Domain
hint: (optional) Only for G Suite hosted domain. Leave empty otherwise.
order: 3

@ -237,7 +237,7 @@ module.exports = {
// -------------------------------- // --------------------------------
$('body').contents().toArray().forEach(item => { $('body').contents().toArray().forEach(item => {
if (item.type === 'text' && item.parent.name === 'body') { if (item && item.type === 'text' && item.parent.name === 'body') {
$(item).wrap('<div></div>') $(item).wrap('<div></div>')
} }
}) })
@ -249,7 +249,7 @@ module.exports = {
function iterateMustacheNode (node) { function iterateMustacheNode (node) {
const list = $(node).contents().toArray() const list = $(node).contents().toArray()
list.forEach(item => { list.forEach(item => {
if (item.type === 'text') { if (item && item.type === 'text') {
const rawText = $(item).text().replace(/\r?\n|\r/g, '') const rawText = $(item).text().replace(/\r?\n|\r/g, '')
if (mustacheRegExp.test(rawText)) { if (mustacheRegExp.test(rawText)) {
$(item).parent().attr('v-pre', true) $(item).parent().attr('v-pre', true)

Loading…
Cancel
Save