diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..06dfb47f --- /dev/null +++ b/.babelrc @@ -0,0 +1,20 @@ +{ + "comments": false, + "presets": [ + ["env", { + "targets": { + "browsers": [ + "last 6 Chrome major versions", + "last 6 Firefox major versions", + "last 4 Safari major versions", + "last 4 Edge major versions", + "last 3 iOS major versions", + "last 3 Android major versions", + "last 2 ChromeAndroid major versions", + "Explorer 11" + ] + } + }], + "stage-2" + ] +} diff --git a/.eslintrc.json b/.eslintrc.json index 283168f4..8bf80646 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,27 +1,14 @@ { - "extends": "standard", + "extends": "requarks", "env": { "node": true, "es6": true, "jest": true }, "globals": { - // Client "document": false, "navigator": false, "window": false, - "siteLang": false, - "socket": true, - "wikijs": true, - "FuseBox": false, - // Server - "appconfig": true, - "appdata": true, - "ROOTPATH": true, - "SERVERPATH": true, - "IS_DEBUG": true - }, - "rules": { - "space-before-function-paren": 0 + "FuseBox": false } } diff --git a/.npmrc b/.npmrc index 22b81d18..6d1bedf0 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ -save-prefix = "~" +save-exact = true +save-prefix = "" diff --git a/.yarnrc b/.yarnrc index 95888f66..d60dfee7 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1 +1,2 @@ -save-prefix "~" +save-exact true +save-prefix "" diff --git a/CHANGELOG.md b/CHANGELOG.md index 63458e51..1d7cde22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -237,11 +237,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Updated dependencies + snyk policy -[v1.0.11]: https://github.com/Requarks/wiki/releases/tag/v1.0.11 -[v1.0.10]: https://github.com/Requarks/wiki/releases/tag/v1.0.10 -[v1.0.9]: https://github.com/Requarks/wiki/releases/tag/v1.0.9 -[v1.0.8]: https://github.com/Requarks/wiki/releases/tag/v1.0.8 -[v1.0.7]: https://github.com/Requarks/wiki/releases/tag/v1.0.7 [v1.0.6]: https://github.com/Requarks/wiki/releases/tag/v1.0.6 [v1.0.5]: https://github.com/Requarks/wiki/releases/tag/v1.0.5 [v1.0.4]: https://github.com/Requarks/wiki/releases/tag/v1.0.4 diff --git a/assets/images/bg.jpg b/assets/images/bg.jpg new file mode 100644 index 00000000..d601fcfe Binary files /dev/null and b/assets/images/bg.jpg differ diff --git a/assets/images/bg_1.jpg b/assets/images/bg_1.jpg deleted file mode 100644 index 1b85b7f0..00000000 Binary files a/assets/images/bg_1.jpg and /dev/null differ diff --git a/assets/images/bg_2.jpg b/assets/images/bg_2.jpg deleted file mode 100644 index df2c53be..00000000 Binary files a/assets/images/bg_2.jpg and /dev/null differ diff --git a/assets/images/bg_3.jpg b/assets/images/bg_3.jpg deleted file mode 100644 index 04be9fe7..00000000 Binary files a/assets/images/bg_3.jpg and /dev/null differ diff --git a/assets/svg/auth-icon-azure.svg b/assets/svg/auth-icon-azure.svg new file mode 100644 index 00000000..13f1c52e --- /dev/null +++ b/assets/svg/auth-icon-azure.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/svg/auth-icon-facebook.svg b/assets/svg/auth-icon-facebook.svg new file mode 100644 index 00000000..fa706aa2 --- /dev/null +++ b/assets/svg/auth-icon-facebook.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/svg/auth-icon-github.svg b/assets/svg/auth-icon-github.svg new file mode 100644 index 00000000..18e9450e --- /dev/null +++ b/assets/svg/auth-icon-github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/svg/auth-icon-google.svg b/assets/svg/auth-icon-google.svg new file mode 100644 index 00000000..06dc52f0 --- /dev/null +++ b/assets/svg/auth-icon-google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/svg/auth-icon-ldap.svg b/assets/svg/auth-icon-ldap.svg new file mode 100644 index 00000000..679fc237 --- /dev/null +++ b/assets/svg/auth-icon-ldap.svg @@ -0,0 +1,10 @@ + + + + + + + diff --git a/assets/svg/auth-icon-local.svg b/assets/svg/auth-icon-local.svg new file mode 100644 index 00000000..da2fe997 --- /dev/null +++ b/assets/svg/auth-icon-local.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/assets/svg/auth-icon-microsoft.svg b/assets/svg/auth-icon-microsoft.svg new file mode 100644 index 00000000..0d47e89a --- /dev/null +++ b/assets/svg/auth-icon-microsoft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/svg/auth-icon-slack.svg b/assets/svg/auth-icon-slack.svg new file mode 100644 index 00000000..47232d6d --- /dev/null +++ b/assets/svg/auth-icon-slack.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/svg/login-bg-dark.svg b/assets/svg/login-bg-dark.svg new file mode 100644 index 00000000..8ab32dde --- /dev/null +++ b/assets/svg/login-bg-dark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/svg/login-bg.svg b/assets/svg/login-bg.svg new file mode 100644 index 00000000..bb1c6ffb --- /dev/null +++ b/assets/svg/login-bg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/client/configure.js b/client/configure.js deleted file mode 100644 index 714ff901..00000000 --- a/client/configure.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict' - -require('./scss/configure.scss') -require('./js/configure.js') diff --git a/client/index.js b/client/index.js index 48f04872..7f5c2c19 100644 --- a/client/index.js +++ b/client/index.js @@ -1,17 +1,4 @@ 'use strict' -let logic = document.documentElement.dataset.logic - -switch (logic) { - case 'error': - require('./scss/error.scss') - break - case 'login': - require('./scss/login.scss') - require('./js/login.js') - break - default: - require('./scss/app.scss') - require('./js/app.js') - break -} +require('./scss/app.scss') +require('./js/app.js') diff --git a/client/js/app.js b/client/js/app.js index 9a9c3b1b..67601a6f 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -1,28 +1,28 @@ 'use strict' -/* global $, siteRoot */ +/* global siteConfig */ /* eslint-disable no-new */ +import CONSTANTS from './constants' + import Vue from 'vue' import VueResource from 'vue-resource' import VueClipboards from 'vue-clipboards' -import VueLodash from 'vue-lodash' +import VeeValidate from 'vee-validate' +import { ApolloClient, createBatchingNetworkInterface } from 'apollo-client' import store from './store' -import io from 'socket-io-client' -import i18next from 'i18next' -import i18nextXHR from 'i18next-xhr-backend' -import VueI18Next from '@panter/vue-i18next' -import 'jquery-contextmenu' -import 'jquery-simple-upload' -import 'jquery-smooth-scroll' -import 'jquery-sticky' + +// ==================================== +// Load Modules +// ==================================== + +import localization from './modules/localization' // ==================================== // Load Helpers // ==================================== import helpers from './helpers' -import _ from './helpers/lodash' // ==================================== // Load Vue Components @@ -36,6 +36,7 @@ import editorFileComponent from './components/editor-file.vue' import editorVideoComponent from './components/editor-video.vue' import historyComponent from './components/history.vue' import loadingSpinnerComponent from './components/loading-spinner.vue' +import loginComponent from './components/login.vue' import modalCreatePageComponent from './components/modal-create-page.vue' import modalCreateUserComponent from './components/modal-create-user.vue' import modalDeletePageComponent from './components/modal-delete-page.vue' @@ -53,19 +54,48 @@ import adminEditUserComponent from './pages/admin-edit-user.component.js' import adminProfileComponent from './pages/admin-profile.component.js' import adminSettingsComponent from './pages/admin-settings.component.js' import adminThemeComponent from './pages/admin-theme.component.js' +import configManagerComponent from './components/config-manager.component.js' import contentViewComponent from './pages/content-view.component.js' import editorComponent from './components/editor.component.js' import sourceViewComponent from './pages/source-view.component.js' +// ==================================== +// Initialize Global Vars +// ==================================== + +window.wiki = null +window.CONSTANTS = CONSTANTS + +// ==================================== +// Initialize Apollo Client (GraphQL) +// ==================================== + +window.graphQL = new ApolloClient({ + networkInterface: createBatchingNetworkInterface({ + uri: window.location.protocol + '//' + window.location.host + siteConfig.path + '/graphql' + }), + connectToDevTools: true +}) + // ==================================== // Initialize Vue Modules // ==================================== Vue.use(VueResource) Vue.use(VueClipboards) -Vue.use(VueI18Next) -Vue.use(VueLodash, _) +Vue.use(localization.VueI18Next) Vue.use(helpers) +Vue.use(VeeValidate, { + enableAutoClasses: true, + classNames: { + touched: 'is-touched', // the control has been blurred + untouched: 'is-untouched', // the control hasn't been blurred + valid: 'is-valid', // model is valid + invalid: 'is-invalid', // model is invalid + pristine: 'is-pristine', // control has not been interacted with + dirty: 'is-dirty' // control has been interacted with + } +}) // ==================================== // Register Vue Components @@ -78,6 +108,7 @@ Vue.component('adminSettings', adminSettingsComponent) Vue.component('adminTheme', adminThemeComponent) Vue.component('anchor', anchorComponent) Vue.component('colorPicker', colorPickerComponent) +Vue.component('configManager', configManagerComponent) Vue.component('contentView', contentViewComponent) Vue.component('editor', editorComponent) Vue.component('editorCodeblock', editorCodeblockComponent) @@ -85,6 +116,7 @@ Vue.component('editorFile', editorFileComponent) Vue.component('editorVideo', editorVideoComponent) Vue.component('history', historyComponent) Vue.component('loadingSpinner', loadingSpinnerComponent) +Vue.component('login', loginComponent) Vue.component('modalCreatePage', modalCreatePageComponent) Vue.component('modalCreateUser', modalCreateUserComponent) Vue.component('modalDeletePage', modalDeletePageComponent) @@ -99,52 +131,26 @@ Vue.component('sourceView', sourceViewComponent) Vue.component('toggle', toggleComponent) Vue.component('tree', treeComponent) -// ==================================== -// Load Localization strings -// ==================================== - -i18next - .use(i18nextXHR) - .init({ - backend: { - loadPath: siteRoot + '/js/i18n/{{lng}}.json' - }, - lng: siteLang, - fallbackLng: siteLang - }) - -$(() => { +document.addEventListener('DOMContentLoaded', ev => { // ==================================== // Notifications // ==================================== - $(window).bind('beforeunload', () => { + window.addEventListener('beforeunload', () => { store.dispatch('startLoading') }) - $(document).ajaxSend(() => { - store.dispatch('startLoading') - }).ajaxComplete(() => { - store.dispatch('stopLoading') - }) - - // ==================================== - // Establish WebSocket connection - // ==================================== - - let socket = io(window.location.origin) - window.socket = socket // ==================================== // Bootstrap Vue // ==================================== - const i18n = new VueI18Next(i18next) - window.wikijs = new Vue({ + const i18n = localization.init() + window.wiki = new Vue({ mixins: [helpers], components: {}, store, i18n, - el: '#root', + el: '#app', methods: { changeTheme(opts) { this.$el.className = `has-stickynav is-primary-${opts.primary} is-alternate-${opts.alt}` @@ -153,9 +159,7 @@ $(() => { } }, mounted() { - $('a:not(.toc-anchor)').smoothScroll({ speed: 500, offset: -50 }) - $('#header').sticky({ topSpacing: 0 }) - $('.sidebar-pagecontents').sticky({ topSpacing: 15, bottomSpacing: 75 }) + } }) }) diff --git a/client/js/app.old.js b/client/js/app.old.js new file mode 100644 index 00000000..fc69cfc3 --- /dev/null +++ b/client/js/app.old.js @@ -0,0 +1,153 @@ +'use strict' + +/* global $, siteConfig */ +/* eslint-disable no-new */ + +import Vue from 'vue' +import VueResource from 'vue-resource' +import VueClipboards from 'vue-clipboards' +import VueLodash from 'vue-lodash' +import store from './store' +import i18next from 'i18next' +import i18nextXHR from 'i18next-xhr-backend' +import VueI18Next from '@panter/vue-i18next' +import 'jquery-contextmenu' +import 'jquery-simple-upload' +import 'jquery-smooth-scroll' +import 'jquery-sticky' + +// ==================================== +// Load Helpers +// ==================================== + +import helpers from './helpers' +import _ from './helpers/lodash' + +// ==================================== +// Load Vue Components +// ==================================== + +import alertComponent from './components/alert.vue' +import anchorComponent from './components/anchor.vue' +import colorPickerComponent from './components/color-picker.vue' +import editorCodeblockComponent from './components/editor-codeblock.vue' +import editorFileComponent from './components/editor-file.vue' +import editorVideoComponent from './components/editor-video.vue' +import historyComponent from './components/history.vue' +import loadingSpinnerComponent from './components/loading-spinner.vue' +import modalCreatePageComponent from './components/modal-create-page.vue' +import modalCreateUserComponent from './components/modal-create-user.vue' +import modalDeleteUserComponent from './components/modal-delete-user.vue' +import modalDiscardPageComponent from './components/modal-discard-page.vue' +import modalMovePageComponent from './components/modal-move-page.vue' +import modalProfile2faComponent from './components/modal-profile-2fa.vue' +import modalUpgradeSystemComponent from './components/modal-upgrade-system.vue' +import pageLoaderComponent from './components/page-loader.vue' +import searchComponent from './components/search.vue' +import toggleComponent from './components/toggle.vue' +import treeComponent from './components/tree.vue' + +import adminEditUserComponent from './pages/admin-edit-user.component.js' +import adminProfileComponent from './pages/admin-profile.component.js' +import adminSettingsComponent from './pages/admin-settings.component.js' +import adminThemeComponent from './pages/admin-theme.component.js' +import contentViewComponent from './pages/content-view.component.js' +import editorComponent from './components/editor.component.js' +import sourceViewComponent from './pages/source-view.component.js' + +// ==================================== +// Initialize Vue Modules +// ==================================== + +Vue.use(VueResource) +Vue.use(VueClipboards) +Vue.use(VueI18Next) +Vue.use(VueLodash, _) +Vue.use(helpers) + +// ==================================== +// Register Vue Components +// ==================================== + +Vue.component('alert', alertComponent) +Vue.component('adminEditUser', adminEditUserComponent) +Vue.component('adminProfile', adminProfileComponent) +Vue.component('adminSettings', adminSettingsComponent) +Vue.component('adminTheme', adminThemeComponent) +Vue.component('anchor', anchorComponent) +Vue.component('colorPicker', colorPickerComponent) +Vue.component('contentView', contentViewComponent) +Vue.component('editor', editorComponent) +Vue.component('editorCodeblock', editorCodeblockComponent) +Vue.component('editorFile', editorFileComponent) +Vue.component('editorVideo', editorVideoComponent) +Vue.component('history', historyComponent) +Vue.component('loadingSpinner', loadingSpinnerComponent) +Vue.component('modalCreatePage', modalCreatePageComponent) +Vue.component('modalCreateUser', modalCreateUserComponent) +Vue.component('modalDeleteUser', modalDeleteUserComponent) +Vue.component('modalDiscardPage', modalDiscardPageComponent) +Vue.component('modalMovePage', modalMovePageComponent) +Vue.component('modalProfile2fa', modalProfile2faComponent) +Vue.component('modalUpgradeSystem', modalUpgradeSystemComponent) +Vue.component('pageLoader', pageLoaderComponent) +Vue.component('search', searchComponent) +Vue.component('sourceView', sourceViewComponent) +Vue.component('toggle', toggleComponent) +Vue.component('tree', treeComponent) + +// ==================================== +// Load Localization strings +// ==================================== + +i18next + .use(i18nextXHR) + .init({ + backend: { + loadPath: siteConfig.path + '/js/i18n/{{lng}}.json' + }, + lng: siteConfig.lang, + fallbackLng: siteConfig.lang + }) + +$(() => { + // ==================================== + // Notifications + // ==================================== + + $(window).bind('beforeunload', () => { + store.dispatch('startLoading') + }) + $(document).ajaxSend(() => { + store.dispatch('startLoading') + }).ajaxComplete(() => { + store.dispatch('stopLoading') + }) + + // ==================================== + // Bootstrap Vue + // ==================================== + + const i18n = new VueI18Next(i18next) + if (document.querySelector('#root')) { + window.wikijs = new Vue({ + mixins: [helpers], + components: {}, + store, + i18n, + el: '#root', + methods: { + changeTheme(opts) { + this.$el.className = `has-stickynav is-primary-${opts.primary} is-alternate-${opts.alt}` + this.$refs.header.className = `nav is-${opts.primary}` + this.$refs.footer.className = `footer is-${opts.footer}` + } + }, + mounted() { + $('a:not(.toc-anchor)').smoothScroll({ speed: 500, offset: -50 }) + $('#header').sticky({ topSpacing: 0 }) + $('.sidebar-pagecontents').sticky({ topSpacing: 15, bottomSpacing: 75 }) + } + }) + } +}) diff --git a/client/js/components/config-manager.component.js b/client/js/components/config-manager.component.js new file mode 100644 index 00000000..a6cea82c --- /dev/null +++ b/client/js/components/config-manager.component.js @@ -0,0 +1,239 @@ +/* global siteConfig */ + +import axios from 'axios' + +export default { + name: 'configManager', + data() { + return { + loading: false, + state: 'welcome', + syscheck: { + ok: false, + error: '', + results: [] + }, + dbcheck: { + ok: false, + error: '' + }, + gitcheck: { + ok: false, + error: '' + }, + final: { + ok: false, + error: '', + results: [] + }, + conf: { + telemetry: true, + upgrade: false, + title: siteConfig.title || 'Wiki', + host: siteConfig.host || 'http://', + port: siteConfig.port || 80, + lang: siteConfig.lang || 'en', + public: (siteConfig.public === true), + pathData: './data', + pathRepo: './repo', + gitUseRemote: (siteConfig.git !== false), + gitUrl: '', + gitBranch: 'master', + gitAuthType: 'ssh', + gitAuthSSHKey: '', + gitAuthUser: '', + gitAuthPass: '', + gitAuthSSL: true, + gitShowUserEmail: true, + gitServerEmail: '', + adminEmail: '', + adminPassword: '', + adminPasswordConfirm: '' + }, + considerations: { + https: false, + port: false, + localhost: false + } + } + }, + computed: { + currentProgress: function () { + let perc = '0%' + switch (this.state) { + case 'welcome': + perc = '0%' + break + case 'syscheck': + perc = (this.syscheck.ok) ? '15%' : '5%' + break + case 'general': + perc = '25%' + break + case 'considerations': + perc = '30%' + break + case 'git': + perc = '50%' + break + case 'gitcheck': + perc = (this.gitcheck.ok) ? '70%' : '55%' + break + case 'admin': + perc = '75%' + break + } + return perc + } + }, + mounted: function () { + /* if (appconfig.paths) { + this.conf.pathData = appconfig.paths.data || './data' + this.conf.pathRepo = appconfig.paths.repo || './repo' + } + if (appconfig.git !== false && _.isPlainObject(appconfig.git)) { + this.conf.gitUrl = appconfig.git.url || '' + this.conf.gitBranch = appconfig.git.branch || 'master' + this.conf.gitShowUserEmail = (appconfig.git.showUserEmail !== false) + this.conf.gitServerEmail = appconfig.git.serverEmail || '' + if (_.isPlainObject(appconfig.git.auth)) { + this.conf.gitAuthType = appconfig.git.auth.type || 'ssh' + this.conf.gitAuthSSHKey = appconfig.git.auth.privateKey || '' + this.conf.gitAuthUser = appconfig.git.auth.username || '' + this.conf.gitAuthPass = appconfig.git.auth.password || '' + this.conf.gitAuthSSL = (appconfig.git.auth.sslVerify !== false) + } + } */ + }, + methods: { + proceedToWelcome: function (ev) { + this.state = 'welcome' + this.loading = false + }, + proceedToSyscheck: function (ev) { + let self = this + this.state = 'syscheck' + this.loading = true + self.syscheck = { + ok: false, + error: '', + results: [] + } + + this.$helpers._.delay(() => { + axios.post('/syscheck').then(resp => { + if (resp.data.ok === true) { + self.syscheck.ok = true + self.syscheck.results = resp.data.results + } else { + self.syscheck.ok = false + self.syscheck.error = resp.data.error + } + self.loading = false + self.$nextTick() + }).catch(err => { + window.alert(err.message) + }) + }, 1000) + }, + proceedToGeneral: function (ev) { + let self = this + self.state = 'general' + self.loading = false + self.$nextTick(() => { + self.$validator.validateAll('general') + }) + }, + proceedToConsiderations: function (ev) { + this.considerations = { + https: !this.$helpers._.startsWith(this.conf.host, 'https'), + port: false, // TODO + localhost: this.$helpers._.includes(this.conf.host, 'localhost') + } + this.state = 'considerations' + this.loading = false + }, + proceedToGit: function (ev) { + let self = this + self.state = 'git' + self.loading = false + self.$nextTick(() => { + self.$validator.validateAll('git') + }) + }, + proceedToGitCheck: function (ev) { + let self = this + this.state = 'gitcheck' + this.loading = true + self.gitcheck = { + ok: false, + results: [], + error: '' + } + + this.$helpers._.delay(() => { + axios.post('/gitcheck', self.conf).then(resp => { + if (resp.data.ok === true) { + self.gitcheck.ok = true + self.gitcheck.results = resp.data.results + } else { + self.gitcheck.ok = false + self.gitcheck.error = resp.data.error + } + self.loading = false + self.$nextTick() + }).catch(err => { + window.alert(err.message) + }) + }, 1000) + }, + proceedToAdmin: function (ev) { + let self = this + self.state = 'admin' + self.loading = false + self.$nextTick(() => { + self.$validator.validateAll('admin') + }) + }, + proceedToFinal: function (ev) { + let self = this + self.state = 'final' + self.loading = true + self.final = { + ok: false, + error: '', + results: [] + } + + this.$helpers._.delay(() => { + axios.post('/finalize', self.conf).then(resp => { + if (resp.data.ok === true) { + self.final.ok = true + self.final.results = resp.data.results + } else { + self.final.ok = false + self.final.error = resp.data.error + } + self.loading = false + self.$nextTick() + }).catch(err => { + window.alert(err.message) + }) + }, 1000) + }, + finish: function (ev) { + let self = this + self.state = 'restart' + + this.$helpers._.delay(() => { + axios.post('/restart', {}).then(resp => { + this.$helpers._.delay(() => { + window.location.assign(self.conf.host) + }, 30000) + }).catch(err => { + window.alert(err.message) + }) + }, 1000) + } + } +} diff --git a/client/js/components/editor-video.vue b/client/js/components/editor-video.vue index 38e9fef8..50e998ed 100644 --- a/client/js/components/editor-video.vue +++ b/client/js/components/editor-video.vue @@ -34,9 +34,9 @@ + diff --git a/client/js/components/page-loader.vue b/client/js/components/page-loader.vue index 8f7071e3..e4171b6d 100644 --- a/client/js/components/page-loader.vue +++ b/client/js/components/page-loader.vue @@ -5,20 +5,19 @@ span {{ msg }} - diff --git a/client/js/constants/graphql.js b/client/js/constants/graphql.js new file mode 100644 index 00000000..e189cce7 --- /dev/null +++ b/client/js/constants/graphql.js @@ -0,0 +1,22 @@ +import gql from 'graphql-tag' + +export default { + GQL_QUERY_AUTHENTICATION: gql` + query($mode: String!) { + authentication(mode:$mode) { + key + useForm + title + icon + } + } + `, + GQL_QUERY_TRANSLATIONS: gql` + query($locale: String!, $namespace: String!) { + translations(locale:$locale, namespace:$namespace) { + key + value + } + } + ` +} diff --git a/client/js/constants/index.js b/client/js/constants/index.js new file mode 100644 index 00000000..56e9acc7 --- /dev/null +++ b/client/js/constants/index.js @@ -0,0 +1,5 @@ +import GRAPHQL from './graphql' + +export default { + GRAPHQL +} diff --git a/client/js/helpers/index.js b/client/js/helpers/index.js index 6f802e8b..6335809b 100644 --- a/client/js/helpers/index.js +++ b/client/js/helpers/index.js @@ -1,6 +1,7 @@ 'use strict' const helpers = { + _: require('./lodash'), common: require('./common'), form: require('./form'), pages: require('./pages') diff --git a/client/js/login.js b/client/js/login.js deleted file mode 100644 index 892e3306..00000000 --- a/client/js/login.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -/* global $ */ - -$(() => { - $('#login-user').focus() -}) diff --git a/client/js/modules/localization.js b/client/js/modules/localization.js new file mode 100644 index 00000000..2ac94cd7 --- /dev/null +++ b/client/js/modules/localization.js @@ -0,0 +1,52 @@ +import i18next from 'i18next' +import i18nextXHR from 'i18next-xhr-backend' +import i18nextCache from 'i18next-localstorage-cache' +import VueI18Next from '@panter/vue-i18next' +import loSet from 'lodash/set' + +/* global siteConfig, graphQL, CONSTANTS */ + +module.exports = { + VueI18Next, + init() { + i18next + .use(i18nextXHR) + .use(i18nextCache) + .init({ + backend: { + loadPath: '{{lng}}/{{ns}}', + parse: (data) => data, + ajax: (url, opts, cb, data) => { + let langParams = url.split('/') + graphQL.query({ + query: CONSTANTS.GRAPHQL.GQL_QUERY_TRANSLATIONS, + variables: { + locale: langParams[0], + namespace: langParams[1] + } + }).then(resp => { + let ns = {} + if (resp.data.translations.length > 0) { + resp.data.translations.forEach(entry => { + loSet(ns, entry.key, entry.value) + }) + } + return cb(ns, {status: '200'}) + }).catch(err => { + console.error(err) + return cb(null, {status: '404'}) + }) + } + }, + cache: { + enabled: true, + expiration: 60 * 60 * 1000 + }, + defaultNS: 'common', + lng: siteConfig.lang, + fallbackLng: siteConfig.lang, + ns: ['common', 'admin', 'auth'] + }) + return new VueI18Next(i18next) + } +} diff --git a/client/scss/app.scss b/client/scss/app.scss index a86c88e8..ab58c08e 100644 --- a/client/scss/app.scss +++ b/client/scss/app.scss @@ -15,6 +15,7 @@ $primary: 'indigo'; @import 'components/button'; @import 'components/collapsable-nav'; @import 'components/color-picker'; +@import 'components/config-manager'; @import 'components/footer'; @import 'components/form'; @import 'components/grid'; @@ -43,6 +44,7 @@ $primary: 'indigo'; @import 'layout/_loader'; @import 'layout/_rtl'; -@import 'pages/_welcome'; +@import 'pages/login'; +@import 'pages/welcome'; @import 'base/print'; diff --git a/client/scss/base/base.scss b/client/scss/base/base.scss index 6d8a688e..54740abe 100644 --- a/client/scss/base/base.scss +++ b/client/scss/base/base.scss @@ -11,10 +11,15 @@ html { display: none; } -#root { +#app { padding-bottom: 67px; position: relative; min-height: 100%; + + &.is-fullscreen { + width: 100vw; + height: 100vh; + } } body { diff --git a/client/scss/components/button.scss b/client/scss/components/button.scss index 97338a0e..0f5c9a09 100644 --- a/client/scss/components/button.scss +++ b/client/scss/components/button.scss @@ -4,7 +4,7 @@ border: 1px solid mc('orange','700'); border-radius: 3px; display: inline-flex; - height: 30px; + height: 40px; align-items: center; padding: 0 15px; font-size: 13px; @@ -61,7 +61,11 @@ background-color: mc($color,'800'); color: #FFF; animation: none; - } + } + + &:focus { + box-shadow: inset 0 0 0 3px rgba(255,255,255, .4); + } } } @@ -74,7 +78,13 @@ &.is-featured { animation: btnInvertedPulse .6s ease alternate infinite; - } + } + + &.is-fullwidth { + width: 100%; + text-align: center; + justify-content: center; + } &.is-disabled, &:disabled { background-color: mc('grey', '300'); @@ -87,7 +97,11 @@ background-color: mc('grey', '300') !important; color: mc('grey', '500') !important; } - } + } + + &.is-small { + height: 30px; + } } diff --git a/client/scss/components/config-manager.scss b/client/scss/components/config-manager.scss new file mode 100644 index 00000000..8ee89d91 --- /dev/null +++ b/client/scss/components/config-manager.scss @@ -0,0 +1,61 @@ +.config-manager { + .welcome { + text-align: center; + padding: 50px 0 15px 0; + color: mc('grey', '700'); + + h2 { + margin: 0; + } + + } + + i.icon-loader { + display: inline-block; + color: mc('indigo', '500') + } + i.icon-check { + color: mc('green', '500') + } + i.icon-square-cross { + color: mc('red', '500') + } + i.icon-warning-outline { + color: mc('orange', '500') + } + + .tst-welcome-leave-active, .tst-welcome-enter-active { + transition: all .5s; + overflow-y: hidden; + } + .tst-welcome-leave, .tst-welcome-enter-to { + opacity: 1; + max-height: 200px; + } + .tst-welcome-leave-to, .tst-welcome-enter { + opacity: 0; + max-height: 0; + padding-top: 0; + } + + .progress-bar { + width: 150px; + height: 10px; + background-color: mc('indigo', '50'); + border:1px solid mc('indigo', '100'); + border-radius: 3px; + position: absolute; + left: 15px; + top: 21px; + padding: 1px; + + > div { + width: 5px; + height: 6px; + background-color: mc('indigo', '200'); + border-radius: 2px; + transition: all 1s ease; + } + + } +} diff --git a/client/scss/login.scss b/client/scss/login.scss deleted file mode 100644 index 725ce498..00000000 --- a/client/scss/login.scss +++ /dev/null @@ -1,13 +0,0 @@ -@charset "utf-8"; - -$primary: 'indigo'; - -@import "base/variables"; -@import "base/colors"; -@import "base/reset"; -@import "base/mixins"; -@import "base/fonts"; -@import "base/base"; - -@import "libs/animate"; -@import 'pages/login'; diff --git a/client/scss/pages/_login.scss b/client/scss/pages/_login.scss index abfd9c93..be90d44f 100644 --- a/client/scss/pages/_login.scss +++ b/client/scss/pages/_login.scss @@ -1,306 +1,264 @@ - -body { - padding: 0; - margin: 0; - font-family: $core-font-standard; - font-size: 14px; -} - -a { - color: #FFF; - transition: color 0.4s ease; - text-decoration: none; - - &:hover { - color: mc('orange','600'); - text-decoration: underline; - } - -} - -#bg { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1; - background-color: #000; - - > div { - background-size: cover; - background-position: center center; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - opacity: 0; - visibility: hidden; - transition: opacity 3s ease, visibility 3s; - animation: bg 30s linear infinite; - - &:nth-child(1) { - animation-delay: 10s; - } - - &:nth-child(2) { - animation-delay: 20s; - } - - } - -} - -#root { - position: fixed; - top: 15vh; - left: 10vw; - z-index: 2; - color: #FFF; - display: flex; - flex-direction: column; - - h1 { - font-size: 4rem; - font-weight: bold; - color: #FFF; - padding: 0; - margin: 0; - animation: headerIntro 3s ease; - } - - h2 { - font-size: 1.5rem; - font-weight: normal; - color: rgba(255,255,255,0.7); - padding: 0; - margin: 0 0 25px 0; - animation: headerIntro 3s ease; - } - - h3 { - font-size: 1.25rem; - font-weight: normal; - color: #FB8C00; - padding: 0; - margin: 0; - animation: shake 1s ease; - - > .fa { - margin-right: 7px; - } - - } - - h4 { - font-size: 0.8rem; - font-weight: normal; - color: rgba(255,255,255,0.7); - padding: 0; - margin: 0 0 15px 0; - animation: fadeIn 3s ease; - } - - form { - display: flex; - flex-direction: column; - } - - input[type=text], input[type=password] { - width: 350px; - max-width: 80vw; - border: 1px solid rgba(255,255,255,0.3); - border-radius: 3px; - background-color: rgba(0,0,0,0.2); - padding: 0 15px; - height: 40px; - margin: 0 0 10px 0; - color: #FFF; - font-weight: bold; - font-size: 14px; - transition: all 0.4s ease; - - &:focus { - outline: none; - border-color: mc('orange','600'); - } - - } - - button { - background-color: mc('orange','600'); - color: #FFF; - border: 1px solid lighten(mc('orange','600'), 10%); - border-radius: 3px; - height: 40px; - width: 125px; - padding: 0; - font-weight: bold; - margin: 15px 0 0 0; - transition: all 0.4s ease; - cursor: pointer; - - span { - font-weight: bold; - } - - &:focus { - outline: none; - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('orange','600'), 10%); - } - - } - - #social { - margin-top: 25px; - - > span { - display: block; - font-weight: bold; - color: rgba(255,255,255,0.7); - } - - button { - margin-right: 5px; - width: auto; - padding: 0 15px; - - > i { - margin-right: 10px; - font-size: 16px; - } - - &.ms { - background-color: mc('blue','600'); - border-color: lighten(mc('blue','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('blue','600'), 10%); - } - - } - - &.google { - background-color: mc('light-blue','600'); - border-color: lighten(mc('light-blue','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('light-blue','600'), 10%); - } - - } - - &.facebook { - background-color: mc('indigo','600'); - border-color: lighten(mc('indigo','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('indigo','600'), 10%); - } - - } - - &.github { - background-color: mc('blue-grey','700'); - border-color: lighten(mc('blue-grey','700'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('blue-grey','700'), 10%); - } - } - - &.slack { - background-color: mc('purple','700'); - border-color: lighten(mc('purple','700'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('purple','700'), 10%); - } - } - - } - - } - -} - -#copyright { - display: flex; - align-items: center; - justify-content: flex-start; - position: absolute; - left: 10vw; - bottom: 10vh; - z-index: 2; - color: rgba(255,255,255,0.5); - font-weight: bold; - - .icon { - font-size: 1.2rem; - margin: 0 8px; - } - - a { - opacity: 0.75; - } - -} - -@include keyframes(bg) { - 0% { - @include prefix(transform, scale(1,1)); - visibility: visible; - opacity: 0; - }, - 5% { - opacity: 0.5; - }, - 33% { - opacity: 0.5; - }, - 38% { - @include prefix(transform, scale(1.2, 1.2)); - opacity: 0; - }, - 39% { - visibility: hidden; - } - 100% { - visibility: hidden; - opacity: 0; - } -} - -@include keyframes(headerIntro) { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } +.login { + background-image: linear-gradient(to right, mc('blue', '400'), mc('blue', '600')); + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + + &.is-error { + background-image: linear-gradient(to right, mc('red', '400'), mc('red', '600')); + } + + &::before { + content: ''; + position: absolute; + background-image: url('../svg/login-bg.svg'); + background-position: center bottom; + background-size: cover; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + } + + &-container { + position: relative; + display: flex; + width: 400px; + align-items: stretch; + box-shadow: 0 14px 28px rgba(0,0,0,0.2); + border-radius: 6px; + + &.is-expanded { + width: 650px; + + .login-frame { + border-radius: 0 6px 6px 0; + border-left: none; + } + } + + @include until($tablet) { + width: 350px; + + &.is-expanded { + width: 400px; + } + } + } + + &-error { + position: absolute; + bottom: 105%; + width: 100%; + min-height: 50px; + background-image: radial-gradient(ellipse at top left, rgba(255,255,255,.9) 0%,rgba(255,255,255,.8) 100%); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + border-radius: 6px; + color: mc('red', '800'); + display: flex; + justify-content: center; + align-items: center; + padding: 1rem; + + strong { + font-weight: 600; + text-transform: uppercase; + display: block; + padding: 0 1rem 0 0; + border-right: 1px solid mc('red', '200'); + } + span { + padding: 0 0 0 1rem; + display: block; + } + } + + &-providers { + display: flex; + flex-direction: column; + width: 250px; + + border-right: none; + border-radius: 6px 0 0 6px; + z-index: 1; + overflow: hidden; + + @include until($tablet) { + width: 50px; + } + + button { + flex: 1 1; + padding: 5px 15px; + border: none; + color: #FFF; + background: linear-gradient(to right, rgba(mc('light-blue', '800'), .7), rgba(mc('light-blue', '800'), 1)); + border-top: 1px solid rgba(mc('light-blue', '900'), .5); + font-family: $core-font-standard; + font-weight: 600; + text-align: left; + min-height: 40px; + display: flex; + justify-content: flex-start; + align-items: center; + transition: all .4s ease; + + &:focus { + outline: none; + } + + @include until($tablet) { + justify-content: center; + } + + &:hover { + background-color: mc('light-blue', '900'); + } + + &:first-child { + border-top: none; + + &.is-active { + border-top: 1px solid rgba(255,255,255, .5); + } + } + + &.is-active { + background-image: linear-gradient(to right, rgba(255,255,255,1) 0%,rgba(255,255,255,.77) 100%); + color: mc('light-blue', '700'); + cursor: default; + + &:hover { + background-color: transparent; + } + + svg path { + fill: mc('light-blue', '800'); + } + } + + i { + margin-right: 10px; + font-size: 16px; + + @include until($tablet) { + margin-right: 0; + font-size: 20px; + } + } + + svg { + margin-right: 10px; + width: auto; + height: 20px; + max-width: 18px; + max-height: 20px; + + path { + fill: #FFF; + } + + @include until($tablet) { + margin-right: 0; + font-size: 20px; + } + } + + span { + font-weight: 600; + + @include until($tablet) { + display: none; + } + } + } + } + + &-frame { + background-image: radial-gradient(circle at top center, rgba(255,255,255,1) 5%,rgba(255,255,255,.6) 100%); + border: 1px solid rgba(255,255,255, .5); + border-radius: 6px; + width: 400px; + padding: 1rem; + color: mc('grey', '700'); + display: flex; + justify-content: center; + flex-direction: column; + text-align: center; + + @include until($tablet) { + width: 350px; + } + + h1 { + font-size: 2rem; + font-weight: 600; + color: mc('light-blue', '700'); + text-shadow: 1px 1px 0 #FFF; + padding: 0; + margin: 0; + } + + h2 { + font-size: 1.5rem; + font-weight: 300; + color: mc('grey', '700'); + text-shadow: 1px 1px 0 #FFF; + padding: 0; + margin: 0 0 25px 0; + } + + form { + display: flex; + flex-direction: column; + } + + input[type=text], input[type=password] { + width: 100%; + border: 1px solid #FFF; + border-radius: 3px; + background-color: rgba(255,255,255,.9); + box-shadow: inset 0 0 0 3px rgba(255,255,255, .25); + padding: 0 15px; + height: 40px; + margin: 0 0 10px 0; + color: mc('grey', '700'); + font-weight: 600; + font-size: .8rem; + transition: all 0.4s ease; + text-align: center; + + &:focus { + outline: none; + border-color: mc('light-blue','500'); + background-color: rgba(255,255,255,1); + box-shadow: inset 0 0 0 3px rgba(mc('light-blue','500'), .25); + color: mc('light-blue', '800'); + } + + } + + } + + &-copyright { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + left: 0; + bottom: 10vh; + width: 100%; + z-index: 2; + color: mc('grey', '500'); + font-weight: 400; + + a { + font-weight: 600; + color: mc('light-blue', '500'); + margin-left: .25rem; + } + + } } diff --git a/config.sample.yml b/config.sample.yml index aa1e7c0a..5421d5a8 100644 --- a/config.sample.yml +++ b/config.sample.yml @@ -5,23 +5,9 @@ # https://docs.requarks.io/wiki/install # --------------------------------------------------------------------- -# Title of this site +# Port the main server should listen to # --------------------------------------------------------------------- -title: Wiki - -# --------------------------------------------------------------------- -# Full public path to the site, without the trailing slash -# --------------------------------------------------------------------- -# INCLUDE CLIENT PORT IF NOT 80/443! - -host: http://localhost - -# --------------------------------------------------------------------- -# Port the main server should listen to (80 by default) -# --------------------------------------------------------------------- -# To use process.env.PORT, comment the line below: - port: 80 # --------------------------------------------------------------------- @@ -33,140 +19,38 @@ paths: data: ./data # --------------------------------------------------------------------- -# Upload Limits -# --------------------------------------------------------------------- -# In megabytes (MB) - -uploads: - maxImageFileSize: 3 - maxOtherFileSize: 100 - -# --------------------------------------------------------------------- -# Site Language -# --------------------------------------------------------------------- -# Possible values: en, de, es, fa, fr, ja, ko, nl, pt, ru, sr, tr or zh - -lang: en - -# Enable for right to left languages (e.g. arabic): -langRtl: false - -# --------------------------------------------------------------------- -# Site Authentication -# --------------------------------------------------------------------- - -public: false - -auth: - defaultReadAccess: false - local: - enabled: true - google: - enabled: true - clientId: GOOGLE_CLIENT_ID - clientSecret: GOOGLE_CLIENT_SECRET - microsoft: - enabled: true - clientId: MS_APP_ID - clientSecret: MS_APP_SECRET - facebook: - enabled: false - clientId: FACEBOOK_APP_ID - clientSecret: FACEBOOK_APP_SECRET - github: - enabled: false - clientId: GITHUB_CLIENT_ID - clientSecret: GITHUB_CLIENT_SECRET - slack: - enabled: false - clientId: 'SLACK_CLIENT_ID' - clientSecret: 'SLACK_CLIENT_SECRET' - ldap: - enabled: false - url: ldap://serverhost:389 - bindDn: cn='root' - bindCredentials: BIND_PASSWORD - searchBase: o=users,o=example.com - searchFilter: (uid={{username}}) - tlsEnabled: false - tlsCertPath: C:\example\root_ca_cert.crt - azure: - enabled: false - clientId: APP_ID - clientSecret: APP_SECRET_KEY - resource: '00000002-0000-0000-c000-000000000000' - tenant: 'YOUR_TENANT.onmicrosoft.com' - -# --------------------------------------------------------------------- -# Secret key to use when encrypting sessions -# --------------------------------------------------------------------- -# Use a long and unique random string (256-bit keys are perfect!) - -sessionSecret: 1234567890abcdefghijklmnopqrstuvxyz - -# --------------------------------------------------------------------- -# Database Connection String -# --------------------------------------------------------------------- -# You can also use an ENV variable by using $ENV_VAR_NAME as the value - -db: mongodb://localhost:27017/wiki - -# --------------------------------------------------------------------- -# Git Connection Info +# Database # --------------------------------------------------------------------- -git: - url: https://github.com/Organization/Repo - branch: master - auth: - - # Type: basic or ssh - type: ssh - - # Only for Basic authentication: - username: marty - password: MartyMcFly88 - - # Only for SSH authentication: - privateKey: /etc/wiki/keys/git.pem - - sslVerify: true - - # Default email to use as commit author - serverEmail: marty@example.com - - # Whether to use user email as author in commits - showUserEmail: true +db: + host: localhost + port: 5432 + user: wikijs + pass: wikijsrocks + db: wiki # --------------------------------------------------------------------- -# Features +# Redis # --------------------------------------------------------------------- -# You can enable / disable specific features below -features: - linebreaks: true - mathjax: true +redis: + host: localhost + port: 6379 + db: 0 + password: null # --------------------------------------------------------------------- -# External Logging +# Background Workers # --------------------------------------------------------------------- +# Leave 0 for auto based on CPU cores -externalLogging: - bugsnag: false - loggly: false - papertrail: false - rollbar: false - sentry: false +workers: 0 # --------------------------------------------------------------------- -# Color Theme +# High Availability # --------------------------------------------------------------------- +# Read the docs BEFORE changing these settings! -theme: - primary: indigo - alt: blue-grey - viewSource: all # all | write | false - footer: blue-grey - code: - dark: true - colorize: true +ha: + nodeuid: primary + readonly: false diff --git a/npm/README.md b/npm/README.md deleted file mode 100644 index d482407e..00000000 --- a/npm/README.md +++ /dev/null @@ -1,14 +0,0 @@ -![Wiki.js](https://raw.githubusercontent.com/Requarks/wiki-site/1.0/assets/images/logo.png) - -# Wiki.js - -[![npm](https://img.shields.io/npm/v/wiki.js.svg?style=flat-square)](https://github.com/Requarks) -[![Release](https://img.shields.io/github/release/Requarks/wiki.svg?style=flat-square&maxAge=3600)](https://github.com/Requarks/wiki/releases) -[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg?style=flat-square)](https://github.com/requarks/wiki/blob/master/LICENSE) - -This npm package is an installer for Wiki.js. -For information about Wiki.js, including detailed installation steps, read the following links: - -- [Official Website](https://wiki.js.org/) -- [Installation Guide](https://wiki.js.org/get-started.html) -- [GitHub Repository](https://github.com/Requarks/wiki) diff --git a/npm/install.js b/npm/install.js deleted file mode 100644 index cd0a0511..00000000 --- a/npm/install.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -// ===================================================== -// Wiki.js -// Installation Script -// ===================================================== - -const path = require('path') -const spawn = require('child_process').spawn -const installDir = path.resolve(__dirname, '../..') -const cmd = (process.platform !== 'win32') - ? 'curl -s -S -o- https://wiki.js.org/install.sh | bash' - : `PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://wiki.js.org/install.ps1'))"` - -console.info(`Executing installation script for ${process.platform} platform...`) - -let inst = spawn(cmd, [], { - cwd: installDir, - env: process.env, - shell: true, - stdio: 'inherit', - detached: true -}) - -inst.unref() diff --git a/npm/package.json b/npm/package.json deleted file mode 100644 index 2098e56c..00000000 --- a/npm/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "wiki.js", - "version": "1.0.5-rev.1", - "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", - "main": "install.js", - "scripts": { - "test": "exit 1", - "postinstall": "node install.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Requarks/wiki.git" - }, - "keywords": [ - "wiki", - "wikis", - "wikijs", - "wiki.js", - "wiki-js", - "docs", - "documentation", - "markdown", - "guides" - ], - "author": "Nicolas Giard", - "license": "AGPL-3.0", - "bugs": { - "url": "https://github.com/Requarks/wiki/issues" - }, - "homepage": "https://github.com/Requarks/wiki#readme", - "dependencies": {} -} diff --git a/package.json b/package.json index ef84b9e1..692165db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wiki", - "version": "1.0.11", + "version": "2.0.0", "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", "main": "wiki.js", "scripts": { @@ -9,7 +9,6 @@ "restart": "node wiki restart", "build": "node tools/fuse", "dev": "node tools/fuse -d", - "dev-configure": "node tools/fuse -c", "test": "jest", "postinstall": "opencollective postinstall" }, @@ -38,135 +37,143 @@ "node": ">=6.11.1" }, "dependencies": { - "auto-load": "~3.0.0", - "axios": "~0.16.2", - "bcryptjs-then": "~1.0.1", - "bluebird": "~3.5.0", - "body-parser": "~1.17.2", - "bunyan": "~1.8.12", - "cheerio": "~1.0.0-rc.2", - "child-process-promise": "~2.2.1", - "chokidar": "~1.7.0", - "compression": "~1.7.0", - "connect-flash": "~0.1.1", - "connect-mongo": "~1.3.2", - "cookie-parser": "~1.4.3", - "cron": "~1.2.1", - "diff2html": "~2.3.0", - "execa": "~0.8.0", - "express": "~4.15.4", + "apollo-server-express": "1.1.3", + "auto-load": "3.0.0", + "axios": "0.16.2", + "bcryptjs-then": "1.0.1", + "bluebird": "3.5.1", + "body-parser": "1.18.2", + "bull": "3.3.0", + "bunyan": "1.8.12", + "cheerio": "1.0.0-rc.2", + "child-process-promise": "2.2.1", + "chokidar": "1.7.0", + "compression": "1.7.1", + "connect-flash": "0.1.1", + "connect-redis": "3.3.2", + "cookie-parser": "1.4.3", + "diff2html": "2.3.1", + "dotize": "^0.2.0", + "execa": "0.8.0", + "express": "4.16.1", "express-brute": "1.0.1", - "express-brute-mongoose": "~0.0.9", - "express-session": "~1.15.5", - "file-type": "~6.1.0", - "filesize.js": "~1.0.2", - "follow-redirects": "~1.2.4", - "fs-extra": "~4.0.1", - "git-wrapper2-promise": "~0.2.9", - "highlight.js": "~9.12.0", - "i18next": "~9.0.0", - "i18next-express-middleware": "~1.0.5", - "i18next-node-fs-backend": "~1.0.0", - "image-size": "~0.6.0", - "jimp": "~0.2.28", - "js-yaml": "~3.9.1", - "jsonwebtoken": "~7.4.3", - "klaw": "~2.1.0", - "levelup": "~1.3.9", - "lodash": "~4.17.4", - "markdown-it": "~8.4.0", - "markdown-it-abbr": "~1.0.4", - "markdown-it-anchor": "~4.0.0", - "markdown-it-attrs": "~1.1.0", - "markdown-it-emoji": "~1.4.0", - "markdown-it-expand-tabs": "~1.0.12", + "express-brute-redis": "0.0.1", + "express-session": "1.15.6", + "file-type": "6.2.0", + "filesize.js": "1.0.2", + "follow-redirects": "1.2.5", + "fs-extra": "4.0.2", + "git-wrapper2-promise": "0.2.9", + "graphql": "0.10.5", + "graphql-tools": "2.2.1", + "highlight.js": "9.12.0", + "i18next": "9.1.0", + "i18next-express-middleware": "1.0.7", + "i18next-localstorage-cache": "1.1.1", + "i18next-node-fs-backend": "1.0.0", + "image-size": "0.6.1", + "ioredis": "3.1.4", + "jimp": "0.2.28", + "js-yaml": "3.10.0", + "jsonwebtoken": "8.0.1", + "klaw": "2.1.0", + "lodash": "4.17.4", + "markdown-it": "8.4.0", + "markdown-it-abbr": "1.0.4", + "markdown-it-anchor": "4.0.0", + "markdown-it-attrs": "1.2.0", + "markdown-it-emoji": "1.4.0", + "markdown-it-expand-tabs": "1.0.12", "markdown-it-external-links": "0.0.6", - "markdown-it-footnote": "~3.0.1", - "markdown-it-mathjax": "~2.0.0", - "markdown-it-task-lists": "~2.0.1", - "mathjax-node": "~1.2.0", - "memdown": "~1.2.4", - "mime-types": "~2.1.16", - "moment": "~2.18.1", - "moment-timezone": "~0.5.13", - "mongodb": "~2.2.31", - "mongoose": "~4.11.9", - "multer": "~1.3.0", - "node-2fa": "~1.1.2", - "node-graceful": "~0.2.3", - "opencollective": "~1.0.3", - "ora": "~1.3.0", - "passport": "~0.4.0", + "markdown-it-footnote": "3.0.1", + "markdown-it-mathjax": "2.0.0", + "markdown-it-task-lists": "2.0.1", + "mathjax-node": "1.2.1", + "mime-types": "2.1.17", + "moment": "2.18.1", + "moment-timezone": "0.5.13", + "multer": "1.3.0", + "node-2fa": "1.1.2", + "node-graceful": "0.2.3", + "ora": "1.3.0", + "passport": "0.4.0", "passport-azure-ad-oauth2": "0.0.4", - "passport-facebook": "~2.1.1", - "passport-github2": "~0.1.10", - "passport-google-oauth20": "~1.0.0", - "passport-ldapauth": "~2.0.0", - "passport-local": "~1.0.0", + "passport-facebook": "2.1.1", + "passport-github2": "0.1.11", + "passport-google-oauth20": "1.0.0", + "passport-ldapauth": "2.0.0", + "passport-local": "1.0.0", "passport-slack": "0.0.7", - "passport-windowslive": "~1.0.2", - "passport.socketio": "~3.7.0", - "pm2": "~2.6.1", - "pug": "~2.0.0-rc.3", - "read-chunk": "~2.1.0", - "remove-markdown": "~0.2.2", - "request": "~2.81.0", - "search-index-adder": "~0.3.9", - "search-index-searcher": "~0.2.10", - "semver": "~5.4.1", - "serve-favicon": "~2.4.3", - "simplemde": "~1.11.2", - "socket.io": "~2.0.2", - "stopword": "~0.1.6", - "stream-to-promise": "~2.2.0", - "tar": "~4.0.1", - "through2": "~2.0.3", - "validator": "~8.1.0", - "validator-as-promised": "~1.0.2", - "winston": "~2.3.1", - "yargs": "~8.0.1" + "passport-windowslive": "1.0.2", + "pg": "6.4.2", + "pg-hstore": "2.3.2", + "pg-promise": "6.10.3", + "pm2": "2.7.1", + "pug": "2.0.0-rc.4", + "qr-image": "3.2.0", + "read-chunk": "2.1.0", + "remove-markdown": "0.2.2", + "request": "2.83.0", + "semver": "5.4.1", + "sequelize": "4.13.5", + "serve-favicon": "2.4.5", + "simplemde": "1.11.2", + "stream-to-promise": "2.2.0", + "tar": "4.0.1", + "through2": "2.0.3", + "validator": "9.0.0", + "validator-as-promised": "1.0.2", + "winston": "2.4.0", + "yargs": "9.0.1" }, "devDependencies": { - "@glimpse/glimpse": "~0.22.15", - "@panter/vue-i18next": "~0.5.0", - "babel-cli": "~6.26.0", - "babel-jest": "~20.0.3", - "babel-plugin-transform-object-assign": "~6.22.0", - "babel-preset-es2015": "~6.24.1", - "brace": "~0.10.0", - "colors": "~1.1.2", - "consolidate": "~0.14.5", - "eslint": "~4.5.0", - "eslint-config-standard": "~10.2.1", - "eslint-plugin-import": "~2.7.0", - "eslint-plugin-node": "~5.1.0", - "eslint-plugin-promise": "~3.5.0", - "eslint-plugin-standard": "~3.0.1", - "fuse-box": "~2.2.2", - "i18next-xhr-backend": "~1.4.2", - "jest": "~20.0.4", - "jest-junit": "~3.1.0", - "jquery": "~3.2.1", - "jquery-contextmenu": "~2.5.0", - "jquery-simple-upload": "~1.0.0", - "jquery-smooth-scroll": "~2.2.0", - "jquery-sticky": "~1.0.4", - "lodash-cli": "~4.17.4", - "lodash-es": "~4.17.4", - "node-sass": "~4.5.3", - "nodemon": "~1.11.0", - "pug-lint": "~2.4.0", - "twemoji-awesome": "~1.0.6", - "typescript": "~2.5.2", - "uglify-es": "~3.0.28", - "vee-validate": "~2.0.0-rc.14", - "vue": "~2.4.2", - "vue-clipboards": "~1.1.0", - "vue-lodash": "~1.0.3", - "vue-resource": "~1.3.4", - "vue-template-compiler": "~2.4.2", - "vue-template-es2015-compiler": "~1.5.3", - "vuex": "~2.4.0" + "@glimpse/glimpse": "0.22.15", + "@panter/vue-i18next": "0.6.1", + "apollo-client": "^1.9.3", + "autoprefixer": "7.1.5", + "babel-cli": "6.26.0", + "babel-core": "6.26.0", + "babel-jest": "21.2.0", + "babel-preset-env": "1.6.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-2": "6.24.1", + "brace": "0.10.0", + "colors": "1.1.2", + "consolidate": "0.14.5", + "eslint": "4.8.0", + "eslint-config-requarks": "1.0.7", + "eslint-config-standard": "10.2.1", + "eslint-plugin-import": "2.7.0", + "eslint-plugin-node": "5.2.0", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-standard": "3.0.1", + "fuse-box": "2.3.3", + "graphql-tag": "^2.4.2", + "i18next-xhr-backend": "1.4.3", + "jest": "21.2.1", + "jquery": "3.2.1", + "jquery-contextmenu": "2.6.2", + "jquery-simple-upload": "1.0.0", + "js-cookie": "2.1.4", + "node-sass": "4.5.3", + "nodemon": "1.12.1", + "postcss-selector-parser": "2.2.3", + "pug-lint": "2.5.0", + "twemoji-awesome": "1.0.6", + "typescript": "2.5.3", + "uglify-es": "3.1.3", + "vee-validate": "2.0.0-rc.18", + "vue": "2.4.4", + "vue-clipboards": "1.1.0", + "vue-hot-reload-api": "2.1.1", + "vue-lodash": "1.0.4", + "vue-material": "^0.7.5", + "vue-resource": "1.3.4", + "vue-simple-breakpoints": "1.0.2", + "vue-template-compiler": "2.4.4", + "vue-template-es2015-compiler": "1.5.3", + "vuex": "2.4.1", + "vuex-persistedstate": "2.0.0" }, "jest": { "testResultsProcessor": "./node_modules/jest-junit", diff --git a/server/agent.js b/server/agent.js deleted file mode 100644 index 38efd466..00000000 --- a/server/agent.js +++ /dev/null @@ -1,222 +0,0 @@ -// =========================================== -// Wiki.js - Background Agent -// 1.0.0 -// Licensed under AGPLv3 -// =========================================== - -const path = require('path') -const ROOTPATH = process.cwd() -const SERVERPATH = path.join(ROOTPATH, 'server') - -global.ROOTPATH = ROOTPATH -global.SERVERPATH = SERVERPATH -const IS_DEBUG = process.env.NODE_ENV === 'development' - -let appconf = require('./libs/config')() -global.appconfig = appconf.config -global.appdata = appconf.data - -// ---------------------------------------- -// Load Winston -// ---------------------------------------- - -global.winston = require('./libs/logger')(IS_DEBUG, 'AGENT') - -// ---------------------------------------- -// Load global modules -// ---------------------------------------- - -global.winston.info('Background Agent is initializing...') - -global.db = require('./libs/db').init() -global.upl = require('./libs/uploads-agent').init() -global.git = require('./libs/git').init() -global.entries = require('./libs/entries').init() -global.lang = require('i18next') -global.mark = require('./libs/markdown') - -// ---------------------------------------- -// Load modules -// ---------------------------------------- - -const moment = require('moment') -const Promise = require('bluebird') -const fs = Promise.promisifyAll(require('fs-extra')) -const klaw = require('klaw') -const Cron = require('cron').CronJob -const i18nBackend = require('i18next-node-fs-backend') - -const entryHelper = require('./helpers/entry') - -// ---------------------------------------- -// Localization Engine -// ---------------------------------------- - -global.lang - .use(i18nBackend) - .init({ - load: 'languageOnly', - ns: ['common', 'admin', 'auth', 'errors', 'git'], - defaultNS: 'common', - saveMissing: false, - preload: [appconfig.lang], - lng: appconfig.lang, - fallbackLng: 'en', - backend: { - loadPath: path.join(SERVERPATH, 'locales/{{lng}}/{{ns}}.json') - } - }) - -// ---------------------------------------- -// Start Cron -// ---------------------------------------- - -let job -let jobIsBusy = false -let jobUplWatchStarted = false - -global.db.onReady.then(() => { - return global.db.Entry.remove({}) -}).then(() => { - job = new Cron({ - cronTime: '0 */5 * * * *', - onTick: () => { - // Make sure we don't start two concurrent jobs - - if (jobIsBusy) { - global.winston.warn('Previous job has not completed gracefully or is still running! Skipping for now. (This is not normal, you should investigate)') - return - } - global.winston.info('Running all jobs...') - jobIsBusy = true - - // Prepare async job collector - - let jobs = [] - let repoPath = path.resolve(ROOTPATH, appconfig.paths.repo) - let dataPath = path.resolve(ROOTPATH, appconfig.paths.data) - let uploadsTempPath = path.join(dataPath, 'temp-upload') - - // ---------------------------------------- - // REGULAR JOBS - // ---------------------------------------- - - //* **************************************** - // -> Sync with Git remote - //* **************************************** - - jobs.push(global.git.resync().then(() => { - // -> Stream all documents - - let cacheJobs = [] - let jobCbStreamDocsResolve = null - let jobCbStreamDocs = new Promise((resolve, reject) => { - jobCbStreamDocsResolve = resolve - }) - - klaw(repoPath).on('data', function (item) { - if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') { - let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path)) - let cachePath = entryHelper.getCachePath(entryPath) - - // -> Purge outdated cache - - cacheJobs.push( - fs.statAsync(cachePath).then((st) => { - return moment(st.mtime).isBefore(item.stats.mtime) ? 'expired' : 'active' - }).catch((err) => { - return (err.code !== 'EEXIST') ? err : 'new' - }).then((fileStatus) => { - // -> Delete expired cache file - - if (fileStatus === 'expired') { - return fs.unlinkAsync(cachePath).return(fileStatus) - } - - return fileStatus - }).then((fileStatus) => { - // -> Update cache and search index - - if (fileStatus !== 'active') { - return global.entries.updateCache(entryPath).then(entry => { - process.send({ - action: 'searchAdd', - content: entry - }) - return true - }) - } - - return true - }) - ) - } - }).on('end', () => { - jobCbStreamDocsResolve(Promise.all(cacheJobs)) - }) - - return jobCbStreamDocs - })) - - //* **************************************** - // -> Clear failed temporary upload files - //* **************************************** - - jobs.push( - fs.readdirAsync(uploadsTempPath).then((ls) => { - let fifteenAgo = moment().subtract(15, 'minutes') - - return Promise.map(ls, (f) => { - return fs.statAsync(path.join(uploadsTempPath, f)).then((s) => { return { filename: f, stat: s } }) - }).filter((s) => { return s.stat.isFile() }).then((arrFiles) => { - return Promise.map(arrFiles, (f) => { - if (moment(f.stat.ctime).isBefore(fifteenAgo, 'minute')) { - return fs.unlinkAsync(path.join(uploadsTempPath, f.filename)) - } else { - return true - } - }) - }) - }) - ) - - // ---------------------------------------- - // Run - // ---------------------------------------- - - Promise.all(jobs).then(() => { - global.winston.info('All jobs completed successfully! Going to sleep for now.') - - if (!jobUplWatchStarted) { - jobUplWatchStarted = true - global.upl.initialScan().then(() => { - job.start() - }) - } - - return true - }).catch((err) => { - global.winston.error('One or more jobs have failed: ', err) - }).finally(() => { - jobIsBusy = false - }) - }, - start: false, - timeZone: 'UTC', - runOnInit: true - }) -}) - -// ---------------------------------------- -// Shutdown gracefully -// ---------------------------------------- - -process.on('disconnect', () => { - global.winston.warn('Lost connection to main server. Exiting...') - job.stop() - process.exit() -}) - -process.on('exit', () => { - job.stop() -}) diff --git a/server/app/data.yml b/server/app/data.yml index 17c1e685..129dc9b9 100644 --- a/server/app/data.yml +++ b/server/app/data.yml @@ -5,67 +5,49 @@ name: Wiki.js defaults: config: - title: Wiki - host: http://localhost port: 80 paths: repo: ./repo data: ./data - uploads: - maxImageFileSize: 3, - maxOtherFileSize: 100 - lang: en - langRtl: false - public: false - auth: - defaultReadAccess: false - local: - enabled: true - microsoft: - enabled: false - google: - enabled: false - facebook: - enabled: false - github: - enabled: false - slack: - enabled: false - ldap: - enabled: false - azure: - enabled: false - db: mongodb://localhost/wiki - sessionSecret: null - admin: null - git: - url: null - branch: master - auth: - type: basic - username: null - password: null - privateKey: null - sslVerify: true - serverEmail: wiki@example.com - showUserEmail: true - features: - linebreaks: true - mathjax: true - externalLogging: - bugsnap: false - loggly: false - papertrail: false - rollbar: false - sentry: false - theme: - primary: indigo - alt: blue-grey - footer: blue-grey - viewSource: false - code: - dark: true - colorize: true + db: + host: localhost + port: 5432 + user: wikijs + pass: wikijsrocks + db: wiki + redis: + host: localhost + port: 6379 + db: 0 + password: null + workers: 0 + ha: + nodeuid: primary + readonly: false + site: + path: '' + lang: en + title: Wiki.js +configNamespaces: + - auth + - features + - git + - logging + - site + - theme + - uploads +queues: + - gitSync + - uplClearTemp +authProviders: + - local + - microsoft + - google + - facebook + - github + - slack + - ldap + - azure colors: - red - pink @@ -108,6 +90,12 @@ langs: - id: ko name: Korean - 한국어 + - + id: fa + name: Persian (Fārsi) - فارسی + - + id: pt + name: Portuguese - Português - id: ru name: Russian - Русский diff --git a/server/authentication/azure.js b/server/authentication/azure.js new file mode 100644 index 00000000..70e23cc4 --- /dev/null +++ b/server/authentication/azure.js @@ -0,0 +1,37 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Azure AD Account +// ------------------------------------ + +const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy + +module.exports = { + key: 'azure', + title: 'Azure Active Directory', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL', 'resource', 'tenant'], + init (passport, conf) { + const jwt = require('jsonwebtoken') + passport.use('azure_ad_oauth2', + new AzureAdOAuth2Strategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL, + resource: conf.resource, + tenant: conf.tenant + }, (accessToken, refreshToken, params, profile, cb) => { + let waadProfile = jwt.decode(params.id_token) + waadProfile.id = waadProfile.oid + waadProfile.provider = 'azure' + wiki.db.User.processProfile(waadProfile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/facebook.js b/server/authentication/facebook.js new file mode 100644 index 00000000..24b31416 --- /dev/null +++ b/server/authentication/facebook.js @@ -0,0 +1,32 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Facebook Account +// ------------------------------------ + +const FacebookStrategy = require('passport-facebook').Strategy + +module.exports = { + key: 'facebook', + title: 'Facebook', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL'], + init (passport, conf) { + passport.use('facebook', + new FacebookStrategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL, + profileFields: ['id', 'displayName', 'email'] + }, function (accessToken, refreshToken, profile, cb) { + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/github.js b/server/authentication/github.js new file mode 100644 index 00000000..2dbca0c4 --- /dev/null +++ b/server/authentication/github.js @@ -0,0 +1,32 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// GitHub Account +// ------------------------------------ + +const GitHubStrategy = require('passport-github2').Strategy + +module.exports = { + key: 'github', + title: 'GitHub', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL'], + init (passport, conf) { + passport.use('github', + new GitHubStrategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL, + scope: ['user:email'] + }, (accessToken, refreshToken, profile, cb) => { + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/google.js b/server/authentication/google.js new file mode 100644 index 00000000..d353e6c4 --- /dev/null +++ b/server/authentication/google.js @@ -0,0 +1,31 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Google ID Account +// ------------------------------------ + +const GoogleStrategy = require('passport-google-oauth20').Strategy + +module.exports = { + key: 'google', + title: 'Google ID', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL'], + init (passport, conf) { + passport.use('google', + new GoogleStrategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL + }, (accessToken, refreshToken, profile, cb) => { + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/ldap.js b/server/authentication/ldap.js new file mode 100644 index 00000000..720b5f4b --- /dev/null +++ b/server/authentication/ldap.js @@ -0,0 +1,46 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// LDAP Account +// ------------------------------------ + +const LdapStrategy = require('passport-ldapauth').Strategy +const fs = require('fs') + +module.exports = { + key: 'ldap', + title: 'LDAP / Active Directory', + useForm: true, + props: ['url', 'bindDn', 'bindCredentials', 'searchBase', 'searchFilter', 'tlsEnabled', 'tlsCertPath'], + init (passport, conf) { + passport.use('ldapauth', + new LdapStrategy({ + server: { + url: conf.url, + bindDn: conf.bindDn, + bindCredentials: conf.bindCredentials, + searchBase: conf.searchBase, + searchFilter: conf.searchFilter, + searchAttributes: ['displayName', 'name', 'cn', 'mail'], + tlsOptions: (conf.tlsEnabled) ? { + ca: [ + fs.readFileSync(conf.tlsCertPath) + ] + } : {} + }, + usernameField: 'email', + passReqToCallback: false + }, (profile, cb) => { + profile.provider = 'ldap' + profile.id = profile.dn + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/local.js b/server/authentication/local.js new file mode 100644 index 00000000..e2ca7faa --- /dev/null +++ b/server/authentication/local.js @@ -0,0 +1,38 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Local Account +// ------------------------------------ + +const LocalStrategy = require('passport-local').Strategy + +module.exports = { + key: 'local', + title: 'Local', + useForm: true, + props: [], + init (passport, conf) { + passport.use('local', + new LocalStrategy({ + usernameField: 'email', + passwordField: 'password' + }, (uEmail, uPassword, done) => { + wiki.db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => { + if (user) { + return user.validatePassword(uPassword).then(() => { + return done(null, user) || true + }).catch((err) => { + return done(err, null) + }) + } else { + return done(new Error('INVALID_LOGIN'), null) + } + }).catch((err) => { + done(err, null) + }) + } + )) + } +} diff --git a/server/authentication/microsoft.js b/server/authentication/microsoft.js new file mode 100644 index 00000000..b761aa41 --- /dev/null +++ b/server/authentication/microsoft.js @@ -0,0 +1,31 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Microsoft Account +// ------------------------------------ + +const WindowsLiveStrategy = require('passport-windowslive').Strategy + +module.exports = { + key: 'microsoft', + title: 'Microsoft Account', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL'], + init (passport, conf) { + passport.use('microsoft', + new WindowsLiveStrategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL + }, function (accessToken, refreshToken, profile, cb) { + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/authentication/slack.js b/server/authentication/slack.js new file mode 100644 index 00000000..e4aa6d5f --- /dev/null +++ b/server/authentication/slack.js @@ -0,0 +1,31 @@ +'use strict' + +/* global wiki */ + +// ------------------------------------ +// Slack Account +// ------------------------------------ + +const SlackStrategy = require('passport-slack').Strategy + +module.exports = { + key: 'slack', + title: 'Slack', + useForm: false, + props: ['clientId', 'clientSecret', 'callbackURL'], + init (passport, conf) { + passport.use('slack', + new SlackStrategy({ + clientID: conf.clientId, + clientSecret: conf.clientSecret, + callbackURL: conf.callbackURL + }, (accessToken, refreshToken, profile, cb) => { + wiki.db.User.processProfile(profile).then((user) => { + return cb(null, user) || true + }).catch((err) => { + return cb(err, null) || true + }) + } + )) + } +} diff --git a/server/configure.js b/server/configure.js index 0766d695..78c00c3c 100644 --- a/server/configure.js +++ b/server/configure.js @@ -1,11 +1,12 @@ -'use strict' +const path = require('path') -module.exports = (port, spinner) => { - const path = require('path') +/* global wiki */ - const ROOTPATH = process.cwd() - const SERVERPATH = path.join(ROOTPATH, 'server') - const IS_DEBUG = process.env.NODE_ENV === 'development' +module.exports = () => { + wiki.config.site = { + path: '', + title: 'Wiki.js' + } // ---------------------------------------- // Load modules @@ -26,28 +27,30 @@ module.exports = (port, spinner) => { // Define Express App // ---------------------------------------- - var app = express() + let app = express() app.use(compression()) - var server + let server // ---------------------------------------- // Public Assets // ---------------------------------------- - app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico'))) - app.use(express.static(path.join(ROOTPATH, 'assets'))) + app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) + app.use(express.static(path.join(wiki.ROOTPATH, 'assets'))) // ---------------------------------------- // View Engine Setup // ---------------------------------------- - app.set('views', path.join(SERVERPATH, 'views')) + app.set('views', path.join(wiki.SERVERPATH, 'views')) app.set('view engine', 'pug') app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) + app.locals.config = wiki.config + app.locals.data = wiki.data app.locals._ = require('lodash') // ---------------------------------------- @@ -55,21 +58,8 @@ module.exports = (port, spinner) => { // ---------------------------------------- app.get('*', (req, res) => { - let langs = [] - let conf = {} - try { - langs = yaml.safeLoad(fs.readFileSync(path.join(SERVERPATH, 'app/data.yml'), 'utf8')).langs - conf = yaml.safeLoad(fs.readFileSync(path.join(ROOTPATH, 'config.yml'), 'utf8')) - } catch (err) { - console.error(err) - } - res.render('configure/index', { - langs, - conf, - runmode: { - staticPort: (process.env.WIKI_JS_HEROKU || process.env.WIKI_JS_DOCKER), - staticMongo: (!_.isNil(process.env.WIKI_JS_HEROKU)) - } + fs.readJsonAsync(path.join(wiki.ROOTPATH, 'package.json')).then(packageObj => { + res.render('configure/index', { packageObj }) }) }) @@ -80,15 +70,15 @@ module.exports = (port, spinner) => { Promise.mapSeries([ () => { const semver = require('semver') - if (!semver.satisfies(semver.clean(process.version), '>=6.9.0')) { - throw new Error('Node.js version is too old. Minimum is v6.6.0.') + if (!semver.satisfies(semver.clean(process.version), '>=6.11.1')) { + throw new Error('Node.js version is too old. Minimum is 6.11.1.') } - return 'Node.js ' + process.version + ' detected. Minimum is v6.9.0.' + return 'Node.js ' + process.version + ' detected. Minimum is 6.11.1.' }, () => { return Promise.try(() => { require('crypto') - }).catch(err => { // eslint-disable-line handle-callback-err + }).catch(err => { throw new Error('Crypto Node.js module is not available.') }).return('Node.js Crypto module is available.') }, @@ -102,24 +92,24 @@ module.exports = (port, spinner) => { } 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 v2.7.4.')) + reject(new Error('Git version is too old. Minimum is 2.7.4.')) } - resolve('Git v' + gitver + ' detected. Minimum is v2.7.4.') + resolve('Git ' + gitver + ' detected. 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.') + if (os.totalmem() < 1000 * 1000 * 512) { + throw new Error('Not enough memory. Minimum is 512 MB.') } - return _.round(os.totalmem() / (1024 * 1024)) + ' MB of system memory available. Minimum is 768 MB.' + return _.round(os.totalmem() / (1024 * 1024)) + ' MB of system memory available. Minimum is 512 MB.' }, () => { let fs = require('fs') return Promise.try(() => { - fs.accessSync(path.join(ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK) - }).catch(err => { // eslint-disable-line handle-callback-err + 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('config.yml is writable by the setup process.') } @@ -130,43 +120,6 @@ module.exports = (port, spinner) => { }) }) - /** - * Check the DB connection - */ - app.post('/dbcheck', (req, res) => { - let mongo = require('mongodb').MongoClient - let mongoURI = cfgHelper.parseConfigValue(req.body.db) - mongo.connect(mongoURI, { - autoReconnect: false, - reconnectTries: 2, - reconnectInterval: 1000, - connectTimeoutMS: 5000, - socketTimeoutMS: 5000 - }, (err, db) => { - if (err === null) { - // Try to create a test collection - db.createCollection('test', (err, results) => { - if (err === null) { - // Try to drop test collection - db.dropCollection('test', (err, results) => { - if (err === null) { - res.json({ ok: true }) - } else { - res.json({ ok: false, error: 'Unable to delete test collection. Verify permissions. ' + err.message }) - } - db.close() - }) - } else { - res.json({ ok: false, error: 'Unable to create test collection. Verify permissions. ' + err.message }) - db.close() - } - }) - } else { - res.json({ ok: false, error: err.message }) - } - }) - }) - /** * Check the Git connection */ @@ -174,8 +127,8 @@ module.exports = (port, spinner) => { const exec = require('execa') const url = require('url') - const dataDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) - const gitDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) + const dataDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) + const gitDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) let gitRemoteUrl = '' @@ -315,7 +268,7 @@ module.exports = (port, spinner) => { } }) }), - fs.readFileAsync(path.join(ROOTPATH, 'config.yml'), 'utf8').then(confRaw => { + fs.readFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), 'utf8').then(confRaw => { let conf = yaml.safeLoad(confRaw) conf.title = req.body.title conf.host = req.body.host @@ -356,12 +309,12 @@ module.exports = (port, spinner) => { return crypto.randomBytesAsync(32).then(buf => { conf.sessionSecret = buf.toString('hex') confRaw = yaml.safeDump(conf) - return fs.writeFileAsync(path.join(ROOTPATH, 'config.yml'), confRaw) + return fs.writeFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), confRaw) }) }) ).then(() => { if (process.env.IS_HEROKU) { - return fs.outputJsonAsync(path.join(SERVERPATH, 'app/heroku.json'), { configured: true }) + return fs.outputJsonAsync(path.join(wiki.SERVERPATH, 'app/heroku.json'), { configured: true }) } else { return true } @@ -377,7 +330,7 @@ module.exports = (port, spinner) => { */ app.post('/restart', (req, res) => { res.status(204).end() - server.destroy(() => { + /* server.destroy(() => { spinner.text = 'Setup wizard terminated. Restarting in normal mode...' _.delay(() => { const exec = require('execa') @@ -386,7 +339,7 @@ module.exports = (port, spinner) => { process.exit(0) }) }, 1000) - }) + }) */ }) // ---------------------------------------- @@ -403,21 +356,20 @@ module.exports = (port, spinner) => { res.status(err.status || 500) res.send({ message: err.message, - error: IS_DEBUG ? err : {} + error: wiki.IS_DEBUG ? err : {} }) - spinner.fail(err.message) - process.exit(1) + wiki.logger.error(err.message) }) // ---------------------------------------- // Start HTTP server // ---------------------------------------- - spinner.text = 'Starting HTTP server...' + wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`) - app.set('port', port) + app.set('port', wiki.config.port) server = http.createServer(app) - server.listen(port) + server.listen(wiki.config.port) var openConnections = [] @@ -443,10 +395,10 @@ module.exports = (port, spinner) => { switch (error.code) { case 'EACCES': - spinner.fail('Listening on port ' + port + ' requires elevated privileges!') + wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!') return process.exit(1) case 'EADDRINUSE': - spinner.fail('Port ' + port + ' is already in use!') + wiki.logger.error('Port ' + wiki.config.port + ' is already in use!') return process.exit(1) default: throw error @@ -454,6 +406,6 @@ module.exports = (port, spinner) => { }) server.on('listening', () => { - spinner.text = 'Browse to http://localhost:' + port + ' to configure Wiki.js!' + wiki.logger.info('HTTP Server: RUNNING') }) } diff --git a/server/controllers/admin.js b/server/controllers/admin.js index bc7554e0..962c6161 100644 --- a/server/controllers/admin.js +++ b/server/controllers/admin.js @@ -1,6 +1,6 @@ 'use strict' -/* global db, lang, rights, winston */ +/* global wiki */ var express = require('express') var router = express.Router() @@ -33,14 +33,14 @@ router.post('/profile', (req, res) => { return res.render('error-forbidden') } - return db.User.findById(req.user.id).then((usr) => { + return wiki.db.User.findById(req.user.id).then((usr) => { usr.name = _.trim(req.body.name) if (usr.provider === 'local' && req.body.password !== '********') { let nPwd = _.trim(req.body.password) if (nPwd.length < 6) { return Promise.reject(new Error('New Password too short!')) } else { - return db.User.hashPassword(nPwd).then((pwd) => { + return wiki.db.User.hashPassword(nPwd).then((pwd) => { usr.password = pwd return usr.save() }) @@ -61,9 +61,9 @@ router.get('/stats', (req, res) => { } Promise.all([ - db.Entry.count(), - db.UplFile.count(), - db.User.count() + wiki.db.Entry.count(), + wiki.db.UplFile.count(), + wiki.db.User.count() ]).spread((totalEntries, totalUploads, totalUsers) => { return res.render('pages/admin/stats', { totalEntries, totalUploads, totalUsers, adminTab: 'stats' @@ -78,7 +78,7 @@ router.get('/users', (req, res) => { return res.render('error-forbidden') } - db.User.find({}) + wiki.db.User.find({}) .select('-password -rights') .sort('name email') .exec().then((usrs) => { @@ -95,7 +95,7 @@ router.get('/users/:id', (req, res) => { return res.render('error-forbidden') } - db.User.findById(req.params.id) + wiki.db.User.findById(req.params.id) .select('-password -providerId') .exec().then((usr) => { let usrOpts = { @@ -137,12 +137,12 @@ router.post('/users/create', (req, res) => { return res.status(400).json({ msg: 'Name is missing' }) } - db.User.findOne({ email: nUsr.email, provider: nUsr.provider }).then(exUsr => { + wiki.db.User.findOne({ email: nUsr.email, provider: nUsr.provider }).then(exUsr => { if (exUsr) { return res.status(400).json({ msg: 'User already exists!' }) || true } - let pwdGen = (nUsr.provider === 'local') ? db.User.hashPassword(nUsr.password) : Promise.resolve(true) + let pwdGen = (nUsr.provider === 'local') ? wiki.db.User.hashPassword(nUsr.password) : Promise.resolve(true) return pwdGen.then(nPwd => { if (nUsr.provider !== 'local') { nUsr.password = '' @@ -158,37 +158,37 @@ router.post('/users/create', (req, res) => { deny: false }] - return db.User.create(nUsr).then(() => { + return wiki.db.User.create(nUsr).then(() => { return res.json({ ok: true }) }) }).catch(err => { - winston.warn(err) + wiki.logger.warn(err) return res.status(500).json({ msg: err }) }) }).catch(err => { - winston.warn(err) + wiki.logger.warn(err) return res.status(500).json({ msg: err }) }) }) router.post('/users/:id', (req, res) => { if (!res.locals.rights.manage) { - return res.status(401).json({ msg: lang.t('errors:unauthorized') }) + return res.status(401).json({ msg: wiki.lang.t('errors:unauthorized') }) } if (!validator.isMongoId(req.params.id)) { - return res.status(400).json({ msg: lang.t('errors:invaliduserid') }) + return res.status(400).json({ msg: wiki.lang.t('errors:invaliduserid') }) } - return db.User.findById(req.params.id).then((usr) => { + return wiki.db.User.findById(req.params.id).then((usr) => { usr.name = _.trim(req.body.name) usr.rights = JSON.parse(req.body.rights) if (usr.provider === 'local' && req.body.password !== '********') { let nPwd = _.trim(req.body.password) if (nPwd.length < 6) { - return Promise.reject(new Error(lang.t('errors:newpasswordtooshort'))) + return Promise.reject(new Error(wiki.lang.t('errors:newpasswordtooshort'))) } else { - return db.User.hashPassword(nPwd).then((pwd) => { + return wiki.db.User.hashPassword(nPwd).then((pwd) => { usr.password = pwd return usr.save() }) @@ -199,7 +199,7 @@ router.post('/users/:id', (req, res) => { }).then((usr) => { // Update guest rights for future requests if (usr.provider === 'local' && usr.email === 'guest') { - rights.guest = usr + wiki.rights.guest = usr } return usr }).then(() => { @@ -214,14 +214,14 @@ router.post('/users/:id', (req, res) => { */ router.delete('/users/:id', (req, res) => { if (!res.locals.rights.manage) { - return res.status(401).json({ msg: lang.t('errors:unauthorized') }) + return res.status(401).json({ msg: wiki.lang.t('errors:unauthorized') }) } if (!validator.isMongoId(req.params.id)) { - return res.status(400).json({ msg: lang.t('errors:invaliduserid') }) + return res.status(400).json({ msg: wiki.lang.t('errors:invaliduserid') }) } - return db.User.findByIdAndRemove(req.params.id).then(() => { + return wiki.db.User.findByIdAndRemove(req.params.id).then(() => { return res.json({ ok: true }) }).catch((err) => { res.status(500).json({ ok: false, msg: err.message }) @@ -249,7 +249,7 @@ router.get('/system', (req, res) => { cwd: process.cwd() } - fs.readJsonAsync(path.join(ROOTPATH, 'package.json')).then(packageObj => { + fs.readJsonAsync(path.join(wiki.ROOTPATH, 'package.json')).then(packageObj => { axios.get('https://api.github.com/repos/Requarks/wiki/releases/latest').then(resp => { let sysversion = { current: 'v' + packageObj.version, @@ -259,7 +259,7 @@ router.get('/system', (req, res) => { res.render('pages/admin/system', { adminTab: 'system', hostInfo, sysversion }) }).catch(err => { - winston.warn(err) + wiki.logger.warn(err) res.render('pages/admin/system', { adminTab: 'system', hostInfo, sysversion: { current: 'v' + packageObj.version } }) }) }) @@ -287,19 +287,19 @@ router.post('/theme', (req, res) => { return res.render('error-forbidden') } - if (!validator.isIn(req.body.primary, appdata.colors)) { + if (!validator.isIn(req.body.primary, wiki.data.colors)) { return res.status(406).json({ msg: 'Primary color is invalid.' }) - } else if (!validator.isIn(req.body.alt, appdata.colors)) { + } else if (!validator.isIn(req.body.alt, wiki.data.colors)) { return res.status(406).json({ msg: 'Alternate color is invalid.' }) - } else if (!validator.isIn(req.body.footer, appdata.colors)) { + } else if (!validator.isIn(req.body.footer, wiki.data.colors)) { return res.status(406).json({ msg: 'Footer color is invalid.' }) } - appconfig.theme.primary = req.body.primary - appconfig.theme.alt = req.body.alt - appconfig.theme.footer = req.body.footer - appconfig.theme.code.dark = req.body.codedark === 'true' - appconfig.theme.code.colorize = req.body.codecolorize === 'true' + wiki.config.theme.primary = req.body.primary + wiki.config.theme.alt = req.body.alt + wiki.config.theme.footer = req.body.footer + wiki.config.theme.code.dark = req.body.codedark === 'true' + wiki.config.theme.code.colorize = req.body.codecolorize === 'true' return res.json({ msg: 'OK' }) }) diff --git a/server/controllers/auth.js b/server/controllers/auth.js index b513470e..9188102a 100644 --- a/server/controllers/auth.js +++ b/server/controllers/auth.js @@ -1,19 +1,19 @@ -'use strict' - -/* global db, lang */ +/* global wiki */ const Promise = require('bluebird') const express = require('express') const router = express.Router() -const passport = require('passport') const ExpressBrute = require('express-brute') -const ExpressBruteMongooseStore = require('express-brute-mongoose') +const ExpressBruteRedisStore = require('express-brute-redis') const moment = require('moment') +const _ = require('lodash') /** * Setup Express-Brute */ -const EBstore = new ExpressBruteMongooseStore(db.Bruteforce) +const EBstore = new ExpressBruteRedisStore({ + client: wiki.redis +}) const bruteforce = new ExpressBrute(EBstore, { freeRetries: 5, minWait: 60 * 1000, @@ -22,8 +22,8 @@ const bruteforce = new ExpressBrute(EBstore, { failCallback (req, res, next, nextValidRequestDate) { req.flash('alert', { class: 'error', - title: lang.t('auth:errors.toomanyattempts'), - message: lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }), + title: wiki.lang.t('auth:errors.toomanyattempts'), + message: wiki.lang.t('auth:errors.toomanyattemptsmsg', { time: moment(nextValidRequestDate).fromNow() }), iconClass: 'fa-times' }) res.redirect('/login') @@ -35,23 +35,24 @@ const bruteforce = new ExpressBrute(EBstore, { */ router.get('/login', function (req, res, next) { res.render('auth/login', { - usr: res.locals.usr + authStrategies: _.reject(wiki.auth.strategies, { key: 'local' }), + hasMultipleStrategies: Object.keys(wiki.config.auth.strategies).length > 1 }) }) router.post('/login', bruteforce.prevent, function (req, res, next) { new Promise((resolve, reject) => { // [1] LOCAL AUTHENTICATION - passport.authenticate('local', function (err, user, info) { + wiki.auth.passport.authenticate('local', function (err, user, info) { if (err) { return reject(err) } if (!user) { return reject(new Error('INVALID_LOGIN')) } resolve(user) })(req, res, next) }).catch({ message: 'INVALID_LOGIN' }, err => { - if (appconfig.auth.ldap && appconfig.auth.ldap.enabled) { + if (_.has(wiki.config.auth.strategy, 'ldap')) { // [2] LDAP AUTHENTICATION return new Promise((resolve, reject) => { - passport.authenticate('ldapauth', function (err, user, info) { + wiki.auth.passport.authenticate('ldapauth', function (err, user, info) { if (err) { return reject(err) } if (info && info.message) { return reject(new Error(info.message)) } if (!user) { return reject(new Error('INVALID_LOGIN')) } @@ -73,13 +74,13 @@ router.post('/login', bruteforce.prevent, function (req, res, next) { // LOGIN FAIL if (err.message === 'INVALID_LOGIN') { req.flash('alert', { - title: lang.t('auth:errors.invalidlogin'), - message: lang.t('auth:errors.invalidloginmsg') + title: wiki.lang.t('auth:errors.invalidlogin'), + message: wiki.lang.t('auth:errors.invalidloginmsg') }) return res.redirect('/login') } else { req.flash('alert', { - title: lang.t('auth:errors.loginerror'), + title: wiki.lang.t('auth:errors.loginerror'), message: err.message }) return res.redirect('/login') @@ -91,19 +92,19 @@ router.post('/login', bruteforce.prevent, function (req, res, next) { * Social Login */ -router.get('/login/ms', passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] })) -router.get('/login/google', passport.authenticate('google', { scope: ['profile', 'email'] })) -router.get('/login/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email'] })) -router.get('/login/github', passport.authenticate('github', { scope: ['user:email'] })) -router.get('/login/slack', passport.authenticate('slack', { scope: ['identity.basic', 'identity.email'] })) -router.get('/login/azure', passport.authenticate('azure_ad_oauth2')) +router.get('/login/ms', wiki.auth.passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] })) +router.get('/login/google', wiki.auth.passport.authenticate('google', { scope: ['profile', 'email'] })) +router.get('/login/facebook', wiki.auth.passport.authenticate('facebook', { scope: ['public_profile', 'email'] })) +router.get('/login/github', wiki.auth.passport.authenticate('github', { scope: ['user:email'] })) +router.get('/login/slack', wiki.auth.passport.authenticate('slack', { scope: ['identity.basic', 'identity.email'] })) +router.get('/login/azure', wiki.auth.passport.authenticate('azure_ad_oauth2')) -router.get('/login/ms/callback', passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/google/callback', passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/github/callback', passport.authenticate('github', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/slack/callback', passport.authenticate('slack', { failureRedirect: '/login', successRedirect: '/' })) -router.get('/login/azure/callback', passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/ms/callback', wiki.auth.passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/google/callback', wiki.auth.passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/facebook/callback', wiki.auth.passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/github/callback', wiki.auth.passport.authenticate('github', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/slack/callback', wiki.auth.passport.authenticate('slack', { failureRedirect: '/login', successRedirect: '/' })) +router.get('/login/azure/callback', wiki.auth.passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' })) /** * Logout diff --git a/server/controllers/uploads.js b/server/controllers/uploads.js index a2a3f2f2..40b19e68 100644 --- a/server/controllers/uploads.js +++ b/server/controllers/uploads.js @@ -1,6 +1,9 @@ 'use strict' -/* global git, lang, lcdata, upl */ +/* global wiki */ + +module.exports = false +return const express = require('express') const router = express.Router() @@ -12,7 +15,7 @@ const fs = Promise.promisifyAll(require('fs-extra')) const path = require('path') const _ = require('lodash') -const validPathRe = new RegExp('^([a-z0-9/-' + appdata.regex.cjk + appdata.regex.arabic + ']+\\.[a-z0-9]+)$') +const validPathRe = new RegExp('^([a-z0-9/-' + wiki.data.regex.cjk + wiki.data.regex.arabic + ']+\\.[a-z0-9]+)$') const validPathThumbsRe = new RegExp('^([a-z0-9]+\\.png)$') // ========================================== @@ -28,7 +31,7 @@ router.get('/t/*', (req, res, next) => { // todo: Authentication-based access res.sendFile(fileName, { - root: lcdata.getThumbsPath(), + root: wiki.disk.getThumbsPath(), dotfiles: 'deny' }, (err) => { if (err) { @@ -37,12 +40,12 @@ router.get('/t/*', (req, res, next) => { }) }) -router.post('/img', lcdata.uploadImgHandler, (req, res, next) => { +router.post('/img', wiki.disk.uploadImgHandler, (req, res, next) => { let destFolder = _.chain(req.body.folder).trim().toLower().value() - upl.validateUploadsFolder(destFolder).then((destFolderPath) => { + wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => { if (!destFolderPath) { - res.json({ ok: false, msg: lang.t('errors:invalidfolder') }) + res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') }) return true } @@ -50,7 +53,7 @@ router.post('/img', lcdata.uploadImgHandler, (req, res, next) => { let destFilename = '' let destFilePath = '' - return lcdata.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => { + return wiki.disk.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => { destFilename = fname destFilePath = path.resolve(destFolderPath, destFilename) @@ -60,7 +63,7 @@ router.post('/img', lcdata.uploadImgHandler, (req, res, next) => { let mimeInfo = fileType(buf) if (!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) { - return Promise.reject(new Error(lang.t('errors:invalidfiletype'))) + return Promise.reject(new Error(wiki.lang.t('errors:invalidfiletype'))) } return true }).then(() => { @@ -94,12 +97,12 @@ router.post('/img', lcdata.uploadImgHandler, (req, res, next) => { }) }) -router.post('/file', lcdata.uploadFileHandler, (req, res, next) => { +router.post('/file', wiki.disk.uploadFileHandler, (req, res, next) => { let destFolder = _.chain(req.body.folder).trim().toLower().value() - upl.validateUploadsFolder(destFolder).then((destFolderPath) => { + wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => { if (!destFolderPath) { - res.json({ ok: false, msg: lang.t('errors:invalidfolder') }) + res.json({ ok: false, msg: wiki.lang.t('errors:invalidfolder') }) return true } @@ -107,7 +110,7 @@ router.post('/file', lcdata.uploadFileHandler, (req, res, next) => { let destFilename = '' let destFilePath = '' - return lcdata.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => { + return wiki.disk.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => { destFilename = fname destFilePath = path.resolve(destFolderPath, destFilename) @@ -150,7 +153,7 @@ router.get('/*', (req, res, next) => { // todo: Authentication-based access res.sendFile(fileName, { - root: git.getRepoPath() + '/uploads/', + root: wiki.git.getRepoPath() + '/uploads/', dotfiles: 'deny' }, (err) => { if (err) { diff --git a/server/index.js b/server/index.js index 07cc3df8..e74f5c2b 100644 --- a/server/index.js +++ b/server/index.js @@ -1,276 +1,43 @@ -'use strict' - // =========================================== // Wiki.js -// 1.0.0 // Licensed under AGPLv3 // =========================================== const path = require('path') -const ROOTPATH = process.cwd() -const SERVERPATH = path.join(ROOTPATH, 'server') - -global.ROOTPATH = ROOTPATH -global.SERVERPATH = SERVERPATH -const IS_DEBUG = process.env.NODE_ENV === 'development' +const cluster = require('cluster') + +let wiki = { + IS_DEBUG: process.env.NODE_ENV === 'development', + IS_MASTER: cluster.isMaster, + ROOTPATH: process.cwd(), + SERVERPATH: path.join(process.cwd(), 'server'), + configSvc: require('./modules/config'), + kernel: require('./modules/kernel') +} +global.wiki = wiki process.env.VIPS_WARNING = false -// if (IS_DEBUG) { +// if (wiki.IS_DEBUG) { // require('@glimpse/glimpse').init() // } -let appconf = require('./libs/config')() -global.appconfig = appconf.config -global.appdata = appconf.data - -// ---------------------------------------- -// Load Winston -// ---------------------------------------- - -global.winston = require('./libs/logger')(IS_DEBUG, 'SERVER') -global.winston.info('Wiki.js is initializing...') - -// ---------------------------------------- -// Load global modules -// ---------------------------------------- - -global.lcdata = require('./libs/local').init() -global.db = require('./libs/db').init() -global.entries = require('./libs/entries').init() -global.git = require('./libs/git').init(false) -global.lang = require('i18next') -global.mark = require('./libs/markdown') -global.search = require('./libs/search').init() -global.upl = require('./libs/uploads').init() - -// ---------------------------------------- -// Load modules -// ---------------------------------------- - -const autoload = require('auto-load') -const bodyParser = require('body-parser') -const compression = require('compression') -const cookieParser = require('cookie-parser') -const express = require('express') -const favicon = require('serve-favicon') -const flash = require('connect-flash') -const fork = require('child_process').fork -const http = require('http') -const i18nBackend = require('i18next-node-fs-backend') -const passport = require('passport') -const passportSocketIo = require('passport.socketio') -const session = require('express-session') -const SessionMongoStore = require('connect-mongo')(session) -const graceful = require('node-graceful') -const socketio = require('socket.io') - -var mw = autoload(path.join(SERVERPATH, '/middlewares')) -var ctrl = autoload(path.join(SERVERPATH, '/controllers')) - -// ---------------------------------------- -// Define Express App -// ---------------------------------------- - -const app = express() -global.app = app -app.use(compression()) - -// ---------------------------------------- -// Security -// ---------------------------------------- - -app.use(mw.security) - -// ---------------------------------------- -// Public Assets -// ---------------------------------------- - -app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico'))) -app.use(express.static(path.join(ROOTPATH, 'assets'), { - index: false, - maxAge: '7d' -})) +wiki.configSvc.init() // ---------------------------------------- -// Passport Authentication +// Init Logger // ---------------------------------------- -require('./libs/auth')(passport) -global.rights = require('./libs/rights') -global.rights.init() +wiki.logger = require('./modules/logger').init() -let sessionStore = new SessionMongoStore({ - mongooseConnection: global.db.connection, - touchAfter: 15 -}) - -app.use(cookieParser()) -app.use(session({ - name: 'wikijs.sid', - store: sessionStore, - secret: appconfig.sessionSecret, - resave: false, - saveUninitialized: false -})) -app.use(flash()) -app.use(passport.initialize()) -app.use(passport.session()) - -// ---------------------------------------- -// SEO // ---------------------------------------- - -app.use(mw.seo) - -// ---------------------------------------- -// Localization Engine -// ---------------------------------------- - -global.lang - .use(i18nBackend) - .init({ - load: 'languageOnly', - ns: ['common', 'admin', 'auth', 'errors', 'git'], - defaultNS: 'common', - saveMissing: false, - preload: [appconfig.lang], - lng: appconfig.lang, - fallbackLng: 'en', - backend: { - loadPath: path.join(SERVERPATH, 'locales/{{lng}}/{{ns}}.json') - } - }) - +// Init DB // ---------------------------------------- -// View Engine Setup -// ---------------------------------------- - -app.set('views', path.join(SERVERPATH, 'views')) -app.set('view engine', 'pug') - -app.use(bodyParser.json({ limit: '1mb' })) -app.use(bodyParser.urlencoded({ extended: false, limit: '1mb' })) - -// ---------------------------------------- -// View accessible data -// ---------------------------------------- - -app.locals._ = require('lodash') -app.locals.t = global.lang.t.bind(global.lang) -app.locals.moment = require('moment') -app.locals.moment.locale(appconfig.lang) -app.locals.appconfig = appconfig -app.use(mw.flash) - -// ---------------------------------------- -// Controllers -// ---------------------------------------- - -app.use('/', ctrl.auth) - -app.use('/uploads', mw.auth, ctrl.uploads) -app.use('/admin', mw.auth, ctrl.admin) -app.use('/', mw.auth, ctrl.pages) - -// ---------------------------------------- -// Error handling -// ---------------------------------------- - -app.use(function (req, res, next) { - var err = new Error('Not Found') - err.status = 404 - next(err) -}) - -app.use(function (err, req, res, next) { - res.status(err.status || 500) - res.render('error', { - message: err.message, - error: IS_DEBUG ? err : {} - }) -}) - -// ---------------------------------------- -// Start HTTP server -// ---------------------------------------- - -global.winston.info('Starting HTTP/WS server on port ' + appconfig.port + '...') - -app.set('port', appconfig.port) -var server = http.createServer(app) -var io = socketio(server) - -server.listen(appconfig.port) -server.on('error', (error) => { - if (error.syscall !== 'listen') { - throw error - } - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - global.winston.error('Listening on port ' + appconfig.port + ' requires elevated privileges!') - return process.exit(1) - case 'EADDRINUSE': - global.winston.error('Port ' + appconfig.port + ' is already in use!') - return process.exit(1) - default: - throw error - } -}) - -server.on('listening', () => { - global.winston.info('HTTP/WS server started successfully! [RUNNING]') -}) - -// ---------------------------------------- -// WebSocket -// ---------------------------------------- - -io.use(passportSocketIo.authorize({ - key: 'wikijs.sid', - store: sessionStore, - secret: appconfig.sessionSecret, - cookieParser, - success: (data, accept) => { - accept() - }, - fail: (data, message, error, accept) => { - accept() - } -})) - -io.on('connection', ctrl.ws) - -// ---------------------------------------- -// Start child processes -// ---------------------------------------- - -let bgAgent = fork(path.join(SERVERPATH, 'agent.js')) - -bgAgent.on('message', m => { - if (!m.action) { - return - } - switch (m.action) { - case 'searchAdd': - global.search.add(m.content) - break - } -}) +wiki.db = require('./modules/db').init() // ---------------------------------------- -// Graceful shutdown +// Start Kernel // ---------------------------------------- -graceful.on('exit', () => { - global.winston.info('- SHUTTING DOWN - Terminating Background Agent...') - bgAgent.kill() - global.winston.info('- SHUTTING DOWN - Performing git sync...') - return global.git.resync().then(() => { - global.winston.info('- SHUTTING DOWN - Git sync successful. Now safe to exit.') - process.exit() - }) -}) +wiki.kernel.init() diff --git a/server/init.js b/server/init.js deleted file mode 100644 index 95b3ed52..00000000 --- a/server/init.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict' - -const Promise = require('bluebird') -const fs = Promise.promisifyAll(require('fs-extra')) -const pm2 = Promise.promisifyAll(require('pm2')) -const ora = require('ora') -const path = require('path') - -const ROOTPATH = process.cwd() - -module.exports = { - /** - * Detect the most appropriate start mode - */ - startDetect: function () { - if (process.env.WIKI_JS_HEROKU) { - return this.startInHerokuMode() - } else { - return this.startInBackgroundMode() - } - }, - /** - * Start in background mode - */ - startInBackgroundMode: function () { - let spinner = ora('Initializing...').start() - return fs.emptyDirAsync(path.join(ROOTPATH, './logs')).then(() => { - return pm2.connectAsync().then(() => { - return pm2.startAsync({ - name: 'wiki', - script: 'server', - cwd: ROOTPATH, - output: path.join(ROOTPATH, './logs/wiki-output.log'), - error: path.join(ROOTPATH, './logs/wiki-error.log'), - minUptime: 5000, - maxRestarts: 5 - }).then(() => { - spinner.succeed('Wiki.js has started successfully.') - }).finally(() => { - pm2.disconnect() - }) - }) - }).catch(err => { - spinner.fail(err) - process.exit(1) - }) - }, - /** - * Start in Heroku mode - */ - startInHerokuMode: function () { - console.warn('Incorrect command on Heroku, use instead: node server') - process.exit(1) - }, - /** - * Stop Wiki.js process(es) - */ - stop () { - let spinner = ora('Shutting down Wiki.js...').start() - return pm2.connectAsync().then(() => { - return pm2.stopAsync('wiki').then(() => { - spinner.succeed('Wiki.js has stopped successfully.') - }).finally(() => { - pm2.disconnect() - }) - }).catch(err => { - spinner.fail(err) - process.exit(1) - }) - }, - /** - * Restart Wiki.js process(es) - */ - restart: function () { - let self = this - return self.stop().delay(1000).then(() => { - self.startDetect() - }) - }, - /** - * Start the web-based configuration wizard - * - * @param {Number} port Port to bind the HTTP server on - */ - configure (port) { - port = port || 3000 - let spinner = ora('Initializing interactive setup...').start() - require('./configure')(port, spinner) - } -} diff --git a/server/libs/auth.js b/server/libs/auth.js deleted file mode 100644 index 34271ccc..00000000 --- a/server/libs/auth.js +++ /dev/null @@ -1,261 +0,0 @@ -'use strict' - -/* global appconfig, appdata, db, lang, winston */ - -const fs = require('fs') - -module.exports = function (passport) { - // Serialization user methods - - passport.serializeUser(function (user, done) { - done(null, user._id) - }) - - passport.deserializeUser(function (id, done) { - db.User.findById(id).then((user) => { - if (user) { - done(null, user) - } else { - done(new Error(lang.t('auth:errors:usernotfound')), null) - } - return true - }).catch((err) => { - done(err, null) - }) - }) - - // Local Account - - if (appconfig.auth.local && appconfig.auth.local.enabled) { - const LocalStrategy = require('passport-local').Strategy - passport.use('local', - new LocalStrategy({ - usernameField: 'email', - passwordField: 'password' - }, (uEmail, uPassword, done) => { - db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => { - if (user) { - return user.validatePassword(uPassword).then(() => { - return done(null, user) || true - }).catch((err) => { - return done(err, null) - }) - } else { - return done(new Error('INVALID_LOGIN'), null) - } - }).catch((err) => { - done(err, null) - }) - } - )) - } - - // Google ID - - if (appconfig.auth.google && appconfig.auth.google.enabled) { - const GoogleStrategy = require('passport-google-oauth20').Strategy - passport.use('google', - new GoogleStrategy({ - clientID: appconfig.auth.google.clientId, - clientSecret: appconfig.auth.google.clientSecret, - callbackURL: appconfig.host + '/login/google/callback' - }, (accessToken, refreshToken, profile, cb) => { - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // Microsoft Accounts - - if (appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) { - const WindowsLiveStrategy = require('passport-windowslive').Strategy - passport.use('windowslive', - new WindowsLiveStrategy({ - clientID: appconfig.auth.microsoft.clientId, - clientSecret: appconfig.auth.microsoft.clientSecret, - callbackURL: appconfig.host + '/login/ms/callback' - }, function (accessToken, refreshToken, profile, cb) { - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // Facebook - - if (appconfig.auth.facebook && appconfig.auth.facebook.enabled) { - const FacebookStrategy = require('passport-facebook').Strategy - passport.use('facebook', - new FacebookStrategy({ - clientID: appconfig.auth.facebook.clientId, - clientSecret: appconfig.auth.facebook.clientSecret, - callbackURL: appconfig.host + '/login/facebook/callback', - profileFields: ['id', 'displayName', 'email'] - }, function (accessToken, refreshToken, profile, cb) { - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // GitHub - - if (appconfig.auth.github && appconfig.auth.github.enabled) { - const GitHubStrategy = require('passport-github2').Strategy - passport.use('github', - new GitHubStrategy({ - clientID: appconfig.auth.github.clientId, - clientSecret: appconfig.auth.github.clientSecret, - callbackURL: appconfig.host + '/login/github/callback', - scope: ['user:email'] - }, (accessToken, refreshToken, profile, cb) => { - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // Slack - - if (appconfig.auth.slack && appconfig.auth.slack.enabled) { - const SlackStrategy = require('passport-slack').Strategy - passport.use('slack', - new SlackStrategy({ - clientID: appconfig.auth.slack.clientId, - clientSecret: appconfig.auth.slack.clientSecret, - callbackURL: appconfig.host + '/login/slack/callback' - }, (accessToken, refreshToken, profile, cb) => { - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // LDAP - - if (appconfig.auth.ldap && appconfig.auth.ldap.enabled) { - const LdapStrategy = require('passport-ldapauth').Strategy - passport.use('ldapauth', - new LdapStrategy({ - server: { - url: appconfig.auth.ldap.url, - bindDn: appconfig.auth.ldap.bindDn, - bindCredentials: appconfig.auth.ldap.bindCredentials, - searchBase: appconfig.auth.ldap.searchBase, - searchFilter: appconfig.auth.ldap.searchFilter, - searchAttributes: ['displayName', 'name', 'cn', 'mail'], - tlsOptions: (appconfig.auth.ldap.tlsEnabled) ? { - ca: [ - fs.readFileSync(appconfig.auth.ldap.tlsCertPath) - ] - } : {} - }, - usernameField: 'email', - passReqToCallback: false - }, (profile, cb) => { - profile.provider = 'ldap' - profile.id = profile.dn - db.User.processProfile(profile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // AZURE AD - - if (appconfig.auth.azure && appconfig.auth.azure.enabled) { - const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy - const jwt = require('jsonwebtoken') - passport.use('azure_ad_oauth2', - new AzureAdOAuth2Strategy({ - clientID: appconfig.auth.azure.clientId, - clientSecret: appconfig.auth.azure.clientSecret, - callbackURL: appconfig.host + '/login/azure/callback', - resource: appconfig.auth.azure.resource, - tenant: appconfig.auth.azure.tenant - }, (accessToken, refreshToken, params, profile, cb) => { - let waadProfile = jwt.decode(params.id_token) - waadProfile.id = waadProfile.oid - waadProfile.provider = 'azure' - db.User.processProfile(waadProfile).then((user) => { - return cb(null, user) || true - }).catch((err) => { - return cb(err, null) || true - }) - } - )) - } - - // Create users for first-time - - db.onReady.then(() => { - return db.User.findOne({ provider: 'local', email: 'guest' }).then((c) => { - if (c < 1) { - // Create guest account - - return db.User.create({ - provider: 'local', - email: 'guest', - name: 'Guest', - password: '', - rights: [{ - role: 'read', - path: '/', - exact: false, - deny: !appconfig.public - }] - }).then(() => { - winston.info('[AUTH] Guest account created successfully!') - }).catch((err) => { - winston.error('[AUTH] An error occured while creating guest account:') - winston.error(err) - }) - } - }).then(() => { - if (process.env.WIKI_JS_HEROKU) { - return db.User.findOne({ provider: 'local', email: process.env.WIKI_ADMIN_EMAIL }).then((c) => { - if (c < 1) { - // Create root admin account (HEROKU ONLY) - - return db.User.create({ - provider: 'local', - email: process.env.WIKI_ADMIN_EMAIL, - name: 'Administrator', - password: '$2a$04$MAHRw785Xe/Jd5kcKzr3D.VRZDeomFZu2lius4gGpZZ9cJw7B7Mna', // admin123 (default) - rights: [{ - role: 'admin', - path: '/', - exact: false, - deny: false - }] - }).then(() => { - winston.info('[AUTH] Root admin account created successfully!') - }).catch((err) => { - winston.error('[AUTH] An error occured while creating root admin account:') - winston.error(err) - }) - } else { return true } - }) - } else { return true } - }) - }) -} diff --git a/server/libs/config.js b/server/libs/config.js deleted file mode 100644 index 810af0d7..00000000 --- a/server/libs/config.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict' - -const fs = require('fs') -const yaml = require('js-yaml') -const _ = require('lodash') -const path = require('path') -const cfgHelper = require('../helpers/config') - -/** - * Load Application Configuration - * - * @param {Object} confPaths Path to the configuration files - * @return {Object} Application Configuration - */ -module.exports = (confPaths) => { - confPaths = _.defaults(confPaths, { - config: path.join(ROOTPATH, 'config.yml'), - data: path.join(SERVERPATH, 'app/data.yml'), - dataRegex: path.join(SERVERPATH, 'app/regex.js') - }) - - let appconfig = {} - let appdata = {} - - try { - appconfig = yaml.safeLoad( - cfgHelper.parseConfigValue( - fs.readFileSync(confPaths.config, 'utf8') - ) - ) - - appdata = yaml.safeLoad(fs.readFileSync(confPaths.data, 'utf8')) - appdata.regex = require(confPaths.dataRegex) - } catch (ex) { - console.error(ex) - process.exit(1) - } - - // Merge with defaults - - appconfig = _.defaultsDeep(appconfig, appdata.defaults.config) - - // Check port - - if (appconfig.port < 1) { - appconfig.port = process.env.PORT || 80 - } - - // Convert booleans - - appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') - - // List authentication strategies - - appconfig.authStrategies = { - list: _.filter(appconfig.auth, ['enabled', true]), - socialEnabled: (_.chain(appconfig.auth).omit(['local', 'ldap']).filter(['enabled', true]).value().length > 0) - } - if (appconfig.authStrategies.list.length < 1) { - console.error(new Error('You must enable at least 1 authentication strategy!')) - process.exit(1) - } - - return { - config: appconfig, - data: appdata - } -} diff --git a/server/libs/db.js b/server/libs/db.js deleted file mode 100644 index 733d28a2..00000000 --- a/server/libs/db.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' - -/* global ROOTPATH, appconfig, winston */ - -const modb = require('mongoose') -const fs = require('fs') -const path = require('path') -const _ = require('lodash') - -/** - * MongoDB module - * - * @return {Object} MongoDB wrapper instance - */ -module.exports = { - - /** - * Initialize DB - * - * @return {Object} DB instance - */ - init() { - let self = this - - let dbModelsPath = path.join(SERVERPATH, 'models') - - modb.Promise = require('bluebird') - - // Event handlers - - modb.connection.on('error', err => { - winston.error('Failed to connect to MongoDB instance.') - return err - }) - modb.connection.once('open', function () { - winston.log('Connected to MongoDB instance.') - }) - - // Store connection handle - - self.connection = modb.connection - self.ObjectId = modb.Types.ObjectId - - // Load DB Models - - fs - .readdirSync(dbModelsPath) - .filter(function (file) { - return (file.indexOf('.') !== 0) - }) - .forEach(function (file) { - let modelName = _.upperFirst(_.camelCase(_.split(file, '.')[0])) - self[modelName] = require(path.join(dbModelsPath, file)) - }) - - // Connect - - self.onReady = modb.connect(appconfig.db, { useMongoClient: true }) - - return self - } - -} diff --git a/server/libs/logger.js b/server/libs/logger.js deleted file mode 100644 index 4a6f7884..00000000 --- a/server/libs/logger.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict' - -module.exports = (isDebug, processName) => { - let winston = require('winston') - - if (typeof processName === 'undefined') { - processName = 'SERVER' - } - - // Console - - let logger = new (winston.Logger)({ - level: (isDebug) ? 'debug' : 'info', - transports: [ - new (winston.transports.Console)({ - level: (isDebug) ? 'debug' : 'info', - prettyPrint: true, - colorize: true, - silent: false, - timestamp: true - }) - ] - }) - - logger.filters.push((level, msg) => { - return '[' + processName + '] ' + msg - }) - - // External services - - if (appconfig.externalLogging.bugsnag) { - const bugsnagTransport = require('./winston-transports/bugsnag') - logger.add(bugsnagTransport, { - level: 'warn', - key: appconfig.externalLogging.bugsnag - }) - } - - if (appconfig.externalLogging.loggly) { - require('winston-loggly-bulk') - logger.add(winston.transports.Loggly, { - token: appconfig.externalLogging.loggly.token, - subdomain: appconfig.externalLogging.loggly.subdomain, - tags: ['wiki-js'], - level: 'warn', - json: true - }) - } - - if (appconfig.externalLogging.papertrail) { - require('winston-papertrail').Papertrail // eslint-disable-line no-unused-expressions - logger.add(winston.transports.Papertrail, { - host: appconfig.externalLogging.papertrail.host, - port: appconfig.externalLogging.papertrail.port, - level: 'warn', - program: 'wiki.js' - }) - } - - if (appconfig.externalLogging.rollbar) { - const rollbarTransport = require('./winston-transports/rollbar') - logger.add(rollbarTransport, { - level: 'warn', - key: appconfig.externalLogging.rollbar - }) - } - - if (appconfig.externalLogging.sentry) { - const sentryTransport = require('./winston-transports/sentry') - logger.add(sentryTransport, { - level: 'warn', - key: appconfig.externalLogging.sentry - }) - } - - return logger -} diff --git a/server/libs/search-index/index.js b/server/libs/search-index/index.js deleted file mode 100644 index 807219d9..00000000 --- a/server/libs/search-index/index.js +++ /dev/null @@ -1,81 +0,0 @@ -const bunyan = require('bunyan') -const level = require('levelup') -const down = require('memdown') -const SearchIndexAdder = require('search-index-adder') -const SearchIndexSearcher = require('search-index-searcher') - -module.exports = function (givenOptions, moduleReady) { - const optionsLoaded = function (err, SearchIndex) { - const siUtil = require('./siUtil.js')(SearchIndex.options) - if (err) return moduleReady(err) - SearchIndex.close = siUtil.close - SearchIndex.countDocs = siUtil.countDocs - getAdder(SearchIndex, adderLoaded) - } - - const adderLoaded = function (err, SearchIndex) { - if (err) return moduleReady(err) - getSearcher(SearchIndex, searcherLoaded) - } - - const searcherLoaded = function (err, SearchIndex) { - if (err) return moduleReady(err) - return moduleReady(err, SearchIndex) - } - - getOptions(givenOptions, optionsLoaded) -} - -const getAdder = function (SearchIndex, done) { - SearchIndexAdder(SearchIndex.options, function (err, searchIndexAdder) { - SearchIndex.add = searchIndexAdder.add - SearchIndex.callbackyAdd = searchIndexAdder.concurrentAdd // deprecated - SearchIndex.concurrentAdd = searchIndexAdder.concurrentAdd - SearchIndex.createWriteStream = searchIndexAdder.createWriteStream - SearchIndex.dbWriteStream = searchIndexAdder.dbWriteStream - SearchIndex.defaultPipeline = searchIndexAdder.defaultPipeline - SearchIndex.del = searchIndexAdder.deleter - SearchIndex.deleteStream = searchIndexAdder.deleteStream - SearchIndex.flush = searchIndexAdder.flush - done(err, SearchIndex) - }) -} - -const getSearcher = function (SearchIndex, done) { - SearchIndexSearcher(SearchIndex.options, function (err, searchIndexSearcher) { - SearchIndex.availableFields = searchIndexSearcher.availableFields - SearchIndex.buckets = searchIndexSearcher.bucketStream - SearchIndex.categorize = searchIndexSearcher.categoryStream - SearchIndex.dbReadStream = searchIndexSearcher.dbReadStream - SearchIndex.get = searchIndexSearcher.get - SearchIndex.match = searchIndexSearcher.match - SearchIndex.scan = searchIndexSearcher.scan - SearchIndex.search = searchIndexSearcher.search - SearchIndex.totalHits = searchIndexSearcher.totalHits - done(err, SearchIndex) - }) -} - -const getOptions = function (options, done) { - var SearchIndex = {} - SearchIndex.options = Object.assign({}, { - indexPath: 'si', - keySeparator: '○', - logLevel: 'error' - }, options) - options.log = bunyan.createLogger({ - name: 'search-index', - level: options.logLevel - }) - if (!options.indexes) { - level(SearchIndex.options.indexPath || 'si', { - valueEncoding: 'json', - db: down - }, function (err, db) { - SearchIndex.options.indexes = db - return done(err, SearchIndex) - }) - } else { - return done(null, SearchIndex) - } -} diff --git a/server/libs/search-index/siUtil.js b/server/libs/search-index/siUtil.js deleted file mode 100644 index bad264a7..00000000 --- a/server/libs/search-index/siUtil.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict' - -module.exports = function (siOptions) { - var siUtil = {} - - siUtil.countDocs = function (callback) { - var count = 0 - const gte = 'DOCUMENT' + siOptions.keySeparator - const lte = 'DOCUMENT' + siOptions.keySeparator + siOptions.keySeparator - siOptions.indexes.createReadStream({gte: gte, lte: lte}) - .on('data', function (data) { - count++ - }) - .on('error', function (err) { - return callback(err, null) - }) - .on('end', function () { - return callback(null, count) - }) - } - - siUtil.close = function (callback) { - siOptions.indexes.close(function (err) { - while (!siOptions.indexes.isClosed()) { - // log not always working here- investigate - if (siOptions.log) siOptions.log.info('closing...') - } - if (siOptions.indexes.isClosed()) { - if (siOptions.log) siOptions.log.info('closed...') - callback(err) - } - }) - } - - return siUtil -} diff --git a/server/locales/ja/auth.json b/server/locales/ja/auth.json index eade4c28..e4218ead 100644 --- a/server/locales/ja/auth.json +++ b/server/locales/ja/auth.json @@ -13,7 +13,7 @@ "invalidlogin": "不正なログイン", "invalidloginmsg": "Eメール又はパスワードが無効です。", "invaliduseremail": "無効なユーザーEメール", - "lognerror": "ログインエラー", + "loginerror": "ログインエラー", "notyetauthorized": "まだこのサイトにログインする権限がありません。", "toomanyattempts": "試行回数が多すぎます", "toomanyattemptsmsg": "短期間に失敗した試行回数が多すぎます。{{time}}にもう一度お試しください。", diff --git a/server/master.js b/server/master.js new file mode 100644 index 00000000..4d8a450c --- /dev/null +++ b/server/master.js @@ -0,0 +1,186 @@ +/* global wiki */ + +module.exports = () => { + // ---------------------------------------- + // Load global modules + // ---------------------------------------- + + wiki.auth = require('./modules/auth').init() + wiki.disk = require('./modules/disk').init() + wiki.docs = require('./modules/documents').init() + wiki.git = require('./modules/git').init(false) + wiki.lang = require('./modules/localization').init() + wiki.mark = require('./modules/markdown') + wiki.search = require('./modules/search').init() + wiki.upl = require('./modules/uploads').init() + + // ---------------------------------------- + // Load modules + // ---------------------------------------- + + const autoload = require('auto-load') + const bodyParser = require('body-parser') + const compression = require('compression') + const cookieParser = require('cookie-parser') + const express = require('express') + const favicon = require('serve-favicon') + const flash = require('connect-flash') + const http = require('http') + const path = require('path') + const session = require('express-session') + const SessionRedisStore = require('connect-redis')(session) + const graceful = require('node-graceful') + const graphqlApollo = require('apollo-server-express') + const graphqlSchema = require('./modules/graphql') + + var mw = autoload(path.join(wiki.SERVERPATH, '/middlewares')) + var ctrl = autoload(path.join(wiki.SERVERPATH, '/controllers')) + + // ---------------------------------------- + // Define Express App + // ---------------------------------------- + + const app = express() + wiki.app = app + app.use(compression()) + + // ---------------------------------------- + // Security + // ---------------------------------------- + + app.use(mw.security) + + // ---------------------------------------- + // Public Assets + // ---------------------------------------- + + app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico'))) + app.use(express.static(path.join(wiki.ROOTPATH, 'assets'), { + index: false, + maxAge: '7d' + })) + + // ---------------------------------------- + // Passport Authentication + // ---------------------------------------- + + let sessionStore = new SessionRedisStore({ + client: wiki.redis + }) + + app.use(cookieParser()) + app.use(session({ + name: 'wikijs.sid', + store: sessionStore, + secret: wiki.config.site.sessionSecret, + resave: false, + saveUninitialized: false + })) + app.use(flash()) + app.use(wiki.auth.passport.initialize()) + app.use(wiki.auth.passport.session()) + + // ---------------------------------------- + // SEO + // ---------------------------------------- + + app.use(mw.seo) + + // ---------------------------------------- + // View Engine Setup + // ---------------------------------------- + + app.set('views', path.join(wiki.SERVERPATH, 'views')) + app.set('view engine', 'pug') + + app.use(bodyParser.json({ limit: '1mb' })) + app.use(bodyParser.urlencoded({ extended: false, limit: '1mb' })) + + // ---------------------------------------- + // View accessible data + // ---------------------------------------- + + app.locals.basedir = wiki.ROOTPATH + app.locals._ = require('lodash') + app.locals.t = wiki.lang.engine.t.bind(wiki.lang) + app.locals.moment = require('moment') + app.locals.moment.locale(wiki.config.site.lang) + app.locals.config = wiki.config + app.use(mw.flash) + + // ---------------------------------------- + // Controllers + // ---------------------------------------- + + app.use('/', ctrl.auth) + + app.use('/graphql', graphqlApollo.graphqlExpress({ schema: graphqlSchema })) + app.use('/graphiql', graphqlApollo.graphiqlExpress({ endpointURL: '/graphql' })) + // app.use('/uploads', mw.auth, ctrl.uploads) + app.use('/admin', mw.auth, ctrl.admin) + app.use('/', mw.auth, ctrl.pages) + + // ---------------------------------------- + // Error handling + // ---------------------------------------- + + app.use(function (req, res, next) { + var err = new Error('Not Found') + err.status = 404 + next(err) + }) + + app.use(function (err, req, res, next) { + res.status(err.status || 500) + res.render('error', { + message: err.message, + error: wiki.IS_DEBUG ? err : {} + }) + }) + + // ---------------------------------------- + // Start HTTP server + // ---------------------------------------- + + wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`) + + app.set('port', wiki.config.port) + let server = http.createServer(app) + + server.listen(wiki.config.port) + server.on('error', (error) => { + if (error.syscall !== 'listen') { + throw error + } + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!') + return process.exit(1) + case 'EADDRINUSE': + wiki.logger.error('Port ' + wiki.config.port + ' is already in use!') + return process.exit(1) + default: + throw error + } + }) + + server.on('listening', () => { + wiki.logger.info('HTTP Server: RUNNING') + }) + + // ---------------------------------------- + // Graceful shutdown + // ---------------------------------------- + + graceful.on('exit', () => { + wiki.logger.info('- SHUTTING DOWN - Performing git sync...') + return global.git.resync().then(() => { + wiki.logger.info('- SHUTTING DOWN - Git sync successful. Now safe to exit.') + process.exit() + }) + }) + + return true +} diff --git a/server/middlewares/flash.js b/server/middlewares/flash.js index 98182b47..09e4adf0 100644 --- a/server/middlewares/flash.js +++ b/server/middlewares/flash.js @@ -9,7 +9,7 @@ * @return {any} void */ module.exports = (req, res, next) => { - res.locals.appflash = req.flash('alert') + res.locals.flash = req.flash('alert') next() } diff --git a/server/middlewares/security.js b/server/middlewares/security.js index 3590cff4..0fe2b355 100644 --- a/server/middlewares/security.js +++ b/server/middlewares/security.js @@ -1,7 +1,5 @@ 'use strict' -/* global app */ - /** * Security Middleware * @@ -12,7 +10,7 @@ */ module.exports = function (req, res, next) { // -> Disable X-Powered-By - app.disable('x-powered-by') + req.app.disable('x-powered-by') // -> Disable Frame Embedding res.set('X-Frame-Options', 'deny') diff --git a/server/models/_relations.js b/server/models/_relations.js new file mode 100644 index 00000000..c826a5e0 --- /dev/null +++ b/server/models/_relations.js @@ -0,0 +1,16 @@ +/** + * Associate DB Model relations + */ +module.exports = db => { + db.User.belongsToMany(db.Group, { through: 'userGroups' }) + db.Group.belongsToMany(db.User, { through: 'userGroups' }) + db.Group.hasMany(db.Right) + db.Right.belongsTo(db.Group) + db.Document.belongsToMany(db.Tag, { through: 'documentTags' }) + db.Document.hasMany(db.Comment) + db.Tag.belongsToMany(db.Document, { through: 'documentTags' }) + db.File.belongsTo(db.Folder) + db.Folder.hasMany(db.File) + db.Comment.belongsTo(db.Document) + db.Comment.belongsTo(db.User, { as: 'author' }) +} diff --git a/server/models/bruteforce.js b/server/models/bruteforce.js deleted file mode 100644 index 76981fd7..00000000 --- a/server/models/bruteforce.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict' - -const Mongoose = require('mongoose') - -/** - * BruteForce schema - * - * @type {} - */ -var bruteForceSchema = Mongoose.Schema({ - _id: { type: String, index: 1 }, - data: { - count: Number, - lastRequest: Date, - firstRequest: Date - }, - expires: { type: Date, index: { expires: '1d' } } -}) - -module.exports = Mongoose.model('Bruteforce', bruteForceSchema) diff --git a/server/models/comment.js b/server/models/comment.js new file mode 100644 index 00000000..3b35f42c --- /dev/null +++ b/server/models/comment.js @@ -0,0 +1,16 @@ +/** + * Comment schema + */ +module.exports = (sequelize, DataTypes) => { + let commentSchema = sequelize.define('comment', { + content: { + type: DataTypes.STRING, + allowNull: false + } + }, { + timestamps: true, + version: true + }) + + return commentSchema +} diff --git a/server/models/document.js b/server/models/document.js new file mode 100644 index 00000000..957fd91a --- /dev/null +++ b/server/models/document.js @@ -0,0 +1,64 @@ +/** + * Document schema + */ +module.exports = (sequelize, DataTypes) => { + let documentSchema = sequelize.define('setting', { + path: { + type: DataTypes.STRING, + allowNull: false + }, + title: { + type: DataTypes.STRING, + allowNull: false, + validate: { + len: [2, 255] + } + }, + subtitle: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: '' + }, + parentPath: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: '' + }, + parentTitle: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: '' + }, + isDirectory: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + isEntry: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + isDraft: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + searchContent: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: '' + } + }, { + timestamps: true, + version: true, + indexes: [ + { + unique: true, + fields: ['path'] + } + ] + }) + + return documentSchema +} diff --git a/server/models/entry.js b/server/models/entry.js deleted file mode 100644 index 746d6d28..00000000 --- a/server/models/entry.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict' - -const Mongoose = require('mongoose') - -/** - * Entry schema - * - * @type {} - */ -var entrySchema = Mongoose.Schema({ - _id: String, - - title: { - type: String, - required: true, - minlength: 2 - }, - subtitle: { - type: String, - default: '' - }, - parentTitle: { - type: String, - default: '' - }, - parentPath: { - type: String, - default: '' - }, - isDirectory: { - type: Boolean, - default: false - }, - isEntry: { - type: Boolean, - default: false - } -}, { - timestamps: {} -}) - -module.exports = Mongoose.model('Entry', entrySchema) diff --git a/server/models/file.js b/server/models/file.js new file mode 100644 index 00000000..9fca9df4 --- /dev/null +++ b/server/models/file.js @@ -0,0 +1,42 @@ +/** + * File schema + */ +module.exports = (sequelize, DataTypes) => { + let fileSchema = sequelize.define('file', { + category: { + type: DataTypes.ENUM('binary', 'image'), + allowNull: false, + defaultValue: 'binary' + }, + mime: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: 'application/octet-stream' + }, + extra: { + type: DataTypes.JSONB, + allowNull: true + }, + filename: { + type: DataTypes.STRING, + allowNull: false + }, + basename: { + type: DataTypes.STRING, + allowNull: false + }, + filesize: { + type: DataTypes.INTEGER, + allowNull: false, + validate: { + isInt: true, + min: 0 + } + } + }, { + timestamps: true, + version: true + }) + + return fileSchema +} diff --git a/server/models/folder.js b/server/models/folder.js new file mode 100644 index 00000000..fdab4f7d --- /dev/null +++ b/server/models/folder.js @@ -0,0 +1,22 @@ +/** + * Folder schema + */ +module.exports = (sequelize, DataTypes) => { + let folderSchema = sequelize.define('folder', { + name: { + type: DataTypes.STRING, + allowNull: false + } + }, { + timestamps: true, + version: true, + indexes: [ + { + unique: true, + fields: ['name'] + } + ] + }) + + return folderSchema +} diff --git a/server/models/group.js b/server/models/group.js new file mode 100644 index 00000000..942ed07e --- /dev/null +++ b/server/models/group.js @@ -0,0 +1,16 @@ +/** + * Group schema + */ +module.exports = (sequelize, DataTypes) => { + let groupSchema = sequelize.define('group', { + name: { + type: DataTypes.STRING, + allowNull: false + } + }, { + timestamps: true, + version: true + }) + + return groupSchema +} diff --git a/server/models/right.js b/server/models/right.js new file mode 100644 index 00000000..eeed3155 --- /dev/null +++ b/server/models/right.js @@ -0,0 +1,36 @@ +/** + * Right schema + */ +module.exports = (sequelize, DataTypes) => { + let rightSchema = sequelize.define('right', { + path: { + type: DataTypes.STRING, + allowNull: false + }, + role: { + type: DataTypes.ENUM('read', 'write', 'manage'), + allowNull: false, + defaultValue: 'read' + }, + exact: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + allow: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + } + }, { + timestamps: true, + version: true, + indexes: [ + { + fields: ['path'] + } + ] + }) + + return rightSchema +} diff --git a/server/models/setting.js b/server/models/setting.js index 73686af2..9759b7c3 100644 --- a/server/models/setting.js +++ b/server/models/setting.js @@ -1,22 +1,26 @@ -'use strict' - -const Mongoose = require('mongoose') - /** * Settings schema - * - * @type {} */ -var settingSchema = Mongoose.Schema({ - key: { - type: String, - required: true, - index: true - }, - value: { - type: String, - required: true - } -}, { timestamps: {} }) +module.exports = (sequelize, DataTypes) => { + let settingSchema = sequelize.define('setting', { + key: { + type: DataTypes.STRING, + allowNull: false + }, + config: { + type: DataTypes.JSONB, + allowNull: false + } + }, { + timestamps: true, + version: true, + indexes: [ + { + unique: true, + fields: ['key'] + } + ] + }) -module.exports = Mongoose.model('Setting', settingSchema) + return settingSchema +} diff --git a/server/models/tag.js b/server/models/tag.js new file mode 100644 index 00000000..6c44859d --- /dev/null +++ b/server/models/tag.js @@ -0,0 +1,22 @@ +/** + * Tags schema + */ +module.exports = (sequelize, DataTypes) => { + let tagSchema = sequelize.define('tag', { + key: { + type: DataTypes.STRING, + allowNull: false + } + }, { + timestamps: true, + version: true, + indexes: [ + { + unique: true, + fields: ['key'] + } + ] + }) + + return tagSchema +} diff --git a/server/models/upl-file.js b/server/models/upl-file.js deleted file mode 100644 index a48602bb..00000000 --- a/server/models/upl-file.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -const Mongoose = require('mongoose') - -/** - * Upload File schema - * - * @type {} - */ -var uplFileSchema = Mongoose.Schema({ - - _id: String, - - category: { - type: String, - required: true, - default: 'binary' - }, - mime: { - type: String, - required: true, - default: 'application/octet-stream' - }, - extra: { - type: Object - }, - folder: { - type: String, - ref: 'UplFolder' - }, - filename: { - type: String, - required: true - }, - basename: { - type: String, - required: true - }, - filesize: { - type: Number, - required: true - } - -}, { timestamps: {} }) - -module.exports = Mongoose.model('UplFile', uplFileSchema) diff --git a/server/models/upl-folder.js b/server/models/upl-folder.js deleted file mode 100644 index 80028b6f..00000000 --- a/server/models/upl-folder.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -const Mongoose = require('mongoose') - -/** - * Upload Folder schema - * - * @type {} - */ -var uplFolderSchema = Mongoose.Schema({ - - _id: String, - - name: { - type: String, - index: true - } - -}, { timestamps: {} }) - -module.exports = Mongoose.model('UplFolder', uplFolderSchema) diff --git a/server/models/user.js b/server/models/user.js index 18b2e429..c9102ac7 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,109 +1,120 @@ -'use strict' +/* global wiki */ -/* global db, lang */ - -const Mongoose = require('mongoose') const Promise = require('bluebird') const bcrypt = require('bcryptjs-then') const _ = require('lodash') /** * Users schema - * - * @type {} */ -var userSchema = Mongoose.Schema({ - - email: { - type: String, - required: true, - index: true - }, - - provider: { - type: String, - required: true - }, - - providerId: { - type: String - }, - - password: { - type: String - }, - - name: { - type: String - }, - - rights: [{ - role: String, - path: String, - exact: Boolean, - deny: Boolean - }] - -}, { timestamps: {} }) +module.exports = (sequelize, DataTypes) => { + let userSchema = sequelize.define('user', { + email: { + type: DataTypes.STRING, + allowNull: false, + validate: { + isEmail: true + } + }, + provider: { + type: DataTypes.STRING, + allowNull: false + }, + providerId: { + type: DataTypes.STRING, + allowNull: true + }, + password: { + type: DataTypes.STRING, + allowNull: true + }, + name: { + type: DataTypes.STRING, + allowNull: true + }, + role: { + type: DataTypes.ENUM('admin', 'user', 'guest'), + allowNull: false + }, + tfaIsActive: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + tfaSecret: { + type: DataTypes.STRING, + allowNull: true + } + }, { + timestamps: true, + version: true, + indexes: [ + { + unique: true, + fields: ['provider', 'email'] + } + ] + }) -userSchema.statics.processProfile = (profile) => { - let primaryEmail = '' - if (_.isArray(profile.emails)) { - let e = _.find(profile.emails, ['primary', true]) - primaryEmail = (e) ? e.value : _.first(profile.emails).value - } else if (_.isString(profile.email) && profile.email.length > 5) { - primaryEmail = profile.email - } else if (_.isString(profile.mail) && profile.mail.length > 5) { - primaryEmail = profile.mail - } else if (profile.user && profile.user.email && profile.user.email.length > 5) { - primaryEmail = profile.user.email - } else { - return Promise.reject(new Error(lang.t('auth:errors.invaliduseremail'))) + userSchema.prototype.validatePassword = function (rawPwd) { + return bcrypt.compare(rawPwd, this.password).then((isValid) => { + return (isValid) ? true : Promise.reject(new Error(wiki.lang.t('auth:errors:invalidlogin'))) + }) } - profile.provider = _.lowerCase(profile.provider) - primaryEmail = _.toLower(primaryEmail) + userSchema.processProfile = (profile) => { + let primaryEmail = '' + if (_.isArray(profile.emails)) { + let e = _.find(profile.emails, ['primary', true]) + primaryEmail = (e) ? e.value : _.first(profile.emails).value + } else if (_.isString(profile.email) && profile.email.length > 5) { + primaryEmail = profile.email + } else if (_.isString(profile.mail) && profile.mail.length > 5) { + primaryEmail = profile.mail + } else if (profile.user && profile.user.email && profile.user.email.length > 5) { + primaryEmail = profile.user.email + } else { + return Promise.reject(new Error(wiki.lang.t('auth:errors.invaliduseremail'))) + } - return db.User.findOneAndUpdate({ - email: primaryEmail, - provider: profile.provider - }, { - email: primaryEmail, - provider: profile.provider, - providerId: profile.id, - name: profile.displayName || profile.cn || _.split(primaryEmail, '@')[0] - }, { - new: true - }).then((user) => { - // Handle unregistered accounts - if (!user && profile.provider !== 'local' && (appconfig.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) { - let nUsr = { - email: primaryEmail, - provider: profile.provider, - providerId: profile.id, - password: '', - name: profile.displayName || profile.name || profile.cn, - rights: [{ - role: 'read', - path: '/', - exact: false, - deny: false - }] + profile.provider = _.lowerCase(profile.provider) + primaryEmail = _.toLower(primaryEmail) + + return wiki.db.User.findOneAndUpdate({ + email: primaryEmail, + provider: profile.provider + }, { + email: primaryEmail, + provider: profile.provider, + providerId: profile.id, + name: profile.displayName || _.split(primaryEmail, '@')[0] + }, { + new: true + }).then((user) => { + // Handle unregistered accounts + if (!user && profile.provider !== 'local' && (appconfig.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) { + let nUsr = { + email: primaryEmail, + provider: profile.provider, + providerId: profile.id, + password: '', + name: profile.displayName || profile.name || profile.cn, + rights: [{ + role: 'read', + path: '/', + exact: false, + deny: false + }] + } + return wiki.db.User.create(nUsr) } - return db.User.create(nUsr) - } - return user || Promise.reject(new Error(lang.t('auth:errors:notyetauthorized'))) - }) -} + return user || Promise.reject(new Error(wiki.lang.t('auth:errors:notyetauthorized'))) + }) + } -userSchema.statics.hashPassword = (rawPwd) => { - return bcrypt.hash(rawPwd) -} + userSchema.hashPassword = (rawPwd) => { + return bcrypt.hash(rawPwd) + } -userSchema.methods.validatePassword = function (rawPwd) { - return bcrypt.compare(rawPwd, this.password).then((isValid) => { - return (isValid) ? true : Promise.reject(new Error(lang.t('auth:errors:invalidlogin'))) - }) + return userSchema } - -module.exports = Mongoose.model('User', userSchema) diff --git a/server/modules/auth.js b/server/modules/auth.js new file mode 100644 index 00000000..690d0971 --- /dev/null +++ b/server/modules/auth.js @@ -0,0 +1,106 @@ +/* global wiki */ + +const _ = require('lodash') +const passport = require('passport') +const fs = require('fs-extra') +const path = require('path') + +module.exports = { + strategies: {}, + init() { + this.passport = passport + + // Serialization user methods + + passport.serializeUser(function (user, done) { + done(null, user._id) + }) + + passport.deserializeUser(function (id, done) { + wiki.db.User.findById(id).then((user) => { + if (user) { + done(null, user) + } else { + done(new Error(wiki.lang.t('auth:errors:usernotfound')), null) + } + return true + }).catch((err) => { + done(err, null) + }) + }) + + // Load authentication strategies + + wiki.config.auth.strategies.local = {} + + _.forOwn(wiki.config.auth.strategies, (strategyConfig, strategyKey) => { + strategyConfig.callbackURL = `${wiki.config.site.host}${wiki.config.site.path}/login/${strategyKey}/callback` + let strategy = require(`../authentication/${strategyKey}`) + strategy.init(passport, strategyConfig) + fs.readFile(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${strategyKey}.svg`), 'utf8').then(iconData => { + strategy.icon = iconData + }).catch(err => { + if (err.code === 'ENOENT') { + strategy.icon = '[missing icon]' + } else { + wiki.logger.error(err) + } + }) + this.strategies[strategy.key] = strategy + wiki.logger.info(`Authentication Provider ${strategyKey}: OK`) + }) + + // Create Guest account for first-time + + wiki.db.User.findOne({ + where: { + provider: 'local', + email: 'guest@example.com' + } + }).then((c) => { + if (c < 1) { + return wiki.db.User.create({ + provider: 'local', + email: 'guest@example.com', + name: 'Guest', + password: '', + role: 'guest' + }).then(() => { + wiki.logger.info('[AUTH] Guest account created successfully!') + return true + }).catch((err) => { + wiki.logger.error('[AUTH] An error occured while creating guest account:') + wiki.logger.error(err) + return err + }) + } + }) + + // .then(() => { + // if (process.env.WIKI_JS_HEROKU) { + // return wiki.db.User.findOne({ provider: 'local', email: process.env.WIKI_ADMIN_EMAIL }).then((c) => { + // if (c < 1) { + // // Create root admin account (HEROKU ONLY) + + // return wiki.db.User.create({ + // provider: 'local', + // email: process.env.WIKI_ADMIN_EMAIL, + // name: 'Administrator', + // password: '$2a$04$MAHRw785Xe/Jd5kcKzr3D.VRZDeomFZu2lius4gGpZZ9cJw7B7Mna', // admin123 (default) + // role: 'admin' + // }).then(() => { + // wiki.logger.info('[AUTH] Root admin account created successfully!') + // return true + // }).catch((err) => { + // wiki.logger.error('[AUTH] An error occured while creating root admin account:') + // wiki.logger.error(err) + // return err + // }) + // } else { return true } + // }) + // } else { return true } + // }) + + return this + } +} diff --git a/server/modules/config.js b/server/modules/config.js new file mode 100644 index 00000000..a8e15378 --- /dev/null +++ b/server/modules/config.js @@ -0,0 +1,85 @@ +/* global wiki */ + +const fs = require('fs') +const yaml = require('js-yaml') +const _ = require('lodash') +const path = require('path') +const cfgHelper = require('../helpers/config') + +module.exports = { + /** + * Load root config from disk + */ + init() { + let confPaths = { + config: path.join(wiki.ROOTPATH, 'config.yml'), + data: path.join(wiki.SERVERPATH, 'app/data.yml'), + dataRegex: path.join(wiki.SERVERPATH, 'app/regex.js') + } + + let appconfig = {} + let appdata = {} + + try { + appconfig = yaml.safeLoad( + cfgHelper.parseConfigValue( + fs.readFileSync(confPaths.config, 'utf8') + ) + ) + appdata = yaml.safeLoad(fs.readFileSync(confPaths.data, 'utf8')) + appdata.regex = require(confPaths.dataRegex) + } catch (ex) { + console.error(ex) + process.exit(1) + } + + // Merge with defaults + + appconfig = _.defaultsDeep(appconfig, appdata.defaults.config) + + // Check port + + if (appconfig.port < 1) { + appconfig.port = process.env.PORT || 80 + } + + // Convert booleans + + appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') + + // List authentication strategies + wiki.config = appconfig + wiki.data = appdata + }, + + /** + * Load config from DB + * + * @param {Array} subsets Array of subsets to load + * @returns Promise + */ + loadFromDb(subsets) { + if (!_.isArray(subsets) || subsets.length === 0) { + subsets = wiki.data.configNamespaces + } + + return wiki.db.Setting.findAll({ + attributes: ['key', 'config'], + where: { + key: { + $in: subsets + } + } + }).then(results => { + if (_.isArray(results) && results.length === subsets.length) { + results.forEach(result => { + wiki.config[result.key] = result.config + }) + return true + } else { + wiki.logger.warn('DB Configuration is empty or incomplete.') + return false + } + }) + } +} diff --git a/server/modules/db.js b/server/modules/db.js new file mode 100644 index 00000000..7063f7f1 --- /dev/null +++ b/server/modules/db.js @@ -0,0 +1,137 @@ +'use strict' + +/* global wiki */ + +const fs = require('fs') +const path = require('path') +const _ = require('lodash') +const Promise = require('bluebird') +const Sequelize = require('sequelize') +const Op = Sequelize.Op + +const operatorsAliases = { + $eq: Op.eq, + $ne: Op.ne, + $gte: Op.gte, + $gt: Op.gt, + $lte: Op.lte, + $lt: Op.lt, + $not: Op.not, + $in: Op.in, + $notIn: Op.notIn, + $is: Op.is, + $like: Op.like, + $notLike: Op.notLike, + $iLike: Op.iLike, + $notILike: Op.notILike, + $regexp: Op.regexp, + $notRegexp: Op.notRegexp, + $iRegexp: Op.iRegexp, + $notIRegexp: Op.notIRegexp, + $between: Op.between, + $notBetween: Op.notBetween, + $overlap: Op.overlap, + $contains: Op.contains, + $contained: Op.contained, + $adjacent: Op.adjacent, + $strictLeft: Op.strictLeft, + $strictRight: Op.strictRight, + $noExtendRight: Op.noExtendRight, + $noExtendLeft: Op.noExtendLeft, + $and: Op.and, + $or: Op.or, + $any: Op.any, + $all: Op.all, + $values: Op.values, + $col: Op.col +} + +/** + * PostgreSQL DB module + */ +module.exports = { + + Sequelize, + Op: Sequelize.Op, + + /** + * Initialize DB + * + * @return {Object} DB instance + */ + init() { + let self = this + + let dbModelsPath = path.join(wiki.SERVERPATH, 'models') + + // Define Sequelize instance + + self.inst = new self.Sequelize(wiki.config.db.db, wiki.config.db.user, wiki.config.db.pass, { + host: wiki.config.db.host, + port: wiki.config.db.port, + dialect: 'postgres', + pool: { + max: 10, + min: 0, + idle: 10000 + }, + logging: log => { wiki.logger.log('verbose', log) }, + operatorsAliases + }) + + // Attempt to connect and authenticate to DB + + self.inst.authenticate().then(() => { + wiki.logger.info('Database (PostgreSQL) connection: OK') + }).catch(err => { + wiki.logger.error('Failed to connect to PostgreSQL instance.') + return err + }) + + // Load DB Models + + fs + .readdirSync(dbModelsPath) + .filter(file => { + return (file.indexOf('.') !== 0 && file.indexOf('_') !== 0) + }) + .forEach(file => { + let modelName = _.upperFirst(_.camelCase(_.split(file, '.')[0])) + self[modelName] = self.inst.import(path.join(dbModelsPath, file)) + }) + + // Associate DB Models + + require(path.join(dbModelsPath, '_relations.js'))(self) + + // Set init tasks + + let initTasks = { + // -> Sync DB Schemas + syncSchemas() { + return self.inst.sync({ + force: false, + logging: log => { wiki.logger.log('verbose', log) } + }) + }, + // -> Set Connection App Name + setAppName() { + return self.inst.query(`set application_name = 'Wiki.js'`, { raw: true }) + } + } + + let initTasksQueue = (wiki.IS_MASTER) ? [ + initTasks.syncSchemas, + initTasks.setAppName + ] : [ + initTasks.setAppName + ] + + // Perform init tasks + + self.onReady = Promise.each(initTasksQueue, t => t()).return(true) + + return self + } + +} diff --git a/server/libs/local.js b/server/modules/disk.js similarity index 59% rename from server/libs/local.js rename to server/modules/disk.js index 3053e63b..0fafcd68 100644 --- a/server/libs/local.js +++ b/server/modules/disk.js @@ -1,6 +1,6 @@ 'use strict' -/* global lang, winston */ +/* global wiki */ const path = require('path') const Promise = require('bluebird') @@ -10,7 +10,7 @@ const os = require('os') const _ = require('lodash') /** - * Local Data Storage + * Local Disk Storage */ module.exports = { @@ -21,29 +21,26 @@ module.exports = { /** * Initialize Local Data Storage model - * - * @return {Object} Local Data Storage model instance */ init () { - this._uploadsPath = path.resolve(ROOTPATH, appconfig.paths.repo, 'uploads') - this._uploadsThumbsPath = path.resolve(ROOTPATH, appconfig.paths.data, 'thumbs') + this._uploadsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo, 'uploads') + this._uploadsThumbsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'thumbs') - this.createBaseDirectories(appconfig) - this.initMulter(appconfig) + this.createBaseDirectories() + // this.initMulter() return this }, /** * Init Multer upload handlers - * - * @param {Object} appconfig The application config - * @return {boolean} Void */ - initMulter (appconfig) { + initMulter () { let maxFileSizes = { - img: appconfig.uploads.maxImageFileSize * 1024 * 1024, - file: appconfig.uploads.maxOtherFileSize * 1024 * 1024 + // img: wiki.config.uploads.maxImageFileSize * 1024 * 1024, + // file: wiki.config.uploads.maxOtherFileSize * 1024 * 1024 + img: 3 * 1024 * 1024, + file: 10 * 1024 * 1024 } // -> IMAGES @@ -51,7 +48,7 @@ module.exports = { this.uploadImgHandler = multer({ storage: multer.diskStorage({ destination: (req, f, cb) => { - cb(null, path.resolve(ROOTPATH, appconfig.paths.data, 'temp-upload')) + cb(null, path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'temp-upload')) } }), fileFilter: (req, f, cb) => { @@ -76,7 +73,7 @@ module.exports = { this.uploadFileHandler = multer({ storage: multer.diskStorage({ destination: (req, f, cb) => { - cb(null, path.resolve(ROOTPATH, appconfig.paths.data, 'temp-upload')) + cb(null, path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'temp-upload')) } }), fileFilter: (req, f, cb) => { @@ -95,35 +92,30 @@ module.exports = { /** * Creates a base directories (Synchronous). - * - * @param {Object} appconfig The application config - * @return {Void} Void */ - createBaseDirectories (appconfig) { - winston.info('Checking data directories...') - + createBaseDirectories () { try { - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data)) - fs.emptyDirSync(path.resolve(ROOTPATH, appconfig.paths.data)) - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './cache')) - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './thumbs')) - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './temp-upload')) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data)) + fs.emptyDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data)) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data, './cache')) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data, './thumbs')) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data, './temp-upload')) if (os.type() !== 'Windows_NT') { - fs.chmodSync(path.resolve(ROOTPATH, appconfig.paths.data, './temp-upload'), '755') + fs.chmodSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.data, './temp-upload'), '755') } - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.repo)) - fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.repo, './uploads')) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.repo)) + fs.ensureDirSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.repo, './uploads')) if (os.type() !== 'Windows_NT') { - fs.chmodSync(path.resolve(ROOTPATH, appconfig.paths.repo, './uploads'), '755') + fs.chmodSync(path.resolve(wiki.ROOTPATH, wiki.config.paths.repo, './uploads'), '755') } } catch (err) { - winston.error(err) + wiki.logger.error(err) } - winston.info('Data and Repository directories are OK.') + wiki.logger.info('Disk Data Paths: OK') }, /** @@ -154,7 +146,7 @@ module.exports = { */ validateUploadsFilename (f, fld, isImage) { let fObj = path.parse(f) - let fname = _.chain(fObj.name).trim().toLower().kebabCase().value().replace(new RegExp('[^a-z0-9-' + appdata.regex.cjk + appdata.regex.arabic + ']', 'g'), '') + let fname = _.chain(fObj.name).trim().toLower().kebabCase().value().replace(new RegExp('[^a-z0-9-' + wiki.data.regex.cjk + wiki.data.regex.arabic + ']', 'g'), '') let fext = _.toLower(fObj.ext) if (isImage && !_.includes(['.jpg', '.jpeg', '.png', '.gif', '.webp'], fext)) { @@ -165,7 +157,7 @@ module.exports = { let fpath = path.resolve(this._uploadsPath, fld, f) return fs.statAsync(fpath).then((s) => { - throw new Error(lang.t('errors:fileexists', { path: f })) + throw new Error(wiki.lang.t('errors:fileexists', { path: f })) }).catch((err) => { if (err.code === 'ENOENT') { return f diff --git a/server/libs/entries.js b/server/modules/documents.js similarity index 97% rename from server/libs/entries.js rename to server/modules/documents.js index af6f1104..8406be0d 100644 --- a/server/libs/entries.js +++ b/server/modules/documents.js @@ -1,6 +1,6 @@ 'use strict' -/* global db, git, lang, mark, rights, search, winston */ +/* global wiki */ const Promise = require('bluebird') const path = require('path') @@ -10,7 +10,7 @@ const _ = require('lodash') const entryHelper = require('../helpers/entry') /** - * Entries Model + * Documents Model */ module.exports = { @@ -25,10 +25,10 @@ module.exports = { init() { let self = this - self._repoPath = path.resolve(ROOTPATH, appconfig.paths.repo) - self._cachePath = path.resolve(ROOTPATH, appconfig.paths.data, 'cache') - appdata.repoPath = self._repoPath - appdata.cachePath = self._cachePath + self._repoPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo) + self._cachePath = path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'cache') + wiki.data.repoPath = self._repoPath + wiki.data.cachePath = self._cachePath return self }, diff --git a/server/libs/git.js b/server/modules/git.js similarity index 71% rename from server/libs/git.js rename to server/modules/git.js index 7787f37a..68f78e1f 100644 --- a/server/libs/git.js +++ b/server/modules/git.js @@ -1,6 +1,6 @@ 'use strict' -/* global lang, winston */ +/* global wiki */ const Git = require('git-wrapper2-promise') const Promise = require('bluebird') @@ -43,21 +43,19 @@ module.exports = { // -> Build repository path - if (_.isEmpty(appconfig.paths.repo)) { - self._repo.path = path.join(ROOTPATH, 'repo') + if (_.isEmpty(wiki.config.paths.repo)) { + self._repo.path = path.join(wiki.ROOTPATH, 'repo') } else { - self._repo.path = appconfig.paths.repo + self._repo.path = wiki.config.paths.repo } // -> Initialize repository - self.onReady = self._initRepo(appconfig) + self.onReady = (wiki.IS_MASTER) ? self._initRepo() : Promise.resolve() - if (appconfig.git) { - // Set repo branch - self._repo.branch = appconfig.git.branch || 'master' - // Define signature - self._signature.email = appconfig.git.serverEmail || 'wiki@example.com' + if (wiki.config.git) { + self._repo.branch = wiki.config.git.branch || 'master' + self._signature.email = wiki.config.git.serverEmail || 'wiki@example.com' } return self @@ -66,19 +64,17 @@ module.exports = { /** * Initialize Git repository * - * @param {Object} appconfig The application config + * @param {Object} wiki.config The application config * @return {Object} Promise */ - _initRepo(appconfig) { + _initRepo() { let self = this - winston.info('Checking Git repository...') - // -> Check if path is accessible return fs.mkdirAsync(self._repo.path).catch((err) => { if (err.code !== 'EEXIST') { - winston.error('Invalid Git repository path or missing permissions.') + wiki.logger.error('Invalid Git repository path or missing permissions.') } }).then(() => { self._git = new Git({ 'git-dir': self._repo.path }) @@ -92,28 +88,28 @@ module.exports = { self._repo.exists = false }) }).then(() => { - if (appconfig.git === false) { - winston.info('Remote Git syncing is disabled. Not recommended!') + if (wiki.config.git === false) { + wiki.logger.warn('Remote Git syncing is disabled. Not recommended!') return Promise.resolve(true) } // Initialize remote - let urlObj = URL.parse(appconfig.git.url) - if (appconfig.git.auth.type !== 'ssh') { - urlObj.auth = appconfig.git.auth.username + ':' + appconfig.git.auth.password + let urlObj = URL.parse(wiki.config.git.url) + if (wiki.config.git.auth.type !== 'ssh') { + urlObj.auth = wiki.config.git.auth.username + ':' + wiki.config.git.auth.password } self._url = URL.format(urlObj) let gitConfigs = [ () => { return self._git.exec('config', ['--local', 'user.name', 'Wiki']) }, () => { return self._git.exec('config', ['--local', 'user.email', self._signature.email]) }, - () => { return self._git.exec('config', ['--local', '--bool', 'http.sslVerify', _.toString(appconfig.git.auth.sslVerify)]) } + () => { return self._git.exec('config', ['--local', '--bool', 'http.sslVerify', _.toString(wiki.config.git.auth.sslVerify)]) } ] - if (appconfig.git.auth.type === 'ssh') { + if (wiki.config.git.auth.type === 'ssh') { gitConfigs.push(() => { - return self._git.exec('config', ['--local', 'core.sshCommand', 'ssh -i "' + appconfig.git.auth.privateKey + '" -o StrictHostKeyChecking=no']) + return self._git.exec('config', ['--local', 'core.sshCommand', 'ssh -i "' + wiki.config.git.auth.privateKey + '" -o StrictHostKeyChecking=no']) }) } @@ -126,14 +122,14 @@ module.exports = { return self._git.exec('remote', ['set-url', 'origin', self._url]) } }).catch(err => { - winston.error(err) + wiki.logger.error(err) }) }) }).catch((err) => { - winston.error('Git remote error!') + wiki.logger.error('Git remote error!') throw err }).then(() => { - winston.info('Git repository is OK.') + wiki.logger.info('Git Repository: OK') return true }) }, @@ -144,7 +140,7 @@ module.exports = { * @return {String} The repo path. */ getRepoPath() { - return this._repo.path || path.join(ROOTPATH, 'repo') + return this._repo.path || path.join(wiki.ROOTPATH, 'repo') }, /** @@ -157,18 +153,18 @@ module.exports = { // Is git remote disabled? - if (appconfig.git === false) { + if (wiki.config.git === false) { return Promise.resolve(true) } // Fetch - winston.info('Performing pull from remote Git repository...') + wiki.logger.info('Performing pull from remote Git repository...') return self._git.pull('origin', self._repo.branch).then((cProc) => { - winston.info('Git Pull completed.') + wiki.logger.info('Git Pull completed.') }) .catch((err) => { - winston.error('Unable to fetch from git origin!') + wiki.logger.error('Unable to fetch from git origin!') throw err }) .then(() => { @@ -178,19 +174,19 @@ module.exports = { let out = cProc.stdout.toString() if (_.includes(out, 'commit')) { - winston.info('Performing push to remote Git repository...') + wiki.logger.info('Performing push to remote Git repository...') return self._git.push('origin', self._repo.branch).then(() => { - return winston.info('Git Push completed.') + return wiki.logger.info('Git Push completed.') }) } else { - winston.info('Git Push skipped. Repository is already in sync.') + wiki.logger.info('Git Push skipped. Repository is already in sync.') } return true }) }) .catch((err) => { - winston.error('Unable to push changes to remote Git repository!') + wiki.logger.error('Unable to push changes to remote Git repository!') throw err }) }, @@ -210,7 +206,7 @@ module.exports = { let out = cProc.stdout.toString() return _.includes(out, gitFilePath) }).then((isTracked) => { - commitMsg = (isTracked) ? lang.t('git:updated', { path: gitFilePath }) : lang.t('git:added', { path: gitFilePath }) + commitMsg = (isTracked) ? wiki.lang.t('git:updated', { path: gitFilePath }) : wiki.lang.t('git:added', { path: gitFilePath }) return self._git.add(gitFilePath) }).then(() => { let commitUsr = securityHelper.sanitizeCommitUser(author) @@ -245,29 +241,6 @@ module.exports = { }) }, - /** - * Delete a document. - * - * @param {String} entryPath The entry path - * @return {Promise} Resolve on success - */ - deleteDocument(entryPath, author) { - let self = this - let gitFilePath = entryPath + '.md' - - return this._git.exec('rm', [gitFilePath]).then((cProc) => { - let out = cProc.stdout.toString() - if (_.includes(out, 'fatal')) { - let errorMsg = _.capitalize(_.head(_.split(_.replace(out, 'fatal: ', ''), ','))) - throw new Error(errorMsg) - } - let commitUsr = securityHelper.sanitizeCommitUser(author) - return self._git.exec('commit', ['-m', lang.t('git:deleted', { path: gitFilePath }), '--author="' + commitUsr.name + ' <' + commitUsr.email + '>"']).catch((err) => { - if (_.includes(err.stdout, 'nothing to commit')) { return true } - }) - }) - }, - /** * Commits uploads changes. * diff --git a/server/modules/graphql.js b/server/modules/graphql.js new file mode 100644 index 00000000..aa6a6f7d --- /dev/null +++ b/server/modules/graphql.js @@ -0,0 +1,43 @@ +'use strict' + +/* global wiki */ + +const gqlTools = require('graphql-tools') +const fs = require('fs') +const path = require('path') +const _ = require('lodash') + +const typeDefs = fs.readFileSync(path.join(wiki.SERVERPATH, 'schemas/types.graphql'), 'utf8') + +const DateScalar = require('../schemas/scalar-date') +const AuthenticationResolvers = require('../schemas/resolvers-authentication') +const CommentResolvers = require('../schemas/resolvers-comment') +const DocumentResolvers = require('../schemas/resolvers-document') +const FileResolvers = require('../schemas/resolvers-file') +const FolderResolvers = require('../schemas/resolvers-folder') +const GroupResolvers = require('../schemas/resolvers-group') +const SettingResolvers = require('../schemas/resolvers-setting') +const TagResolvers = require('../schemas/resolvers-tag') +const TranslationResolvers = require('../schemas/resolvers-translation') +const UserResolvers = require('../schemas/resolvers-user') + +const resolvers = _.merge( + AuthenticationResolvers, + CommentResolvers, + DocumentResolvers, + FileResolvers, + FolderResolvers, + GroupResolvers, + SettingResolvers, + TagResolvers, + TranslationResolvers, + UserResolvers, + DateScalar +) + +const Schema = gqlTools.makeExecutableSchema({ + typeDefs, + resolvers +}) + +module.exports = Schema diff --git a/server/modules/kernel.js b/server/modules/kernel.js new file mode 100644 index 00000000..48e1659f --- /dev/null +++ b/server/modules/kernel.js @@ -0,0 +1,91 @@ +const cluster = require('cluster') +const Promise = require('bluebird') +const _ = require('lodash') + +/* global wiki */ + +module.exports = { + numWorkers: 1, + workers: [], + init() { + if (cluster.isMaster) { + wiki.logger.info('=======================================') + wiki.logger.info('= Wiki.js =============================') + wiki.logger.info('=======================================') + + wiki.redis = require('./redis').init() + wiki.queue = require('./queue').init() + + this.setWorkerLimit() + this.bootMaster() + } else { + this.bootWorker() + } + }, + /** + * Pre-Master Boot Sequence + */ + preBootMaster() { + return Promise.mapSeries([ + () => { return wiki.db.onReady }, + () => { return wiki.configSvc.loadFromDb() }, + () => { return wiki.queue.clean() } + ], fn => { return fn() }) + }, + /** + * Boot Master Process + */ + bootMaster() { + this.preBootMaster().then(sequenceResults => { + if (_.every(sequenceResults, rs => rs === true)) { + this.postBootMaster() + } else { + wiki.logger.info('Starting configuration manager...') + require('../configure')() + } + return true + }).catch(err => { + wiki.logger.error(err) + process.exit(1) + }) + }, + /** + * Post-Master Boot Sequence + */ + postBootMaster() { + require('../master')().then(() => { + _.times(this.numWorker, this.spawnWorker) + + wiki.queue.uplClearTemp.add({}, { + repeat: { cron: '*/15 * * * *' } + }) + }) + + cluster.on('exit', (worker, code, signal) => { + wiki.logger.info(`Background Worker #${worker.id} was terminated.`) + }) + }, + /** + * Boot Worker Process + */ + bootWorker() { + wiki.logger.info(`Background Worker #${cluster.worker.id} is initializing...`) + require('../worker') + }, + /** + * Spawn new Worker process + */ + spawnWorker() { + this.workers.push(cluster.fork()) + }, + /** + * Set Worker count based on config + system capabilities + */ + setWorkerLimit() { + const numCPUs = require('os').cpus().length + this.numWorkers = (wiki.config.workers > 0) ? wiki.config.workers : numCPUs + if (this.numWorkers > numCPUs) { + this.numWorkers = numCPUs + } + } +} diff --git a/server/modules/localization.js b/server/modules/localization.js new file mode 100644 index 00000000..d832935b --- /dev/null +++ b/server/modules/localization.js @@ -0,0 +1,52 @@ +const _ = require('lodash') +const dotize = require('dotize') +const i18nBackend = require('i18next-node-fs-backend') +const i18next = require('i18next') +const path = require('path') +const Promise = require('bluebird') + +/* global wiki */ + +module.exports = { + engine: null, + namespaces: ['common', 'admin', 'auth', 'errors', 'git'], + init() { + this.engine = i18next + this.engine.use(i18nBackend).init({ + load: 'languageOnly', + ns: this.namespaces, + defaultNS: 'common', + saveMissing: false, + preload: [wiki.config.site.lang], + lng: wiki.config.site.lang, + fallbackLng: 'en', + backend: { + loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.json') + } + }) + return this + }, + getByNamespace(locale, namespace) { + if (this.engine.hasResourceBundle(locale, namespace)) { + let data = this.engine.getResourceBundle(locale, namespace) + return _.map(dotize.convert(data), (value, key) => { + return { + key, + value + } + }) + } else { + throw new Error('Invalid locale or namespace') + } + }, + loadLocale(locale) { + return Promise.fromCallback(cb => { + return this.engine.loadLanguages(locale, cb) + }) + }, + setCurrentLocale(locale) { + return Promise.fromCallback(cb => { + return this.engine.changeLanguage(locale, cb) + }) + } +} diff --git a/server/modules/logger.js b/server/modules/logger.js new file mode 100644 index 00000000..8b134d05 --- /dev/null +++ b/server/modules/logger.js @@ -0,0 +1,80 @@ +'use strict' + +/* global wiki */ + +const cluster = require('cluster') + +module.exports = { + init() { + let winston = require('winston') + + // Console + + let logger = new (winston.Logger)({ + level: (wiki.IS_DEBUG) ? 'debug' : 'info', + transports: [ + new (winston.transports.Console)({ + level: (wiki.IS_DEBUG) ? 'debug' : 'info', + prettyPrint: true, + colorize: true, + silent: false, + timestamp: true + }) + ] + }) + + logger.filters.push((level, msg) => { + let processName = (cluster.isMaster) ? 'MASTER' : `WORKER-${cluster.worker.id}` + return '[' + processName + '] ' + msg + }) + + // External services + + // if (wiki.config.externalLogging.bugsnag) { + // const bugsnagTransport = require('./winston-transports/bugsnag') + // logger.add(bugsnagTransport, { + // level: 'warn', + // key: wiki.config.externalLogging.bugsnag + // }) + // } + + // if (wiki.config.externalLogging.loggly) { + // require('winston-loggly-bulk') + // logger.add(winston.transports.Loggly, { + // token: wiki.config.externalLogging.loggly.token, + // subdomain: wiki.config.externalLogging.loggly.subdomain, + // tags: ['wiki-js'], + // level: 'warn', + // json: true + // }) + // } + + // if (wiki.config.externalLogging.papertrail) { + // require('winston-papertrail').Papertrail // eslint-disable-line no-unused-expressions + // logger.add(winston.transports.Papertrail, { + // host: wiki.config.externalLogging.papertrail.host, + // port: wiki.config.externalLogging.papertrail.port, + // level: 'warn', + // program: 'wiki.js' + // }) + // } + + // if (wiki.config.externalLogging.rollbar) { + // const rollbarTransport = require('./winston-transports/rollbar') + // logger.add(rollbarTransport, { + // level: 'warn', + // key: wiki.config.externalLogging.rollbar + // }) + // } + + // if (wiki.config.externalLogging.sentry) { + // const sentryTransport = require('./winston-transports/sentry') + // logger.add(sentryTransport, { + // level: 'warn', + // key: wiki.config.externalLogging.sentry + // }) + // } + + return logger + } +} diff --git a/server/libs/markdown.js b/server/modules/markdown.js similarity index 96% rename from server/libs/markdown.js rename to server/modules/markdown.js index 14b0c887..71e0ea54 100644 --- a/server/libs/markdown.js +++ b/server/modules/markdown.js @@ -1,6 +1,6 @@ 'use strict' -/* global winston */ +/* global wiki */ const Promise = require('bluebird') const md = require('markdown-it') @@ -23,11 +23,12 @@ const mdRemove = require('remove-markdown') var mkdown = md({ html: true, - breaks: appconfig.features.linebreaks, + // breaks: wiki.config.features.linebreaks, + breaks: true, linkify: true, typography: true, highlight(str, lang) { - if (appconfig.theme.code.colorize && lang && hljs.getLanguage(lang)) { + if (wiki.config.theme.code.colorize && lang && hljs.getLanguage(lang)) { try { return '
' + hljs.highlight(lang, str, true).value + '
' } catch (err) { @@ -57,7 +58,8 @@ var mkdown = md({ }) .use(mdAttrs) -if (appconfig.features.mathjax) { +// if (wiki.config.features.mathjax) { +if (true) { mkdown.use(mdMathjax) } @@ -94,7 +96,7 @@ const videoRules = [ // Regex -const textRegex = new RegExp('\\b[a-z0-9-.,' + appdata.regex.cjk + appdata.regex.arabic + ']+\\b', 'g') +const textRegex = new RegExp('\\b[a-z0-9-.,' + wiki.data.regex.cjk + wiki.data.regex.arabic + ']+\\b', 'g') const mathRegex = [ { format: 'TeX', @@ -301,7 +303,7 @@ const parseContent = (content) => { // Mathjax Post-processor - if (appconfig.features.mathjax) { + if (wiki.config.features.mathjax) { return processMathjax(cr.html()) } else { return Promise.resolve(cr.html()) @@ -339,7 +341,7 @@ const processMathjax = (content) => { resolve(result.svg) } else { resolve(currentMatch[0]) - winston.warn(result.errors.join(', ')) + wiki.logger.warn(result.errors.join(', ')) } }) }) diff --git a/server/modules/queue.js b/server/modules/queue.js new file mode 100644 index 00000000..4bbb6dc0 --- /dev/null +++ b/server/modules/queue.js @@ -0,0 +1,37 @@ +'use strict' + +/* global wiki */ + +const Bull = require('bull') +const Promise = require('bluebird') + +module.exports = { + init() { + wiki.data.queues.forEach(queueName => { + this[queueName] = new Bull(queueName, { + prefix: `q-${wiki.config.ha.nodeuid}`, + redis: wiki.config.redis + }) + }) + return this + }, + clean() { + return Promise.each(wiki.data.queues, queueName => { + return new Promise((resolve, reject) => { + let keyStream = wiki.redis.scanStream({ + match: `q-${wiki.config.ha.nodeuid}:${queueName}:*` + }) + keyStream.on('data', resultKeys => { + if (resultKeys.length > 0) { + wiki.redis.del(resultKeys) + } + }) + keyStream.on('end', resolve) + }) + }).then(() => { + wiki.logger.info('Purging old queue jobs: OK') + }).return(true).catch(err => { + wiki.logger.error(err) + }) + } +} diff --git a/server/modules/redis.js b/server/modules/redis.js new file mode 100644 index 00000000..6eb7999b --- /dev/null +++ b/server/modules/redis.js @@ -0,0 +1,33 @@ +'use strict' + +/* global wiki */ + +const Redis = require('ioredis') +const { isPlainObject } = require('lodash') + +/** + * Redis module + * + * @return {Object} Redis client wrapper instance + */ +module.exports = { + + /** + * Initialize Redis client + * + * @return {Object} Redis client instance + */ + init() { + if (isPlainObject(wiki.config.redis)) { + let red = new Redis(wiki.config.redis) + red.on('ready', () => { + wiki.logger.info('Redis connection: OK') + }) + return red + } else { + wiki.logger.error('Invalid Redis configuration!') + process.exit(1) + } + } + +} diff --git a/server/libs/rights.js b/server/modules/rights.js similarity index 94% rename from server/libs/rights.js rename to server/modules/rights.js index ce82882b..d06de758 100644 --- a/server/libs/rights.js +++ b/server/modules/rights.js @@ -1,6 +1,6 @@ 'use strict' -/* global db */ +/* global wiki */ const _ = require('lodash') @@ -32,8 +32,8 @@ module.exports = { init () { let self = this - db.onReady.then(() => { - db.User.findOne({ provider: 'local', email: 'guest' }).then((u) => { + wiki.db.onReady.then(() => { + wiki.db.User.findOne({ provider: 'local', email: 'guest' }).then((u) => { if (u) { self.guest = u } diff --git a/server/libs/search.js b/server/modules/search.js similarity index 87% rename from server/libs/search.js rename to server/modules/search.js index 7c446b17..7801a739 100644 --- a/server/libs/search.js +++ b/server/modules/search.js @@ -1,13 +1,13 @@ 'use strict' -/* global winston */ +/* global wiki */ const Promise = require('bluebird') const _ = require('lodash') -const searchIndex = require('./search-index') +// const searchIndex = require('./search-index') const stopWord = require('stopword') const streamToPromise = require('stream-to-promise') -const searchAllowedChars = new RegExp('[^a-z0-9' + appdata.regex.cjk + appdata.regex.arabic + ' ]', 'g') +const searchAllowedChars = new RegExp('[^a-z0-9' + wiki.data.regex.cjk + wiki.data.regex.arabic + ' ]', 'g') module.exports = { @@ -22,24 +22,24 @@ module.exports = { init () { let self = this self._isReady = new Promise((resolve, reject) => { - searchIndex({ + /*searchIndex({ deletable: true, fieldedSearch: true, indexPath: 'wiki', logLevel: 'error', - stopwords: _.get(stopWord, appconfig.lang, []) + stopwords: _.get(stopWord, wiki.config.lang, []) }, (err, si) => { if (err) { - winston.error('Failed to initialize search index.', err) + wiki.logger.error('Failed to initialize search index.', err) reject(err) } else { self._si = Promise.promisifyAll(si) self._si.flushAsync().then(() => { - winston.info('Search index flushed and ready.') + wiki.logger.info('Search index flushed and ready.') resolve(true) }) } - }) + }) */ }) return self @@ -95,13 +95,13 @@ module.exports = { parent: content.parent || '', content: content.text || '' }]).then(() => { - winston.log('verbose', 'Entry ' + content._id + ' added/updated to search index.') + wiki.logger.log('verbose', 'Entry ' + content._id + ' added/updated to search index.') return true }).catch((err) => { - winston.error(err) + wiki.logger.error(err) }) }).catch((err) => { - winston.error(err) + wiki.logger.error(err) }) }) }, @@ -131,7 +131,7 @@ module.exports = { if (err.type === 'NotFoundError') { return true } else { - winston.error(err) + wiki.logger.error(err) } }) }) @@ -204,7 +204,7 @@ module.exports = { suggest: [] } } else { - winston.error(err) + wiki.logger.error(err) } }) } diff --git a/server/libs/system.js b/server/modules/system.js similarity index 100% rename from server/libs/system.js rename to server/modules/system.js diff --git a/server/libs/uploads-agent.js b/server/modules/uploads-agent.js similarity index 88% rename from server/libs/uploads-agent.js rename to server/modules/uploads-agent.js index a8ae79ec..6b861733 100644 --- a/server/libs/uploads-agent.js +++ b/server/modules/uploads-agent.js @@ -1,6 +1,6 @@ 'use strict' -/* global db, git, lang, upl */ +/* global wiki */ const path = require('path') const Promise = require('bluebird') @@ -32,8 +32,8 @@ module.exports = { init () { let self = this - self._uploadsPath = path.resolve(ROOTPATH, appconfig.paths.repo, 'uploads') - self._uploadsThumbsPath = path.resolve(ROOTPATH, appconfig.paths.data, 'thumbs') + self._uploadsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo, 'uploads') + self._uploadsThumbsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'thumbs') return self }, @@ -59,16 +59,16 @@ module.exports = { self._watcher.on('add', (p) => { let pInfo = self.parseUploadsRelPath(p) return self.processFile(pInfo.folder, pInfo.filename).then((mData) => { - return db.UplFile.findByIdAndUpdate(mData._id, mData, { upsert: true }) + return wiki.db.UplFile.findByIdAndUpdate(mData._id, mData, { upsert: true }) }).then(() => { - return git.commitUploads(lang.t('git:uploaded', { path: p })) + return wiki.git.commitUploads(wiki.lang.t('git:uploaded', { path: p })) }) }) // -> Remove upload file self._watcher.on('unlink', (p) => { - return git.commitUploads(lang.t('git:deleted', { path: p })) + return wiki.git.commitUploads(wiki.lang.t('git:deleted', { path: p })) }) }, @@ -91,8 +91,8 @@ module.exports = { // Add folders to DB - return db.UplFolder.remove({}).then(() => { - return db.UplFolder.insertMany(_.map(folderNames, (f) => { + return wiki.db.UplFolder.remove({}).then(() => { + return wiki.db.UplFolder.insertMany(_.map(folderNames, (f) => { return { _id: 'f:' + f, name: f @@ -107,7 +107,7 @@ module.exports = { let fldPath = path.join(self._uploadsPath, fldName) return fs.readdirAsync(fldPath).then((fList) => { return Promise.map(fList, (f) => { - return upl.processFile(fldName, f).then((mData) => { + return wiki.upl.processFile(fldName, f).then((mData) => { if (mData) { allFiles.push(mData) } @@ -118,9 +118,9 @@ module.exports = { }, {concurrency: 1}).finally(() => { // Add files to DB - return db.UplFile.remove({}).then(() => { + return wiki.db.UplFile.remove({}).then(() => { if (_.isArray(allFiles) && allFiles.length > 0) { - return db.UplFile.insertMany(allFiles) + return wiki.db.UplFile.insertMany(allFiles) } else { return true } @@ -131,7 +131,7 @@ module.exports = { }).then(() => { // Watch for new changes - return upl.watch() + return wiki.upl.watch() }) }, diff --git a/server/libs/uploads.js b/server/modules/uploads.js similarity index 81% rename from server/libs/uploads.js rename to server/modules/uploads.js index 2bee6322..f56ecab3 100644 --- a/server/libs/uploads.js +++ b/server/modules/uploads.js @@ -1,6 +1,6 @@ 'use strict' -/* global db, lang, lcdata, upl, winston */ +/* global wiki */ const path = require('path') const Promise = require('bluebird') @@ -27,8 +27,8 @@ module.exports = { * @return {Object} Uploads model instance */ init () { - this._uploadsPath = path.resolve(ROOTPATH, appconfig.paths.repo, 'uploads') - this._uploadsThumbsPath = path.resolve(ROOTPATH, appconfig.paths.data, 'thumbs') + this._uploadsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo, 'uploads') + this._uploadsThumbsPath = path.resolve(wiki.ROOTPATH, wiki.config.paths.data, 'thumbs') return this }, @@ -48,7 +48,7 @@ module.exports = { * @return {Array} The uploads folders. */ getUploadsFolders () { - return db.UplFolder.find({}, 'name').sort('name').exec().then((results) => { + return wiki.db.Folder.find({}, 'name').sort('name').exec().then((results) => { return (results) ? _.map(results, 'name') : [{ name: '' }] }) }, @@ -69,7 +69,7 @@ module.exports = { } return fs.ensureDirAsync(path.join(self._uploadsPath, folderName)).then(() => { - return db.UplFolder.findOneAndUpdate({ + return wiki.db.UplFolder.findOneAndUpdate({ _id: 'f:' + folderName }, { name: folderName @@ -88,7 +88,7 @@ module.exports = { * @return {Boolean} True if valid */ validateUploadsFolder (folderName) { - return db.UplFolder.findOne({ name: folderName }).then((f) => { + return wiki.db.UplFolder.findOne({ name: folderName }).then((f) => { return (f) ? path.resolve(this._uploadsPath, folderName) : false }) }, @@ -101,7 +101,7 @@ module.exports = { */ addUploadsFiles (arrFiles) { if (_.isArray(arrFiles) || _.isPlainObject(arrFiles)) { - // this._uploadsDb.Files.insert(arrFiles); + // this._uploadswiki.Db.Files.insert(arrFiles); } }, @@ -113,7 +113,7 @@ module.exports = { * @return {Array} The files matching the query */ getUploadsFiles (cat, fld) { - return db.UplFile.find({ + return wiki.db.UplFile.find({ category: cat, folder: 'f:' + fld }).sort('filename').exec() @@ -128,7 +128,7 @@ module.exports = { deleteUploadsFile (uid) { let self = this - return db.UplFile.findOneAndRemove({ _id: uid }).then((f) => { + return wiki.db.UplFile.findOneAndRemove({ _id: uid }).then((f) => { if (f) { return self.deleteUploadsFileTry(f, 0) } @@ -150,7 +150,7 @@ module.exports = { return self.deleteUploadsFileTry(f, attempt + 1) }) } else { - winston.warn('Unable to delete uploads file ' + f.filename + '. File is locked by another process and multiple attempts failed.') + wiki.logger.warn('Unable to delete uploads file ' + f.filename + '. File is locked by another process and multiple attempts failed.') return true } }) @@ -168,12 +168,12 @@ module.exports = { let fUrlFilename = _.last(_.split(fUrlObj.pathname, '/')) let destFolder = _.chain(fFolder).trim().toLower().value() - return upl.validateUploadsFolder(destFolder).then((destFolderPath) => { + return wiki.upl.validateUploadsFolder(destFolder).then((destFolderPath) => { if (!destFolderPath) { - return Promise.reject(new Error(lang.t('errors:invalidfolder'))) + return Promise.reject(new Error(wiki.lang.t('errors:invalidfolder'))) } - return lcdata.validateUploadsFilename(fUrlFilename, destFolder).then((destFilename) => { + return wiki.disk.validateUploadsFilename(fUrlFilename, destFolder).then((destFilename) => { let destFilePath = path.resolve(destFolderPath, destFilename) return new Promise((resolve, reject) => { @@ -194,7 +194,7 @@ module.exports = { rq.abort() destFileStream.destroy() fs.remove(destFilePath) - reject(new Error(lang.t('errors:remotetoolarge'))) + reject(new Error(wiki.lang.t('errors:remotetoolarge'))) } }).on('error', (err) => { destFileStream.destroy() @@ -223,15 +223,15 @@ module.exports = { moveUploadsFile (uid, fld, nFilename) { let self = this - return db.UplFolder.findById('f:' + fld).then((folder) => { + return wiki.db.UplFolder.finwiki.dById('f:' + fld).then((folder) => { if (folder) { - return db.UplFile.findById(uid).then((originFile) => { + return wiki.db.UplFile.finwiki.dById(uid).then((originFile) => { // -> Check if rename is valid let nameCheck = null if (nFilename) { let originFileObj = path.parse(originFile.filename) - nameCheck = lcdata.validateUploadsFilename(nFilename + originFileObj.ext, folder.name) + nameCheck = wiki.disk.validateUploadsFilename(nFilename + originFileObj.ext, folder.name) } else { nameCheck = Promise.resolve(originFile.filename) } @@ -245,12 +245,12 @@ module.exports = { // -> Check for invalid operations if (sourceFilePath === destFilePath) { - return Promise.reject(new Error(lang.t('errors:invalidoperation'))) + return Promise.reject(new Error(wiki.lang.t('errors:invalidoperation'))) } - // -> Delete DB entry + // -> Delete wiki.DB entry - preMoveOps.push(db.UplFile.findByIdAndRemove(uid)) + preMoveOps.push(wiki.db.UplFile.finwiki.dByIdAndRemove(uid)) // -> Move thumbnail ahead to avoid re-generation @@ -273,7 +273,7 @@ module.exports = { }) }) } else { - return Promise.reject(new Error(lang.t('errors:invaliddestfolder'))) + return Promise.reject(new Error(wiki.lang.t('errors:invaliddestfolder'))) } }) } diff --git a/server/libs/winston-transports/bugsnag.js b/server/modules/winston-transports/bugsnag.js similarity index 100% rename from server/libs/winston-transports/bugsnag.js rename to server/modules/winston-transports/bugsnag.js diff --git a/server/libs/winston-transports/rollbar.js b/server/modules/winston-transports/rollbar.js similarity index 100% rename from server/libs/winston-transports/rollbar.js rename to server/modules/winston-transports/rollbar.js diff --git a/server/libs/winston-transports/sentry.js b/server/modules/winston-transports/sentry.js similarity index 100% rename from server/libs/winston-transports/sentry.js rename to server/modules/winston-transports/sentry.js diff --git a/server/queues/git-sync.js b/server/queues/git-sync.js new file mode 100644 index 00000000..6c46e8ef --- /dev/null +++ b/server/queues/git-sync.js @@ -0,0 +1,68 @@ +'use strict' + +/* global wiki */ + +const Promise = require('bluebird') +const fs = Promise.promisifyAll(require('fs-extra')) +const klaw = require('klaw') +const moment = require('moment') +const path = require('path') +const entryHelper = require('../helpers/entry') + +module.exports = (job) => { + return wiki.git.resync().then(() => { + // -> Stream all documents + + let cacheJobs = [] + let jobCbStreamDocsResolve = null + let jobCbStreamDocs = new Promise((resolve, reject) => { + jobCbStreamDocsResolve = resolve + }) + + klaw(wiki.REPOPATH).on('data', function (item) { + if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') { + let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path)) + let cachePath = entryHelper.getCachePath(entryPath) + + // -> Purge outdated cache + + cacheJobs.push( + fs.statAsync(cachePath).then((st) => { + return moment(st.mtime).isBefore(item.stats.mtime) ? 'expired' : 'active' + }).catch((err) => { + return (err.code !== 'EEXIST') ? err : 'new' + }).then((fileStatus) => { + // -> Delete expired cache file + + if (fileStatus === 'expired') { + return fs.unlinkAsync(cachePath).return(fileStatus) + } + + return fileStatus + }).then((fileStatus) => { + // -> Update cache and search index + + if (fileStatus !== 'active') { + return global.entries.updateCache(entryPath).then(entry => { + process.send({ + action: 'searchAdd', + content: entry + }) + return true + }) + } + + return true + }) + ) + } + }).on('end', () => { + jobCbStreamDocsResolve(Promise.all(cacheJobs)) + }) + + return jobCbStreamDocs + }).then(() => { + wiki.logger.info('Git remote repository sync: DONE') + return true + }) +} diff --git a/server/queues/upl-clear-temp.js b/server/queues/upl-clear-temp.js new file mode 100644 index 00000000..9c3a1b5b --- /dev/null +++ b/server/queues/upl-clear-temp.js @@ -0,0 +1,29 @@ +'use strict' + +/* global wiki */ + +const Promise = require('bluebird') +const fs = Promise.promisifyAll(require('fs-extra')) +const moment = require('moment') +const path = require('path') + +module.exports = (job) => { + return fs.readdirAsync(wiki.UPLTEMPPATH).then((ls) => { + let fifteenAgo = moment().subtract(15, 'minutes') + + return Promise.map(ls, (f) => { + return fs.statAsync(path.join(wiki.UPLTEMPPATH, f)).then((s) => { return { filename: f, stat: s } }) + }).filter((s) => { return s.stat.isFile() }).then((arrFiles) => { + return Promise.map(arrFiles, (f) => { + if (moment(f.stat.ctime).isBefore(fifteenAgo, 'minute')) { + return fs.unlinkAsync(path.join(wiki.UPLTEMPPATH, f.filename)) + } else { + return true + } + }) + }) + }).then(() => { + wiki.logger.info('Purging temporary upload files: DONE') + return true + }) +} diff --git a/server/schemas/resolvers-authentication.js b/server/schemas/resolvers-authentication.js new file mode 100644 index 00000000..572c9d37 --- /dev/null +++ b/server/schemas/resolvers-authentication.js @@ -0,0 +1,40 @@ +const _ = require('lodash') +const fs = require('fs-extra') +const path = require('path') + +/* global wiki */ + +module.exports = { + Query: { + authentication(obj, args, context, info) { + switch (args.mode) { + case 'active': + let strategies = _.chain(wiki.auth.strategies).map(str => { + return { + key: str.key, + title: str.title, + useForm: str.useForm + } + }).sortBy(['title']).value() + let localStrategy = _.remove(strategies, str => str.key === 'local') + return _.concat(localStrategy, strategies) + case 'all': + + break + default: + return null + } + } + }, + Mutation: {}, + AuthenticationProvider: { + icon (ap, args) { + return fs.readFileAsync(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${ap.key}.svg`), 'utf8').catch(err => { + if (err.code === 'ENOENT') { + return null + } + throw err + }) + } + } +} diff --git a/server/schemas/resolvers-comment.js b/server/schemas/resolvers-comment.js new file mode 100644 index 00000000..fec565b3 --- /dev/null +++ b/server/schemas/resolvers-comment.js @@ -0,0 +1,42 @@ + +/* global wiki */ + +module.exports = { + Query: { + comments(obj, args, context, info) { + return wiki.db.Comment.findAll({ where: args }) + } + }, + Mutation: { + createComment(obj, args) { + return wiki.db.Comment.create({ + content: args.content, + author: args.userId, + document: args.documentId + }) + }, + deleteComment(obj, args) { + return wiki.db.Comment.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + modifyComment(obj, args) { + return wiki.db.Comment.update({ + content: args.content + }, { + where: { id: args.id } + }) + } + }, + Comment: { + author(cm) { + return cm.getAuthor() + }, + document(cm) { + return cm.getDocument() + } + } +} diff --git a/server/schemas/resolvers-document.js b/server/schemas/resolvers-document.js new file mode 100644 index 00000000..41dc9160 --- /dev/null +++ b/server/schemas/resolvers-document.js @@ -0,0 +1,46 @@ + +/* global wiki */ + +module.exports = { + Query: { + documents(obj, args, context, info) { + return wiki.db.Document.findAll({ where: args }) + } + }, + Mutation: { + createDocument(obj, args) { + return wiki.db.Document.create(args) + }, + deleteDocument(obj, args) { + return wiki.db.Document.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + modifyDocument(obj, args) { + return wiki.db.Document.update({ + title: args.title, + subtitle: args.subtitle + }, { + where: { id: args.id } + }) + }, + moveDocument(obj, args) { + return wiki.db.Document.update({ + path: args.path + }, { + where: { id: args.id } + }) + } + }, + Document: { + comments(doc) { + return doc.getComments() + }, + tags(doc) { + return doc.getTags() + } + } +} diff --git a/server/schemas/resolvers-file.js b/server/schemas/resolvers-file.js new file mode 100644 index 00000000..c8913413 --- /dev/null +++ b/server/schemas/resolvers-file.js @@ -0,0 +1,51 @@ + +/* global wiki */ + +const gql = require('graphql') + +module.exports = { + Query: { + files(obj, args, context, info) { + return wiki.db.File.findAll({ where: args }) + } + }, + Mutation: { + uploadFile(obj, args) { + // todo + return wiki.db.File.create(args) + }, + deleteFile(obj, args) { + return wiki.db.File.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + renameFile(obj, args) { + return wiki.db.File.update({ + filename: args.filename + }, { + where: { id: args.id } + }) + }, + moveFile(obj, args) { + return wiki.db.File.findById(args.fileId).then(fl => { + if (!fl) { + throw new gql.GraphQLError('Invalid File ID') + } + return wiki.db.Folder.findById(args.folderId).then(fld => { + if (!fld) { + throw new gql.GraphQLError('Invalid Folder ID') + } + return fl.setFolder(fld) + }) + }) + } + }, + File: { + folder(fl) { + return fl.getFolder() + } + } +} diff --git a/server/schemas/resolvers-folder.js b/server/schemas/resolvers-folder.js new file mode 100644 index 00000000..b7fc9a2b --- /dev/null +++ b/server/schemas/resolvers-folder.js @@ -0,0 +1,35 @@ + +/* global wiki */ + +module.exports = { + Query: { + folders(obj, args, context, info) { + return wiki.db.Folder.findAll({ where: args }) + } + }, + Mutation: { + createFolder(obj, args) { + return wiki.db.Folder.create(args) + }, + deleteGroup(obj, args) { + return wiki.db.Folder.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + renameFolder(obj, args) { + return wiki.db.Folder.update({ + name: args.name + }, { + where: { id: args.id } + }) + } + }, + Folder: { + files(grp) { + return grp.getFiles() + } + } +} diff --git a/server/schemas/resolvers-group.js b/server/schemas/resolvers-group.js new file mode 100644 index 00000000..cc9b10b7 --- /dev/null +++ b/server/schemas/resolvers-group.js @@ -0,0 +1,63 @@ + +/* global wiki */ + +const gql = require('graphql') + +module.exports = { + Query: { + groups(obj, args, context, info) { + return wiki.db.Group.findAll({ where: args }) + } + }, + Mutation: { + assignUserToGroup(obj, args) { + return wiki.db.Group.findById(args.groupId).then(grp => { + if (!grp) { + throw new gql.GraphQLError('Invalid Group ID') + } + return wiki.db.User.findById(args.userId).then(usr => { + if (!usr) { + throw new gql.GraphQLError('Invalid User ID') + } + return grp.addUser(usr) + }) + }) + }, + createGroup(obj, args) { + return wiki.db.Group.create(args) + }, + deleteGroup(obj, args) { + return wiki.db.Group.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + removeUserFromGroup(obj, args) { + return wiki.db.Group.findById(args.groupId).then(grp => { + if (!grp) { + throw new gql.GraphQLError('Invalid Group ID') + } + return wiki.db.User.findById(args.userId).then(usr => { + if (!usr) { + throw new gql.GraphQLError('Invalid User ID') + } + return grp.removeUser(usr) + }) + }) + }, + renameGroup(obj, args) { + return wiki.db.Group.update({ + name: args.name + }, { + where: { id: args.id } + }) + } + }, + Group: { + users(grp) { + return grp.getUsers() + } + } +} diff --git a/server/schemas/resolvers-right.js b/server/schemas/resolvers-right.js new file mode 100644 index 00000000..3b286deb --- /dev/null +++ b/server/schemas/resolvers-right.js @@ -0,0 +1,53 @@ + +/* global wiki */ + +const gql = require('graphql') + +module.exports = { + Query: { + rights(obj, args, context, info) { + return wiki.db.Right.findAll({ where: args }) + } + }, + Mutation: { + addRightToGroup(obj, args) { + return wiki.db.Group.findById(args.groupId).then(grp => { + if (!grp) { + throw new gql.GraphQLError('Invalid Group ID') + } + return wiki.db.Right.create({ + path: args.path, + role: args.role, + exact: args.exact, + allow: args.allow, + group: grp + }) + }) + }, + removeRightFromGroup(obj, args) { + return wiki.db.Right.destroy({ + where: { + id: args.rightId + }, + limit: 1 + }) + }, + modifyRight(obj, args) { + return wiki.db.Right.update({ + path: args.path, + role: args.role, + exact: args.exact, + allow: args.allow + }, { + where: { + id: args.id + } + }) + } + }, + Right: { + group(rt) { + return rt.getGroup() + } + } +} diff --git a/server/schemas/resolvers-setting.js b/server/schemas/resolvers-setting.js new file mode 100644 index 00000000..dc0c4f9e --- /dev/null +++ b/server/schemas/resolvers-setting.js @@ -0,0 +1,24 @@ + +/* global wiki */ + +const _ = require('lodash') + +module.exports = { + Query: { + settings(obj, args, context, info) { + return wiki.db.Setting.findAll({ where: args, raw: true }).then(entries => { + return _.map(entries, entry => { + entry.config = JSON.stringify(entry.config) + return entry + }) + }) + } + }, + Mutation: { + setConfigEntry(obj, args) { + return wiki.db.Setting.update({ + value: args.value + }, { where: { key: args.key } }) + } + } +} diff --git a/server/schemas/resolvers-tag.js b/server/schemas/resolvers-tag.js new file mode 100644 index 00000000..0aa3e89e --- /dev/null +++ b/server/schemas/resolvers-tag.js @@ -0,0 +1,63 @@ + +/* global wiki */ + +const gql = require('graphql') + +module.exports = { + Query: { + tags(obj, args, context, info) { + return wiki.db.Tag.findAll({ where: args }) + } + }, + Mutation: { + assignTagToDocument(obj, args) { + return wiki.db.Tag.findById(args.tagId).then(tag => { + if (!tag) { + throw new gql.GraphQLError('Invalid Tag ID') + } + return wiki.db.Document.findById(args.documentId).then(doc => { + if (!doc) { + throw new gql.GraphQLError('Invalid Document ID') + } + return tag.addDocument(doc) + }) + }) + }, + createTag(obj, args) { + return wiki.db.Tag.create(args) + }, + deleteTag(obj, args) { + return wiki.db.Tag.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + removeTagFromDocument(obj, args) { + return wiki.db.Tag.findById(args.tagId).then(tag => { + if (!tag) { + throw new gql.GraphQLError('Invalid Tag ID') + } + return wiki.db.Document.findById(args.documentId).then(doc => { + if (!doc) { + throw new gql.GraphQLError('Invalid Document ID') + } + return tag.removeDocument(doc) + }) + }) + }, + renameTag(obj, args) { + return wiki.db.Group.update({ + key: args.key + }, { + where: { id: args.id } + }) + } + }, + Tag: { + documents(tag) { + return tag.getDocuments() + } + } +} diff --git a/server/schemas/resolvers-translation.js b/server/schemas/resolvers-translation.js new file mode 100644 index 00000000..aed8d57d --- /dev/null +++ b/server/schemas/resolvers-translation.js @@ -0,0 +1,12 @@ + +/* global wiki */ + +module.exports = { + Query: { + translations (obj, args, context, info) { + return wiki.lang.getByNamespace(args.locale, args.namespace) + } + }, + Mutation: {}, + Translation: {} +} diff --git a/server/schemas/resolvers-user.js b/server/schemas/resolvers-user.js new file mode 100644 index 00000000..90133707 --- /dev/null +++ b/server/schemas/resolvers-user.js @@ -0,0 +1,45 @@ + +/* global wiki */ + +module.exports = { + Query: { + users(obj, args, context, info) { + return wiki.db.User.findAll({ where: args }) + } + }, + Mutation: { + createUser(obj, args) { + return wiki.db.User.create(args) + }, + deleteUser(obj, args) { + return wiki.db.User.destroy({ + where: { + id: args.id + }, + limit: 1 + }) + }, + modifyUser(obj, args) { + return wiki.db.User.update({ + email: args.email, + name: args.name, + provider: args.provider, + providerId: args.providerId, + role: args.role + }, { + where: { id: args.id } + }) + }, + resetUserPassword(obj, args) { + return false + }, + setUserPassword(obj, args) { + return false + } + }, + User: { + groups(usr) { + return usr.getGroups() + } + } +} diff --git a/server/schemas/scalar-date.js b/server/schemas/scalar-date.js new file mode 100644 index 00000000..472312ad --- /dev/null +++ b/server/schemas/scalar-date.js @@ -0,0 +1,21 @@ + +const gql = require('graphql') + +module.exports = { + Date: new gql.GraphQLScalarType({ + name: 'Date', + description: 'ISO date-time string at UTC', + parseValue(value) { + return new Date(value) + }, + serialize(value) { + return value.toISOString() + }, + parseLiteral(ast) { + if (ast.kind !== gql.Kind.STRING) { + throw new TypeError('Date value must be an string!') + } + return new Date(ast.value) + } + }) +} diff --git a/server/schemas/types.graphql b/server/schemas/types.graphql new file mode 100644 index 00000000..a47305b4 --- /dev/null +++ b/server/schemas/types.graphql @@ -0,0 +1,342 @@ +# SCALARS + +scalar Date + +# ENUMS + +enum UserRole { + guest + user + admin +} + +enum FileType { + binary + image +} + +enum RightRole { + read + write + manage +} + +# INTERFACES + +interface Base { + id: Int! + createdAt: Date + updatedAt: Date +} + +# TYPES + +type AuthenticationProvider { + key: String! + useForm: Boolean! + title: String! + props: [String] + icon: String + config: String +} + +type Comment implements Base { + id: Int! + createdAt: Date + updatedAt: Date + content: String + document: Document! + author: User! +} + +type Document implements Base { + id: Int! + createdAt: Date + updatedAt: Date + path: String! + title: String! + subtitle: String + parentPath: String + parentTitle: String + isDirectory: Boolean! + isEntry: Boolean! + searchContent: String + comments: [Comment] + tags: [Tag] +} + +type File implements Base { + id: Int! + createdAt: Date + updatedAt: Date + category: FileType! + mime: String! + extra: String + filename: String! + basename: String! + filesize: Int! + folder: Folder +} + +type Folder implements Base { + id: Int! + createdAt: Date + updatedAt: Date + name: String! + files: [File] +} + +type Group implements Base { + id: Int! + createdAt: Date + updatedAt: Date + name: String! + users: [User] + rights: [Right] +} + +type Right implements Base { + id: Int! + createdAt: Date + updatedAt: Date + path: String! + role: RightRole! + exact: Boolean! + allow: Boolean! + group: Group! +} + +type SearchResult { + path: String + title: String + tags: [String] +} + +type Setting implements Base { + id: Int! + createdAt: Date + updatedAt: Date + key: String! + config: String! +} + +# Tags are attached to one or more documents +type Tag implements Base { + id: Int! + createdAt: Date + updatedAt: Date + key: String! + documents: [Document] +} + +type Translation { + key: String! + value: String! +} + +# A User +type User implements Base { + id: Int! + createdAt: Date + updatedAt: Date + email: String! + provider: String! + providerId: String + name: String + role: UserRole! + groups: [Group] +} + +type OperationResult { + succeded: Boolean! + message: String +} + +# Query (Read) +type Query { + authentication(mode: String!): [AuthenticationProvider] + comments(id: Int): [Comment] + documents(id: Int, path: String): [Document] + files(id: Int): [File] + folders(id: Int, name: String): [Folder] + groups(id: Int, name: String): [Group] + rights(id: Int): [Right] + search(q: String, tags: [String]): [SearchResult] + settings(key: String): [Setting] + tags(key: String): [Tag] + translations(locale: String!, namespace: String!): [Translation] + users(id: Int, email: String, provider: String, providerId: String, role: UserRole): [User] +} + +# Mutations (Create, Update, Delete) +type Mutation { + addRightToGroup( + groupId: Int! + path: String! + role: RightRole! + exact: Boolean! + allow: Boolean! + ): Right + + assignTagToDocument( + tagId: Int! + documentId: Int! + ): OperationResult + + assignUserToGroup( + userId: Int! + groupId: Int! + ): OperationResult + + createComment( + userId: Int! + documentId: Int! + content: String! + ): Comment + + createDocument( + path: String! + title: String! + subtitle: String + ): Document + + createFolder( + name: String! + ): Folder + + createGroup( + name: String! + ): Group + + createTag( + name: String! + ): Tag + + createUser( + email: String! + name: String + passwordRaw: String + provider: String! + providerId: String + role: UserRole! + ): User + + deleteComment( + id: Int! + ): OperationResult + + deleteDocument( + id: Int! + ): OperationResult + + deleteFile( + id: Int! + ): OperationResult + + deleteFolder( + id: Int! + ): OperationResult + + deleteGroup( + id: Int! + ): OperationResult + + deleteTag( + id: Int! + ): OperationResult + + deleteUser( + id: Int! + ): OperationResult + + modifyComment( + id: Int! + content: String! + ): Document + + modifyDocument( + id: Int! + title: String + subtitle: String + ): Document + + modifyUser( + id: Int! + email: String + name: String + provider: String + providerId: String + role: UserRole + ): User + + modifyRight( + id: Int! + path: String + role: RightRole + exact: Boolean + allow: Boolean + ): Right + + moveDocument( + id: Int! + path: String! + ): OperationResult + + moveFile( + id: Int! + folderId: Int! + ): OperationResult + + renameFile( + id: Int! + name: String! + ): OperationResult + + renameFolder( + id: Int! + name: String! + ): OperationResult + + renameGroup( + id: Int! + name: String! + ): OperationResult + + renameTag( + id: Int! + key: String! + ): OperationResult + + removeTagFromDocument( + tagId: Int! + documentId: Int! + ): OperationResult + + removeRightFromGroup( + rightId: Int! + ): OperationResult + + removeUserFromGroup( + userId: Int! + groupId: Int! + ): OperationResult + + resetUserPassword( + id: Int! + ): OperationResult + + setConfigEntry( + key: String! + value: String! + ): OperationResult + + setUserPassword( + id: Int! + passwordRaw: String! + ): OperationResult + + uploadFile( + category: FileType! + filename: String! + ): File +} diff --git a/server/views/auth/login.pug b/server/views/auth/login.pug index ad860349..44ebc019 100644 --- a/server/views/auth/login.pug +++ b/server/views/auth/login.pug @@ -1,75 +1,6 @@ -doctype html -html(data-logic='login') - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png') - title= appconfig.title - - // Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href='/manifest.json') - - // JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') +extends ../master.pug +block body body - #bg - each bg in _.sampleSize([1, 2, 3],3) - div(style='background-image:url(/images/bg_' + bg + '.jpg);') - #root - h1= appconfig.title - h2= t('auth:loginrequired') - if appflash.length > 0 - h3 - i.icon-warning-outline - = appflash[0].title - h4= appflash[0].message - if appconfig.auth.local.enabled - form(method='post', action='/login') - input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser')) - input#login-pass(type='password', name='password', placeholder=t('auth:fields.password')) - button(type='submit')= t('auth:actions.login') - if appconfig.authStrategies.socialEnabled - #social - if appconfig.auth.local.enabled - span= t('auth:loginusingalt') - else - span= t('auth:loginusing') - if appconfig.auth.microsoft && appconfig.auth.microsoft.enabled - button.ms(onclick='window.location.assign("/login/ms")') - i.icon-windows2 - span= t('auth:providers.windowslive') - if appconfig.auth.azure && appconfig.auth.azure.enabled - button.ms(onclick='window.location.assign("/login/azure")') - i.icon-windows2 - span= t('auth:providers.azure') - if appconfig.auth.google && appconfig.auth.google.enabled - button.google(onclick='window.location.assign("/login/google")') - i.icon-google - span= t('auth:providers.google') - if appconfig.auth.facebook && appconfig.auth.facebook.enabled - button.facebook(onclick='window.location.assign("/login/facebook")') - i.icon-facebook - span= t('auth:providers.facebook') - if appconfig.auth.github && appconfig.auth.github.enabled - button.github(onclick='window.location.assign("/login/github")') - i.icon-github - span= t('auth:providers.github') - if appconfig.auth.slack && appconfig.auth.slack.enabled - button.slack(onclick='window.location.assign("/login/slack")') - i.icon-slack - span= t('auth:providers.slack') - #copyright - = t('footer.poweredby') + ' ' - a.icon(href='https://github.com/Requarks/wiki') - i.icon-github - a(href='https://wiki.requarks.io/') Wiki.js + #app.is-fullscreen + login diff --git a/server/views/configure/index.pug b/server/views/configure/index.pug index d6c1f62a..aa268c77 100644 --- a/server/views/configure/index.pug +++ b/server/views/configure/index.pug @@ -1,31 +1,9 @@ -doctype html -html(data-logic='configure') - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - title Wiki.js | Configure - - // Favicon - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png') - - // JS / CSS - script(type='text/javascript'). - var appconfig = !{JSON.stringify(conf)}; - var runmode = !{JSON.stringify(runmode)}; - script(type='text/javascript', src='/js/vendor.js') - script(type='text/javascript', src='/js/configure.js') +extends ../master.pug +block body body - #root - #header-container - nav.nav#header - .nav-left - a.nav-item - h1 - i.icon-layers - | Wiki.js - main + #app.config-manager + config-manager(inline-template) .container transition(name='tst-welcome') .welcome(v-if='state === "welcome" || state === "restart"') @@ -44,10 +22,22 @@ html(data-logic='configure') i(v-if='loading') .panel-content.is-text p This installation wizard will guide you through the steps needed to get your wiki up and running in no time! - p Detailed information about installation and usage can be found on the #[a(href='https://docs.wiki.requarks.io/') official documentation site]. #[br] Should you have any question or would like to report something that doesn't look right, feel free to create a new issue on the #[a(href='https://github.com/Requarks/wiki/issues') GitHub project]. + p Detailed information about installation and usage can be found on the #[a(href='https://wiki.requarks.io/docs') official documentation site]. #[br] Should you have any question or would like to report something that doesn't look right, feel free to create a new issue on the #[a(href='https://github.com/Requarks/wiki/issues') GitHub project]. + .panel-content.form-sections + section + p #[i.nc-icon-outline.tech_cd-reader] You are about to install Wiki.js #[strong= packageObj.version]. + section + p.control.is-fullwidth + input#ipt-telemetry(type='checkbox', v-model='conf.telemetry', name='ipt-telemetry') + label.label(for='ipt-telemetry') Enable telemetry + span.desc Help Wiki.js developers improve this app with anonymized #[a(href='https://wiki.requarks.io/docs/telemetry') telemetry]. + p.control.is-fullwidth + input#ipt-upgrade(type='checkbox', v-model='conf.upgrade', name='ipt-upgrade') + label.label(for='ipt-upgrade') Upgrade from Wiki.js 1.x + span.desc Check this box if you are upgrading from Wiki.js 1.x and wish to migrate your existing data. .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start + button.button.is-small.is-light-blue(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start //- ============================================== //- SYSTEM CHECK @@ -69,9 +59,10 @@ html(data-logic='configure') p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }} .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back - button.button.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again - button.button.is-light-blue(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back + button.button.is-small.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again + button.button.is-small.is-red.is-outlined(v-on:click='proceedToGeneral', v-if='!loading && !syscheck.ok') Continue Anyway + button.button.is-small.is-light-blue(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue //- ============================================== //- GENERAL @@ -92,20 +83,24 @@ html(data-logic='configure') p.control.is-fullwidth label.label Host input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, min: 4 }') - span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are #[u not supported]. - if !runmode.staticPort - section - p.control - label.label Port - input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }') - span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.
Set $(PORT) to use PORT environment variable. + span.desc The full URL to your wiki, without the trailing slash, e.g.: http://wiki.domain.com. Make sure to include the port if different than 80/443. + section + p.control + label.label Port + input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }') + span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.
Set $(PORT) to use PORT environment variable. section p.control label.label Site UI Language select(v-model='conf.lang') - each lg in langs + each lg in data.langs option(value=lg.id)= lg.name span.desc The language in which navigation, help and other UI elements will be displayed. + section + p.control.is-fullwidth + label.label Local Repository Path + input(type='text', placeholder='e.g. ./repo', v-model='conf.pathRepo', data-vv-scope='general', name='ipt-repopath', v-validate='{ required: true, min: 2 }') + span.desc The path where the local git repository will be created, used to store content in markdown files and uploads.#[br] #[strong It is recommended to leave the default value]. section p.control.is-fullwidth input#ipt-public(type='checkbox', v-model='conf.public', data-vv-scope='general', name='ipt-public') @@ -113,8 +108,8 @@ html(data-logic='configure') span.desc Should the site be accessible (read only) without login. .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back - button.button.is-light-blue(v-on:click='proceedToConsiderations', v-bind:disabled='loading || errors.any("general")') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back + button.button.is-small.is-light-blue(v-on:click='proceedToConsiderations', v-bind:disabled='loading || errors.any("general")') Continue //- ============================================== //- CONSIDERATIONS @@ -134,88 +129,18 @@ html(data-logic='configure') li - Do not rewrite URLs after the domain. This can cause unexpected issues in Wiki.js navigation. li - Do not remove or alter the client IP when proxying the requests. This can cause the authentication brute force protection to engage unexpectedly. template(v-if='considerations.https') - h3 The site will not be using HTTPS? #[i.icon-warning-outline.animated.fadeOut.infinite] + h3 The site will not be using HTTPS? #[i.nc-icon-outline.ui-3_alert.animated.fadeOut.infinite] p The host URL you specified is not HTTPS. It is highly recommended to use HTTPS. You must use a web server / proxy (e.g. nginx / apache / IIS) in front of Wiki.js to use HTTPS. Wiki.js does not provide HTTPS handling by itself. template(v-if='considerations.port') h3 You are using a non-standard port. p If you are not planning on using a web server / proxy in front of Wiki.js, be aware that users will need to specify the port when accessing the wiki. Make sure this is the intended behavior. Otherwise set a standard HTTP port such as 80. template(v-if='considerations.localhost') - h3 Are you sure you want to use localhost as the host base URL? #[i.icon-warning-outline.animated.fadeOut.infinite] + h3 Are you sure you want to use localhost as the host base URL? #[i.nc-icon-outline.ui-3_alert.animated.fadeOut.infinite] p The host URL you specified is localhost. Unless you are a developer running Wiki.js locally on your machine, this is not recommended! .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back - button.button.is-light-blue(v-on:click='proceedToDb', v-bind:disabled='loading') Continue - - //- ============================================== - //- DATABASE - //- ============================================== - - template(v-else-if='state === "db"') - .panel - h2.panel-title.is-featured - span Database - i(v-if='loading') - .panel-content.is-text - p Wiki.js stores administrative data such as users, permissions and assets metadata in a MongoDB database. Article contents and uploads are not stored in the DB. Instead, they are stored on-disk and synced automatically with a remote git repository of your choice. - .panel-content.form-sections - section - p.control.is-fullwidth - label.label MongoDB Connection String - input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db', data-vv-scope='db', name='ipt-db', v-validate='{ required: true, min: 3 }') - span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.
You can also specify an environment variable as the connection string, e.g. $(MONGO_URI). - .panel-footer - .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back - button.button.is-light-blue(v-on:click='proceedToDbcheck', v-bind:disabled='loading || errors.any("db")') Connect - - //- ============================================== - //- DATABASE CHECK - //- ============================================== - - template(v-else-if='state === "dbcheck"') - .panel - h2.panel-title.is-featured - span Database Check - i(v-if='loading') - .panel-content.is-text - p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Testing the connection to MongoDB... - p(v-if='!loading && dbcheck.ok') - i.icon-check - strong Connected successfully! - p(v-if='!loading && !dbcheck.ok') #[i.icon-square-cross] Error: {{ dbcheck.error }} - .panel-footer - .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back - button.button.is-teal(v-on:click='proceedToDbcheck', v-if='!loading && !dbcheck.ok') Try Again - button.button.is-light-blue(v-on:click='proceedToPaths', v-if='loading || dbcheck.ok', v-bind:disabled='loading') Continue - - //- ============================================== - //- PATHS - //- ============================================== - - template(v-else-if='state === "paths"') - .panel - h2.panel-title.is-featured - span Paths - i(v-if='loading') - .panel-content.is-text - p It is recommended to leave the default values. - .panel-content.form-sections - section - p.control.is-fullwidth - label.label Local Data Path - input(type='text', placeholder='e.g. ./data', v-model='conf.pathData', data-vv-scope='paths', name='ipt-datapath', v-validate='{ required: true, min: 2 }') - span.desc The path where cache (processed content, thumbnails, search index, etc.) will be stored on disk. - section - p.control.is-fullwidth - label.label Local Repository Path - input(type='text', placeholder='e.g. ./repo', v-model='conf.pathRepo', data-vv-scope='paths', name='ipt-repopath', v-validate='{ required: true, min: 2 }') - span.desc The path where the local git repository will be created, used to store content in markdown files and uploads. - .panel-footer - .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back - button.button.is-light-blue(v-on:click='proceedToGit', v-bind:disabled='loading || errors.any("paths")') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back + button.button.is-small.is-light-blue(v-on:click='proceedToGit', v-bind:disabled='loading') Continue //- ============================================== //- GIT @@ -279,9 +204,9 @@ html(data-logic='configure') span.desc The default/fallback email to use when creating commits to the git repository. .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToPaths', v-bind:disabled='loading') Back - button.button.is-light-blue.is-outlined(v-on:click='conf.gitUseRemote = false; proceedToGitCheck()', v-bind:disabled='loading') Skip this step - button.button.is-light-blue(v-on:click='conf.gitUseRemote = true; proceedToGitCheck()', v-bind:disabled='loading || errors.any("git")') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back + button.button.is-small.is-light-blue.is-outlined(v-on:click='conf.gitUseRemote = false; proceedToGitCheck()', v-bind:disabled='loading') Skip this step + button.button.is-small.is-light-blue(v-on:click='conf.gitUseRemote = true; proceedToGitCheck()', v-bind:disabled='loading || errors.any("git")') Continue //- ============================================== //- GIT CHECK @@ -303,9 +228,9 @@ html(data-logic='configure') p(v-if='!loading && !gitcheck.ok') #[i.icon-square-cross] Error: {{ gitcheck.error }} .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back - button.button.is-teal(v-on:click='proceedToGitCheck', v-if='!loading && !gitcheck.ok') Try Again - button.button.is-light-blue(v-on:click='proceedToAdmin', v-if='loading || gitcheck.ok', v-bind:disabled='loading') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back + button.button.is-small.is-teal(v-on:click='proceedToGitCheck', v-if='!loading && !gitcheck.ok') Try Again + button.button.is-small.is-light-blue(v-on:click='proceedToAdmin', v-if='loading || gitcheck.ok', v-bind:disabled='loading') Continue //- ============================================== //- ADMINISTRATOR ACCOUNT @@ -337,8 +262,8 @@ html(data-logic='configure') span.desc Verify your password again. .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back - button.button.is-light-blue(v-on:click='proceedToFinal', v-bind:disabled='loading || errors.any("admin")') Continue + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back + button.button.is-small.is-light-blue(v-on:click='proceedToFinal', v-bind:disabled='loading || errors.any("admin")') Continue //- ============================================== //- FINAL @@ -359,9 +284,9 @@ html(data-logic='configure') p(v-if='!loading && !final.ok') #[i.icon-square-cross] Error: {{ final.error }} .panel-footer .progress-bar: div(v-bind:style='{width: currentProgress}') - button.button.is-light-blue.is-outlined(v-on:click='proceedToAdmin', v-bind:disabled='loading') Back - button.button.is-teal(v-on:click='proceedToFinal', v-if='!loading && !final.ok') Try Again - button.button.is-green(v-on:click='finish', v-if='loading || final.ok', v-bind:disabled='loading') Start + button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToAdmin', v-bind:disabled='loading') Back + button.button.is-small.is-teal(v-on:click='proceedToFinal', v-if='!loading && !final.ok') Try Again + button.button.is-small.is-green(v-on:click='finish', v-if='loading || final.ok', v-bind:disabled='loading') Start //- ============================================== //- RESTART @@ -376,11 +301,4 @@ html(data-logic='configure') p #[i.icon-loader.animated.rotateIn.infinite] Restarting Wiki.js in normal mode... p You'll automatically be redirected to the homepage when ready. This usually takes about 30 seconds. .panel-footer - button.button.is-green(disabled='disabled') Start - - footer.footer - span - | Powered by - a(href='https://github.com/Requarks/wiki') Wiki.js - | . - block outside + button.button.is-small.is-green(disabled='disabled') Start diff --git a/server/views/error.pug b/server/views/error.pug index 3ef6c43f..51b53efe 100644 --- a/server/views/error.pug +++ b/server/views/error.pug @@ -1,32 +1,12 @@ -doctype html -html(data-logic='error') - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content=appconfig.host + '/favicons/ms-icon-144x144.png') - title= appconfig.title - - // Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href=appconfig.host + '/manifest.json') - - // JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') +extends ./master.pug +block body body(class='is-error') .container - a(href='/'): img(src=appconfig.host + '/images/logo.png') + a(href='/'): img(src=config.site.path + '/images/logo.png') h1= message h2= t('errors:generic') - a.button.is-amber.is-inverted.is-featured(href=appconfig.host + '/')= t('errors:actions.gohome') + a.button.is-amber.is-inverted.is-featured(href=config.site.path+ '/')= t('errors:actions.gohome') if error.stack h3= t('errors:debugmsg') diff --git a/server/views/layout.pug b/server/views/layout.pug index 36c75734..1d704f7e 100644 --- a/server/views/layout.pug +++ b/server/views/layout.pug @@ -1,35 +1,8 @@ -doctype html -html - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content=appconfig.host + '/favicons/ms-icon-144x144.png') - title= appconfig.title +extends ./master.pug - //- Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href=appconfig.host + '/manifest.json') - - //- Site Lang - script. - var siteLang = '!{appconfig.lang}'; - var siteRoot = '!{appconfig.host}'; - - //- JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') - - block head - - body(class={ 'rtl': appconfig.langRtl }) - #root.has-stickynav(class=['is-primary-' + appconfig.theme.primary, 'is-alternate-' + appconfig.theme.alt]) +block body + body + #app.has-stickynav(class=['is-primary-' + appconfig.theme.primary, 'is-alternate-' + appconfig.theme.alt]) include ./common/header.pug alert main diff --git a/server/views/master.pug b/server/views/master.pug new file mode 100644 index 00000000..dc45732a --- /dev/null +++ b/server/views/master.pug @@ -0,0 +1,30 @@ +doctype html +html + head + meta(http-equiv='X-UA-Compatible', content='IE=edge') + meta(charset='UTF-8') + meta(name='viewport', content='width=device-width, initial-scale=1') + meta(name='theme-color', content='#009688') + meta(name='msapplication-TileColor', content='#009688') + meta(name='msapplication-TileImage', content=config.site.path + '/favicons/ms-icon-144x144.png') + title= config.site.title + + //- Favicon + each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] + link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=config.site.path + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') + link(rel='icon', type='image/png', sizes='192x192', href=config.site.path + '/favicons/android-icon-192x192.png') + each favsize in [32, 96, 16] + link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=config.site.path + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') + link(rel='manifest', href=config.site.path + '/manifest.json') + + //- Site Lang + script. + var siteConfig = !{JSON.stringify(config.site)} + + //- JS / CSS + script(type='text/javascript', src=config.site.path + '/js/libs.js') + script(type='text/javascript', src=config.site.path + '/js/app.js') + + block head + + block body diff --git a/server/worker.js b/server/worker.js new file mode 100644 index 00000000..6ca90eba --- /dev/null +++ b/server/worker.js @@ -0,0 +1,67 @@ +/* global wiki */ + +const Promise = require('bluebird') + +module.exports = Promise.join( + wiki.db.onReady, + wiki.configSvc.loadFromDb(['features', 'git', 'logging', 'site', 'uploads']) +).then(() => { + const path = require('path') + + wiki.REPOPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.repo) + wiki.DATAPATH = path.resolve(wiki.ROOTPATH, wiki.config.paths.data) + wiki.UPLTEMPPATH = path.join(wiki.DATAPATH, 'temp-upload') + + // ---------------------------------------- + // Load global modules + // ---------------------------------------- + + // wiki.upl = require('./modules/uploads-agent').init() + // wiki.git = require('./modules/git').init() + // wiki.entries = require('./modules/entries').init() + wiki.lang = require('i18next') + wiki.mark = require('./modules/markdown') + + // ---------------------------------------- + // Localization Engine + // ---------------------------------------- + + const i18nBackend = require('i18next-node-fs-backend') + wiki.lang.use(i18nBackend).init({ + load: 'languageOnly', + ns: ['common', 'admin', 'auth', 'errors', 'git'], + defaultNS: 'common', + saveMissing: false, + preload: [wiki.config.lang], + lng: wiki.config.lang, + fallbackLng: 'en', + backend: { + loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.json') + } + }) + + // ---------------------------------------- + // Start Queues + // ---------------------------------------- + + const Bull = require('bull') + const autoload = require('auto-load') + + let queues = autoload(path.join(wiki.SERVERPATH, 'queues')) + + for (let queueName in queues) { + new Bull(queueName, { + prefix: `q-${wiki.config.ha.nodeuid}`, + redis: wiki.config.redis + }).process(queues[queueName]) + } + + // ---------------------------------------- + // Shutdown gracefully + // ---------------------------------------- + + process.on('disconnect', () => { + wiki.logger.warn('Lost connection to Master. Exiting...') + process.exit() + }) +}) diff --git a/themes/default/theme.yml b/themes/default/theme.yml new file mode 100644 index 00000000..e5c0a6d8 --- /dev/null +++ b/themes/default/theme.yml @@ -0,0 +1,28 @@ +name: Default +author: Nicolas Giard +site: https://wiki.requarks.io/ +version: 1.0.0 +requirements: + minimum: '>= 2.0.0' + maximum: '< 3.0.0' +fields: + primary: + title: Primary Color + description: Used for top navigation bar, headers, links, etc. + type: color + default: indigo + alt: + title: Alternate Color + description: Used for the sidebar (in a darker tone) + type: color + default: blue-grey + codeDark: + title: Code Blocks - Use Dark Theme + description: todo + type: boolean + default: true + codeColorize: + title: Code Blocks - Colorize syntax + description: todo + type: boolean + default: true \ No newline at end of file diff --git a/themes/default/thumbnail.png b/themes/default/thumbnail.png new file mode 100644 index 00000000..489e3f83 Binary files /dev/null and b/themes/default/thumbnail.png differ diff --git a/tools/fuse.js b/tools/fuse.js index 719bf6ef..70aede3c 100644 --- a/tools/fuse.js +++ b/tools/fuse.js @@ -6,16 +6,15 @@ * Client & Server compiler / bundler / watcher */ +const autoprefixer = require('autoprefixer') const colors = require('colors/safe') const fsbx = require('fuse-box') const nodemon = require('nodemon') -const babel = require('babel-core') -const uglify = require('uglify-es') const fs = require('fs-extra') -// ====================================================== +// ------------------------------------------------------- // Parse cmd arguments -// ====================================================== +// ------------------------------------------------------- const args = require('yargs') .option('d', { @@ -23,30 +22,21 @@ const args = require('yargs') describe: 'Start in Developer mode', type: 'boolean' }) - .option('c', { - alias: 'dev-configure', - describe: 'Start in Configure Developer mode', - type: 'boolean' - }) .help('h') .alias('h', 'help') .argv -let mode = 'build' -const dev = args.d || args.c -if (args.d) { +const dev = args.dev + +if (dev) { console.info(colors.bgWhite.black(' Starting Fuse in DEVELOPER mode... ')) - mode = 'dev' -} else if (args.c) { - console.info(colors.bgWhite.black(' Starting Fuse in CONFIGURE DEVELOPER mode... ')) - mode = 'dev-configure' } else { console.info(colors.bgWhite.black(' Starting Fuse in BUILD mode... ')) } -// ====================================================== +// ------------------------------------------------------- // BUILD VARS -// ====================================================== +// ------------------------------------------------------- const ALIASES = { 'brace-ext-modelist': 'brace/ext/modelist.js', @@ -71,16 +61,31 @@ const SHIMS = { } } -// ====================================================== +// ------------------------------------------------------- // Global Tasks -// ====================================================== +// ------------------------------------------------------- console.info(colors.white('└── ') + colors.green('Running global tasks...')) let globalTasks = require('./fuse_tasks') -// ====================================================== -// Fuse Tasks -// ====================================================== +// ------------------------------------------------------- +// FUSEBOX PRODUCER +// ------------------------------------------------------- + +const babelrc = fs.readJsonSync('.babelrc') +const scssChain = [ + fsbx.SassPlugin({ + includePaths: ['node_modules'], + outputStyle: dev ? 'nested' : 'compressed' + }), + fsbx.PostCSS([ + autoprefixer({ + remove: false, + browsers: babelrc.presets[0][1].targets.browsers + }) + ]), + fsbx.CSSPlugin() +] globalTasks.then(() => { let fuse = fsbx.FuseBox.init({ @@ -91,100 +96,60 @@ globalTasks.then(() => { tsConfig: './tsconfig.json', plugins: [ fsbx.EnvPlugin({ NODE_ENV: (dev) ? 'development' : 'production' }), - fsbx.VuePlugin(), - ['.scss', fsbx.SassPlugin({ outputStyle: (dev) ? 'nested' : 'compressed' }), fsbx.CSSPlugin()], - fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }), + fsbx.VueComponentPlugin({ + script: fsbx.BabelPlugin(babelrc), + template: fsbx.ConsolidatePlugin({ + engine: 'pug' + }), + style: scssChain + }), + scssChain, + fsbx.BabelPlugin(babelrc), fsbx.JSONPlugin() - /* !dev && fsbx.QuantumPlugin({ - target: 'browser', - uglify: true, - api: (core) => { - core.solveComputed('default/js/components/editor-codeblock.vue', { - mapping: '/js/ace/ace.js', - fn: (statement, core) => { - statement.setExpression(`'/js/ace/ace.js'`) - } - }) - core.solveComputed('default/js/components/editor.component.js', { - mapping: '/js/simplemde/simplemde.min.js', - fn: (statement, core) => { - statement.setExpression(`'/js/simplemde/simplemde.min.js'`) - } - }) - } - }) */ - // !dev && fsbx.UglifyESPlugin() ], debug: false, log: true }) - const bundleVendor = fuse.bundle('vendor').shim(SHIMS).instructions('~ index.js') // eslint-disable-line no-unused-vars - const bundleApp = fuse.bundle('app').instructions('!> [index.js]') - // const bundleApp = fuse.bundle('app').shim(SHIMS).instructions('> index.js') - const bundleSetup = fuse.bundle('configure').instructions('> configure.js') - - switch (mode) { - case 'dev': - bundleApp.watch() - break - case 'dev-configure': - bundleSetup.watch() - break + // ------------------------------------------------------- + // FUSEBOX DEV + // ------------------------------------------------------- + + if (dev) { + fuse.dev({ + port: 5555, + httpServer: false + }) } + // ------------------------------------------------------- + // FUSEBOX BUNDLES + // ------------------------------------------------------- + + if (dev) { + fuse.bundle('libs').shim(SHIMS).instructions('~ index.js') + fuse.bundle('app').instructions('!> [index.js]').hmr({ reload: true }).watch() + } else { + fuse.bundle('bundle.min.js').shim(SHIMS).instructions('> index.js') + } + + // ------------------------------------------------------- + // FUSEBOX RUN + // ------------------------------------------------------- + fuse.run().then(() => { console.info(colors.green.bold('\nAssets compilation + bundling completed.')) if (dev) { nodemon({ - exec: (args.d) ? 'node server' : 'node wiki configure', - ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/'], - ext: 'js json', - watch: (args.d) ? ['server'] : ['server/configure.js'], + exec: 'node server', + ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/', 'tools/'], + ext: 'js json graphql', + watch: ['server'], env: { 'NODE_ENV': 'development' } }) - } else { - console.info(colors.yellow.bold('\nTranspiling vendor bundle...')) - let appCode = babel.transform(fs.readFileSync('./assets/js/app.js', 'utf8'), { - babelrc: false, - compact: false, - filename: 'app.js', - plugins: ['transform-object-assign'] - }).code - let vendorCode = babel.transform(fs.readFileSync('./assets/js/vendor.js', 'utf8'), { - babelrc: false, - comments: false, - compact: false, - filename: 'vendor.js', - plugins: [ - 'transform-es2015-arrow-functions', - 'transform-es2015-block-scoped-functions', - 'transform-es2015-block-scoping', - 'transform-es2015-classes', - 'transform-es2015-computed-properties', - 'transform-es2015-destructuring', - 'transform-es2015-duplicate-keys', - 'transform-es2015-for-of', - 'transform-es2015-function-name', - 'transform-es2015-literals', - 'transform-es2015-object-super', - 'transform-es2015-parameters', - 'transform-es2015-shorthand-properties', - 'transform-es2015-spread', - 'transform-es2015-sticky-regex', - 'transform-es2015-template-literals', - 'transform-es2015-typeof-symbol', - 'transform-es2015-unicode-regex' - ] - }).code - console.info(colors.yellow.bold('Minifing bundles...')) - fs.writeFileSync('./assets/js/vendor.js', uglify.minify(vendorCode).code, 'utf8') - fs.writeFileSync('./assets/js/app.js', uglify.minify(appCode).code, 'utf8') - fs.writeFileSync('./assets/js/configure.js', uglify.minify(fs.readFileSync('./assets/js/configure.js', 'utf8')).code, 'utf8') - console.info(colors.green.bold('\nBUILD SUCCEEDED.')) - return true } + return true }).catch(err => { console.error(colors.red(' X Bundle compilation failed! ' + err.message)) process.exit(1) diff --git a/tools/fuse_tasks.js b/tools/fuse_tasks.js index 90e7b61b..c9d0ee03 100644 --- a/tools/fuse_tasks.js +++ b/tools/fuse_tasks.js @@ -65,27 +65,6 @@ module.exports = Promise.mapSeries([ } }) }, - /** - * i18n - */ - () => { - console.info(colors.white(' └── ') + colors.green('Copying i18n client files...')) - return fs.ensureDirAsync('./assets/js/i18n').then(() => { - return fs.readJsonAsync('./server/locales/en/browser.json').then(enContent => { - return fs.readdirAsync('./server/locales').then(langs => { - return Promise.map(langs, lang => { - console.info(colors.white(' ' + lang + '.json')) - let outputPath = path.join('./assets/js/i18n', lang + '.json') - return fs.readJsonAsync(path.join('./server/locales', lang, 'browser.json'), 'utf8').then((content) => { - return fs.outputJsonAsync(outputPath, _.defaultsDeep(content, enContent)) - }).catch(err => { // eslint-disable-line handle-callback-err - return fs.outputJsonAsync(outputPath, enContent) - }) - }) - }) - }) - }) - }, /** * Delete Fusebox cache */ diff --git a/wiki.js b/wiki.js index fcfb1358..4f14f1bb 100644 --- a/wiki.js +++ b/wiki.js @@ -1,13 +1,72 @@ #!/usr/bin/env node -'use strict' // =========================================== // Wiki.js -// 1.0.0 +// 2.0 // Licensed under AGPLv3 // =========================================== -const init = require('./server/init') +const Promise = require('bluebird') +const fs = Promise.promisifyAll(require('fs-extra')) +const pm2 = Promise.promisifyAll(require('pm2')) +const ora = require('ora') +const path = require('path') + +const ROOTPATH = process.cwd() + +const init = { + /** + * Start in background mode + */ + start () { + let spinner = ora('Initializing...').start() + return fs.emptyDirAsync(path.join(ROOTPATH, './logs')).then(() => { + return pm2.connectAsync().then(() => { + return pm2.startAsync({ + name: 'wiki', + script: 'server', + cwd: ROOTPATH, + output: path.join(ROOTPATH, './logs/wiki-output.log'), + error: path.join(ROOTPATH, './logs/wiki-error.log'), + minUptime: 5000, + maxRestarts: 5 + }).then(() => { + spinner.succeed('Wiki.js has started successfully.') + }).finally(() => { + pm2.disconnect() + }) + }) + }).catch(err => { + spinner.fail(err) + process.exit(1) + }) + }, + /** + * Stop Wiki.js process(es) + */ + stop () { + let spinner = ora('Shutting down Wiki.js...').start() + return pm2.connectAsync().then(() => { + return pm2.stopAsync('wiki').then(() => { + spinner.succeed('Wiki.js has stopped successfully.') + }).finally(() => { + pm2.disconnect() + }) + }).catch(err => { + spinner.fail(err) + process.exit(1) + }) + }, + /** + * Restart Wiki.js process(es) + */ + restart: function () { + let self = this + return self.stop().delay(1000).then(() => { + self.startDetect() + }) + } +} require('yargs') // eslint-disable-line no-unused-expressions .usage('Usage: node $0 [args]') @@ -16,7 +75,7 @@ require('yargs') // eslint-disable-line no-unused-expressions alias: ['boot', 'init'], desc: 'Start Wiki.js process', handler: argv => { - init.startDetect() + init.start() } }) .command({ @@ -35,18 +94,9 @@ require('yargs') // eslint-disable-line no-unused-expressions init.restart() } }) - .command({ - command: 'configure [port]', - alias: ['config', 'conf', 'cfg', 'setup'], - desc: 'Configure Wiki.js using the web-based setup wizard', - builder: (yargs) => yargs.default('port', 3000), - handler: argv => { - init.configure(argv.port) - } - }) .recommendCommands() .demandCommand(1, 'You must provide one of the accepted commands above.') .help() .version() - .epilogue('Read the docs at https://wiki.requarks.io') + .epilogue('Read the docs at https://docs.requarks.io/wiki') .argv diff --git a/yarn.lock b/yarn.lock index e1e9f9f2..343424e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -48,7 +48,7 @@ lru-cache "^4.0.0" moment "^2.16.1" -"@glimpse/glimpse@~0.22.15": +"@glimpse/glimpse@0.22.15": version "0.22.15" resolved "https://registry.yarnpkg.com/@glimpse/glimpse/-/glimpse-0.22.15.tgz#593adafc9173bafa6aa6dab301575b9ce88e6ece" dependencies: @@ -58,9 +58,9 @@ command-line-usage "^4.0.0" lodash "^4.15.0" -"@panter/vue-i18next@~0.5.0": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@panter/vue-i18next/-/vue-i18next-0.5.1.tgz#714bbeb62c25850231f2681ad11142d3c6e3c645" +"@panter/vue-i18next@0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@panter/vue-i18next/-/vue-i18next-0.6.1.tgz#11228dd34e28db741c9c71ba90854afeb761b563" "@types/express-serve-static-core@*": version "4.0.49" @@ -75,6 +75,22 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/geojson@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.2.tgz#b02d10ab028e2928ac592a051aaa4981a1941d03" + +"@types/graphql@0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.10.2.tgz#d7c79acbaa17453b6681c80c34b38fcb10c4c08c" + +"@types/graphql@^0.11.4": + version "0.11.5" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.11.5.tgz#e70f051e80b299be5b12f7e60d962f30c9596072" + +"@types/graphql@^0.9.0": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.9.4.tgz#cdeb6bcbef9b6c584374b81aa7f48ecf3da404fa" + "@types/ldapjs@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/ldapjs/-/ldapjs-1.0.0.tgz#d940cb412140caec14edaa9c76d5b92799dab495" @@ -89,7 +105,7 @@ version "8.0.14" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.14.tgz#4a19dc6bb61d16c01cbadc7b30ac23518fff176b" -"@types/node@^6.0.46": +"@types/node@^6.0.46", "@types/node@^6.0.48": version "6.0.84" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab" @@ -110,13 +126,6 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -JSONStream@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - abab@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d" @@ -125,31 +134,26 @@ abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" -abstract-leveldown@2.4.1, abstract-leveldown@~2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.4.1.tgz#b3bfedb884eb693a12775f0c55e9f0a420ccee64" - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.1.tgz#f9014a5669b746418e145168dea49a044ae15900" +accepts@~1.2.12: + version "1.2.13" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea" dependencies: - xtend "~4.0.0" + mime-types "~2.1.6" + negotiator "0.5.3" -accepts@1.3.3, accepts@~1.3.3: +accepts@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" dependencies: mime-types "~2.1.11" negotiator "0.6.1" -accepts@~1.2.12: - version "1.2.13" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea" +accepts@~1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" dependencies: - mime-types "~2.1.6" - negotiator "0.5.3" + mime-types "~2.1.16" + negotiator "0.6.1" acorn-es7-plugin@^1.1.7: version "1.1.7" @@ -179,6 +183,12 @@ acorn-jsx@^4.0.1: dependencies: acorn "^5.0.3" +acorn-object-rest-spread@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/acorn-object-rest-spread/-/acorn-object-rest-spread-1.1.0.tgz#78699aefdd18ec3182caadadf52e2697c048f476" + dependencies: + acorn "^5.0.3" + acorn@^2.6.4: version "2.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" @@ -195,10 +205,6 @@ acorn@^5.0.3, acorn@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" -after@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" - ajax-request@^1.2.0: version "1.2.3" resolved "https://registry.yarnpkg.com/ajax-request/-/ajax-request-1.2.3.tgz#99fcbec1d6d2792f85fa949535332bd14f5f3790" @@ -217,6 +223,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.3.tgz#c06f598778c44c6b161abafe3466b81ad1814ed2" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + ajv@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" @@ -248,13 +263,19 @@ amp@0.3.1, amp@~0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/amp/-/amp-0.3.1.tgz#6adf8d58a74f361e82c1fa8d389c079e139fc47d" -ansi-escape-sequences@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz#e0ecb042958b71e42942d35c1fcf1d9b00a0f67e" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" dependencies: - array-back "^2.0.0" + string-width "^2.0.0" + +ansi-escape-sequences@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-3.0.0.tgz#1c18394b6af9b76ff9a63509fa497669fd2ce53e" + dependencies: + array-back "^1.0.3" -ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: +ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -262,7 +283,11 @@ ansi-escapes@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" -ansi-regex@^2.0.0, ansi-regex@^2.1.1: +ansi-escapes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + +ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -274,12 +299,18 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.0.0, ansi-styles@^3.1.0: +ansi-styles@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" dependencies: color-convert "^1.0.0" +ansi-styles@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + ansi@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" @@ -295,6 +326,63 @@ anymatch@^1.3.0: arrify "^1.0.0" micromatch "^2.1.5" +apollo-client@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-1.9.3.tgz#37000b3c801f4571b7b089739e696a158896aeab" + dependencies: + apollo-link-core "^0.5.0" + graphql "^0.10.0" + graphql-anywhere "^3.0.1" + graphql-tag "^2.0.0" + redux "^3.4.0" + symbol-observable "^1.0.2" + whatwg-fetch "^2.0.0" + optionalDependencies: + "@types/graphql" "0.10.2" + +apollo-link-core@^0.5.0: + version "0.5.4" + resolved "https://registry.yarnpkg.com/apollo-link-core/-/apollo-link-core-0.5.4.tgz#8efd4cd747959872a32f313f0ccfc2a76b396668" + dependencies: + graphql "^0.10.3" + graphql-tag "^2.4.2" + zen-observable-ts "^0.4.4" + +apollo-link@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-0.7.0.tgz#a8f09069b31821c27285584264356b1b6e6be6f2" + dependencies: + apollo-utilities "^0.2.0-beta.0" + graphql "^0.11.3" + zen-observable-ts "^0.5.0" + +apollo-server-core@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.1.3.tgz#1c1f223ab96097e095969a3494e6408cefdc9689" + dependencies: + apollo-tracing "^0.0.7" + +apollo-server-express@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.1.3.tgz#ccca554327458a91c9ff3216bb6998fccb6ad9e4" + dependencies: + apollo-server-core "^1.1.3" + apollo-server-module-graphiql "^1.1.3" + +apollo-server-module-graphiql@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.1.3.tgz#cf59be3320fda301ef369660697486f172457abb" + +apollo-tracing@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.0.7.tgz#78466cfefdb52a0802a57b488d26a1a67a25909f" + dependencies: + graphql-tools "^1.1.0" + +apollo-utilities@^0.2.0-beta.0: + version "0.2.0-beta.2" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-0.2.0-beta.2.tgz#95b61e00fa0cb67f6af65921484bca33114d55e1" + app-root-path@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-1.4.0.tgz#6335d865c9640d0fad99004e5a79232238e92dfa" @@ -352,12 +440,6 @@ array-back@^1.0.3, array-back@^1.0.4: dependencies: typical "^2.6.0" -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - dependencies: - typical "^2.6.1" - array-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" @@ -384,10 +466,6 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" -arraybuffer.slice@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" - arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -412,6 +490,10 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -431,22 +513,12 @@ async@1.5, async@^1.4.0, async@^1.5: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4" - dependencies: - lodash "^4.14.0" - -async@^2.1.4, async@^2.3.0, async@^2.5: +async@^2.1.4, async@^2.5: version "2.5.0" resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: lodash "^4.14.0" -async@~0.2.6: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" @@ -455,26 +527,41 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -auto-load@~3.0.0: +auto-load@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/auto-load/-/auto-load-3.0.0.tgz#f3c91d15120a32c89524b420d7283584c72088aa" +autoprefixer@7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.5.tgz#d65d14b83c7cd1dd7bc801daa00557addf5a06b2" + dependencies: + browserslist "^2.5.0" + caniuse-lite "^1.0.30000744" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^6.0.13" + postcss-value-parser "^3.2.3" + aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" -aws4@^1.2.1: +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -axios@~0.16.2: +axios@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d" dependencies: follow-redirects "^1.2.3" is-buffer "^1.1.5" -babel-cli@~6.26.0: +babel-cli@6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" dependencies: @@ -511,6 +598,30 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@6.26.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + babel-core@^6.0.0, babel-core@^6.24.1: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" @@ -535,30 +646,6 @@ babel-core@^6.0.0, babel-core@^6.24.1: slash "^1.0.0" source-map "^0.5.0" -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - babel-generator@^6.18.0, babel-generator@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" @@ -585,6 +672,22 @@ babel-generator@^6.26.0: source-map "^0.5.6" trim-right "^1.0.1" +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -603,6 +706,23 @@ babel-helper-define-map@^6.24.1: babel-types "^6.24.1" lodash "^4.2.0" +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" @@ -642,6 +762,16 @@ babel-helper-regex@^6.24.1: babel-types "^6.24.1" lodash "^4.2.0" +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" @@ -660,13 +790,12 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-jest@^20.0.3, babel-jest@~20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-20.0.3.tgz#e4a03b13dc10389e140fc645d09ffc4ced301671" +babel-jest@21.2.0, babel-jest@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-21.2.0.tgz#2ce059519a9374a2c46f2455b6fbef5ad75d863e" dependencies: - babel-core "^6.0.0" babel-plugin-istanbul "^4.0.0" - babel-preset-jest "^20.0.3" + babel-preset-jest "^21.2.0" babel-messages@^6.23.0: version "6.23.0" @@ -688,9 +817,76 @@ babel-plugin-istanbul@^4.0.0: istanbul-lib-instrument "^1.7.2" test-exclude "^4.1.1" -babel-plugin-jest-hoist@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz#afedc853bd3f8dc3548ea671fbe69d03cc2c1767" +babel-plugin-jest-hoist@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" @@ -704,6 +900,16 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: dependencies: babel-runtime "^6.22.0" +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + babel-plugin-transform-es2015-block-scoping@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" @@ -714,7 +920,7 @@ babel-plugin-transform-es2015-block-scoping@^6.24.1: babel-types "^6.24.1" lodash "^4.2.0" -babel-plugin-transform-es2015-classes@^6.24.1: +babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" dependencies: @@ -728,33 +934,33 @@ babel-plugin-transform-es2015-classes@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-plugin-transform-es2015-computed-properties@^6.24.1: +babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-destructuring@^6.22.0: +babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-duplicate-keys@^6.24.1: +babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-es2015-for-of@^6.22.0: +babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-function-name@^6.24.1: +babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" dependencies: @@ -768,7 +974,7 @@ babel-plugin-transform-es2015-literals@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-modules-amd@^6.24.1: +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" dependencies: @@ -776,6 +982,15 @@ babel-plugin-transform-es2015-modules-amd@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" +babel-plugin-transform-es2015-modules-commonjs@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" @@ -785,7 +1000,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.24.1: babel-template "^6.24.1" babel-types "^6.24.1" -babel-plugin-transform-es2015-modules-systemjs@^6.24.1: +babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" dependencies: @@ -793,7 +1008,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-umd@^6.24.1: +babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" dependencies: @@ -801,14 +1016,14 @@ babel-plugin-transform-es2015-modules-umd@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-object-super@^6.24.1: +babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-parameters@^6.24.1: +babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" dependencies: @@ -819,7 +1034,7 @@ babel-plugin-transform-es2015-parameters@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-plugin-transform-es2015-shorthand-properties@^6.24.1: +babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" dependencies: @@ -832,7 +1047,7 @@ babel-plugin-transform-es2015-spread@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-sticky-regex@^6.24.1: +babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" dependencies: @@ -846,13 +1061,13 @@ babel-plugin-transform-es2015-template-literals@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-typeof-symbol@^6.22.0: +babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-unicode-regex@^6.24.1: +babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" dependencies: @@ -860,12 +1075,27 @@ babel-plugin-transform-es2015-unicode-regex@^6.24.1: babel-runtime "^6.22.0" regexpu-core "^2.0.0" -babel-plugin-transform-object-assign@~6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz#f99d2f66f1a0b0d498e346c5359684740caa20ba" +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + babel-plugin-transform-regenerator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" @@ -895,7 +1125,42 @@ babel-polyfill@^6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-es2015@~6.24.1: +babel-preset-env@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^2.1.2" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-es2015@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" dependencies: @@ -924,11 +1189,31 @@ babel-preset-es2015@~6.24.1: babel-plugin-transform-es2015-unicode-regex "^6.24.1" babel-plugin-transform-regenerator "^6.24.1" -babel-preset-jest@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz#cbacaadecb5d689ca1e1de1360ebfc66862c178a" +babel-preset-jest@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz#ff9d2bce08abd98e8a36d9a8a5189b9173b85638" dependencies: - babel-plugin-jest-hoist "^20.0.3" + babel-plugin-jest-hoist "^21.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-preset-stage-2@6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" babel-register@^6.24.1: version "6.24.1" @@ -1042,10 +1327,6 @@ babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" -backo2@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - backoff@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" @@ -1056,10 +1337,6 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" -base64-arraybuffer@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" - base64-img@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/base64-img/-/base64-img-1.0.3.tgz#a8c0284900047103421e1f9e0214011333866806" @@ -1071,10 +1348,6 @@ base64-js@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" -base64id@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" - base64url@2.0.0, base64url@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" @@ -1085,7 +1358,7 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bcryptjs-then@~1.0.1: +bcryptjs-then@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/bcryptjs-then/-/bcryptjs-then-1.0.1.tgz#0c03b22a5032dec7e25109faa6ce425eb5015158" dependencies: @@ -1096,12 +1369,6 @@ bcryptjs@^2.3.0, bcryptjs@^2.4.0: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" -better-assert@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" - dependencies: - callsite "1.0.0" - bignumber.js@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" @@ -1110,35 +1377,25 @@ binary-extensions@^1.0.0: version "1.8.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" -bindings@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" - -bl@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" - dependencies: - readable-stream "^2.0.5" +bisection@: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bisection/-/bisection-0.0.3.tgz#9891d506d86ec7d50910c5157bb592dbb03f33db" blessed@^0.1.81: version "0.1.81" resolved "https://registry.yarnpkg.com/blessed/-/blessed-0.1.81.tgz#f962d687ec2c369570ae71af843256e6d0ca1129" -blob@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" - block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" dependencies: inherits "~2.0.0" -bluebird@2.10.2: - version "2.10.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.10.2.tgz#024a5517295308857f14f91f1106fc3b555f446b" +bluebird@3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" -bluebird@^3.0, bluebird@^3.1.1, bluebird@^3.4.1, bluebird@~3.5.0: +bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.4.1, bluebird@^3.4.6, bluebird@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" @@ -1146,7 +1403,22 @@ bmp-js@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a" -body-parser@^1.14.2, body-parser@~1.17.2: +body-parser@1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.1" + http-errors "~1.6.2" + iconv-lite "0.4.19" + on-finished "~2.3.0" + qs "6.5.1" + raw-body "2.3.2" + type-is "~1.6.15" + +body-parser@^1.14.2: version "1.17.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: @@ -1171,6 +1443,30 @@ boom@2.x.x: dependencies: hoek "2.x.x" +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +boxen@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.2.1.tgz#0f11e7fe344edb9397977fc13ede7f64d956481d" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^1.0.0" + brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -1178,7 +1474,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace@~0.10.0: +brace@0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/brace/-/brace-0.10.0.tgz#edef4eb9b0928ba1ee5f717ffc157749a6dd5d76" dependencies: @@ -1198,11 +1494,12 @@ browser-resolve@^1.11.2: dependencies: resolve "1.1.7" -bser@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169" +browserslist@^2.1.2, browserslist@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.5.0.tgz#0ea00d22813a4dfae5786485225a9c584b3ef37c" dependencies: - node-int64 "^0.4.0" + caniuse-lite "^1.0.30000744" + electron-to-chromium "^1.3.24" bser@^2.0.0: version "2.0.0" @@ -1210,10 +1507,6 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" -bson@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.4.tgz#93c10d39eaa5b58415cbc4052f3e53e562b0b72c" - buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -1222,26 +1515,38 @@ buffer-equal@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" +buffer-writer@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08" builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" -bunyan@^1.8.1, bunyan@^1.8.10, bunyan@^1.8.3: - version "1.8.10" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.10.tgz#201fedd26c7080b632f416072f53a90b9a52981c" +bull@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/bull/-/bull-3.3.0.tgz#79fc48f0ab6c63cc10fc053adfec4ddcbbc5dd44" + dependencies: + bluebird "^3.5.0" + cron-parser "^2.4.1" + debuglog "^1.0.0" + ioredis "^3.1.4" + lodash "^4.17.4" + semver "^5.4.1" + uuid "^3.1.0" + +bunyan@1.8.12: + version "1.8.12" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" optionalDependencies: dtrace-provider "~0.8" moment "^2.10.6" mv "~2" safe-json-stringify "~1" -bunyan@~1.8.12: - version "1.8.12" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" +bunyan@^1.8.3: + version "1.8.10" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.10.tgz#201fedd26c7080b632f416072f53a90b9a52981c" optionalDependencies: dtrace-provider "~0.8" moment "^2.10.6" @@ -1259,9 +1564,9 @@ bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" -bytes@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a" +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" caller-path@^0.1.0: version "0.1.0" @@ -1269,10 +1574,6 @@ caller-path@^0.1.0: dependencies: callsites "^0.2.0" -callsite@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" @@ -1300,10 +1601,18 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.1.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" +caniuse-lite@^1.0.30000744: + version "1.0.30000744" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000744.tgz#860fa5c83ba34fe619397d607f30bb474821671b" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1359,7 +1668,7 @@ charm@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/charm/-/charm-0.1.2.tgz#06c21eed1a1b06aeb67553cdc53e23274bac2296" -cheerio@~1.0.0-rc.2: +cheerio@1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" dependencies: @@ -1370,13 +1679,7 @@ cheerio@~1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -child-process-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-1.1.0.tgz#131e01a705f15ed4a05d554dd5e032e52612cf30" - dependencies: - q "^1.1.2" - -child-process-promise@~2.2.1: +child-process-promise@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" dependencies: @@ -1384,7 +1687,13 @@ child-process-promise@~2.2.1: node-version "^1.0.0" promise-polyfill "^6.0.1" -chokidar@^1.4.3, chokidar@^1.6.1, chokidar@^1.7, chokidar@~1.7.0: +child-process-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-1.1.0.tgz#131e01a705f15ed4a05d554dd5e032e52612cf30" + dependencies: + q "^1.1.2" + +chokidar@1.7.0, chokidar@^1.6.1, chokidar@^1.7, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -1418,6 +1727,10 @@ clean-css@^3.3.0: commander "2.8.x" source-map "0.4.x" +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1462,11 +1775,16 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -closure-compiler@0.2.12: - version "0.2.12" - resolved "https://registry.yarnpkg.com/closure-compiler/-/closure-compiler-0.2.12.tgz#6c3087cad12742c79e47f0ce50e87af91cf8e171" +cls-bluebird@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.0.1.tgz#c259a480ae02c0e506134307bb13db30446ee2e7" dependencies: - google-closure-compiler "20150901.x" + is-bluebird "^1.0.2" + shimmer "^1.1.0" + +cluster-key-slot@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.0.8.tgz#7654556085a65330932a2e8b5976f8e2d0b3e414" co@^4.6.0: version "4.6.0" @@ -1486,7 +1804,7 @@ codemirror@*: version "5.27.4" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.27.4.tgz#0e817c839bfea9959dd16cd48ae14acc0e43c3b6" -color-convert@^1.0.0: +color-convert@^1.0.0, color-convert@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" dependencies: @@ -1500,7 +1818,7 @@ colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" -colors@~1.1.2: +colors@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1511,21 +1829,21 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: delayed-stream "~1.0.0" command-line-args@^4.0.6: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" + version "4.0.6" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.6.tgz#0ff87a1dd159890dcaeb2a005abdae71e55059fc" dependencies: - array-back "^2.0.0" + array-back "^1.0.4" find-replace "^1.0.3" typical "^2.6.1" command-line-usage@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.0.1.tgz#d89cf16c8ae71e8e8a6e6aabae1652af76ff644e" + version "4.0.0" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.0.0.tgz#816b32788b58f9feba44d1e6dac60fcaeb29b5ea" dependencies: - ansi-escape-sequences "^4.0.0" - array-back "^2.0.0" - table-layout "^0.4.1" - typical "^2.6.1" + ansi-escape-sequences "^3.0.0" + array-back "^1.0.4" + table-layout "^0.4.0" + typical "^2.6.0" commander@2.11.0, commander@^2.11.0, commander@^2.9.0, commander@~2.11.0: version "2.11.0" @@ -1537,35 +1855,23 @@ commander@2.8.x: dependencies: graceful-readlink ">= 1.0.0" -component-bind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" - -component-emitter@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - -component-inherit@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" - -compressible@~2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.10.tgz#feda1c7f7617912732b29bf8cf26252a20b9eecd" +compressible@~2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.11.tgz#16718a75de283ed8e604041625a2064586797d8a" dependencies: - mime-db ">= 1.27.0 < 2" + mime-db ">= 1.29.0 < 2" -compression@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.0.tgz#030c9f198f1643a057d776a738e922da4373012d" +compression@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db" dependencies: - accepts "~1.3.3" - bytes "2.5.0" - compressible "~2.0.10" - debug "2.6.8" + accepts "~1.3.4" + bytes "3.0.0" + compressible "~2.0.11" + debug "2.6.9" on-headers "~1.0.1" safe-buffer "5.1.1" - vary "~1.1.1" + vary "~1.1.2" concat-map@0.0.1: version "0.0.1" @@ -1592,35 +1898,33 @@ config-chain@^1.1.10: ini "^1.3.4" proto-list "~1.2.1" -configstore@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021" +configstore@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" dependencies: + dot-prop "^4.1.0" graceful-fs "^4.1.2" - mkdirp "^0.5.0" - object-assign "^4.0.1" - os-tmpdir "^1.0.0" - osenv "^0.1.0" - uuid "^2.0.1" - write-file-atomic "^1.1.2" - xdg-basedir "^2.0.0" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" -connect-flash@~0.1.1: +connect-flash@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/connect-flash/-/connect-flash-0.1.1.tgz#d8630f26d95a7f851f9956b1e8cc6732f3b6aa30" -connect-mongo@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/connect-mongo/-/connect-mongo-1.3.2.tgz#7cbf58dfff26760e5e00e017d0a85b4bc90b9d37" +connect-redis@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/connect-redis/-/connect-redis-3.3.2.tgz#3706f9bfef1ec9b5d11c4b35b265de42c218b408" dependencies: - bluebird "^3.0" - mongodb ">= 1.2.0 <3.0.0" + debug "^3.1.0" + redis "^2.1.0" console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" -consolidate@~0.14.5: +consolidate@0.14.5: version "0.14.5" resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.14.5.tgz#5a25047bc76f73072667c8cb52c989888f494c63" dependencies: @@ -1653,6 +1957,10 @@ content-type@~1.0.1, content-type@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + continuation-local-storage@^3.1.4: version "3.2.0" resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.0.tgz#e19fc36b597090a5d4e4a3b2ea3ebc5e29694a24" @@ -1664,7 +1972,7 @@ convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" -cookie-parser@~1.4.3: +cookie-parser@1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.3.tgz#0fe31fa19d000b95f4aadf1f53fdc2b8a203baa5" dependencies: @@ -1687,20 +1995,20 @@ cookie@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.2.4.tgz#a8c155aa7b9b2cf2c4d32ebc7b9a0aa288ccc6bd" -cookies@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.6.1.tgz#ef693b1bc6f01f567d46e2f504e9c15fb70cba90" +cookies@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.1.tgz#7c8a615f5481c61ab9f16c833731bcb8f663b99b" dependencies: - depd "~1.1.0" - keygrip "~1.0.0" + depd "~1.1.1" + keygrip "~1.0.2" core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" core-js@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + version "2.5.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.0.tgz#569c050918be6486b3837552028ae0466b717086" core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -1717,7 +2025,20 @@ crc@3.4.4, crc@^3.4.0: version "3.4.4" resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" -cron@1.2.1, cron@~1.2.1: +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cron-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.4.1.tgz#022befce1af293e4d3144ff04c2cbd2edb491271" + dependencies: + is-nan "^1.2.1" + moment-timezone "^0.5.0" + +cron@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/cron/-/cron-1.2.1.tgz#3a86c09b41b8f261ac863a7cc85ea4735857eab2" dependencies: @@ -1751,6 +2072,16 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" @@ -1798,21 +2129,33 @@ de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" -debug@*, debug@2.6.8, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.4.5, debug@^2.6, debug@^2.6.3, debug@^2.6.8, debug@~2.6.4, debug@~2.6.6: +debug@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" + dependencies: + ms "2.0.0" + +debug@2.6.9, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.4.5, debug@^2.6.3, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" -debug@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" +debug@^3, debug@^3.0, debug@^3.0.1, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: - ms "0.7.2" + ms "2.0.0" -debug@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" +debug@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64" dependencies: ms "2.0.0" @@ -1822,6 +2165,10 @@ debug@~2.2.0: dependencies: ms "0.7.1" +debuglog@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1832,14 +2179,10 @@ decompress-response@^3.2.0: dependencies: mimic-response "^1.0.0" -deep-extend@~0.4.0: +deep-extend@~0.4.0, deep-extend@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deep-extend@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803" - deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1850,11 +2193,12 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" -deferred-leveldown@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.1.tgz#5d25c3310f5fe909946f6240dc9f90dd109a71ef" +define-properties@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" dependencies: - abstract-leveldown "~2.4.0" + foreach "^2.0.5" + object-keys "^1.0.8" del@^2.0.2: version "2.2.2" @@ -1880,7 +2224,11 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.0, depd@~1.1.0: +denque@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.1.1.tgz#10229c2b88eec1bd15ff82c5fde356e7beb6db9e" + +depd@1.1.0, depd@^1.1.0, depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" @@ -1888,6 +2236,10 @@ depd@1.1.1, depd@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -1905,11 +2257,11 @@ dicer@0.2.5, dicer@^0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff2html@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/diff2html/-/diff2html-2.3.0.tgz#375fb0783ca8fa90307749399bc9c75eb7cf6580" +diff2html@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/diff2html/-/diff2html-2.3.1.tgz#8bf7f351607826e217446163cab6da52c560e0ab" dependencies: - diff "^3.2.0" + diff "^3.3.1" hogan.js "^3.0.2" whatwg-fetch "^2.0.3" @@ -1917,13 +2269,9 @@ diff@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" -docproc@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/docproc/-/docproc-1.0.1.tgz#12f572e0f0eec1fa0985094e7042308f09a8e8d5" - dependencies: - pumpify "^1.3.5" - term-frequency "^0.0.15" - term-vector "^0.1.2" +diff@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" doctrine@1.5.0: version "1.5.0" @@ -1982,6 +2330,24 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +dotize@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dotize/-/dotize-0.2.0.tgz#69e52f4a2b13344c56ff23c703c3074a2d6e57c7" + +dottie@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.0.tgz#da191981c8b8d713ca0115d5898cf397c2f0ddd0" + +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + dtrace-provider@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.7.1.tgz#c06b308f2f10d5d5838aec9c571e5d588dc71d04" @@ -2002,15 +2368,6 @@ duplexer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" -duplexify@^3.1.2, duplexify@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604" - dependencies: - end-of-stream "1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - eachr@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/eachr/-/eachr-3.2.0.tgz#2c35e43ea086516f7997cf80b7aa64d55a4a4484" @@ -2039,6 +2396,10 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" +electron-to-chromium@^1.3.24: + version "1.3.24" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6" + emitter-listener@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.0.1.tgz#b2499ea6e58230a52c268d5df261eecd9f10fe97" @@ -2055,69 +2416,17 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" -end-of-stream@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e" - dependencies: - once "~1.3.0" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" - dependencies: - once "^1.4.0" - end-of-stream@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.1.0.tgz#e9353258baa9108965efc41cb0ef8ade2f3cfb07" dependencies: once "~1.3.0" -engine.io-client@~3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.1.tgz#415a9852badb14fa008fa3ef1e31608db6761325" - dependencies: - component-emitter "1.2.1" - component-inherit "0.0.3" - debug "~2.6.4" - engine.io-parser "~2.1.1" - has-cors "1.1.0" - indexof "0.0.1" - parsejson "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" - ws "~2.3.1" - xmlhttprequest-ssl "1.5.3" - yeast "0.1.2" - -engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.1.tgz#e0fb3f0e0462f7f58bb77c1a52e9f5a7e26e4668" - dependencies: - after "0.8.2" - arraybuffer.slice "0.0.6" - base64-arraybuffer "0.1.5" - blob "0.0.4" - has-binary2 "~1.0.2" - -engine.io@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.1.0.tgz#5ca438e3ce9fdbc915c4a21c8dd9e1266706e57e" - dependencies: - accepts "1.3.3" - base64id "1.0.0" - cookie "0.3.1" - debug "~2.6.4" - engine.io-parser "~2.1.0" - ws "~2.3.1" - optionalDependencies: - uws "~0.14.4" - entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -errno@^0.1.4, errno@~0.1.1: +errno@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" dependencies: @@ -2129,11 +2438,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es6-promise@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4" - -es6-promise@^3.0.2: +es6-promise@^3.0.2, es6-promise@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" @@ -2160,7 +2465,11 @@ escodegen@^1.6.1, escodegen@^1.8.1: optionalDependencies: source-map "~0.2.0" -eslint-config-standard@~10.2.1: +eslint-config-requarks@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eslint-config-requarks/-/eslint-config-requarks-1.0.7.tgz#d2f1495ace70d5c88961c8bec4741efddd03458a" + +eslint-config-standard@10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591" @@ -2178,7 +2487,7 @@ eslint-module-utils@^2.1.1: debug "^2.6.8" pkg-dir "^1.0.0" -eslint-plugin-import@~2.7.0: +eslint-plugin-import@2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" dependencies: @@ -2193,20 +2502,20 @@ eslint-plugin-import@~2.7.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" -eslint-plugin-node@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.1.1.tgz#a7ed956e780c22aef6afd1116005acd82f26eac6" +eslint-plugin-node@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.2.0.tgz#e1efca04a385516cff3f2f04027ce8c5ae6db749" dependencies: ignore "^3.3.3" minimatch "^3.0.4" resolve "^1.3.3" semver "5.3.0" -eslint-plugin-promise@~3.5.0: +eslint-plugin-promise@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz#78fbb6ffe047201627569e85a6c5373af2a68fca" -eslint-plugin-standard@~3.0.1: +eslint-plugin-standard@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" @@ -2217,19 +2526,19 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.5.0.tgz#bb75d3b8bde97fb5e13efcd539744677feb019c3" +eslint@4.8.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.8.0.tgz#229ef0e354e0e61d837c7a80fdfba825e199815e" dependencies: ajv "^5.2.0" babel-code-frame "^6.22.0" chalk "^2.1.0" concat-stream "^1.6.0" cross-spawn "^5.1.0" - debug "^2.6.8" + debug "^3.0.1" doctrine "^2.0.0" eslint-scope "^3.7.1" - espree "^3.5.0" + espree "^3.5.1" esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" @@ -2250,7 +2559,7 @@ eslint@~4.5.0: natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^4.0.0" + pluralize "^7.0.0" progress "^2.0.0" require-uncached "^1.0.3" semver "^5.3.0" @@ -2259,9 +2568,9 @@ eslint@~4.5.0: table "^4.0.1" text-table "~0.2.0" -espree@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" +espree@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.1.tgz#0c988b8ab46db53100a1954ae4ba995ddd27d87e" dependencies: acorn "^5.1.1" acorn-jsx "^3.0.0" @@ -2307,6 +2616,10 @@ etag@~1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + event-stream@~3.3.0: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -2333,6 +2646,18 @@ exec-sh@^0.2.0: dependencies: merge "^1.1.3" +execa@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" @@ -2345,9 +2670,9 @@ execa@^0.5.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@~0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2373,17 +2698,24 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expand-template@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.0.3.tgz#6c303323177a62b1b22c070279f7861287b69b1a" +expect@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-21.2.1.tgz#003ac2ac7005c3c29e73b38a272d4afadd6d1d7b" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^21.2.1" + jest-get-type "^21.2.0" + jest-matcher-utils "^21.2.1" + jest-message-util "^21.2.1" + jest-regex-util "^21.2.0" -express-brute-mongoose@~0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/express-brute-mongoose/-/express-brute-mongoose-0.0.9.tgz#7f8001c9548f78b705e6810be06f4c1e85745bd2" +express-brute-redis@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/express-brute-redis/-/express-brute-redis-0.0.1.tgz#0f4c833a5c3c2505c0c5c9ba55108e224a247ef8" dependencies: - express-brute "~0.5.0" - moment "^2.18.1" - mongoose "*" + express-brute "~0.4.2" + redis "~0.10.0" + underscore "~1.5.1" express-brute@1.0.1: version "1.0.1" @@ -2392,25 +2724,61 @@ express-brute@1.0.1: long-timeout "~0.1.1" underscore "~1.8.3" -express-brute@~0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/express-brute/-/express-brute-0.5.3.tgz#0c8aabafe09dd722666587916f471b976f0c2a48" +express-brute@~0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/express-brute/-/express-brute-0.4.2.tgz#3bc34fb01252b8f47e737bf72dd01ff4df1d9c07" dependencies: + memcached "~0.2.4" underscore "~1.5.1" -express-session@~1.15.5: - version "1.15.5" - resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.5.tgz#f49a18227263b316f6f8544da5fee25a540259ec" +express-session@1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.6.tgz#47b4160c88f42ab70fe8a508e31cbff76757ab0a" dependencies: cookie "0.3.1" cookie-signature "1.0.6" crc "3.4.4" - debug "2.6.8" + debug "2.6.9" depd "~1.1.1" on-headers "~1.0.1" - parseurl "~1.3.1" - uid-safe "~2.1.4" - utils-merge "1.0.0" + parseurl "~1.3.2" + uid-safe "~2.1.5" + utils-merge "1.0.1" + +express@4.16.1: + version "4.16.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.1.tgz#6b33b560183c9b253b7b62144df33a4654ac9ed0" + dependencies: + accepts "~1.3.4" + array-flatten "1.1.1" + body-parser "1.18.2" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.0" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.2" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.1" + serve-static "1.13.1" + setprototypeof "1.1.0" + statuses "~1.3.1" + type-is "~1.6.15" + utils-merge "1.0.1" + vary "~1.1.2" express@^4.14.0: version "4.15.3" @@ -2475,40 +2843,7 @@ express@~4.13.1: utils-merge "1.0.0" vary "~1.0.1" -express@~4.15.4: - version "4.15.4" - resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1" - dependencies: - accepts "~1.3.3" - array-flatten "1.1.1" - content-disposition "0.5.2" - content-type "~1.0.2" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.8" - depd "~1.1.1" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.8.0" - finalhandler "~1.0.4" - fresh "0.5.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.1" - path-to-regexp "0.1.7" - proxy-addr "~1.1.5" - qs "6.5.0" - range-parser "~1.2.0" - send "0.15.4" - serve-static "1.12.4" - setprototypeof "1.0.3" - statuses "~1.3.1" - type-is "~1.6.15" - utils-merge "1.0.0" - vary "~1.1.1" - -extend@^3.0.0, extend@~3.0.0: +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -2554,33 +2889,25 @@ fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" -fast-future@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" - fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" -fb-watchman@^1.8.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.2.tgz#a24cf47827f82d38fb59a69ad70b76e3b6ae7383" - dependencies: - bser "1.0.2" - fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" dependencies: bser "^2.0.0" -fclone@1.0.11: +fclone@1.0.11, fclone@^1: version "1.0.11" resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" -fclone@1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.8.tgz#a0d4a73d983249978c0e0671a161520b996467eb" +feature-detect-es6@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/feature-detect-es6/-/feature-detect-es6-1.3.1.tgz#f888736af9cb0c91f55663bfa4762eb96ee7047f" + dependencies: + array-back "^1.0.3" figures@^2.0.0: version "2.0.0" @@ -2608,14 +2935,14 @@ file-system@^2.1.0, file-system@^2.1.1: file-match "^1.0.1" utils-extend "^1.0.4" +file-type@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + file-type@^3.1.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" -file-type@~6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.1.0.tgz#5a7dba98138fa0abec7afc43e5a9a0b2aac729f1" - filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -2627,7 +2954,7 @@ fileset@^2.0.2: glob "^7.0.3" minimatch "^3.0.3" -filesize.js@~1.0.2: +filesize.js@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/filesize.js/-/filesize.js-1.0.2.tgz#934c013395a71804875cf11e6f1ffe211c3f2192" @@ -2650,6 +2977,18 @@ finalhandler@0.4.1: on-finished "~2.3.0" unpipe "~1.0.0" +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + finalhandler@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" @@ -2662,18 +3001,6 @@ finalhandler@~1.0.3: statuses "~1.3.1" unpipe "~1.0.0" -finalhandler@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7" - dependencies: - debug "2.6.8" - encodeurl "~1.0.1" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.1" - statuses "~1.3.1" - unpipe "~1.0.0" - find-line-column@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/find-line-column/-/find-line-column-0.5.2.tgz#db00238ff868551a182e74a103416d295a98c8ca" @@ -2707,13 +3034,27 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + +flexbuffer@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/flexbuffer/-/flexbuffer-0.0.6.tgz#039fdf23f8823e440c38f3277e6fef1174215b30" + fliplog@^0.3.13: version "0.3.13" resolved "https://registry.yarnpkg.com/fliplog/-/fliplog-0.3.13.tgz#dd0d786e821822aae272e0ddc84012596a96154c" dependencies: chain-able "^1.0.1" -follow-redirects@^1.2.3, follow-redirects@~1.2.4: +follow-redirects@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.5.tgz#ffd3e14cbdd5eaa72f61b6368c1f68516c2a26cc" + dependencies: + debug "^2.6.9" + +follow-redirects@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.4.tgz#355e8f4d16876b43f577b0d5ce2668b9723214ea" dependencies: @@ -2735,6 +3076,10 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2747,10 +3092,22 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + forwarded@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + fresh@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" @@ -2759,10 +3116,22 @@ fresh@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + from@~0: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" +fs-extra@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" @@ -2770,14 +3139,6 @@ fs-extra@^2.0.0: graceful-fs "^4.1.2" jsonfile "^2.1.0" -fs-extra@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.1.tgz#7fc0c6c8957f983f57f306a24e5b9ddd8d0dd880" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^3.0.0" - universalify "^0.1.0" - fs-readdir-recursive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" @@ -2786,7 +3147,7 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.0.0: +fsevents@^1.0.0, fsevents@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" dependencies: @@ -2818,14 +3179,15 @@ functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" -fuse-box@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/fuse-box/-/fuse-box-2.2.2.tgz#eec3c4c49496dbfca08d43179a189fbfbce67fda" +fuse-box@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fuse-box/-/fuse-box-2.3.3.tgz#0d3e551c7617f37886df75c57e67df6fe05ea0db" dependencies: acorn "^5.0.3" acorn-es7 "^0.1.0" acorn-es7-plugin "^1.1.7" acorn-jsx "^4.0.1" + acorn-object-rest-spread "^1.1.0" ansi "^0.3.1" app-root-path "^2.0.1" base64-img "^1.0.3" @@ -2875,6 +3237,14 @@ gaze@^1.0.0: dependencies: globule "^1.0.0" +generic-pool@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-2.4.3.tgz#780c36f69dfad05a5a045dd37be7adca11a4f6ff" + +generic-pool@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.1.8.tgz#09844b6545bc9177ec218bd35d4ad894c65be271" + get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" @@ -2906,16 +3276,12 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -git-wrapper2-promise@~0.2.9: +git-wrapper2-promise@0.2.9: version "0.2.9" resolved "https://registry.yarnpkg.com/git-wrapper2-promise/-/git-wrapper2-promise-0.2.9.tgz#2c781e26a16246b05eba45fa17df687403bbfd7d" dependencies: child-process-promise "^1.1.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - "gkt@https://tgz.pm2.io/gkt-1.0.0.tgz": version "1.0.0" resolved "https://tgz.pm2.io/gkt-1.0.0.tgz#405502b007f319c3f47175c4474527300f2ab5ad" @@ -2933,17 +3299,6 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" @@ -3001,24 +3356,21 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -google-closure-compiler@20150901.x: - version "20150901.0.0" - resolved "https://registry.yarnpkg.com/google-closure-compiler/-/google-closure-compiler-20150901.0.0.tgz#3d01c6cade65790a9bfb4e30b2158b7635acbade" - -got@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca" +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" dependencies: - duplexify "^3.2.0" - infinity-agent "^2.0.0" + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" is-stream "^1.0.0" lowercase-keys "^1.0.0" - nested-error-stacks "^1.0.0" - object-assign "^3.0.0" - prepend-http "^1.0.0" - read-all-stream "^3.0.0" - timed-out "^2.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" got@^7.0.0: version "7.1.0" @@ -3047,6 +3399,45 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +graphql-anywhere@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-3.1.0.tgz#3ea0d8e8646b5cee68035016a9a7557c15c21e96" + +graphql-tag@^2.0.0, graphql-tag@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.4.2.tgz#6a63297d8522d03a2b72d26f1b239aab343840cd" + +graphql-tools@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-2.2.1.tgz#ff4d73d3e52e09b38b3f2f4ed53c29d4baa122b1" + dependencies: + apollo-link "^0.7.0" + deprecated-decorator "^0.1.6" + uuid "^3.1.0" + optionalDependencies: + "@types/graphql" "^0.11.4" + +graphql-tools@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-1.2.1.tgz#8d462abaa7b0f3bb2aa633df1e7a848720197671" + dependencies: + deprecated-decorator "^0.1.6" + uuid "^3.0.1" + optionalDependencies: + "@types/graphql" "^0.9.0" + +graphql@0.10.5, graphql@^0.10.0, graphql@^0.10.3: + version "0.10.5" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.10.5.tgz#c9be17ca2bdfdbd134077ffd9bbaa48b8becd298" + dependencies: + iterall "^1.1.0" + +graphql@^0.11.3: + version "0.11.7" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6" + dependencies: + iterall "1.1.3" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -3065,6 +3456,10 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + har-validator@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" @@ -3072,22 +3467,19 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" dependencies: ansi-regex "^2.0.0" -has-binary2@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98" - dependencies: - isarray "2.0.1" - -has-cors@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" - has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -3116,6 +3508,13 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" +hashring@0.0.x: + version "0.0.8" + resolved "https://registry.yarnpkg.com/hashring/-/hashring-0.0.8.tgz#203ab13c364119f10106526d2eaf7bd42b484c31" + dependencies: + bisection "" + simple-lru-cache "0.0.x" + hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -3125,11 +3524,20 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + he@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" -highlight.js@~9.12.0: +highlight.js@9.12.0: version "9.12.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" @@ -3137,6 +3545,10 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + hogan.js@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/hogan.js/-/hogan.js-3.0.2.tgz#4cd9e1abd4294146e7679e41d7898732b02c7bfd" @@ -3151,10 +3563,6 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -hooks-fixed@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hooks-fixed/-/hooks-fixed-2.0.0.tgz#a01d894d52ac7f6599bbb1f63dfc9c411df70cba" - hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -3176,6 +3584,15 @@ htmlparser2@^3.9.1: inherits "^2.0.1" readable-stream "^2.0.2" +http-errors@1.6.2, http-errors@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + http-errors@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" @@ -3192,15 +3609,6 @@ http-errors@~1.6.1: setprototypeof "1.0.3" statuses ">= 1.3.1 < 2" -http-errors@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" - dependencies: - depd "1.1.1" - inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" - http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -3209,26 +3617,38 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" -i18next-express-middleware@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/i18next-express-middleware/-/i18next-express-middleware-1.0.5.tgz#12dce7c553866e11c108943d46ce494baf982219" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +i18next-express-middleware@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/i18next-express-middleware/-/i18next-express-middleware-1.0.7.tgz#7909233f4e6e94b5bd4964a114247dc8d6f3f839" dependencies: - cookies "0.6.1" + cookies "0.7.1" + +i18next-localstorage-cache@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/i18next-localstorage-cache/-/i18next-localstorage-cache-1.1.1.tgz#575256cc35e8cb2d88148f754766fdd2d24bb1b7" -i18next-node-fs-backend@~1.0.0: +i18next-node-fs-backend@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/i18next-node-fs-backend/-/i18next-node-fs-backend-1.0.0.tgz#f5a625a3b287c1d098c7171b7dd376bb07299b59" dependencies: js-yaml "3.5.4" json5 "0.5.0" -i18next-xhr-backend@~1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.4.2.tgz#7aa766292c46ca83ff6477bb55074b363a646a62" +i18next-xhr-backend@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.4.3.tgz#d72f70536a3bf6a3892261dde352bc77d708886a" -i18next@~9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-9.0.0.tgz#a89ab0481b5b6b3964f55b12f03de9063d8f4500" +i18next@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-9.1.0.tgz#408005fe262a990c8d93946a6de0c77bba11667b" iconv-lite@0.4.13: version "0.4.13" @@ -3238,6 +3658,10 @@ iconv-lite@0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.18" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" @@ -3246,7 +3670,7 @@ ieee754@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore-by-default@^1.0.0: +ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -3254,13 +3678,13 @@ ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" -image-size@~0.6.0: +image-size@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.1.tgz#98122a562d59dcc097ef1b2c8191866eb8f5d663" -immediate@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" imurmurhash@^0.1.4: version "0.1.4" @@ -3276,13 +3700,13 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" -infinity-agent@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/infinity-agent/-/infinity-agent-2.0.3.tgz#45e0e2ff7a9eb030b27d62b74b3744b7a7ac4216" +inflection@1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" inflight@^1.0.4: version "1.0.6" @@ -3344,10 +3768,6 @@ interpret@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" -intersect-arrays-to-stream@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/intersect-arrays-to-stream/-/intersect-arrays-to-stream-0.0.3.tgz#fc0318953e872f12a12f3d33d04f4e7630e59f3b" - invariant@^2.2.0, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -3358,6 +3778,34 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +ioredis@3.1.4, ioredis@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-3.1.4.tgz#8688293f5f2f1757e1c812ad17cce49f46d811bc" + dependencies: + bluebird "^3.3.4" + cluster-key-slot "^1.0.6" + debug "^2.2.0" + denque "^1.1.0" + flexbuffer "0.0.6" + lodash.assign "^4.2.0" + lodash.bind "^4.2.1" + lodash.clone "^4.5.0" + lodash.clonedeep "^4.5.0" + lodash.defaults "^4.2.0" + lodash.difference "^4.5.0" + lodash.flatten "^4.4.0" + lodash.foreach "^4.5.0" + lodash.isempty "^4.4.0" + lodash.keys "^4.2.0" + lodash.noop "^3.0.1" + lodash.partial "^4.2.1" + lodash.pick "^4.4.0" + lodash.sample "^4.2.1" + lodash.shuffle "^4.2.0" + lodash.values "^4.3.0" + redis-commands "^1.2.0" + redis-parser "^2.4.0" + ip-regex@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" @@ -3370,9 +3818,9 @@ ipaddr.js@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" -ipaddr.js@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" +ipaddr.js@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" is-arrayish@^0.2.1: version "0.2.1" @@ -3384,6 +3832,10 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-bluebird@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2" + is-buffer@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" @@ -3458,6 +3910,12 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" +is-nan@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2" + dependencies: + define-properties "^1.1.1" + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -3474,6 +3932,10 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" @@ -3554,14 +4016,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isarray@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" - -isemail@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -3646,226 +4100,246 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jest-changed-files@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-20.0.3.tgz#9394d5cc65c438406149bef1bf4d52b68e03e3f8" +iterall@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9" + +iterall@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.1.tgz#f7f0af11e9a04ec6426260f5019d9fcca4d50214" -jest-cli@^20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-20.0.4.tgz#e532b19d88ae5bc6c417e8b0593a6fe954b1dc93" +jackpot@>=0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/jackpot/-/jackpot-0.0.6.tgz#3cff064285cbf66f4eab2593c90bce816a821849" dependencies: - ansi-escapes "^1.4.0" - callsites "^2.0.0" - chalk "^1.1.3" + retry "0.6.0" + +jest-changed-files@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-21.2.0.tgz#5dbeecad42f5d88b482334902ce1cba6d9798d29" + dependencies: + throat "^4.0.0" + +jest-cli@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-21.2.1.tgz#9c528b6629d651911138d228bdb033c157ec8c00" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + glob "^7.1.2" graceful-fs "^4.1.11" is-ci "^1.0.10" istanbul-api "^1.1.1" istanbul-lib-coverage "^1.0.1" istanbul-lib-instrument "^1.4.2" istanbul-lib-source-maps "^1.1.0" - jest-changed-files "^20.0.3" - jest-config "^20.0.4" - jest-docblock "^20.0.3" - jest-environment-jsdom "^20.0.3" - jest-haste-map "^20.0.4" - jest-jasmine2 "^20.0.4" - jest-message-util "^20.0.3" - jest-regex-util "^20.0.3" - jest-resolve-dependencies "^20.0.3" - jest-runtime "^20.0.4" - jest-snapshot "^20.0.3" - jest-util "^20.0.3" + jest-changed-files "^21.2.0" + jest-config "^21.2.1" + jest-environment-jsdom "^21.2.1" + jest-haste-map "^21.2.0" + jest-message-util "^21.2.1" + jest-regex-util "^21.2.0" + jest-resolve-dependencies "^21.2.0" + jest-runner "^21.2.1" + jest-runtime "^21.2.1" + jest-snapshot "^21.2.1" + jest-util "^21.2.1" micromatch "^2.3.11" node-notifier "^5.0.2" - pify "^2.3.0" + pify "^3.0.0" slash "^1.0.0" - string-length "^1.0.1" - throat "^3.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" which "^1.2.12" worker-farm "^1.3.1" - yargs "^7.0.2" + yargs "^9.0.0" -jest-config@^20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-20.0.4.tgz#e37930ab2217c913605eff13e7bd763ec48faeea" +jest-config@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-21.2.1.tgz#c7586c79ead0bcc1f38c401e55f964f13bf2a480" dependencies: - chalk "^1.1.3" + chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^20.0.3" - jest-environment-node "^20.0.3" - jest-jasmine2 "^20.0.4" - jest-matcher-utils "^20.0.3" - jest-regex-util "^20.0.3" - jest-resolve "^20.0.4" - jest-validate "^20.0.3" - pretty-format "^20.0.3" - -jest-diff@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-20.0.3.tgz#81f288fd9e675f0fb23c75f1c2b19445fe586617" + jest-environment-jsdom "^21.2.1" + jest-environment-node "^21.2.1" + jest-get-type "^21.2.0" + jest-jasmine2 "^21.2.1" + jest-regex-util "^21.2.0" + jest-resolve "^21.2.0" + jest-util "^21.2.1" + jest-validate "^21.2.1" + pretty-format "^21.2.1" + +jest-diff@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.2.1.tgz#46cccb6cab2d02ce98bc314011764bb95b065b4f" dependencies: - chalk "^1.1.3" + chalk "^2.0.1" diff "^3.2.0" - jest-matcher-utils "^20.0.3" - pretty-format "^20.0.3" + jest-get-type "^21.2.0" + pretty-format "^21.2.1" -jest-docblock@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712" +jest-docblock@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" -jest-environment-jsdom@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz#048a8ac12ee225f7190417713834bb999787de99" +jest-environment-jsdom@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz#38d9980c8259b2a608ec232deee6289a60d9d5b4" dependencies: - jest-mock "^20.0.3" - jest-util "^20.0.3" + jest-mock "^21.2.0" + jest-util "^21.2.1" jsdom "^9.12.0" -jest-environment-node@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-20.0.3.tgz#d488bc4612af2c246e986e8ae7671a099163d403" +jest-environment-node@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-21.2.1.tgz#98c67df5663c7fbe20f6e792ac2272c740d3b8c8" dependencies: - jest-mock "^20.0.3" - jest-util "^20.0.3" + jest-mock "^21.2.0" + jest-util "^21.2.1" + +jest-get-type@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23" -jest-haste-map@^20.0.4: - version "20.0.5" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-20.0.5.tgz#abad74efb1a005974a7b6517e11010709cab9112" +jest-haste-map@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-21.2.0.tgz#1363f0a8bb4338f24f001806571eff7a4b2ff3d8" dependencies: fb-watchman "^2.0.0" graceful-fs "^4.1.11" - jest-docblock "^20.0.3" + jest-docblock "^21.2.0" micromatch "^2.3.11" - sane "~1.6.0" + sane "^2.0.0" worker-farm "^1.3.1" -jest-jasmine2@^20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz#fcc5b1411780d911d042902ef1859e852e60d5e1" +jest-jasmine2@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz#9cc6fc108accfa97efebce10c4308548a4ea7592" dependencies: - chalk "^1.1.3" + chalk "^2.0.1" + expect "^21.2.1" graceful-fs "^4.1.11" - jest-diff "^20.0.3" - jest-matcher-utils "^20.0.3" - jest-matchers "^20.0.3" - jest-message-util "^20.0.3" - jest-snapshot "^20.0.3" - once "^1.4.0" - p-map "^1.1.1" - -jest-junit@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-3.1.0.tgz#3bd0b7a8bfd5b91f86376d44ff0f4c7f136f4287" - dependencies: - mkdirp "^0.5.1" - strip-ansi "^4.0.0" - xml "^1.0.1" - -jest-matcher-utils@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612" - dependencies: - chalk "^1.1.3" - pretty-format "^20.0.3" + jest-diff "^21.2.1" + jest-matcher-utils "^21.2.1" + jest-message-util "^21.2.1" + jest-snapshot "^21.2.1" + p-cancelable "^0.3.0" -jest-matchers@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-20.0.3.tgz#ca69db1c32db5a6f707fa5e0401abb55700dfd60" +jest-matcher-utils@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz#72c826eaba41a093ac2b4565f865eb8475de0f64" dependencies: - jest-diff "^20.0.3" - jest-matcher-utils "^20.0.3" - jest-message-util "^20.0.3" - jest-regex-util "^20.0.3" + chalk "^2.0.1" + jest-get-type "^21.2.0" + pretty-format "^21.2.1" -jest-message-util@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-20.0.3.tgz#6aec2844306fcb0e6e74d5796c1006d96fdd831c" +jest-message-util@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-21.2.1.tgz#bfe5d4692c84c827d1dcf41823795558f0a1acbe" dependencies: - chalk "^1.1.3" + chalk "^2.0.1" micromatch "^2.3.11" slash "^1.0.0" -jest-mock@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-20.0.3.tgz#8bc070e90414aa155c11a8d64c869a0d5c71da59" +jest-mock@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-21.2.0.tgz#7eb0770e7317968165f61ea2a7281131534b3c0f" -jest-regex-util@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-20.0.3.tgz#85bbab5d133e44625b19faf8c6aa5122d085d762" +jest-regex-util@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-21.2.0.tgz#1b1e33e63143babc3e0f2e6c9b5ba1eb34b2d530" -jest-resolve-dependencies@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz#6e14a7b717af0f2cb3667c549de40af017b1723a" +jest-resolve-dependencies@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz#9e231e371e1a736a1ad4e4b9a843bc72bfe03d09" dependencies: - jest-regex-util "^20.0.3" + jest-regex-util "^21.2.0" -jest-resolve@^20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-20.0.4.tgz#9448b3e8b6bafc15479444c6499045b7ffe597a5" +jest-resolve@^21.2.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-21.2.0.tgz#068913ad2ba6a20218e5fd32471f3874005de3a6" dependencies: browser-resolve "^1.11.2" + chalk "^2.0.1" is-builtin-module "^1.0.0" - resolve "^1.3.2" -jest-runtime@^20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-20.0.4.tgz#a2c802219c4203f754df1404e490186169d124d8" +jest-runner@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-21.2.1.tgz#194732e3e518bfb3d7cbfc0fd5871246c7e1a467" + dependencies: + jest-config "^21.2.1" + jest-docblock "^21.2.0" + jest-haste-map "^21.2.0" + jest-jasmine2 "^21.2.1" + jest-message-util "^21.2.1" + jest-runtime "^21.2.1" + jest-util "^21.2.1" + pify "^3.0.0" + throat "^4.0.0" + worker-farm "^1.3.1" + +jest-runtime@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-21.2.1.tgz#99dce15309c670442eee2ebe1ff53a3cbdbbb73e" dependencies: babel-core "^6.0.0" - babel-jest "^20.0.3" + babel-jest "^21.2.0" babel-plugin-istanbul "^4.0.0" - chalk "^1.1.3" + chalk "^2.0.1" convert-source-map "^1.4.0" graceful-fs "^4.1.11" - jest-config "^20.0.4" - jest-haste-map "^20.0.4" - jest-regex-util "^20.0.3" - jest-resolve "^20.0.4" - jest-util "^20.0.3" + jest-config "^21.2.1" + jest-haste-map "^21.2.0" + jest-regex-util "^21.2.0" + jest-resolve "^21.2.0" + jest-util "^21.2.1" json-stable-stringify "^1.0.1" micromatch "^2.3.11" + slash "^1.0.0" strip-bom "3.0.0" - yargs "^7.0.2" + write-file-atomic "^2.1.0" + yargs "^9.0.0" -jest-snapshot@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-20.0.3.tgz#5b847e1adb1a4d90852a7f9f125086e187c76566" +jest-snapshot@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-21.2.1.tgz#29e49f16202416e47343e757e5eff948c07fd7b0" dependencies: - chalk "^1.1.3" - jest-diff "^20.0.3" - jest-matcher-utils "^20.0.3" - jest-util "^20.0.3" + chalk "^2.0.1" + jest-diff "^21.2.1" + jest-matcher-utils "^21.2.1" + mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^20.0.3" + pretty-format "^21.2.1" -jest-util@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-20.0.3.tgz#0c07f7d80d82f4e5a67c6f8b9c3fe7f65cfd32ad" +jest-util@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-21.2.1.tgz#a274b2f726b0897494d694a6c3d6a61ab819bb78" dependencies: - chalk "^1.1.3" + callsites "^2.0.0" + chalk "^2.0.1" graceful-fs "^4.1.11" - jest-message-util "^20.0.3" - jest-mock "^20.0.3" - jest-validate "^20.0.3" - leven "^2.1.0" + jest-message-util "^21.2.1" + jest-mock "^21.2.0" + jest-validate "^21.2.1" mkdirp "^0.5.1" -jest-validate@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-20.0.3.tgz#d0cfd1de4f579f298484925c280f8f1d94ec3cab" +jest-validate@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7" dependencies: - chalk "^1.1.3" - jest-matcher-utils "^20.0.3" + chalk "^2.0.1" + jest-get-type "^21.2.0" leven "^2.1.0" - pretty-format "^20.0.3" + pretty-format "^21.2.1" -jest@~20.0.4: - version "20.0.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-20.0.4.tgz#3dd260c2989d6dad678b1e9cc4d91944f6d602ac" +jest@21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-21.2.1.tgz#c964e0b47383768a1438e3ccf3c3d470327604e1" dependencies: - jest-cli "^20.0.4" + jest-cli "^21.2.1" -jimp@~0.2.28: +jimp@0.2.28: version "0.2.28" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" dependencies: @@ -3886,42 +4360,21 @@ jimp@~0.2.28: tinycolor2 "^1.1.2" url-regex "^3.0.0" -joi@^6.10.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" - dependencies: - hoek "2.x.x" - isemail "1.x.x" - moment "2.x.x" - topo "1.x.x" - jpeg-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" -jquery-contextmenu@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/jquery-contextmenu/-/jquery-contextmenu-2.5.0.tgz#940dbadbd0f2d7e0a0a8f1bbc5e71667d8257405" +jquery-contextmenu@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/jquery-contextmenu/-/jquery-contextmenu-2.6.2.tgz#83c7ba45c67c814cc4095b19551fd12e5d71da7e" -jquery-simple-upload@~1.0.0: +jquery-simple-upload@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/jquery-simple-upload/-/jquery-simple-upload-1.0.0.tgz#0b89238bf9b35b77b41bfe11840c1b383e97a3bd" dependencies: jquery ">=1.7.0" -jquery-smooth-scroll@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/jquery-smooth-scroll/-/jquery-smooth-scroll-2.2.0.tgz#87dc1add84168b7f466b3cdaeeb81c803fd22a2a" - dependencies: - jquery ">=1.7.0" - -jquery-sticky@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/jquery-sticky/-/jquery-sticky-1.0.4.tgz#2fe8d03dc904685340daa12cbdd1ca0c921b09ac" - dependencies: - jquery "*" - -jquery@*, jquery@>=1.7.0, jquery@~3.2.1: +jquery@3.2.1, jquery@>=1.7.0: version "3.2.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787" @@ -3929,6 +4382,14 @@ js-base64@^2.1.8: version "2.1.9" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" +js-cookie@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.1.4.tgz#da4ec503866f149d164cf25f579ef31015025d8d" + +js-string-escape@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + js-stringify@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" @@ -3937,6 +4398,13 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +js-yaml@3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.4.tgz#f64f16dcd78beb9ce8361068e733ebe47b079179" @@ -3951,7 +4419,7 @@ js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.9.1, js-yaml@~3.9.1: +js-yaml@^3.9.1: version "3.9.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" dependencies: @@ -4030,9 +4498,9 @@ jsonfile@^2.1.0: optionalDependencies: graceful-fs "^4.1.6" -jsonfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" optionalDependencies: graceful-fs "^4.1.6" @@ -4040,16 +4508,17 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - -jsonwebtoken@~7.4.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" +jsonwebtoken@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.0.1.tgz#50daef8d0a8c7de2cd06bc1013b75b04ccf3f0cf" dependencies: - joi "^6.10.1" jws "^3.1.4" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" lodash.once "^4.0.0" ms "^2.0.0" xtend "^4.0.1" @@ -4087,17 +4556,9 @@ jws@^3.1.4: jwa "^1.1.4" safe-buffer "^5.0.1" -kareem@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.4.2.tgz#3b4af5dbfaf3ac1c08b8e5518fdd81ba90c2ab72" - -kareem@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.5.0.tgz#e3e4101d9dcfde299769daf4b4db64d895d17448" - -keygrip@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.1.tgz#b02fa4816eef21a8c4b35ca9e52921ffc89a30e9" +keygrip@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91" kind-of@^3.0.2: version "3.2.2" @@ -4111,17 +4572,17 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -klaw@~2.1.0: +klaw@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/klaw/-/klaw-2.1.0.tgz#694a269019f4321d9233fb1b9abdae21e38259fb" dependencies: graceful-fs "^4.1.9" -latest-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-1.0.1.tgz#72cfc46e3e8d1be651e1ebb54ea9f6ea96f374bb" +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" dependencies: - package-json "^1.0.0" + package-json "^4.0.0" lazy-cache@^1.0.3: version "1.0.4" @@ -4175,63 +4636,6 @@ lego-api@^1.0.7: dependencies: chain-able "^3.0.0" -level-codec@~6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-6.1.0.tgz#f5df0a99582f76dac43855151ab6f4e4d0d60045" - -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - -level-errors@^1.0.3, level-errors@~1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.4.tgz#3585e623974c737a93755492a43c0267cda4425f" - dependencies: - errno "~0.1.1" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -leveldown@^1.6.0, leveldown@^1.7.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-1.7.2.tgz#5e3467bb27ee246a4a7b8dbd8fb2b16206a6eb8b" - dependencies: - abstract-leveldown "~2.6.1" - bindings "~1.2.1" - fast-future "~1.0.2" - nan "~2.6.1" - prebuild-install "^2.1.0" - -levelup@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.8.tgz#fb442c488efbea1043f7eb9929a792a74fbd1da6" - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~6.1.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.1.0" - xtend "~4.0.0" - -levelup@~1.3.9: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~7.0.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.4.1" - xtend "~4.0.0" - leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" @@ -4287,17 +4691,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash-cli@~4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash-cli/-/lodash-cli-4.17.4.tgz#23b727cd0e91e28484fafda1521900a8a811df81" - dependencies: - closure-compiler "0.2.12" - glob "7.1.1" - lodash "4.17.4" - semver "5.3.0" - uglify-js "2.7.5" - -lodash-es@~4.17.4: +lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" @@ -4344,7 +4738,15 @@ lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" -lodash.clonedeep@^4.3.2: +lodash.bind@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + +lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + +lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -4359,6 +4761,10 @@ lodash.defaults@^3.1.2: lodash.assign "^3.0.0" lodash.restparam "^3.0.0" +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + lodash.difference@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" @@ -4367,9 +4773,17 @@ lodash.findindex@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106" -lodash.intersection@^4.4.0: +lodash.flatten@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.intersection/-/lodash.intersection-4.4.0.tgz#0a11ba631d0e95c23c7f2f4cbb9a692ed178e705" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.foreach@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" lodash.isarguments@^3.0.0: version "3.1.0" @@ -4379,10 +4793,34 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" -lodash.isequal@^4.0.0, lodash.isequal@^4.1.3: +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + +lodash.isempty@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" + +lodash.isequal@^4.0.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -4391,6 +4829,10 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash.keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-4.2.0.tgz#a08602ac12e4fb83f91fc1fb7a360a4d9ba35205" + lodash.merge@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" @@ -4399,6 +4841,10 @@ lodash.mergewith@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" +lodash.noop@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" @@ -4407,6 +4853,14 @@ lodash.padend@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" +lodash.partial@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.partial/-/lodash.partial-4.2.1.tgz#49f3d8cfdaa3bff8b3a91d127e923245418961d4" + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + lodash.repeat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/lodash.repeat/-/lodash.repeat-4.1.0.tgz#fc7de8131d8c8ac07e4b49f74ffe829d1f2bec44" @@ -4415,23 +4869,19 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" -lodash.sortedindexof@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.sortedindexof/-/lodash.sortedindexof-4.1.0.tgz#7b661d2f86f55668770802d56baa8f02d6620f3c" - -lodash.spread@^4.2.1: +lodash.sample@^4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.spread/-/lodash.spread-4.2.1.tgz#07bf5569e83b40534f7361d954a9fab02da5d4fc" + resolved "https://registry.yarnpkg.com/lodash.sample/-/lodash.sample-4.2.1.tgz#5e4291b0c753fa1abeb0aab8fb29df1b66f07f6d" -lodash.union@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" +lodash.shuffle@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz#145b5053cf875f6f5c2a33f48b6e9948c6ec7b4b" -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" +lodash.values@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347" -lodash@4.17.4, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.4: +lodash@4.17.4, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.1, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -4449,7 +4899,7 @@ longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.1.0: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: @@ -4477,9 +4927,11 @@ lru-cache@^4.0.0, lru-cache@^4.0.1, lru-cache@^4.0.2: pseudomap "^1.0.2" yallist "^2.1.2" -ltgt@~2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" +make-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" + dependencies: + pify "^2.3.0" makeerror@1.0.x: version "1.0.11" @@ -4487,6 +4939,10 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +manakin@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/manakin/-/manakin-0.5.1.tgz#c4a7116f6b00df3d5f1a37ad3ca515d22065a658" + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -4495,25 +4951,25 @@ map-stream@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" -markdown-it-abbr@~1.0.4: +markdown-it-abbr@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz#d66b5364521cbb3dd8aa59dadfba2fb6865c8fd8" -markdown-it-anchor@~4.0.0: +markdown-it-anchor@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-4.0.0.tgz#e87fb5543e01965adf71506c6bf7b0491841b7e3" dependencies: string "^3.3.3" -markdown-it-attrs@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/markdown-it-attrs/-/markdown-it-attrs-1.1.0.tgz#6f5c7bc8d0c29e628ef335bcc1e0bf454d204f5d" +markdown-it-attrs@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/markdown-it-attrs/-/markdown-it-attrs-1.2.0.tgz#6baad67036a411483d5902c127d46ee229435484" -markdown-it-emoji@~1.4.0: +markdown-it-emoji@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" -markdown-it-expand-tabs@~1.0.12: +markdown-it-expand-tabs@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/markdown-it-expand-tabs/-/markdown-it-expand-tabs-1.0.12.tgz#f54bd2f303f858ee6798ca2bd83fe70144814ca0" dependencies: @@ -4523,19 +4979,19 @@ markdown-it-external-links@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/markdown-it-external-links/-/markdown-it-external-links-0.0.6.tgz#9503258fce4c81010ea15fe71769d63a1346d801" -markdown-it-footnote@~3.0.1: +markdown-it-footnote@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-3.0.1.tgz#7f3730747cacc86e2fe0bf8a17a710f34791517a" -markdown-it-mathjax@~2.0.0: +markdown-it-mathjax@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/markdown-it-mathjax/-/markdown-it-mathjax-2.0.0.tgz#ae2b4f4c5c719a03f9e475c664f7b2685231d9e9" -markdown-it-task-lists@~2.0.1: +markdown-it-task-lists@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.0.1.tgz#a9ce7f55cde9f45e0fca629071d11d3fd5a69416" -markdown-it@~8.4.0: +markdown-it@8.4.0: version "8.4.0" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d" dependencies: @@ -4549,9 +5005,9 @@ marked@*: version "0.3.6" resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" -mathjax-node@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mathjax-node/-/mathjax-node-1.2.0.tgz#538d01f85ca18b90f3cc6ce68c7caeed44bb9f7f" +mathjax-node@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/mathjax-node/-/mathjax-node-1.2.1.tgz#f4a0e272149104f2e00a3d268c81e42bee1324fd" dependencies: jsdom "7.0 - 9.12" mathjax "*" @@ -4574,15 +5030,12 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -memdown@~1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.2.4.tgz#cd9a34aaf074d53445a271108eb4b8dd4ec0f27f" +memcached@~0.2.4: + version "0.2.8" + resolved "https://registry.yarnpkg.com/memcached/-/memcached-0.2.8.tgz#ffbf9498cbc30779625b77e77770bd50dc525212" dependencies: - abstract-leveldown "2.4.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.1.3" + hashring "0.0.x" + jackpot ">=0.0.6" meow@^3.7.0: version "3.7.0" @@ -4629,14 +5082,24 @@ micromatch@^2.1.5, micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -"mime-db@>= 1.27.0 < 2", mime-db@~1.29.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" +"mime-db@>= 1.29.0 < 2", mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" +mime-db@~1.29.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" + +mime-types@2.1.17, mime-types@~2.1.17: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.6, mime-types@~2.1.7: version "2.1.15" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" @@ -4653,6 +5116,10 @@ mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + mime@^1.3.4: version "1.3.6" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" @@ -4711,125 +5178,25 @@ mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" -moment-timezone@^0.5.x, moment-timezone@~0.5.13: +moment-timezone@0.5.13, moment-timezone@^0.5.0, moment-timezone@^0.5.4, moment-timezone@^0.5.x: version "0.5.13" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.13.tgz#99ce5c7d827262eb0f1f702044177f60745d7b90" dependencies: moment ">= 2.9.0" -moment@2.x.x, "moment@>= 2.9.0", moment@^2.10.6, moment@^2.16.1, moment@^2.18, moment@^2.18.1, moment@~2.18.1: +moment@2.18.1, "moment@>= 2.9.0", moment@^2.10.6, moment@^2.13.0, moment@^2.16.1, moment@^2.18: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" -mongodb-core@2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.11.tgz#1c38776ceb174997a99c28860eed9028da9b3e1a" - dependencies: - bson "~1.0.4" - require_optional "~1.0.0" - -mongodb-core@2.1.14: - version "2.1.14" - resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.14.tgz#13cba2764226b5be3d18992af0c963ce5ea0f0fd" - dependencies: - bson "~1.0.4" - require_optional "~1.0.0" - -mongodb-core@2.1.15: - version "2.1.15" - resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.15.tgz#841f53b87ffff4c7458189c35c8ae827e1169764" - dependencies: - bson "~1.0.4" - require_optional "~1.0.0" - -mongodb@2.2.27: - version "2.2.27" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.27.tgz#34122034db66d983bcf6ab5adb26a24a70fef6e6" - dependencies: - es6-promise "3.2.1" - mongodb-core "2.1.11" - readable-stream "2.2.7" - -mongodb@2.2.31, mongodb@~2.2.31: - version "2.2.31" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.31.tgz#1940445c661e19217bb3bf8245d9854aaef548db" - dependencies: - es6-promise "3.2.1" - mongodb-core "2.1.15" - readable-stream "2.2.7" - -"mongodb@>= 1.2.0 <3.0.0": - version "2.2.30" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.30.tgz#8ccd801f676c8172040c2f2b47e9602a0d5634ab" - dependencies: - es6-promise "3.2.1" - mongodb-core "2.1.14" - readable-stream "2.2.7" - -mongoose@*: - version "4.11.3" - resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.11.3.tgz#f93d427b282c2e798b0fe1532fb41a7dde6e98d3" - dependencies: - async "2.1.4" - bson "~1.0.4" - hooks-fixed "2.0.0" - kareem "1.4.2" - mongodb "2.2.27" - mpath "0.3.0" - mpromise "0.5.5" - mquery "2.3.1" - ms "2.0.0" - muri "1.2.2" - regexp-clone "0.0.1" - sliced "1.0.1" - -mongoose@~4.11.9: - version "4.11.9" - resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.11.9.tgz#58f89a72e75674d9bcdfa4e65ebe1b49b4477637" - dependencies: - async "2.1.4" - bson "~1.0.4" - hooks-fixed "2.0.0" - kareem "1.5.0" - mongodb "2.2.31" - mpath "0.3.0" - mpromise "0.5.5" - mquery "2.3.1" - ms "2.0.0" - muri "1.2.2" - regexp-clone "0.0.1" - sliced "1.0.1" - -mpath@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.3.0.tgz#7a58f789e9b5fd3c94520634157960f26bd5ef44" - -mpromise@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mpromise/-/mpromise-0.5.5.tgz#f5b24259d763acc2257b0a0c8c6d866fd51732e6" - -mquery@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/mquery/-/mquery-2.3.1.tgz#9ab36749714800ff0bb53a681ce4bc4d5f07c87b" - dependencies: - bluebird "2.10.2" - debug "2.6.8" - regexp-clone "0.0.1" - sliced "0.0.5" - ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - ms@2.0.0, ms@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -multer@~1.3.0: +multer@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/multer/-/multer-1.3.0.tgz#092b2670f6846fa4914965efc8cf94c20fec6cd2" dependencies: @@ -4842,10 +5209,6 @@ multer@~1.3.0: type-is "^1.6.4" xtend "^4.0.0" -muri@1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/muri/-/muri-1.2.2.tgz#63198132650db08a04cc79ccd00dd389afd2631c" - mustache@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.0.tgz#4028f7778b17708a489930a6e52ac3bca0da41d0" @@ -4862,7 +5225,7 @@ mv@~2: ncp "~2.0.0" rimraf "~2.4.0" -nan@^2.3.0, nan@^2.3.2, nan@^2.3.3, nan@~2.6.1: +nan@^2.3.0, nan@^2.3.2, nan@^2.3.3: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" @@ -4893,27 +5256,13 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" -nested-error-stacks@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz#19f619591519f096769a5ba9a86e6eeec823c3cf" - dependencies: - inherits "~2.0.1" - -ngraminator@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ngraminator/-/ngraminator-0.0.1.tgz#29cfd699df6970f42de9b2f0bdc7f4b60fad6f8e" - -node-2fa@~1.1.2: +node-2fa@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/node-2fa/-/node-2fa-1.1.2.tgz#5bc5691474afe35ae6b3b76459b98b7c20c7158c" dependencies: notp "^2.0.3" thirty-two "0.0.2" -node-abi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.1.0.tgz#50ad834affcf17440e12bfc5f9ba0946f572d10c" - node-fetch@1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" @@ -4921,7 +5270,7 @@ node-fetch@1.6.3: encoding "^0.1.11" is-stream "^1.0.1" -node-graceful@~0.2.3: +node-graceful@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/node-graceful/-/node-graceful-0.2.3.tgz#ab120e1eed8c0c2b5e2ac874bf2754519c3fa942" @@ -4970,7 +5319,7 @@ node-pre-gyp@^0.6.36: tar "^2.2.1" tar-pack "^3.4.0" -node-sass@~4.5.3: +node-sass@4.5.3: version "4.5.3" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.5.3.tgz#d09c9d1179641239d1b97ffc6231fdcec53e1568" dependencies: @@ -4997,24 +5346,20 @@ node-version@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.0.0.tgz#1b9b9584a9a7f7a6123f215cd14a652bf21ab19e" -nodemon@~1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.11.0.tgz#226c562bd2a7b13d3d7518b49ad4828a3623d06c" +nodemon@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.12.1.tgz#996a56dc49d9f16bbf1b78a4de08f13634b3878d" dependencies: - chokidar "^1.4.3" - debug "^2.2.0" - es6-promise "^3.0.2" - ignore-by-default "^1.0.0" + chokidar "^1.7.0" + debug "^2.6.8" + es6-promise "^3.3.1" + ignore-by-default "^1.0.1" lodash.defaults "^3.1.2" - minimatch "^3.0.0" - ps-tree "^1.0.1" - touch "1.0.0" + minimatch "^3.0.4" + ps-tree "^1.1.0" + touch "^3.1.0" undefsafe "0.0.3" - update-notifier "0.5.0" - -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + update-notifier "^2.2.0" nopt@1.0.10, nopt@~1.0.10: version "1.0.10" @@ -5050,6 +5395,10 @@ normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + notp@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/notp/-/notp-2.0.3.tgz#a9fd11e25cfe1ccb39fc6689544ee4c10ef9a577" @@ -5060,7 +5409,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.1, npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -5082,6 +5431,10 @@ nth-check@~1.0.1: dependencies: boolbase "~1.0.0" +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -5090,7 +5443,7 @@ number-is-nan@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.1.tgz#7ae9b07b0ea804db7e25f05cb5fe4097d4e4949f" -oauth-sign@~0.8.1: +oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -5098,17 +5451,25 @@ oauth@0.9.x: version "0.9.15" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" +object-assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + object-assign@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@~4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -object-component@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object-path@^0.11.2: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" object.omit@^2.0.0: version "2.0.1" @@ -5127,7 +5488,7 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: +once@^1.3.0, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -5145,7 +5506,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opencollective@^1.0.3, opencollective@~1.0.3: +opencollective@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" dependencies: @@ -5185,7 +5546,7 @@ options@>=0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" -ora@~1.3.0: +ora@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ora/-/ora-1.3.0.tgz#80078dd2b92a934af66a3ad72a5b910694ede51a" dependencies: @@ -5194,7 +5555,7 @@ ora@~1.3.0: cli-spinners "^1.0.0" log-symbols "^1.0.2" -os-homedir@^1.0.0, os-homedir@^1.0.1: +os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -5216,7 +5577,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@0, osenv@^0.1.0, osenv@^0.1.4: +osenv@0, osenv@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" dependencies: @@ -5249,22 +5610,24 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-map@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a" - p-timeout@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.0.tgz#9820f99434c5817868b4f34809ee5291660d5b6c" dependencies: p-finally "^1.0.0" -package-json@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0" +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" dependencies: - got "^3.2.0" - registry-url "^3.0.0" + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +packet-reader@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27" parse-bmfont-ascii@^1.0.3: version "1.0.6" @@ -5313,53 +5676,39 @@ parse5@^3.0.1: dependencies: "@types/node" "^6.0.46" -parsejson@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" - dependencies: - better-assert "~1.0.0" - -parseqs@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" - dependencies: - better-assert "~1.0.0" - -parseuri@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" - dependencies: - better-assert "~1.0.0" - parseurl@^1.3.0, parseurl@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + passport-azure-ad-oauth2@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/passport-azure-ad-oauth2/-/passport-azure-ad-oauth2-0.0.4.tgz#1a09d8869efd4afd095116e228941961b3a5c120" dependencies: passport-oauth "1.0.x" -passport-facebook@~2.1.1: +passport-facebook@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/passport-facebook/-/passport-facebook-2.1.1.tgz#c39d0b52ae4d59163245a4e21a7b9b6321303311" dependencies: passport-oauth2 "1.x.x" -passport-github2@~0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/passport-github2/-/passport-github2-0.1.10.tgz#50a21c1e95b83113e4da32c81c2c1a64429bb5bd" +passport-github2@0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/passport-github2/-/passport-github2-0.1.11.tgz#c92b56f3c38a44e766aac7e9e7c1384c5e93c999" dependencies: passport-oauth2 "1.x.x" -passport-google-oauth20@~1.0.0: +passport-google-oauth20@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-1.0.0.tgz#3b960e8a1d70d1dbe794615c827c68c40392a5d0" dependencies: passport-oauth2 "1.x.x" -passport-ldapauth@~2.0.0: +passport-ldapauth@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/passport-ldapauth/-/passport-ldapauth-2.0.0.tgz#42dff004417185d0a4d9f776a3eed8d4731fd689" dependencies: @@ -5368,7 +5717,7 @@ passport-ldapauth@~2.0.0: ldapauth-fork "^4.0.1" passport-strategy "^1.0.0" -passport-local@~1.0.0: +passport-local@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" dependencies: @@ -5417,17 +5766,18 @@ passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" -passport-windowslive@~1.0.2: +passport-windowslive@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/passport-windowslive/-/passport-windowslive-1.0.2.tgz#383cfee6589ffb5ecc2ad19c3a41ef691462a705" dependencies: passport-oauth2 "1.x.x" -passport.socketio@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/passport.socketio/-/passport.socketio-3.7.0.tgz#2ee5fafe9695d4281c8cddd3fe975ecd18e6726e" +passport@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" dependencies: - xtend "^4.0.0" + passport-strategy "1.x.x" + pause "0.0.1" passport@~0.1.1: version "0.1.18" @@ -5436,13 +5786,6 @@ passport@~0.1.1: pause "0.0.1" pkginfo "0.2.x" -passport@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -5501,6 +5844,85 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pg-connection-string@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" + +pg-hstore@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.2.tgz#f7ef053e7b9b892ae986af2f7cbe86432dfcf24f" + dependencies: + underscore "^1.7.0" + +pg-minify@~0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/pg-minify/-/pg-minify-0.5.3.tgz#aa09befa3cbe29fab6461bf819100e0471215011" + +pg-pool@1.*: + version "1.8.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-1.8.0.tgz#f7ec73824c37a03f076f51bfdf70e340147c4f37" + dependencies: + generic-pool "2.4.3" + object-assign "4.1.0" + +pg-pool@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.3.tgz#c022032c8949f312a4f91fb6409ce04076be3257" + +pg-promise@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/pg-promise/-/pg-promise-6.10.3.tgz#1818d515f08757b6a1898ef2301438cfa4a3dcd7" + dependencies: + manakin "~0.5.1" + pg "~7.3.0" + pg-minify "~0.5.3" + spex "~2.0.0" + +pg-types@1.*, pg-types@~1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2" + dependencies: + postgres-array "~1.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.0" + postgres-interval "^1.1.0" + +pg@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/pg/-/pg-6.4.2.tgz#c364011060eac7a507a2ae063eb857ece910e27f" + dependencies: + buffer-writer "1.0.1" + js-string-escape "1.0.1" + packet-reader "0.3.1" + pg-connection-string "0.1.3" + pg-pool "1.*" + pg-types "1.*" + pgpass "1.*" + semver "4.3.2" + +pg@~7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-7.3.0.tgz#275e27466e54a645f6b4a16f6acadf6b849ad83b" + dependencies: + buffer-writer "1.0.1" + js-string-escape "1.0.1" + packet-reader "0.3.1" + pg-connection-string "0.1.3" + pg-pool "~2.0.3" + pg-types "~1.12.1" + pgpass "1.x" + semver "4.3.2" + +pgpass@1.*, pgpass@1.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" + dependencies: + split "^1.0.0" + pidusage@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/pidusage/-/pidusage-1.1.5.tgz#b8c8d32bdfaf36212ca9e741028876ea33217e66" @@ -5539,24 +5961,24 @@ pkginfo@0.2.x: version "0.2.3" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.2.3.tgz#7239c42a5ef6c30b8f328439d9b9ff71042490f8" -pluralize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" -pm2-axon-rpc@0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/pm2-axon-rpc/-/pm2-axon-rpc-0.4.5.tgz#fb62e9a53f3e2b7bed1afe16e3b0d1b06fe8ba69" +pm2-axon-rpc@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pm2-axon-rpc/-/pm2-axon-rpc-0.5.0.tgz#ad08d6a27f580d5c7be4d7bf9dddff398f868994" dependencies: - debug "*" - fclone "1.0.8" + debug "^3.0" + fclone "^1" -pm2-axon@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pm2-axon/-/pm2-axon-3.0.2.tgz#53de1d34edbf266d58f6b1dea2d8244c71ad24b9" +pm2-axon@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pm2-axon/-/pm2-axon-3.1.0.tgz#1b4527f3385e203adc1a5b0488bb52f0322731da" dependencies: amp "~0.3.1" amp-message "~0.1.1" - debug "~2.2.0" + debug "^3.0" escape-regexp "0.0.1" pm2-deploy@^0.3.5: @@ -5572,9 +5994,9 @@ pm2-multimeter@^0.1.2: dependencies: charm "~0.1.1" -pm2@~2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/pm2/-/pm2-2.6.1.tgz#a9c2fdb7bf1676655935eb4176239003fca5c8da" +pm2@2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/pm2/-/pm2-2.7.1.tgz#b7b8404d8bec587526fd58bc21feffea351bec15" dependencies: async "^2.5" blessed "^0.1.81" @@ -5583,7 +6005,7 @@ pm2@~2.6.1: cli-table-redemption "^1.0.0" commander "2.11.0" cron "1.2.1" - debug "^2.6" + debug "^3.0" eventemitter2 "1.0.5" fclone "1.0.11" mkdirp "0.5.1" @@ -5591,26 +6013,26 @@ pm2@~2.6.1: needle "1.6.0" nssocket "0.6.0" pidusage "^1.1.0" - pm2-axon "3.0.2" - pm2-axon-rpc "0.4.5" + pm2-axon "3.1.0" + pm2-axon-rpc "0.5.0" pm2-deploy "^0.3.5" pm2-multimeter "^0.1.2" - pmx "^1.2.0" + pmx "~1.5.0" promptly "2.2.0" semver "^5.3" shelljs "0.7.8" - source-map-support "^0.4.15" + source-map-support "^0.4.18" sprintf-js "1.1.1" vizion "^0.2" yamljs "0.3.0" optionalDependencies: gkt "https://tgz.pm2.io/gkt-1.0.0.tgz" -pmx@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pmx/-/pmx-1.2.0.tgz#712a9e1fdea53a9b061169cc7676b14838c87585" +pmx@~1.5.0: + version "1.5.4" + resolved "https://registry.yarnpkg.com/pmx/-/pmx-1.5.4.tgz#27d71c54e727b5186485545b9c70c21eabc81c0f" dependencies: - debug "^2.6" + debug "^3" json-stringify-safe "^5.0" vxx "^1.2.0" @@ -5618,6 +6040,18 @@ pngjs@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.2.0.tgz#fc9fcea1a8a375da54a51148019d5abd41dbabde" +postcss-selector-parser@2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" + postcss@^6.0.1: version "6.0.8" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.8.tgz#89067a9ce8b11f8a84cbc5117efc30419a0857b3" @@ -5626,24 +6060,31 @@ postcss@^6.0.1: source-map "^0.5.6" supports-color "^4.2.0" -prebuild-install@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.2.0.tgz#55934756a32bac8747390ca44ff663cee8b99b69" +postcss@^6.0.13: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f" dependencies: - expand-template "^1.0.2" - github-from-package "0.0.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - node-abi "^2.0.0" - noop-logger "^0.1.1" - npmlog "^4.0.1" - os-homedir "^1.0.1" - pump "^1.0.1" - rc "^1.1.6" - simple-get "^1.4.2" - tar-fs "^1.13.0" - tunnel-agent "^0.6.0" - xtend "4.0.1" + chalk "^2.1.0" + source-map "^0.6.1" + supports-color "^4.4.0" + +postgres-array@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.2.tgz#8e0b32eb03bf77a5c0a7851e0441c169a256a238" + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + +postgres-date@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8" + +postgres-interval@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.1.tgz#acdb0f897b4b1c6e496d9d4e0a853e1c428f06f0" + dependencies: + xtend "^4.0.0" precond@0.2: version "0.2.3" @@ -5653,7 +6094,7 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" -prepend-http@^1.0.0, prepend-http@^1.0.1: +prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -5661,12 +6102,12 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -pretty-format@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14" +pretty-format@^21.2.1: + version "21.2.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36" dependencies: - ansi-regex "^2.1.1" - ansi-styles "^3.0.0" + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" pretty-time@^0.2.0: version "0.2.0" @@ -5729,22 +6170,18 @@ proxy-addr@~1.1.4: forwarded "~0.1.0" ipaddr.js "1.3.0" -proxy-addr@~1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" +proxy-addr@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" dependencies: - forwarded "~0.1.0" - ipaddr.js "1.4.0" + forwarded "~0.1.2" + ipaddr.js "1.5.2" prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - -ps-tree@^1.0.1: +ps-tree@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" dependencies: @@ -5762,9 +6199,9 @@ pug-attrs@^2.0.1, pug-attrs@^2.0.2: js-stringify "^1.0.1" pug-runtime "^2.0.3" -pug-code-gen@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-1.1.1.tgz#1cf72744ef2a039eae6a3340caaa1105871258e8" +pug-code-gen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.0.tgz#96aea39a9e62f1ec5d2b6a5b42a29d528c70b43d" dependencies: constantinople "^3.0.1" doctypes "^1.1.0" @@ -5779,15 +6216,15 @@ pug-error@^1.3.0, pug-error@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.2.tgz#53ae7d9d29bb03cf564493a026109f54c47f5f26" -pug-filters@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.4.tgz#ab247c0f58765414b61be7b54fe979e9f6fc898f" +pug-filters@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.5.tgz#66bf6e80d97fbef829bab0aa35eddff33fc964f3" dependencies: clean-css "^3.3.0" constantinople "^3.0.1" jstransformer "1.0.0" pug-error "^1.3.2" - pug-walk "^1.1.4" + pug-walk "^1.1.5" resolve "^1.1.6" uglify-js "^2.6.1" @@ -5807,16 +6244,16 @@ pug-lexer@^3.1.0: is-expression "^3.0.0" pug-error "^1.3.2" -pug-linker@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.2.tgz#cc0780cf9f3f5522b270871785492b99588d3142" +pug-linker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.3.tgz#25f59eb750237f0368e59c3379764229c0189c41" dependencies: pug-error "^1.3.2" - pug-walk "^1.1.4" + pug-walk "^1.1.5" -pug-lint@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/pug-lint/-/pug-lint-2.4.0.tgz#1f584c1624fac48e5a0d03e40823caef736702e0" +pug-lint@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pug-lint/-/pug-lint-2.5.0.tgz#4419ee301aeca45f54061b0eca4a9a471f3aa9a9" dependencies: acorn "^4.0.1" commander "^2.9.0" @@ -5832,16 +6269,16 @@ pug-lint@~2.4.0: strip-json-comments "^2.0.1" void-elements "^2.0.1" -pug-load@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.8.tgz#1df1c1716f3e68c70d71699cff9458472dc38b9b" +pug-load@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.9.tgz#ee217c914cc1d9324d44b86c32d1df241d36de7a" dependencies: object-assign "^4.1.0" - pug-walk "^1.1.4" + pug-walk "^1.1.5" -pug-parser@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-3.0.1.tgz#dc0c5dd6c9c2d89da6105abbdf3d1b0fb4d39b5e" +pug-parser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-4.0.0.tgz#c9f52322e4eabe4bf5beeba64ed18373bb627801" dependencies: pug-error "^1.3.2" token-stream "0.0.1" @@ -5856,38 +6293,23 @@ pug-strip-comments@^1.0.2: dependencies: pug-error "^1.3.2" -pug-walk@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.4.tgz#29e5174af43b67e99c31b448632e1ff86ddd671c" +pug-walk@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.5.tgz#90e943acbcf7021e6454cf1b32245891cba6f851" -pug@~2.0.0-rc.3: - version "2.0.0-rc.3" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.3.tgz#553cb3c3a97bb54ec3cb1e08591dcae3b6f58891" +pug@2.0.0-rc.4: + version "2.0.0-rc.4" + resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.4.tgz#b7b08f6599bd5302568042b7436984fb28c80a13" dependencies: - pug-code-gen "^1.1.1" - pug-filters "^2.1.4" + pug-code-gen "^2.0.0" + pug-filters "^2.1.5" pug-lexer "^3.1.0" - pug-linker "^3.0.2" - pug-load "^2.0.8" - pug-parser "^3.0.1" + pug-linker "^3.0.3" + pug-load "^2.0.9" + pug-parser "^4.0.0" pug-runtime "^2.0.3" pug-strip-comments "^1.0.2" -pump@^1.0.0, pump@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b" - dependencies: - duplexify "^3.1.2" - inherits "^2.0.1" - pump "^1.0.0" - punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -5896,6 +6318,10 @@ q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" +qr-image@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/qr-image/-/qr-image-3.2.0.tgz#9fa8295beae50c4a149cf9f909a1db464a8672e8" + qs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" @@ -5904,9 +6330,9 @@ qs@6.4.0, qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" -qs@6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49" +qs@6.5.1, qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" random-bytes@~1.0.0: version "1.0.0" @@ -5927,6 +6353,15 @@ range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" +raw-body@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + dependencies: + bytes "3.0.0" + http-errors "1.6.2" + iconv-lite "0.4.19" + unpipe "1.0.0" + raw-body@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" @@ -5944,24 +6379,17 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -read-all-stream@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" - dependencies: - pinkie-promise "^2.0.0" - readable-stream "^2.0.0" - -read-chunk@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" - -read-chunk@~2.1.0: +read-chunk@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" dependencies: pify "^3.0.0" safe-buffer "^5.1.1" +read-chunk@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -5998,7 +6426,7 @@ read@^1.0.4: dependencies: mute-stream "~0.0.4" -readable-stream@1.1.x, readable-stream@^1.0.33: +readable-stream@1.1.x: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: @@ -6007,19 +6435,7 @@ readable-stream@1.1.x, readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" - dependencies: - buffer-shims "~1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~1.0.0" - util-deprecate "~1.0.1" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -6060,10 +6476,39 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +redis-commands@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" + +redis-parser@^2.4.0, redis-parser@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + +redis@^2.1.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/redis/-/redis-2.7.1.tgz#7d56f7875b98b20410b71539f1d878ed58ebf46a" + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.5.0" + +redis@~0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/redis/-/redis-0.10.3.tgz#8927fe2110ee39617bcf3fd37b89d8e123911bb6" + reduce-flatten@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" +redux@^3.4.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b" + dependencies: + lodash "^4.2.1" + lodash-es "^4.2.1" + loose-envify "^1.1.0" + symbol-observable "^1.0.3" + regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" @@ -6084,6 +6529,14 @@ regenerator-transform@0.9.11: babel-types "^6.19.0" private "^0.1.6" +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + regex-cache@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" @@ -6091,10 +6544,6 @@ regex-cache@^0.4.2: is-equal-shallow "^0.1.3" is-primitive "^2.0.0" -regexp-clone@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-0.0.1.tgz#a7c2e09891fdbf38fbb10d376fb73003e68ac589" - regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -6103,7 +6552,14 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -registry-url@^3.0.0: +registry-auth-token@^3.0.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" dependencies: @@ -6119,7 +6575,7 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" -remove-markdown@~0.2.2: +remove-markdown@0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.2.2.tgz#66b0ceeba9fb77ca9636bb1b0307ce21a32a12a6" @@ -6135,19 +6591,13 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" -repeating@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" - dependencies: - is-finite "^1.0.0" - repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" dependencies: is-finite "^1.0.0" -request@2, request@^2.65.0, request@^2.67.0, request@^2.79.0, request@^2.81.0, request@~2.81.0: +request@2, request@^2.65.0, request@^2.67.0, request@^2.79.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -6164,15 +6614,42 @@ request@2, request@^2.65.0, request@^2.67.0, request@^2.79.0, request@^2.81.0, r is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@2.83.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" tunnel-agent "^0.6.0" - uuid "^3.0.0" + uuid "^3.1.0" require-directory@^2.1.1: version "2.1.1" @@ -6189,26 +6666,15 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" -require_optional@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" - dependencies: - resolve-from "^2.0.0" - semver "^5.1.0" - resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.3.3: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: @@ -6221,6 +6687,17 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +retry-as-promised@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-2.3.1.tgz#f75059183f9730771c09bad1eed57537931cbc9d" + dependencies: + bluebird "^3.4.6" + debug "^2.2.0" + +retry@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.0.tgz#1c010713279a6fd1e8def28af0c3ff1871caa537" + right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" @@ -6259,10 +6736,6 @@ rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" -safe-buffer@5.0.1, safe-buffer@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" - safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -6271,17 +6744,19 @@ safe-json-stringify@~1: version "1.0.4" resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz#81a098f447e4bbc3ff3312a243521bc060ef5911" -sane@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-1.6.0.tgz#9610c452307a135d29c1fdfe2547034180c46775" +sane@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.0.0.tgz#99cb79f21f4a53a69d4d0cd957c2db04024b8eb2" dependencies: anymatch "^1.3.0" exec-sh "^0.2.0" - fb-watchman "^1.8.0" + fb-watchman "^2.0.0" minimatch "^3.0.2" minimist "^1.1.1" walker "~1.0.5" watch "~0.10.0" + optionalDependencies: + fsevents "^1.1.1" sass-graph@^2.1.1: version "2.2.4" @@ -6303,36 +6778,6 @@ scss-tokenizer@^0.2.3: js-base64 "^2.1.8" source-map "^0.4.2" -search-index-adder@~0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/search-index-adder/-/search-index-adder-0.3.9.tgz#a94b5fc5b27f1827c43eab599c760dcc4c29599d" - dependencies: - JSONStream "^1.2.1" - async "^2.3.0" - bunyan "^1.8.10" - docproc "^1.0.0" - levelup "^1.3.8" - pumpify "^1.3.5" - optionalDependencies: - leveldown "^1.7.1" - -search-index-searcher@~0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/search-index-searcher/-/search-index-searcher-0.2.10.tgz#3b52b8bb643065883997dfce57c6c792ec551cb0" - dependencies: - bunyan "^1.8.1" - intersect-arrays-to-stream "^0.0.3" - levelup "^1.3.8" - lodash.difference "^4.5.0" - lodash.intersection "^4.4.0" - lodash.sortedindexof "^4.1.0" - lodash.spread "^4.2.1" - lodash.union "^4.6.0" - lodash.uniq "^4.5.0" - ngraminator "0.0.1" - optionalDependencies: - leveldown "^1.6.0" - select@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" @@ -6347,11 +6792,11 @@ semver-diff@^2.0.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" -semver@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19" +semver@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" -semver@~5.4.1: +semver@5.4.1, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -6407,33 +6852,55 @@ send@0.15.3: range-parser "~1.2.0" statuses "~1.3.1" -send@0.15.4: - version "0.15.4" - resolved "https://registry.yarnpkg.com/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9" +send@0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" dependencies: - debug "2.6.8" + debug "2.6.9" depd "~1.1.1" destroy "~1.0.4" encodeurl "~1.0.1" escape-html "~1.0.3" - etag "~1.8.0" - fresh "0.5.0" + etag "~1.8.1" + fresh "0.5.2" http-errors "~1.6.2" - mime "1.3.4" + mime "1.4.1" ms "2.0.0" on-finished "~2.3.0" range-parser "~1.2.0" statuses "~1.3.1" -serve-favicon@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.4.3.tgz#5986b17b0502642b641c21f818b1acce32025d23" +sequelize@4.13.5: + version "4.13.5" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-4.13.5.tgz#f3a397858c2821da5384e51b4eb98a9ff65ecb16" + dependencies: + bluebird "^3.4.6" + cls-bluebird "^2.0.1" + debug "^3.0.0" + depd "^1.1.0" + dottie "^2.0.0" + generic-pool "^3.1.8" + inflection "1.12.0" + lodash "^4.17.1" + moment "^2.13.0" + moment-timezone "^0.5.4" + retry-as-promised "^2.3.1" + semver "^5.0.1" + terraformer-wkt-parser "^1.1.2" + toposort-class "^1.0.1" + uuid "^3.0.0" + validator "^8.0.0" + wkx "^0.4.1" + +serve-favicon@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.4.5.tgz#49d9a46863153a9240691c893d2b0e7d85d6d436" dependencies: - etag "~1.8.0" - fresh "0.5.0" + etag "~1.8.1" + fresh "0.5.2" ms "2.0.0" - parseurl "~1.3.1" - safe-buffer "5.0.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" serve-static@1.12.3: version "1.12.3" @@ -6444,14 +6911,14 @@ serve-static@1.12.3: parseurl "~1.3.1" send "0.15.3" -serve-static@1.12.4: - version "1.12.4" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961" +serve-static@1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" dependencies: encodeurl "~1.0.1" escape-html "~1.0.3" - parseurl "~1.3.1" - send "0.15.4" + parseurl "~1.3.2" + send "0.16.1" serve-static@~1.10.2: version "1.10.3" @@ -6473,6 +6940,10 @@ setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -6511,15 +6982,15 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -simple-get@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-1.4.3.tgz#e9755eda407e96da40c5e5158c9ea37b33becbeb" - dependencies: - once "^1.3.1" - unzip-response "^1.0.0" - xtend "^4.0.0" +simple-breakpoints@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/simple-breakpoints/-/simple-breakpoints-1.1.2.tgz#2a690bb989228bc1f80acf802785f61f53ed6b92" -simplemde@~1.11.2: +simple-lru-cache@0.0.x: + version "0.0.2" + resolved "https://registry.yarnpkg.com/simple-lru-cache/-/simple-lru-cache-0.0.2.tgz#d59cc3a193c1a5d0320f84ee732f6e4713e511dd" + +simplemde@1.11.2: version "1.11.2" resolved "https://registry.yarnpkg.com/simplemde/-/simplemde-1.11.2.tgz#a23a35d978d2c40ef07dec008c92f070d8e080e3" dependencies: @@ -6535,67 +7006,17 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -sliced@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/sliced/-/sliced-0.0.5.tgz#5edc044ca4eb6f7816d50ba2fc63e25d8fe4707f" - -sliced@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" dependencies: hoek "2.x.x" -socket.io-adapter@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.0.tgz#c7aa46501dd556c2cb8a28af8ff95c0b5e1daa4c" - dependencies: - debug "2.3.3" - -socket.io-client@~2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.3.tgz#6caf4aff9f85b19fd91b6ce13d69adb564f8873b" - dependencies: - backo2 "1.0.2" - base64-arraybuffer "0.1.5" - component-bind "1.0.0" - component-emitter "1.2.1" - debug "~2.6.4" - engine.io-client "~3.1.0" - has-cors "1.1.0" - indexof "0.0.1" - object-component "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" - socket.io-parser "~3.1.1" - to-array "0.1.4" - -socket.io-parser@~3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2" - dependencies: - component-emitter "1.2.1" - debug "~2.6.4" - has-binary2 "~1.0.2" - isarray "2.0.1" - -socket.io@~2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.0.3.tgz#4359f06a24933ae6bd087798af78c680eae345e3" +sntp@2.x.x: + version "2.0.2" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.0.2.tgz#5064110f0af85f7cfdb7d6b67a40028ce52b4b2b" dependencies: - debug "~2.6.6" - engine.io "~3.1.0" - object-assign "~4.1.1" - socket.io-adapter "~1.1.0" - socket.io-client "~2.0.2" - socket.io-parser "~3.1.1" + hoek "4.x.x" source-map-support@^0.4.15, source-map-support@^0.4.2: version "0.4.15" @@ -6603,6 +7024,12 @@ source-map-support@^0.4.15, source-map-support@^0.4.2: dependencies: source-map "^0.5.6" +source-map-support@^0.4.18: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + source-map@0.4.x, source-map@^0.4.2, source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" @@ -6613,6 +7040,10 @@ source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, sour version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" @@ -6633,12 +7064,22 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" +spex@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/spex/-/spex-2.0.0.tgz#63e1b8655159a32028eb6a237ffb0589e85f3c32" + split@0.3: version "0.3.3" resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" dependencies: through "2" +split@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.0.tgz#c4395ce683abcd254bc28fe1dabb6e5c27dcffae" + dependencies: + through "2" + sprintf-js@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" @@ -6679,20 +7120,12 @@ stdout-stream@^1.4.0: dependencies: readable-stream "^2.0.1" -stopword@~0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/stopword/-/stopword-0.1.6.tgz#435cc3e9d4311aedca2876ed4cae79153cd3d0fb" - stream-combiner@~0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" dependencies: duplexer "~0.1.1" -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - stream-to-array@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" @@ -6705,7 +7138,7 @@ stream-to-buffer@^0.1.0: dependencies: stream-to "~0.2.0" -stream-to-promise@~2.2.0: +stream-to-promise@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-2.2.0.tgz#b1edb2e1c8cb11289d1b503c08d3f2aef51e650f" dependencies: @@ -6721,11 +7154,12 @@ streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" -string-length@^1.0.0, string-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" dependencies: - strip-ansi "^3.0.0" + astral-regex "^1.0.0" + strip-ansi "^4.0.0" string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" @@ -6750,13 +7184,13 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" -string_decoder@~1.0.0, string_decoder@~1.0.3: +string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4: +stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -6812,19 +7246,29 @@ supports-color@^4.0.0, supports-color@^4.2.0: dependencies: has-flag "^2.0.0" +supports-color@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + +symbol-observable@^1.0.2, symbol-observable@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + symbol-tree@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" -table-layout@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.2.tgz#10e9043c142a1e2d155da7257e478f0ef4981786" +table-layout@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.0.tgz#c70ff0455d9add63b91f7c15a77926295c0e0e7d" dependencies: - array-back "^2.0.0" - deep-extend "~0.5.0" + array-back "^1.0.4" + deep-extend "~0.4.1" lodash.padend "^4.6.1" - typical "^2.6.1" - wordwrapjs "^3.0.0" + typical "^2.6.0" + wordwrapjs "^2.0.0" table@^4.0.1: version "4.0.1" @@ -6837,15 +7281,6 @@ table@^4.0.1: slice-ansi "0.0.4" string-width "^2.0.0" -tar-fs@^1.13.0: - version "1.15.3" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.15.3.tgz#eccf935e941493d8151028e636e51ce4c3ca7f20" - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - tar-pack@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" @@ -6859,14 +7294,15 @@ tar-pack@^3.4.0: tar "^2.2.1" uid-number "^0.0.6" -tar-stream@^1.1.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016" +tar@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.0.1.tgz#3f5b2e5289db30c2abe4c960f43d0d9fff96aaf0" dependencies: - bl "^1.0.0" - end-of-stream "^1.0.0" - readable-stream "^2.0.0" - xtend "^4.0.0" + chownr "^1.0.1" + minipass "^2.0.2" + minizlib "^1.0.3" + mkdirp "^0.5.0" + yallist "^3.0.2" tar@^2.0.0, tar@^2.2.1: version "2.2.1" @@ -6876,25 +7312,23 @@ tar@^2.0.0, tar@^2.2.1: fstream "^1.0.2" inherits "2" -tar@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.0.1.tgz#3f5b2e5289db30c2abe4c960f43d0d9fff96aaf0" +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" dependencies: - chownr "^1.0.1" - minipass "^2.0.2" - minizlib "^1.0.3" - mkdirp "^0.5.0" - yallist "^3.0.2" + execa "^0.7.0" -term-frequency@^0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/term-frequency/-/term-frequency-0.0.15.tgz#ff4aeaff2ac31ee1096b5c685852816a5da676e7" +terraformer-wkt-parser@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/terraformer-wkt-parser/-/terraformer-wkt-parser-1.1.2.tgz#336a0c8fc82094a5aff83288f69aedecd369bf0c" + dependencies: + terraformer "~1.0.5" -term-vector@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/term-vector/-/term-vector-0.1.2.tgz#774e7e44aef2274b3b1d8a2441981f99d0f7e0aa" +terraformer@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/terraformer/-/terraformer-1.0.8.tgz#51e0ad89746fcf2161dc6f65aa70e42377c8b593" dependencies: - lodash.isequal "^4.1.3" + "@types/geojson" "^1.0.0" test-exclude@^4.1.1: version "4.1.1" @@ -6921,25 +7355,21 @@ thirty-two@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-0.0.2.tgz#4253e29d8cb058f0480267c5698c0e4927e54b6a" -throat@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-3.2.0.tgz#50cb0670edbc40237b9e347d7e1f88e4620af836" +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -through2@~2.0.3: +through2@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" dependencies: readable-stream "^2.1.5" xtend "~4.0.1" -through@2, "through@>=2.2.7 <3", through@^2.3.6, through@~2.3, through@~2.3.1: +through@2, through@^2.3.6, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" -timed-out@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" - timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -6962,10 +7392,6 @@ tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" -to-array@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" - to-fast-properties@^1.0.1, to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -6974,15 +7400,13 @@ token-stream@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" -topo@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" - dependencies: - hoek "2.x.x" +toposort-class@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" -touch@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de" +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" dependencies: nopt "~1.0.10" @@ -6992,6 +7416,12 @@ tough-cookie@^2.3.2, tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + dependencies: + punycode "^1.4.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -7026,7 +7456,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" -twemoji-awesome@~1.0.6: +twemoji-awesome@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/twemoji-awesome/-/twemoji-awesome-1.0.6.tgz#3167c3abb95753da997291f8f1c53cbac61852a5" @@ -7053,9 +7483,9 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@~2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.2.tgz#038a95f7d9bbb420b1bf35ba31d4c5c1dd3ffe34" +typescript@2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d" typical@^2.6.0, typical@^2.6.1: version "2.6.1" @@ -7069,22 +7499,13 @@ uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" -uglify-es@~3.0.28: - version "3.0.28" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.0.28.tgz#1cdedbbcdb7865223065281ad7b2347629851d4b" +uglify-es@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.3.tgz#a21eeb149cb120a1f8302563689e19496550780b" dependencies: commander "~2.11.0" source-map "~0.5.1" -uglify-js@2.7.5: - version "2.7.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" - dependencies: - async "~0.2.6" - source-map "~0.5.1" - uglify-to-browserify "~1.0.0" - yargs "~3.10.0" - uglify-js@^2.6, uglify-js@^2.6.1: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -7102,9 +7523,9 @@ uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -uid-safe@~2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.4.tgz#3ad6f38368c6d4c8c75ec17623fb79aa1d071d81" +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" dependencies: random-bytes "~1.0.0" @@ -7116,21 +7537,27 @@ ultron@1.0.x: version "1.0.2" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" -ultron@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864" - undefsafe@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-0.0.3.tgz#ecca3a03e56b9af17385baac812ac83b994a962f" +underscore@^1.7.0, underscore@~1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + underscore@~1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.5.2.tgz#1335c5e4f5e6d33bbb4b006ba8c86a00f556de08" -underscore@~1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" universalify@^0.1.0: version "0.1.1" @@ -7140,21 +7567,22 @@ unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" -unzip-response@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" -update-notifier@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.5.0.tgz#07b5dc2066b3627ab3b4f530130f7eddda07a4cc" +update-notifier@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.2.0.tgz#1b5837cf90c0736d88627732b661c138f86de72f" dependencies: + boxen "^1.0.0" chalk "^1.0.0" - configstore "^1.0.0" + configstore "^3.0.0" + import-lazy "^2.1.0" is-npm "^1.0.0" - latest-version "^1.0.0" - repeating "^1.1.2" + latest-version "^3.0.0" semver-diff "^2.0.0" - string-length "^1.0.0" + xdg-basedir "^3.0.0" url-parse-lax@^1.0.0: version "1.0.0" @@ -7201,18 +7629,18 @@ utils-merge@1.0.0, utils-merge@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@^2.0.1, uuid@^2.0.2: +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" -uuid@^3.0.0, uuid@^3.0.1: +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -uws@~0.14.4: - version "0.14.5" - resolved "https://registry.yarnpkg.com/uws/-/uws-0.14.5.tgz#67aaf33c46b2a587a5f6666d00f7691328f149dc" - v8flags@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" @@ -7226,7 +7654,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -validator-as-promised@~1.0.2: +validator-as-promised@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/validator-as-promised/-/validator-as-promised-1.0.2.tgz#2ea062b2fa703b7dfd71cb34a2f12fe0894f41ce" dependencies: @@ -7234,11 +7662,15 @@ validator-as-promised@~1.0.2: lodash "^4.14.0" validator "^5.5.0" +validator@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-9.0.0.tgz#6c1ef955e007af704adea86ae8a76da84a6c172e" + validator@^5.5.0: version "5.7.0" resolved "https://registry.yarnpkg.com/validator/-/validator-5.7.0.tgz#7a87a58146b695ac486071141c0c49d67da05e5c" -validator@~8.1.0: +validator@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/validator/-/validator-8.1.0.tgz#89cf6b512ff71eba886afd8d10d47f8dc800eac0" @@ -7250,15 +7682,19 @@ vary@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + vasync@^1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/vasync/-/vasync-1.6.4.tgz#dfe93616ad0e7ae801b332a9d88bfc5cdc8e1d1f" dependencies: verror "1.6.0" -vee-validate@~2.0.0-rc.14: - version "2.0.0-rc.14" - resolved "https://registry.yarnpkg.com/vee-validate/-/vee-validate-2.0.0-rc.14.tgz#ecbd3ddff33fa6a42ebb4a468c343e1eb5d2b38f" +vee-validate@2.0.0-rc.18: + version "2.0.0-rc.18" + resolved "https://registry.yarnpkg.com/vee-validate/-/vee-validate-2.0.0-rc.18.tgz#30857abeb2ba87e52d3e66c09b35a78e66419527" verror@1.3.6: version "1.3.6" @@ -7290,40 +7726,61 @@ void-elements@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" -vue-clipboards@~1.1.0: +vue-clipboards@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/vue-clipboards/-/vue-clipboards-1.1.0.tgz#708d95b64e64f83e565f7fc464e7213fb6ef2d8a" dependencies: clipboard "^1.7.1" -vue-lodash@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/vue-lodash/-/vue-lodash-1.0.3.tgz#777ef3e190a4cdde0d211a614e52a0b38659c13f" +vue-hot-reload-api@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.1.1.tgz#1ba6712166182fd651753804b9d8d8d02d855579" -vue-resource@~1.3.4: +vue-lodash@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vue-lodash/-/vue-lodash-1.0.4.tgz#99f4f2f5832ce0168c4d45618789288a638562cd" + +vue-material@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/vue-material/-/vue-material-0.7.5.tgz#045517403c1338aceabd73030f3dd6b5c744fe55" + +vue-resource@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.4.tgz#9fc0bdf6a2f5cab430129fc99d347b3deae7b099" dependencies: got "^7.0.0" -vue-template-compiler@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.4.2.tgz#5a45d843f148b098f6c1d1e35ac20c4956d30ad1" +vue-simple-breakpoints@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/vue-simple-breakpoints/-/vue-simple-breakpoints-1.0.2.tgz#87aae092f853c7f26e6b99950385f108ccf399c9" + dependencies: + simple-breakpoints "^1.1.1" + +vue-template-compiler@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.4.4.tgz#2cde3b704124985c27d50b5387c9691ba515fb57" dependencies: de-indent "^1.0.2" he "^1.1.0" -vue-template-es2015-compiler@~1.5.3: +vue-template-es2015-compiler@1.5.3: version "1.5.3" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.5.3.tgz#22787de4e37ebd9339b74223bc467d1adee30545" -vue@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.4.2.tgz#a9855261f191c978cc0dc1150531b8d08149b58c" +vue@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.4.4.tgz#ea9550b96a71465fd2b8b17b61673b3561861789" -vuex@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/vuex/-/vuex-2.4.0.tgz#e1d0430646282b40007fdd06ec6ae88a9f5a1e14" +vuex-persistedstate@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vuex-persistedstate/-/vuex-persistedstate-2.0.0.tgz#b84f530da4679bdf694c5ddf65c23033aa79b1bb" + dependencies: + lodash.merge "^4.6.0" + object-path "^0.11.2" + +vuex@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/vuex/-/vuex-2.4.1.tgz#7890b650ba8565b70937b4e7670577082dfe8bc1" vxx@^1.2.0: version "1.2.2" @@ -7376,7 +7833,7 @@ whatwg-encoding@^1.0.1: dependencies: iconv-lite "0.4.13" -whatwg-fetch@^2.0.3: +whatwg-fetch@^2.0.0, whatwg-fetch@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" @@ -7407,13 +7864,19 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -winston@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.3.1.tgz#0b48420d978c01804cf0230b648861598225a119" +winston@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee" dependencies: async "~1.0.0" colors "1.0.x" @@ -7429,6 +7892,12 @@ with@^5.0.0: acorn "^3.1.0" acorn-globals "^3.0.0" +wkx@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.1.tgz#2fc171b5e9cb55c6256fef4bde1f21be413befee" + dependencies: + "@types/node" "^6.0.48" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -7441,12 +7910,14 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -wordwrapjs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-3.0.0.tgz#c94c372894cadc6feb1a66bff64e1d9af92c5d1e" +wordwrapjs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-2.0.0.tgz#ab55f695e6118da93858fdd70c053d1c5e01ac20" dependencies: + array-back "^1.0.3" + feature-detect-es6 "^1.3.1" reduce-flatten "^1.0.1" - typical "^2.6.1" + typical "^2.6.0" worker-farm@^1.3.1: version "1.4.1" @@ -7466,13 +7937,13 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^1.1.2: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" - slide "^1.1.5" + signal-exit "^3.0.2" write@^0.2.1: version "0.2.1" @@ -7487,18 +7958,9 @@ ws@^1.1.1: options ">=0.0.5" ultron "1.0.x" -ws@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80" - dependencies: - safe-buffer "~5.0.1" - ultron "~1.1.0" - -xdg-basedir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" - dependencies: - os-homedir "^1.0.0" +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" xhr@^2.0.1: version "2.4.0" @@ -7524,21 +7986,13 @@ xml2js@^0.4.5: sax ">=0.6.0" xmlbuilder "^4.1.0" -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - xmlbuilder@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" dependencies: lodash "^4.0.0" -xmlhttprequest-ssl@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" - -xtend@4.0.1, xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -7573,7 +8027,25 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" -yargs@^7.0.0, yargs@^7.0.2: +yargs@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +yargs@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" dependencies: @@ -7591,18 +8063,9 @@ yargs@^7.0.0, yargs@^7.0.2: y18n "^3.2.1" yargs-parser "^5.0.0" -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yargs@~8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" +yargs@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.0.tgz#efe5b1ad3f94bdc20423411b90628eeec0b25f3c" dependencies: camelcase "^4.1.0" cliui "^3.2.0" @@ -7618,9 +8081,22 @@ yargs@~8.0.1: y18n "^3.2.1" yargs-parser "^7.0.0" -yeast@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + +zen-observable-ts@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.4.4.tgz#c244c71eaebef79a985ccf9895bc90307a6e9712" + +zen-observable-ts@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.5.0.tgz#c5021e7ac486fc281f6126d574673cfb6daf0069" zone.js@0.7.6: version "0.7.6"