feat: core improvements + local fs provider + UI fixes

This commit is contained in:
NGPixel 2018-07-29 22:23:33 -04:00
parent 803d86ff63
commit 2817c72ec3
65 changed files with 482 additions and 264 deletions

View File

@ -110,7 +110,7 @@ Vue.prototype.Velocity = Velocity
Vue.component('admin', () => import(/* webpackChunkName: "admin" */ './components/admin.vue'))
Vue.component('editor', () => import(/* webpackChunkName: "editor" */ './components/editor.vue'))
Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue'))
Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/nav-header.vue'))
Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/common/nav-header.vue'))
Vue.component('profile', () => import(/* webpackChunkName: "profile" */ './components/profile.vue'))
Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue'))
Vue.component('v-card-chin', () => import(/* webpackMode: "eager" */ './components/common/v-card-chin.vue'))

View File

@ -13,14 +13,34 @@
v-toolbar-title
.subheading {{ $t('admin:general.siteInfo') }}
v-subheader General
.px-3
.px-3.pb-3
v-text-field(label='Site Title', required, :counter='50', v-model='siteTitle', prepend-icon='public')
v-divider.mt-3
v-divider
v-subheader SEO
.px-3
.px-3.pb-3
v-text-field(label='Site Description', :counter='255', prepend-icon='public')
v-text-field(label='Site Keywords', :counter='255', prepend-icon='public')
v-select(label='Meta Robots', chips, tags, :items='metaRobots', v-model='metaRobotsSelection', prepend-icon='public')
v-divider
v-subheader Analytics
.px-3.pb-3
v-text-field(
label='Google Analytics ID'
:counter='255'
prepend-icon='public'
persistent-hint
hint='Property tracking ID for Google Analytics.'
)
v-divider
v-subheader Footer Copyright
.px-3.pb-3
v-text-field(
label='Company / Organization Name'
:counter='255'
prepend-icon='public'
persistent-hint
hint='Name to use when displaying copyright notice in the footer. Leave empty to hide.'
)
v-card-chin
v-spacer
v-btn(color='primary')

View File

@ -4,10 +4,22 @@
v-flex(xs12)
.headline.primary--text Statistics
.subheading.grey--text Useful information about your wiki
.pa-3
fingerprint-spinner(
:animation-duration='1500'
:size='128'
color='#e91e63'
)
.caption.pink--text.mt-3 Compiling latest data...
</template>
<script>
import { FingerprintSpinner } from 'epic-spinners'
export default {
components: {
FingerprintSpinner
},
data() {
return {}
}

View File

@ -18,7 +18,6 @@
:key='tgt.key'
:label='tgt.title'
color='primary'
:disabled='tgt.key === `local`'
hide-details
)
@ -30,26 +29,38 @@
template(v-else, v-for='cfg in tgt.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.key | startCase'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.key | startCase'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.key | startCase'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Sync Direction

View File

@ -36,12 +36,18 @@
v-subheader Rescan Modules
v-card-text.pt-0.pl-4
.body-1 Look for new modules on disk. Existing configurations will be merged.
v-btn(depressed).ml-0
v-icon(left, color='grey') youtube_searched_for
span Authentication
v-btn(depressed).ml-0
v-icon(left, color='grey') youtube_searched_for
span Storage
v-select.mt-3(
v-model='rescanModuleType'
:items='moduleTypes'
label='Modules Type'
outline
background-color='grey lighten-1'
hide-details
dense
)
v-btn.ml-0(color='primary', depressed, dark)
v-icon(left) chevron_right
span Rescan
v-flex(xs12, sm6)
v-card
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
@ -58,50 +64,50 @@
.subheading Graph Endpoint
v-card-text
.body-1 The Graph API Endpoint from which remote resources like locales, themes and plugins are fetched.
.caption Do not change unless you know what you're doing!
v-text-field.my-2.grey.lighten-3(solo, flat, label='Graph Endpoint', value='https://graph.requarks.io')
.caption.red--text Do not change unless you know what you're doing!
v-text-field.my-2(outline, hide-details, background-color='grey lighten-1', label='Graph Endpoint', value='https://graph.requarks.io')
v-btn.ml-0(color='primary', depressed, dark)
v-icon(left) chevron_right
span Save
v-tab-item(key='telemetry', :transition='false', :reverse-transition='false')
v-card.pa-3
v-card
v-form
v-subheader What is telemetry?
.body-1.pl-3 Telemetry allows the developers of Wiki.js to improve the software by collecting basic anonymized data about its usage and the host info. #[br] This is entirely optional and #[strong absolutely no] private data (such as content or personal data) is collected.
.body-1.pt-3.pl-3 For maximum privacy, a random client ID is generated every time Wiki.js is started. This ID is used to group requests together while keeping complete anonymity.
v-divider
v-subheader What is collected?
.body-1.pl-3 When telemetry is enabled, only the following data is transmitted:
v-list(dense)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Version of Wiki.js installed
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Basic OS information (version, CPU cores, RAM available)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Crash debug data
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Setup analytics (step reached)
.body-2.pl-3
v-divider
v-subheader Settings
.pl-3
v-switch(
v-model='telemetry',
label='Enable Telemetry',
:value='true',
color='primary',
hint='Allow Wiki.js to transmit telemetry data.',
persistent-hint
)
.subheading.mt-3.grey--text.text--darken-1 Client ID
.body-1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
v-divider
v-card-actions
v-card-text
v-subheader What is telemetry?
.body-1.pl-3 Telemetry allows the developers of Wiki.js to improve the software by collecting basic anonymized data about its usage and the host info. #[br] This is entirely optional and #[strong absolutely no] private data (such as content or personal data) is collected.
.body-1.pt-3.pl-3 For maximum privacy, a random client ID is generated every time Wiki.js is started. This ID is used to group requests together while keeping complete anonymity.
v-divider.my-3
v-subheader What is collected?
.body-1.pl-3 When telemetry is enabled, only the following data is transmitted:
v-list(dense)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Version of Wiki.js installed
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Basic OS information (version, CPU cores, RAM available)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Crash debug data
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Setup analytics (step reached)
.body-2.pl-3
v-divider.my-3
v-subheader Settings
.pl-3
v-switch.mt-0(
v-model='telemetry',
label='Enable Telemetry',
:value='true',
color='primary',
hint='Allow Wiki.js to transmit telemetry data.',
persistent-hint
)
.subheading.mt-3.grey--text.text--darken-1 Client ID
.body-1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
v-card-chin
v-btn(color='primary')
v-icon(left) chevron_right
| Save Changes
@ -117,13 +123,13 @@
v-btn.ml-3.mt-3(depressed, dark, color='grey darken-2', href='https://github.com/Requarks/wiki/issues', target='_blank')
icon-github-circle.mr-3(fillColor='#FFFFFF')
span Submit an issue
v-divider
v-divider.my-3
v-subheader Suggest a New Feature / Enhancement
.body-1.pl-3 Have an idea for a new feature or something that could be improved?
v-btn.ml-3.mt-3(depressed, dark, color='indigo', href='https://requests.requarks.io/wiki', target='_blank')
v-icon(left) lightbulb_outline
span Submit an idea
v-divider
v-divider.my-3
v-subheader Questions / Comments
.body-1.pl-3 Join our gitter channel. We are very active and friendly!
v-btn.ml-3.mt-3(depressed, dark, color='pink', href='https://gitter.im/Requarks/wiki', target='_blank')
@ -144,6 +150,15 @@ export default {
data() {
return {
tab: '0',
moduleTypes: [
{ text: 'Authentication', value: 'authentication' },
{ text: 'Editor', value: 'editor' },
{ text: 'Logging', value: 'logging' },
{ text: 'Rendering', value: 'renderer' },
{ text: 'Search Engine', value: 'search' },
{ text: 'Storage', value: 'storage' }
],
rescanModuleType: 'authentication',
telemetry: true
}
},

View File

@ -1,5 +1,5 @@
<template lang='pug'>
v-toolbar(color='black', dark, app, clipped-left, fixed, flat, dense)
v-toolbar(color='black', dark, app, clipped-left, fixed, flat, :dense='dense')
v-menu(open-on-hover, offset-y, bottom, left, nudge-top='-18', min-width='250')
v-toolbar-side-icon(slot='activator')
v-icon view_module
@ -41,15 +41,15 @@
v-if='searchIsShown',
v-model='search',
clearable,
color='blue',
color='white',
label='Search...',
single-line,
solo
flat
hide-details,
append-icon='search',
:append-icon-cb='searchEnter',
prepend-inner-icon='search',
:loading='searchIsLoading',
@keyup.enter='searchEnter',
@keyup.esc='searchToggle'
@keyup.enter='searchEnter'
)
v-progress-linear(
indeterminate,
@ -58,11 +58,9 @@
color='blue'
)
v-spacer
v-progress-circular.mr-3(indeterminate, color='blue', :size='22', :width='2' v-show='isLoading')
.navHeaderLoading.mr-3
v-progress-circular(indeterminate, color='blue', :size='22', :width='2' v-show='isLoading')
slot(name='actions')
transition(name='navHeaderSearch')
v-btn(icon, @click='searchToggle', v-if='!searchIsShown')
v-icon(color='grey') search
v-btn(icon, href='/a')
v-icon(color='grey') settings
v-menu(offset-y, min-width='300')
@ -90,11 +88,21 @@ import { mapGetters } from 'vuex'
/* global siteConfig */
export default {
props: {
dense: {
type: Boolean,
default: false
},
hideSearch: {
type: Boolean,
default: false
}
},
data() {
return {
menuIsShown: true,
searchIsLoading: false,
searchIsShown: false,
searchIsShown: true,
search: ''
}
},
@ -102,16 +110,12 @@ export default {
...mapGetters(['isLoading']),
title() { return siteConfig.title }
},
created() {
if (this.hideSearch || this.dense) {
this.searchIsShown = false
}
},
methods: {
searchToggle() {
this.searchIsLoading = false
this.searchIsShown = !this.searchIsShown
if (this.searchIsShown) {
this.$nextTick(() => {
this.$refs.searchField.focus()
})
}
},
searchEnter() {
this.searchIsLoading = true
}
@ -130,7 +134,10 @@ export default {
}
&-enter, &-leave-to {
opacity: 0;
transform: translateY(-25px);
transform: scale(.7, .7);
}
}
.navHeaderLoading { // To avoid search bar jumping
width: 22px;
}
</style>

View File

@ -1,6 +1,6 @@
<template lang="pug">
.editor
nav-header
nav-header(dense)
template(slot='actions')
v-btn(outline, color='green', @click.native.stop='save')
v-icon(color='green', left) check

View File

@ -57,6 +57,7 @@
:items='namespaces'
v-model='locale'
hide-details
:disabled='mode !== "create"'
)
v-flex(xs12, md10)
v-text-field(
@ -68,6 +69,7 @@
hint='Do not include any leading or trailing slashes.'
persistent-hint
@click:append='showPathSelector'
:disabled='mode !== "create"'
)
v-combobox(
background-color='grey lighten-2'
@ -186,7 +188,7 @@
<script>
import _ from 'lodash'
import { sync } from 'vuex-pathify'
import { sync, get } from 'vuex-pathify'
export default {
data() {
@ -204,6 +206,7 @@ export default {
}
},
computed: {
mode: get('editor/mode'),
title: sync('editor/title'),
description: sync('editor/description'),
locale: sync('editor/locale'),

View File

@ -3,7 +3,7 @@
@import "base/base";
@import 'base/icons';
// @import "../libs/animate/animate";
@import "../libs/animate/animate";
@import 'components/markdown-content';
@import 'components/btn';

View File

@ -33,11 +33,28 @@
}
}
&::after {
content: '';
display: block;
width: 95vw;
height: 95vh;
border: 3px dotted rgba(255,255,255,.2);
border-radius: 50px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
z-index: 1;
}
img {
width: 500px;
filter: grayscale(100%) brightness(160%);
margin-bottom: 3rem;
z-index: 2;
animation-duration: 3s;
@include until($tablet) {
width: 300px;
@ -52,7 +69,7 @@
margin-bottom: 3rem;
z-index: 2;
}
.button {
.v-btn {
z-index: 2;
}
}

View File

@ -17,7 +17,7 @@ module.exports = {
})
passport.deserializeUser(function (id, done) {
WIKI.db.users.query().findById(id).then((user) => {
WIKI.models.users.query().findById(id).then((user) => {
if (user) {
done(null, user)
} else {
@ -40,7 +40,7 @@ module.exports = {
_.forEach(currentStrategies, stg => { passport.unuse(stg) })
// Load enabled strategies
const enabledStrategies = await WIKI.db.authentication.getStrategies()
const enabledStrategies = await WIKI.models.authentication.getStrategies()
for (let idx in enabledStrategies) {
const stg = enabledStrategies[idx]
if (!stg.isEnabled) { continue }

View File

@ -52,7 +52,7 @@ module.exports = {
* Load config from DB
*/
async loadFromDb() {
let conf = await WIKI.db.settings.getConfig()
let conf = await WIKI.models.settings.getConfig()
if (conf) {
WIKI.config = _.defaultsDeep(conf, WIKI.config)
} else {
@ -73,9 +73,9 @@ module.exports = {
if (!_.isPlainObject(value)) {
value = { v: value }
}
let affectedRows = await WIKI.db.settings.query().patch({ value }).where('key', key)
let affectedRows = await WIKI.models.settings.query().patch({ value }).where('key', key)
if (affectedRows === 0 && value) {
await WIKI.db.settings.query().insert({ key, value })
await WIKI.models.settings.query().insert({ key, value })
}
}
} catch (err) {

View File

@ -74,7 +74,7 @@ module.exports = {
// Load DB Models
const models = autoload(path.join(WIKI.SERVERPATH, 'db/models'))
const models = autoload(path.join(WIKI.SERVERPATH, 'models'))
// Set init tasks

View File

@ -6,7 +6,7 @@ module.exports = {
WIKI.logger.info('= Wiki.js =============================')
WIKI.logger.info('=======================================')
WIKI.db = require('./db').init()
WIKI.models = require('./db').init()
WIKI.redis = require('./redis').init()
WIKI.queue = require('./queue').init()
@ -18,7 +18,7 @@ module.exports = {
*/
async preBootMaster() {
try {
await WIKI.db.onReady
await WIKI.models.onReady
await WIKI.configSvc.loadFromDb()
await WIKI.queue.clean()
} catch (err) {
@ -48,6 +48,7 @@ module.exports = {
*/
async postBootMaster() {
await WIKI.auth.activateStrategies()
await WIKI.models.storage.refreshTargetsFromDisk()
await WIKI.queue.start()
}
}

View File

@ -52,7 +52,7 @@ module.exports = {
}
},
async loadLocale(locale, opts = { silent: false }) {
const res = await WIKI.db.locales.query().findOne('code', locale)
const res = await WIKI.models.locales.query().findOne('code', locale)
if (res) {
if (_.isPlainObject(res.strings)) {
_.forOwn(res.strings, (data, ns) => {

View File

@ -45,7 +45,7 @@ module.exports = {
$not: 'guest'
}
}).toArray()
await WIKI.db.User.bulkCreate(_.map(userData, usr => {
await WIKI.models.User.bulkCreate(_.map(userData, usr => {
return {
email: usr.email,
name: usr.name || 'Imported User',

View File

@ -79,6 +79,7 @@ exports.up = knex => {
table.string('publishStartDate')
table.string('publishEndDate')
table.text('content')
table.string('contentType').notNullable()
table.string('createdAt').notNullable()
})
// PAGES -------------------------------
@ -92,6 +93,7 @@ exports.up = knex => {
table.string('publishStartDate')
table.string('publishEndDate')
table.text('content')
table.string('contentType').notNullable()
table.string('createdAt').notNullable()
table.string('updatedAt').notNullable()
})

View File

@ -16,7 +16,7 @@ module.exports = {
},
AuthenticationQuery: {
async strategies(obj, args, context, info) {
let strategies = await WIKI.db.authentication.getStrategies()
let strategies = await WIKI.models.authentication.getStrategies()
strategies = strategies.map(stg => ({
...stg,
config: _.sortBy(_.transform(stg.config, (res, value, key) => {
@ -31,7 +31,7 @@ module.exports = {
AuthenticationMutation: {
async login(obj, args, context) {
try {
let authResult = await WIKI.db.users.login(args, context)
let authResult = await WIKI.models.users.login(args, context)
return {
...authResult,
responseResult: graphHelper.generateSuccess('Login success')
@ -42,7 +42,7 @@ module.exports = {
},
async loginTFA(obj, args, context) {
try {
let authResult = await WIKI.db.users.loginTFA(args, context)
let authResult = await WIKI.models.users.loginTFA(args, context)
return {
...authResult,
responseResult: graphHelper.generateSuccess('TFA success')
@ -54,7 +54,7 @@ module.exports = {
async updateStrategies(obj, args, context) {
try {
for (let str of args.strategies) {
await WIKI.db.authentication.query().patch({
await WIKI.models.authentication.query().patch({
isEnabled: str.isEnabled,
config: _.reduce(str.config, (result, value, key) => {
_.set(result, `${value.key}.value`, value.value)

View File

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

View File

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

View File

@ -6,16 +6,16 @@ const gql = require('graphql')
module.exports = {
Query: {
files(obj, args, context, info) {
return WIKI.db.File.findAll({ where: args })
return WIKI.models.File.findAll({ where: args })
}
},
Mutation: {
uploadFile(obj, args) {
// todo
return WIKI.db.File.create(args)
return WIKI.models.File.create(args)
},
deleteFile(obj, args) {
return WIKI.db.File.destroy({
return WIKI.models.File.destroy({
where: {
id: args.id
},
@ -23,18 +23,18 @@ module.exports = {
})
},
renameFile(obj, args) {
return WIKI.db.File.update({
return WIKI.models.File.update({
filename: args.filename
}, {
where: { id: args.id }
})
},
moveFile(obj, args) {
return WIKI.db.File.findById(args.fileId).then(fl => {
return WIKI.models.File.findById(args.fileId).then(fl => {
if (!fl) {
throw new gql.GraphQLError('Invalid File ID')
}
return WIKI.db.Folder.findById(args.folderId).then(fld => {
return WIKI.models.Folder.findById(args.folderId).then(fld => {
if (!fld) {
throw new gql.GraphQLError('Invalid Folder ID')
}

View File

@ -4,15 +4,15 @@
module.exports = {
Query: {
folders(obj, args, context, info) {
return WIKI.db.Folder.findAll({ where: args })
return WIKI.models.Folder.findAll({ where: args })
}
},
Mutation: {
createFolder(obj, args) {
return WIKI.db.Folder.create(args)
return WIKI.models.Folder.create(args)
},
deleteFolder(obj, args) {
return WIKI.db.Folder.destroy({
return WIKI.models.Folder.destroy({
where: {
id: args.id
},
@ -20,7 +20,7 @@ module.exports = {
})
},
renameFolder(obj, args) {
return WIKI.db.Folder.update({
return WIKI.models.Folder.update({
name: args.name
}, {
where: { id: args.id }

View File

@ -13,22 +13,22 @@ module.exports = {
},
GroupQuery: {
async list(obj, args, context, info) {
return WIKI.db.groups.query().select(
return WIKI.models.groups.query().select(
'groups.*',
WIKI.db.groups.relatedQuery('users').count().as('userCount')
WIKI.models.groups.relatedQuery('users').count().as('userCount')
)
},
async single(obj, args, context, info) {
return WIKI.db.groups.query().findById(args.id)
return WIKI.models.groups.query().findById(args.id)
}
},
GroupMutation: {
async assignUser(obj, args) {
const grp = await WIKI.db.groups.query().findById(args.groupId)
const grp = await WIKI.models.groups.query().findById(args.groupId)
if (!grp) {
throw new gql.GraphQLError('Invalid Group ID')
}
const usr = await WIKI.db.users.query().findById(args.userId)
const usr = await WIKI.models.users.query().findById(args.userId)
if (!usr) {
throw new gql.GraphQLError('Invalid User ID')
}
@ -38,7 +38,7 @@ module.exports = {
}
},
async create(obj, args) {
const group = await WIKI.db.groups.query().insertAndFetch({
const group = await WIKI.models.groups.query().insertAndFetch({
name: args.name
})
return {
@ -47,17 +47,17 @@ module.exports = {
}
},
async delete(obj, args) {
await WIKI.db.groups.query().deleteById(args.id)
await WIKI.models.groups.query().deleteById(args.id)
return {
responseResult: graphHelper.generateSuccess('Group has been deleted.')
}
},
async unassignUser(obj, args) {
const grp = await WIKI.db.groups.query().findById(args.groupId)
const grp = await WIKI.models.groups.query().findById(args.groupId)
if (!grp) {
throw new gql.GraphQLError('Invalid Group ID')
}
const usr = await WIKI.db.users.query().findById(args.userId)
const usr = await WIKI.models.users.query().findById(args.userId)
if (!usr) {
throw new gql.GraphQLError('Invalid User ID')
}
@ -67,7 +67,7 @@ module.exports = {
}
},
async update(obj, args) {
await WIKI.db.groups.query().patch({ name: args.name }).where('id', args.id)
await WIKI.models.groups.query().patch({ name: args.name }).where('id', args.id)
return {
responseResult: graphHelper.generateSuccess('Group has been updated.')
}

View File

@ -13,7 +13,7 @@ module.exports = {
LocalizationQuery: {
async locales(obj, args, context, info) {
let remoteLocales = await WIKI.redis.get('locales')
let localLocales = await WIKI.db.locales.query().select('id', 'code', 'isRTL', 'name', 'nativeName', 'createdAt', 'updatedAt')
let localLocales = await WIKI.models.locales.query().select('id', 'code', 'isRTL', 'name', 'nativeName', 'createdAt', 'updatedAt')
remoteLocales = (remoteLocales) ? JSON.parse(remoteLocales) : localLocales
return _.map(remoteLocales, rl => {
let isInstalled = _.some(localLocales, ['code', rl.code])

View File

@ -11,18 +11,18 @@ module.exports = {
},
PageQuery: {
async list(obj, args, context, info) {
return WIKI.db.pages.query().select(
return WIKI.models.pages.query().select(
'pages.*',
WIKI.db.pages.relatedQuery('users').count().as('userCount')
WIKI.models.pages.relatedQuery('users').count().as('userCount')
)
},
async single(obj, args, context, info) {
return WIKI.db.pages.query().findById(args.id)
return WIKI.models.pages.query().findById(args.id)
}
},
PageMutation: {
async create(obj, args, context) {
const page = await WIKI.db.pages.createPage({
const page = await WIKI.models.pages.createPage({
...args,
authorId: context.req.user.id
})
@ -32,13 +32,13 @@ module.exports = {
}
},
async delete(obj, args) {
await WIKI.db.groups.query().deleteById(args.id)
await WIKI.models.groups.query().deleteById(args.id)
return {
responseResult: graphHelper.generateSuccess('Page has been deleted.')
}
},
async update(obj, args, context) {
const page = await WIKI.db.pages.updatePage({
const page = await WIKI.models.pages.updatePage({
...args,
authorId: context.req.user.id
})

View File

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

View File

@ -6,7 +6,7 @@ const _ = require('lodash')
module.exports = {
Query: {
settings(obj, args, context, info) {
return WIKI.db.Setting.findAll({ where: args, raw: true }).then(entries => {
return WIKI.models.Setting.findAll({ where: args, raw: true }).then(entries => {
return _.map(entries, entry => {
entry.config = JSON.stringify(entry.config)
return entry
@ -16,7 +16,7 @@ module.exports = {
},
Mutation: {
setConfigEntry(obj, args) {
return WIKI.db.Setting.update({
return WIKI.models.Setting.update({
value: args.value
}, { where: { key: args.key } })
}

View File

@ -12,13 +12,24 @@ module.exports = {
},
StorageQuery: {
async targets(obj, args, context, info) {
let targets = await WIKI.db.storage.getTargets()
targets = targets.map(tgt => ({
...tgt,
config: _.sortBy(_.transform(tgt.config, (res, value, key) => {
res.push({ key, value: JSON.stringify(value) })
}, []), 'key')
}))
let targets = await WIKI.models.storage.getTargets()
targets = targets.map(tgt => {
const targetInfo = _.find(WIKI.data.storage, ['key', tgt.key]) || {}
console.info(targetInfo)
return {
...tgt,
config: _.sortBy(_.transform(tgt.config, (res, value, key) => {
const configData = _.get(targetInfo.props, key, {})
res.push({
key,
value: JSON.stringify({
...configData,
value
})
})
}, []), 'key')
}
})
if (args.filter) { targets = graphHelper.filter(targets, args.filter) }
if (args.orderBy) { targets = graphHelper.orderBy(targets, args.orderBy) }
return targets
@ -28,11 +39,11 @@ module.exports = {
async updateTargets(obj, args, context) {
try {
for (let tgt of args.targets) {
await WIKI.db.storage.query().patch({
await WIKI.models.storage.query().patch({
isEnabled: tgt.isEnabled,
mode: tgt.mode,
config: _.reduce(tgt.config, (result, value, key) => {
_.set(result, `${value.key}.value`, value.value)
_.set(result, `${value.key}`, value.value)
return result
}, {})
}).where('key', tgt.key)

View File

@ -33,7 +33,7 @@ module.exports = {
configFile: path.join(process.cwd(), 'config.yml'),
currentVersion: WIKI.version,
dbType: _.get(dbTypes, WIKI.config.db.type, 'Unknown DB'),
dbVersion: _.get(WIKI.db, 'knex.client.version', 'Unknown version'),
dbVersion: _.get(WIKI.models, 'knex.client.version', 'Unknown version'),
dbHost: WIKI.config.db.host,
latestVersion: WIKI.version, // TODO
latestVersionReleaseDate: new Date(), // TODO

View File

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

View File

@ -10,18 +10,18 @@ module.exports = {
},
UserQuery: {
async list(obj, args, context, info) {
return WIKI.db.users.query()
return WIKI.models.users.query()
.select('id', 'email', 'name', 'provider', 'role', 'createdAt', 'updatedAt')
},
async search(obj, args, context, info) {
return WIKI.db.users.query()
return WIKI.models.users.query()
.where('email', 'like', `%${args.query}%`)
.orWhere('name', 'like', `%${args.query}%`)
.limit(10)
.select('id', 'email', 'name', 'provider', 'role', 'createdAt', 'updatedAt')
},
async single(obj, args, context, info) {
let usr = await WIKI.db.users.query().findById(args.id)
let usr = await WIKI.models.users.query().findById(args.id)
usr.password = ''
usr.tfaSecret = ''
return usr
@ -29,13 +29,13 @@ module.exports = {
},
UserMutation: {
create(obj, args) {
return WIKI.db.users.query().insertAndFetch(args)
return WIKI.models.users.query().insertAndFetch(args)
},
delete(obj, args) {
return WIKI.db.users.query().deleteById(args.id)
return WIKI.models.users.query().deleteById(args.id)
},
update(obj, args) {
return WIKI.db.users.query().patch({
return WIKI.models.users.query().patch({
email: args.email,
name: args.name,
provider: args.provider,

View File

@ -5,7 +5,7 @@ const { createApolloFetch } = require('apollo-fetch')
/* global WIKI */
WIKI.redis = require('../core/redis').init()
WIKI.db = require('../core/db').init()
WIKI.models = require('../core/db').init()
module.exports = async (job) => {
WIKI.logger.info(`Fetching locale ${job.data.locale} from Graph endpoint...`)
@ -39,8 +39,8 @@ module.exports = async (job) => {
const locales = await WIKI.redis.get('locales')
if (locales) {
const currentLocale = _.find(JSON.parse(locales), ['code', job.data.locale]) || {}
await WIKI.db.locales.query().delete().where('code', job.data.locale)
await WIKI.db.locales.query().insert({
await WIKI.models.locales.query().delete().where('code', job.data.locale)
await WIKI.models.locales.query().insert({
code: job.data.locale,
strings: lcObj,
isRTL: currentLocale.isRTL,

View File

@ -5,7 +5,7 @@ const { createApolloFetch } = require('apollo-fetch')
/* global WIKI */
WIKI.redis = require('../core/redis').init()
WIKI.db = require('../core/db').init()
WIKI.models = require('../core/db').init()
module.exports = async (job) => {
WIKI.logger.info('Syncing locales with Graph endpoint...')
@ -59,7 +59,7 @@ module.exports = async (job) => {
_.set(lcObj, row.key.replace(':', '.'), row.value)
})
await WIKI.db.locales.query().update({
await WIKI.models.locales.query().update({
code: WIKI.config.lang.code,
strings: lcObj,
isRTL: currentLocale.isRTL,

View File

@ -3,7 +3,7 @@ const fs = require('fs-extra')
const path = require('path')
const _ = require('lodash')
const yaml = require('js-yaml')
const commonHelper = require('../../helpers/common')
const commonHelper = require('../helpers/common')
/* global WIKI */
@ -33,7 +33,7 @@ module.exports = class Authentication extends Model {
}
static async getStrategies() {
const strategies = await WIKI.db.authentication.query()
const strategies = await WIKI.models.authentication.query()
return strategies.map(str => ({
...str,
domainWhitelist: _.get(str.domainWhitelist, 'v', []),
@ -43,7 +43,7 @@ module.exports = class Authentication extends Model {
static async refreshStrategiesFromDisk() {
try {
const dbStrategies = await WIKI.db.authentication.query()
const dbStrategies = await WIKI.models.authentication.query()
// -> Fetch definitions from disk
const authDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/authentication'))
@ -86,7 +86,7 @@ module.exports = class Authentication extends Model {
}
})
if (newStrategies.length > 0) {
await WIKI.db.authentication.query().insert(newStrategies)
await WIKI.models.authentication.query().insert(newStrategies)
WIKI.logger.info(`Loaded ${newStrategies.length} new authentication strategies: [ OK ]`)
} else {
WIKI.logger.info(`No new authentication strategies found: [ SKIPPED ]`)

View File

@ -27,12 +27,12 @@ module.exports = class Editor extends Model {
}
static async getEnabledEditors() {
return WIKI.db.editors.query().where({ isEnabled: true })
return WIKI.models.editors.query().where({ isEnabled: true })
}
static async refreshEditorsFromDisk() {
try {
const dbEditors = await WIKI.db.editors.query()
const dbEditors = await WIKI.models.editors.query()
const diskEditors = autoload(path.join(WIKI.SERVERPATH, 'modules/editor'))
let newEditors = []
_.forOwn(diskEditors, (strategy, strategyKey) => {
@ -49,7 +49,7 @@ module.exports = class Editor extends Model {
}
})
if (newEditors.length > 0) {
await WIKI.db.editors.query().insert(newEditors)
await WIKI.models.editors.query().insert(newEditors)
WIKI.logger.info(`Loaded ${newEditors.length} new editors: [ OK ]`)
} else {
WIKI.logger.info(`No new editors found: [ SKIPPED ]`)

View File

@ -82,7 +82,7 @@ module.exports = class PageHistory extends Model {
}
static async addVersion(opts) {
await WIKI.db.pageHistory.query().insert({
await WIKI.models.pageHistory.query().insert({
pageId: opts.id,
authorId: opts.authorId,
content: opts.content,

View File

@ -22,6 +22,7 @@ module.exports = class Page extends Model {
publishStartDate: {type: 'string'},
publishEndDate: {type: 'string'},
content: {type: 'string'},
contentType: {type: 'string'},
createdAt: {type: 'string'},
updatedAt: {type: 'string'}
@ -87,7 +88,7 @@ module.exports = class Page extends Model {
}
static async createPage(opts) {
const page = await WIKI.db.pages.query().insertAndFetch({
const page = await WIKI.models.pages.query().insertAndFetch({
authorId: opts.authorId,
content: opts.content,
creatorId: opts.authorId,
@ -101,7 +102,7 @@ module.exports = class Page extends Model {
publishStartDate: opts.publishStartDate,
title: opts.title
})
await WIKI.db.storage.pageEvent({
await WIKI.models.storage.pageEvent({
event: 'created',
page
})
@ -109,15 +110,21 @@ module.exports = class Page extends Model {
}
static async updatePage(opts) {
const ogPage = await WIKI.db.pages.query().findById(opts.id)
const ogPage = await WIKI.models.pages.query().findById(opts.id)
if (!ogPage) {
throw new Error('Invalid Page Id')
}
await WIKI.db.pageHistory.addVersion(ogPage)
const page = await WIKI.db.pages.query().patchAndFetch({
await WIKI.models.pageHistory.addVersion(ogPage)
const page = await WIKI.models.pages.query().patchAndFetchById(ogPage.id, {
authorId: opts.authorId,
content: opts.content,
description: opts.description,
isPublished: opts.isPublished,
publishEndDate: opts.publishEndDate,
publishStartDate: opts.publishStartDate,
title: opts.title
}).where('id', opts.id)
await WIKI.db.storage.pageEvent({
})
await WIKI.models.storage.pageEvent({
event: 'updated',
page
})

View File

@ -32,7 +32,7 @@ module.exports = class Setting extends Model {
}
static async getConfig() {
const settings = await WIKI.db.settings.query()
const settings = await WIKI.models.settings.query()
if (settings.length > 0) {
return _.reduce(settings, (res, val, key) => {
_.set(res, val.key, (val.value.v) ? val.value.v : val.value)

View File

@ -3,7 +3,7 @@ const path = require('path')
const fs = require('fs-extra')
const _ = require('lodash')
const yaml = require('js-yaml')
const commonHelper = require('../../helpers/common')
const commonHelper = require('../helpers/common')
/* global WIKI */
@ -30,12 +30,12 @@ module.exports = class Storage extends Model {
}
static async getTargets() {
return WIKI.db.storage.query()
return WIKI.models.storage.query()
}
static async refreshTargetsFromDisk() {
try {
const dbTargets = await WIKI.db.storage.query()
const dbTargets = await WIKI.models.storage.query()
// -> Fetch definitions from disk
const storageDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/storage'))
@ -44,10 +44,29 @@ module.exports = class Storage extends Model {
const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/storage', dir, 'definition.yml'), 'utf8')
diskTargets.push(yaml.safeLoad(def))
}
WIKI.data.storage = diskTargets.map(target => ({
...target,
props: _.transform(target.props, (result, value, key) => {
let defaultValue = ''
if (_.isPlainObject(value)) {
defaultValue = !_.isNil(value.default) ? value.default : commonHelper.getTypeDefaultValue(value.type)
} else {
defaultValue = commonHelper.getTypeDefaultValue(value)
}
_.set(result, key, {
default: defaultValue,
type: (value.type || value).toLowerCase(),
title: value.title || _.startCase(key),
hint: value.hint || false,
enum: value.enum || false
})
return result
}, {})
}))
// -> Insert new targets
let newTargets = []
_.forEach(diskTargets, target => {
for (let target of WIKI.data.storage) {
if (!_.some(dbTargets, ['key', target.key])) {
newTargets.push({
key: target.key,
@ -55,28 +74,25 @@ module.exports = class Storage extends Model {
isEnabled: false,
mode: 'push',
config: _.transform(target.props, (result, value, key) => {
if (_.isPlainObject(value)) {
let cfgValue = {
type: value.type.toLowerCase(),
value: !_.isNil(value.default) ? value.default : commonHelper.getTypeDefaultValue(value.type)
}
if (_.isArray(value.enum)) {
cfgValue.enum = value.enum
}
_.set(result, key, cfgValue)
} else {
_.set(result, key, {
type: value.toLowerCase(),
value: commonHelper.getTypeDefaultValue(value)
})
}
_.set(result, key, value.default)
return result
}, {})
})
} else {
const targetConfig = _.get(_.find(dbTargets, ['key', target.key]), 'config', {})
await WIKI.models.storage.query().patch({
title: target.title,
config: _.transform(target.props, (result, value, key) => {
if (!_.has(result, key)) {
_.set(result, key, value.default)
}
return result
}, targetConfig)
}).where('key', target.key)
}
})
}
if (newTargets.length > 0) {
await WIKI.db.storage.query().insert(newTargets)
await WIKI.models.storage.query().insert(newTargets)
WIKI.logger.info(`Loaded ${newTargets.length} new storage targets: [ OK ]`)
} else {
WIKI.logger.info(`No new storage targets found: [ SKIPPED ]`)
@ -87,8 +103,8 @@ module.exports = class Storage extends Model {
}
}
static async pageEvent(event, page) {
const targets = await WIKI.db.storage.query().where('isEnabled', true)
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({

View File

@ -3,7 +3,7 @@
const bcrypt = require('bcryptjs-then')
const _ = require('lodash')
const tfa = require('node-2fa')
const securityHelper = require('../../helpers/security')
const securityHelper = require('../helpers/security')
const Model = require('objection').Model
const bcryptRegexp = /^\$2[ayb]\$[0-9]{2}\$[A-Za-z0-9./]{53}$/
@ -151,7 +151,7 @@ module.exports = class User extends Model {
profile.provider = _.lowerCase(profile.provider)
primaryEmail = _.toLower(primaryEmail)
let user = await WIKI.db.users.query().findOne({
let user = await WIKI.models.users.query().findOne({
email: primaryEmail,
provider: profile.provider
})
@ -163,7 +163,7 @@ module.exports = class User extends Model {
name: profile.displayName || _.split(primaryEmail, '@')[0]
})
} else {
user = await WIKI.db.users.query().insertAndFetch({
user = await WIKI.models.users.query().insertAndFetch({
email: primaryEmail,
provider: profile.provider,
providerId: profile.id,
@ -186,7 +186,7 @@ module.exports = class User extends Model {
// deny: false
// }]
// }
// return WIKI.db.users.query().insert(nUsr)
// return WIKI.models.users.query().insert(nUsr)
// }
return user
@ -238,7 +238,7 @@ module.exports = class User extends Model {
if (result) {
let userId = _.toSafeInteger(result)
if (userId && userId > 0) {
let user = await WIKI.db.users.query().findById(userId)
let user = await WIKI.models.users.query().findById(userId)
if (user && user.verifyTFA(opts.securityCode)) {
return Promise.fromCallback(clb => {
context.req.logIn(user, clb)

View File

@ -15,7 +15,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, function (accessToken, refreshToken, profile, cb) {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -20,7 +20,7 @@ module.exports = {
let waadProfile = jwt.decode(params.id_token)
waadProfile.id = waadProfile.oid
waadProfile.provider = 'azure'
WIKI.db.users.processProfile(waadProfile).then((user) => {
WIKI.models.users.processProfile(waadProfile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -13,7 +13,7 @@ module.exports = {
ssoBaseURL: conf.ssoBaseURL,
serverBaseURL: conf.serverBaseURL
}, (profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -15,7 +15,7 @@ module.exports = {
callbackURL: conf.callbackURL,
scope: 'identify email'
}, function (accessToken, refreshToken, profile, cb) {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -15,7 +15,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -15,7 +15,7 @@ module.exports = {
callbackURL: conf.callbackURL,
profileFields: ['id', 'displayName', 'email']
}, function (accessToken, refreshToken, profile, cb) {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -15,7 +15,7 @@ module.exports = {
callbackURL: conf.callbackURL,
scope: ['user:email']
}, (accessToken, refreshToken, profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -14,7 +14,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -29,7 +29,7 @@ module.exports = {
}, (profile, cb) => {
profile.provider = 'ldap'
profile.id = profile.dn
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -13,7 +13,7 @@ module.exports = {
usernameField: 'email',
passwordField: 'password'
}, (uEmail, uPassword, done) => {
WIKI.db.users.query().findOne({
WIKI.models.users.query().findOne({
email: uEmail,
providerKey: 'local'
}).then((user) => {

View File

@ -14,7 +14,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, function (accessToken, refreshToken, profile, cb) {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -16,7 +16,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -14,7 +14,7 @@ module.exports = {
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
}, (accessToken, refreshToken, profile, cb) => {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -15,7 +15,7 @@ module.exports = {
callbackURL: conf.callbackURL,
scope: 'user_read'
}, function (accessToken, refreshToken, profile, cb) {
WIKI.db.users.processProfile(profile).then((user) => {
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true

View File

@ -0,0 +1,7 @@
key: box
title: Box
author: requarks.io
props:
clientId: String
clientSecret: String
rootFolder: String

View File

@ -0,0 +1,23 @@
module.exports = {
async activated() {
},
async deactivated() {
},
async init() {
},
async created() {
},
async updated() {
},
async deleted() {
},
async renamed() {
}
}

View File

@ -1,5 +1,8 @@
key: disk
title: Local FS
title: Local File System
author: requarks.io
props:
path: String
path:
type: String
title: Path
hint: Absolute path without a trailing slash (e.g. /home/wiki/backup, C:\wiki\backup)

View File

@ -1,23 +1,68 @@
module.exports = {
async activated() {
},
async deactivated() {
},
async init() {
},
async created() {
},
async updated() {
},
async deleted() {
},
async renamed() {
const fs = require('fs-extra')
const path = require('path')
/**
* Get file extension based on content type
*/
const getFileExtension = (contentType) => {
switch (contentType) {
case 'markdown':
return 'md'
case 'html':
return 'html'
default:
return 'txt'
}
}
/**
* Inject page metadata into contents
*/
const injectMetadata = (page) => {
let meta = [
['title', page.title],
['description', page.description]
]
let metaFormatted = ''
switch (page.contentType) {
case 'markdown':
metaFormatted = meta.map(mt => `[//]: # ${mt[0]}: ${mt[1]}`).join('\n')
break
case 'html':
metaFormatted = meta.map(mt => `<!-- ${mt[0]}: ${mt[1]} -->`).join('\n')
break
default:
metaFormatted = meta.map(mt => `#WIKI ${mt[0]}: ${mt[1]}`).join('\n')
break
}
return `${metaFormatted}\n\n${page.content}`
}
module.exports = {
async activated() {
// not used
},
async deactivated() {
// not used
},
async init() {
await fs.ensureDir(this.config.path)
},
async created() {
const filePath = path.join(this.config.path, `${this.page.path}.${getFileExtension(this.page.contentType)}`)
await fs.outputFile(filePath, injectMetadata(this.page), 'utf8')
},
async updated() {
const filePath = path.join(this.config.path, `${this.page.path}.${getFileExtension(this.page.contentType)}`)
await fs.outputFile(filePath, injectMetadata(this.page), 'utf8')
},
async deleted() {
const filePath = path.join(this.config.path, `${this.page.path}.${getFileExtension(this.page.contentType)}`)
await fs.unlink(filePath)
},
async renamed() {
const sourceFilePath = path.join(this.config.path, `${this.page.sourcePath}.${getFileExtension(this.page.contentType)}`)
const destinationFilePath = path.join(this.config.path, `${this.page.destinationPath}.${getFileExtension(this.page.contentType)}`)
await fs.move(sourceFilePath, destinationFilePath, { overwrite: true })
}
}

View File

@ -5,16 +5,32 @@ props:
authType:
type: String
default: 'ssh'
title: Authentication Type
hint: Use SSH for maximum security.
enum:
- 'basic'
- 'ssh'
repoUrl: String
repoUrl:
type: String
title: Repository URI
hint: Git-compliant URI (e.g. git@github.com:org/repo.git for ssh, https://github.com/org/repo.git for basic)
branch:
type: String
default: 'master'
verifySSL:
type: Boolean
default: true
sshPrivateKeyPath: String
basicUsername: String
basicPassword: String
title: Verify SSL Certificate
hint: Some hosts requires SSL certificate checking to be disabled. Leave enabled for proper security.
sshPrivateKeyPath:
type: String
title: SSH Private Key Path
hint: SSH Authentication Only - Absolute path to the key. The key must NOT be passphrase-protected.
basicUsername:
type: String
title: Username
hint: Basic Authentication Only
basicPassword:
type: String
title: Password / PAT
hint: Basic Authentication Only

View File

@ -303,7 +303,7 @@ module.exports = () => {
// Create default locale
WIKI.logger.info('Installing default locale...')
await WIKI.db.locales.query().insert({
await WIKI.models.locales.query().insert({
code: 'en',
strings: require('./locales/default.json'),
isRTL: false,
@ -312,23 +312,23 @@ module.exports = () => {
})
// Load authentication strategies + enable local
await WIKI.db.authentication.refreshStrategiesFromDisk()
await WIKI.db.authentication.query().patch({ isEnabled: true }).where('key', 'local')
await WIKI.models.authentication.refreshStrategiesFromDisk()
await WIKI.models.authentication.query().patch({ isEnabled: true }).where('key', 'local')
// Load editors + enable default
await WIKI.db.editors.refreshEditorsFromDisk()
await WIKI.db.editors.query().patch({ isEnabled: true }).where('key', 'markdown')
await WIKI.models.editors.refreshEditorsFromDisk()
await WIKI.models.editors.query().patch({ isEnabled: true }).where('key', 'markdown')
// Load storage targets
await WIKI.db.storage.refreshTargetsFromDisk()
await WIKI.models.storage.refreshTargetsFromDisk()
// Create root administrator
WIKI.logger.info('Creating root administrator...')
await WIKI.db.users.query().delete().where({
await WIKI.models.users.query().delete().where({
providerKey: 'local',
email: req.body.adminEmail
})
await WIKI.db.users.query().insert({
await WIKI.models.users.query().insert({
email: req.body.adminEmail,
provider: 'local',
password: req.body.adminPassword,
@ -341,12 +341,12 @@ module.exports = () => {
// Create Guest account
WIKI.logger.info('Creating guest account...')
const guestUsr = await WIKI.db.users.query().findOne({
const guestUsr = await WIKI.models.users.query().findOne({
providerKey: 'local',
email: 'guest@example.com'
})
if (!guestUsr) {
await WIKI.db.users.query().insert({
await WIKI.models.users.query().insert({
provider: 'local',
email: 'guest@example.com',
name: 'Guest',

View File

@ -4,7 +4,9 @@ block body
#app.is-fullscreen
v-app
.onboarding
img(src='/svg/logo-wikijs.svg', alt='Wiki.js')
h1= t('welcome.title')
h2= t('welcome.subtitle')
v-btn(color='primary', href='/e/home')= t('welcome.createhome')
img.animated.zoomIn(src='/svg/logo-wikijs.svg', alt='Wiki.js')
.headline= t('welcome.title')
.subheading.mt-3= t('welcome.subtitle')
v-btn.mt-5(color='primary', href='/e/home', large)
v-icon(left) add
span= t('welcome.createhome')

View File

@ -118,7 +118,7 @@ const init = {
},
async reload() {
console.warn(chalk.yellow('--- Closing DB connections...'))
await global.WIKI.db.knex.destroy()
await global.WIKI.models.knex.destroy()
console.warn(chalk.yellow('--- Closing Redis connections...'))
await global.WIKI.redis.quit()
console.warn(chalk.yellow('--- Closing Server connections...'))