feat: admin ssl - renew cert + toggle redirection btn
This commit is contained in:
parent
59a8e9929c
commit
ae53484abd
@ -8,163 +8,259 @@
|
|||||||
.headline.primary--text.animated.fadeInLeft {{ $t('admin:ssl.title') }}
|
.headline.primary--text.animated.fadeInLeft {{ $t('admin:ssl.title') }}
|
||||||
.subtitle-1.grey--text.animated.fadeInLeft {{ $t('admin:ssl.subtitle') }}
|
.subtitle-1.grey--text.animated.fadeInLeft {{ $t('admin:ssl.subtitle') }}
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn.animated.fadeInDown(color='success', depressed, @click='save', large)
|
v-btn.animated.fadeInDown(
|
||||||
v-icon(left) mdi-check
|
v-if='info.sslProvider === `letsencrypt`'
|
||||||
span {{$t('common:actions.apply')}}
|
color='black'
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
@click='renewCertificate'
|
||||||
|
large
|
||||||
|
:loading='loadingRenew'
|
||||||
|
)
|
||||||
|
v-icon(left) mdi-cached
|
||||||
|
span {{$t('admin:ssl.renewCertificate')}}
|
||||||
v-form.pt-3
|
v-form.pt-3
|
||||||
v-layout(row wrap)
|
v-layout(row wrap)
|
||||||
v-flex(lg6 xs12)
|
v-flex(lg6 xs12)
|
||||||
v-form
|
v-card.animated.fadeInUp
|
||||||
v-card.animated.fadeInUp
|
v-subheader {{ $t('admin:ssl.currentState') }}
|
||||||
v-toolbar(color='primary', dark, dense, flat)
|
v-list(two-line, dense)
|
||||||
v-toolbar-title.subtitle-1 {{ $t('admin:ssl.provider') }}
|
v-list-item
|
||||||
v-card-text
|
v-list-item-avatar
|
||||||
v-select(
|
v-icon.indigo.white--text mdi-handshake
|
||||||
:items='providers'
|
v-list-item-content
|
||||||
outlined
|
v-list-item-title {{ $t(`admin:ssl.provider`) }}
|
||||||
:label='$t(`admin:ssl.provider`)'
|
v-list-item-subtitle {{ providerTitle }}
|
||||||
required
|
template(v-if='info.sslProvider === `letsencrypt`')
|
||||||
:counter='255'
|
v-list-item
|
||||||
v-model='config.provider'
|
v-list-item-avatar
|
||||||
prepend-icon='mdi-handshake'
|
v-icon.indigo.white--text mdi-application
|
||||||
:hint='$t(`admin:ssl.providerHint`)'
|
v-list-item-content
|
||||||
persistent-hint
|
v-list-item-title {{ $t(`admin:ssl.domain`) }}
|
||||||
)
|
v-list-item-subtitle {{ info.sslDomain }}
|
||||||
v-text-field.mt-3(
|
v-list-item
|
||||||
outlined
|
v-list-item-avatar
|
||||||
:label='$t(`admin:ssl.domain`)'
|
v-icon.indigo.white--text mdi-at
|
||||||
required
|
v-list-item-content
|
||||||
:counter='255'
|
v-list-item-title {{ $t('admin:ssl.subscriberEmail') }}
|
||||||
v-model='config.domain'
|
v-list-item-subtitle {{ info.sslSubscriberEmail }}
|
||||||
prepend-icon='mdi-earth'
|
v-list-item
|
||||||
:hint='$t(`admin:ssl.domainHint`)'
|
v-list-item-avatar
|
||||||
persistent-hint
|
v-icon.indigo.white--text mdi-calendar-remove-outline
|
||||||
:disabled='config.provider === ``'
|
v-list-item-content
|
||||||
)
|
v-list-item-title {{ $t('admin:ssl.expiration') }}
|
||||||
|
v-list-item-subtitle {{ info.sslExpirationDate | moment('calendar') }}
|
||||||
v-card.animated.fadeInUp.wait-p2s.mt-3(v-if='config.provider !== ``')
|
v-list-item
|
||||||
v-toolbar(color='primary', dark, dense, flat)
|
v-list-item-avatar
|
||||||
v-toolbar-title.subtitle-1 {{$t('admin:ssl.providerOptions')}}
|
v-icon.indigo.white--text mdi-traffic-light
|
||||||
v-card-text ---
|
v-list-item-content
|
||||||
|
v-list-item-title {{ $t(`admin:ssl.status`) }}
|
||||||
|
v-list-item-subtitle {{ info.sslStatus }}
|
||||||
|
|
||||||
v-flex(lg6 xs12)
|
v-flex(lg6 xs12)
|
||||||
v-card.animated.fadeInUp.wait-p2s
|
v-card.animated.fadeInUp.wait-p2s
|
||||||
v-toolbar(color='primary', dark, dense, flat)
|
v-subheader {{ $t('admin:ssl.ports') }}
|
||||||
v-toolbar-title.subtitle-1 {{ $t('admin:ssl.ports') }}
|
v-list(two-line, dense)
|
||||||
v-card-text
|
v-list-item
|
||||||
v-row
|
v-list-item-avatar
|
||||||
v-col(cols='6')
|
v-icon.blue.white--text mdi-lock-open-variant
|
||||||
v-text-field(
|
v-list-item-content
|
||||||
outlined
|
v-list-item-title {{ $t(`admin:ssl.httpPort`) }}
|
||||||
:label='$t(`admin:ssl.httpPort`)'
|
v-list-item-subtitle {{ info.httpPort }}
|
||||||
v-model='config.httpPort'
|
template(v-if='info.httpsPort > 0')
|
||||||
prepend-icon='mdi-lock-open-variant-outline'
|
v-divider
|
||||||
:hint='$t(`admin:ssl.httpPortHint`)'
|
v-list-item
|
||||||
persistent-hint
|
v-list-item-avatar
|
||||||
|
v-icon.green.white--text mdi-lock
|
||||||
|
v-list-item-content
|
||||||
|
v-list-item-title {{ $t(`admin:ssl.httpsPort`) }}
|
||||||
|
v-list-item-subtitle {{ info.httpsPort }}
|
||||||
|
v-divider
|
||||||
|
v-list-item
|
||||||
|
v-list-item-avatar
|
||||||
|
v-icon.indigo.white--text mdi-sign-direction
|
||||||
|
v-list-item-content
|
||||||
|
v-list-item-title {{ $t(`admin:ssl.httpPortRedirect`) }}
|
||||||
|
v-list-item-subtitle {{ info.httpRedirection }}
|
||||||
|
v-list-item-action
|
||||||
|
v-btn.red--text(
|
||||||
|
v-if='info.httpRedirection'
|
||||||
|
depressed
|
||||||
|
:color='$vuetify.theme.dark ? `red darken-4` : `red lighten-5`'
|
||||||
|
:class='$vuetify.theme.dark ? `text--lighten-5` : `text--darken-2`'
|
||||||
|
@click='toggleRedir'
|
||||||
|
:loading='loadingRedir'
|
||||||
)
|
)
|
||||||
v-col(cols='6')
|
v-icon(left) mdi-power
|
||||||
v-checkbox(
|
span {{$t('admin:ssl.httpPortRedirectTurnOff')}}
|
||||||
:label='$t(`admin:ssl.httpPortRedirect`)'
|
v-btn.green--text(
|
||||||
v-model='config.httpRedirect'
|
v-else
|
||||||
:hint='$t(`admin:ssl.httpPortRedirectHint`)'
|
depressed
|
||||||
:disabled='config.provider === ``'
|
:color='$vuetify.theme.dark ? `green darken-4` : `green lighten-5`'
|
||||||
persistent-hint
|
:class='$vuetify.theme.dark ? `text--lighten-5` : `text--darken-2`'
|
||||||
color='primary'
|
@click='toggleRedir'
|
||||||
|
:loading='loadingRedir'
|
||||||
)
|
)
|
||||||
v-col(cols='6')
|
v-icon(left) mdi-power
|
||||||
v-text-field(
|
span {{$t('admin:ssl.httpPortRedirectTurnOn')}}
|
||||||
outlined
|
|
||||||
:label='$t(`admin:ssl.httpsPort`)'
|
v-dialog(
|
||||||
v-model='config.httpsPort'
|
v-model='loadingRenew'
|
||||||
prepend-icon='mdi-lock'
|
persistent
|
||||||
:hint='$t(`admin:ssl.httpsPortHint`)'
|
max-width='450'
|
||||||
persistent-hint
|
)
|
||||||
:disabled='config.provider === ``'
|
v-card(color='black', dark)
|
||||||
)
|
v-card-text.pa-10.text-center
|
||||||
v-card-text.grey(:class='$vuetify.theme.dark ? `darken-4-l5` : `lighten-4`')
|
semipolar-spinner.animated.fadeIn(
|
||||||
.caption {{$t(`admin:ssl.writableConfigFileWarning`)}}
|
:animation-duration='1500'
|
||||||
|
:size='65'
|
||||||
|
color='#FFF'
|
||||||
|
style='margin: 0 auto;'
|
||||||
|
)
|
||||||
|
.mt-5.body-1.white--text {{$t('admin:ssl.renewCertificateLoadingTitle')}}
|
||||||
|
.caption.mt-4 {{$t('admin:ssl.renewCertificateLoadingSubtitle')}}
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import siteConfigQuery from 'gql/admin/site/site-query-config.gql'
|
import gql from 'graphql-tag'
|
||||||
import siteUpdateConfigMutation from 'gql/admin/site/site-mutation-save-config.gql'
|
|
||||||
|
import { SemipolarSpinner } from 'epic-spinners'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
SemipolarSpinner
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: {
|
loadingRenew: false,
|
||||||
provider: '',
|
loadingRedir: false,
|
||||||
domain: '',
|
info: {
|
||||||
httpPort: 3000,
|
sslDomain: '',
|
||||||
httpPortRedirect: true,
|
sslProvider: '',
|
||||||
httpsPort: 443
|
sslSubscriberEmail: '',
|
||||||
|
sslExpirationDate: false,
|
||||||
|
sslStatus: '',
|
||||||
|
httpPort: 0,
|
||||||
|
httpRedirection: false,
|
||||||
|
httpsPort: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
providers () {
|
providerTitle () {
|
||||||
return [
|
switch (this.info.sslProvider) {
|
||||||
{ text: this.$t('admin:ssl.providerDisabled'), value: '' },
|
case 'custom':
|
||||||
{ text: this.$t('admin:ssl.providerLetsEncrypt'), value: 'letsencrypt' },
|
return this.$t('admin:ssl.providerCustomCertificate')
|
||||||
{ text: this.$t('admin:ssl.providerCustomCertificate'), value: 'custom' }
|
case 'letsencrypt':
|
||||||
]
|
return this.$t('admin:ssl.providerLetsEncrypt')
|
||||||
|
default:
|
||||||
|
return this.$t('admin:ssl.providerDisabled')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async save () {
|
async toggleRedir () {
|
||||||
|
this.loadingRedir = true
|
||||||
try {
|
try {
|
||||||
|
this.info.httpRedirection = !this.info.httpRedirection
|
||||||
await this.$apollo.mutate({
|
await this.$apollo.mutate({
|
||||||
mutation: siteUpdateConfigMutation,
|
mutation: gql`
|
||||||
|
mutation ($enabled: Boolean!) {
|
||||||
|
system {
|
||||||
|
setHTTPSRedirection(enabled: $enabled) {
|
||||||
|
responseResult {
|
||||||
|
succeeded
|
||||||
|
errorCode
|
||||||
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
host: _.get(this.config, 'host', ''),
|
enabled: _.get(this.info, 'httpRedirection', false)
|
||||||
title: _.get(this.config, 'title', ''),
|
|
||||||
description: _.get(this.config, 'description', ''),
|
|
||||||
robots: _.get(this.config, 'robots', []),
|
|
||||||
analyticsService: _.get(this.config, 'analyticsService', ''),
|
|
||||||
analyticsId: _.get(this.config, 'analyticsId', ''),
|
|
||||||
company: _.get(this.config, 'company', ''),
|
|
||||||
hasLogo: _.get(this.config, 'hasLogo', false),
|
|
||||||
logoIsSquare: _.get(this.config, 'logoIsSquare', false),
|
|
||||||
featurePageRatings: _.get(this.config, 'featurePageRatings', false),
|
|
||||||
featurePageComments: _.get(this.config, 'featurePageComments', false),
|
|
||||||
featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false),
|
|
||||||
securityIframe: _.get(this.config, 'securityIframe', false),
|
|
||||||
securityReferrerPolicy: _.get(this.config, 'securityReferrerPolicy', false),
|
|
||||||
securityTrustProxy: _.get(this.config, 'securityTrustProxy', false),
|
|
||||||
securitySRI: _.get(this.config, 'securitySRI', false),
|
|
||||||
securityHSTS: _.get(this.config, 'securityHSTS', false),
|
|
||||||
securityHSTSDuration: _.get(this.config, 'securityHSTSDuration', 0),
|
|
||||||
securityCSP: _.get(this.config, 'securityCSP', false),
|
|
||||||
securityCSPDirectives: _.get(this.config, 'securityCSPDirectives', '')
|
|
||||||
},
|
},
|
||||||
watchLoading (isLoading) {
|
watchLoading (isLoading) {
|
||||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update')
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-toggleRedirection')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
style: 'success',
|
style: 'success',
|
||||||
message: 'Configuration saved successfully.',
|
message: this.$t('admin:ssl.httpPortRedirectSaveSuccess'),
|
||||||
icon: 'check'
|
icon: 'check'
|
||||||
})
|
})
|
||||||
this.siteTitle = this.config.title
|
} catch (err) {
|
||||||
this.company = this.config.company
|
this.info.httpRedirection = !this.info.httpRedirection
|
||||||
|
this.$store.commit('pushGraphError', err)
|
||||||
|
}
|
||||||
|
this.loadingRedir = false
|
||||||
|
},
|
||||||
|
async renewCertificate () {
|
||||||
|
this.loadingRenew = true
|
||||||
|
try {
|
||||||
|
const respRaw = await this.$apollo.mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
system {
|
||||||
|
renewHTTPSCertificate {
|
||||||
|
responseResult {
|
||||||
|
succeeded
|
||||||
|
errorCode
|
||||||
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
watchLoading (isLoading) {
|
||||||
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-renew')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const resp = _.get(respRaw, 'data.system.renewHTTPSCertificate.responseResult', {})
|
||||||
|
if (resp.succeeded) {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'success',
|
||||||
|
message: this.$t('admin:ssl.renewCertificateSuccess'),
|
||||||
|
icon: 'check'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw new Error(resp.message)
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.$store.commit('pushGraphError', err)
|
this.$store.commit('pushGraphError', err)
|
||||||
}
|
}
|
||||||
|
this.loadingRenew = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
apollo: {
|
||||||
|
info: {
|
||||||
|
query: gql`
|
||||||
|
{
|
||||||
|
system {
|
||||||
|
info {
|
||||||
|
httpPort
|
||||||
|
httpRedirection
|
||||||
|
httpsPort
|
||||||
|
sslDomain
|
||||||
|
sslExpirationDate
|
||||||
|
sslProvider
|
||||||
|
sslStatus
|
||||||
|
sslSubscriberEmail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
fetchPolicy: 'network-only',
|
||||||
|
update: (data) => _.cloneDeep(data.system.info),
|
||||||
|
watchLoading (isLoading) {
|
||||||
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-refresh')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// apollo: {
|
|
||||||
// config: {
|
|
||||||
// query: siteConfigQuery,
|
|
||||||
// fetchPolicy: 'network-only',
|
|
||||||
// update: (data) => _.cloneDeep(data.site.config),
|
|
||||||
// watchLoading (isLoading) {
|
|
||||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-refresh')
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-brute": "1.0.1",
|
"express-brute": "1.0.1",
|
||||||
"express-session": "1.17.0",
|
"express-session": "1.17.0",
|
||||||
"file-type": "13.1.0",
|
"file-type": "13.1.1",
|
||||||
"filesize": "6.0.1",
|
"filesize": "6.0.1",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"getos": "3.1.1",
|
"getos": "3.1.1",
|
||||||
@ -121,7 +121,7 @@
|
|||||||
"node-2fa": "1.1.2",
|
"node-2fa": "1.1.2",
|
||||||
"node-cache": "5.1.0",
|
"node-cache": "5.1.0",
|
||||||
"nodemailer": "6.4.2",
|
"nodemailer": "6.4.2",
|
||||||
"objection": "1.6.11",
|
"objection": "2.1.2",
|
||||||
"passport": "0.4.1",
|
"passport": "0.4.1",
|
||||||
"passport-auth0": "1.3.1",
|
"passport-auth0": "1.3.1",
|
||||||
"passport-azure-ad": "4.2.1",
|
"passport-azure-ad": "4.2.1",
|
||||||
@ -158,7 +158,7 @@
|
|||||||
"scim-query-filter-parser": "2.0.4",
|
"scim-query-filter-parser": "2.0.4",
|
||||||
"semver": "7.1.1",
|
"semver": "7.1.1",
|
||||||
"serve-favicon": "2.5.0",
|
"serve-favicon": "2.5.0",
|
||||||
"simple-git": "1.129.0",
|
"simple-git": "1.130.0",
|
||||||
"solr-node": "1.2.1",
|
"solr-node": "1.2.1",
|
||||||
"sqlite3": "4.1.1",
|
"sqlite3": "4.1.1",
|
||||||
"ssh2": "0.8.7",
|
"ssh2": "0.8.7",
|
||||||
@ -188,7 +188,7 @@
|
|||||||
"@babel/plugin-syntax-import-meta": "^7.8.3",
|
"@babel/plugin-syntax-import-meta": "^7.8.3",
|
||||||
"@babel/polyfill": "^7.8.3",
|
"@babel/polyfill": "^7.8.3",
|
||||||
"@babel/preset-env": "^7.8.3",
|
"@babel/preset-env": "^7.8.3",
|
||||||
"@mdi/font": "4.7.95",
|
"@mdi/font": "4.8.95",
|
||||||
"@panter/vue-i18next": "0.15.1",
|
"@panter/vue-i18next": "0.15.1",
|
||||||
"@requarks/ckeditor5": "12.4.0-wiki.14",
|
"@requarks/ckeditor5": "12.4.0-wiki.14",
|
||||||
"@vue/babel-preset-app": "4.1.2",
|
"@vue/babel-preset-app": "4.1.2",
|
||||||
|
@ -54,6 +54,8 @@ defaults:
|
|||||||
securityHSTSDuration: 300
|
securityHSTSDuration: 300
|
||||||
securityCSP: false
|
securityCSP: false
|
||||||
securityCSPDirectives: ''
|
securityCSPDirectives: ''
|
||||||
|
server:
|
||||||
|
sslRedir: false
|
||||||
flags:
|
flags:
|
||||||
ldapdebug: false
|
ldapdebug: false
|
||||||
sqllog: false
|
sqllog: false
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const qs = require('querystring')
|
||||||
|
|
||||||
/* global WIKI */
|
/* global WIKI */
|
||||||
|
|
||||||
@ -22,4 +23,16 @@ router.get('/.well-known/acme-challenge/:token', (req, res, next) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to HTTPS if HTTP Redirection is enabled
|
||||||
|
*/
|
||||||
|
router.all('/*', (req, res, next) => {
|
||||||
|
if (WIKI.config.server.sslRedir && !req.secure && WIKI.servers.servers.https) {
|
||||||
|
let query = (!_.isEmpty(req.query)) ? `?${qs.stringify(req.query)}` : ``
|
||||||
|
return res.redirect(`https://${req.hostname}${req.originalUrl}${query}`)
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
@ -46,7 +46,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.servers.http.on('connection', conn => {
|
this.servers.http.on('connection', conn => {
|
||||||
let connKey = `${conn.remoteAddress}:${conn.remotePort}`
|
let connKey = `http:${conn.remoteAddress}:${conn.remotePort}`
|
||||||
this.connections.set(connKey, conn)
|
this.connections.set(connKey, conn)
|
||||||
conn.on('close', () => {
|
conn.on('close', () => {
|
||||||
this.connections.delete(connKey)
|
this.connections.delete(connKey)
|
||||||
@ -108,7 +108,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.servers.https.on('connection', conn => {
|
this.servers.https.on('connection', conn => {
|
||||||
let connKey = `${conn.remoteAddress}:${conn.remotePort}`
|
let connKey = `https:${conn.remoteAddress}:${conn.remotePort}`
|
||||||
this.connections.set(connKey, conn)
|
this.connections.set(connKey, conn)
|
||||||
conn.on('close', () => {
|
conn.on('close', () => {
|
||||||
this.connections.delete(connKey)
|
this.connections.delete(connKey)
|
||||||
@ -135,11 +135,17 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* Close all active connections
|
* Close all active connections
|
||||||
*/
|
*/
|
||||||
closeConnections () {
|
closeConnections (mode = 'all') {
|
||||||
for (const conn of this.connections.values()) {
|
for (const [key, conn] of this.connections) {
|
||||||
|
if (mode !== `all` && key.indexOf(`${mode}:`) !== 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
conn.destroy()
|
conn.destroy()
|
||||||
|
this.connections.delete(key)
|
||||||
|
}
|
||||||
|
if (mode === 'all') {
|
||||||
|
this.connections.clear()
|
||||||
}
|
}
|
||||||
this.connections.clear()
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Stop all servers
|
* Stop all servers
|
||||||
@ -155,5 +161,29 @@ module.exports = {
|
|||||||
this.servers.https = null
|
this.servers.https = null
|
||||||
}
|
}
|
||||||
this.servers.graph = null
|
this.servers.graph = null
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Restart Server
|
||||||
|
*/
|
||||||
|
async restartServer (srv = 'https') {
|
||||||
|
this.closeConnections(srv)
|
||||||
|
switch (srv) {
|
||||||
|
case 'http':
|
||||||
|
if (this.servers.http) {
|
||||||
|
await Promise.fromCallback(cb => { this.servers.http.close(cb) })
|
||||||
|
this.servers.http = null
|
||||||
|
}
|
||||||
|
this.startHTTP()
|
||||||
|
break
|
||||||
|
case 'https':
|
||||||
|
if (this.servers.https) {
|
||||||
|
await Promise.fromCallback(cb => { this.servers.https.close(cb) })
|
||||||
|
this.servers.https = null
|
||||||
|
}
|
||||||
|
this.startHTTPS()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new Error('Cannot restart server: Invalid designation')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,38 @@ module.exports = {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
return graphHelper.generateError(err)
|
return graphHelper.generateError(err)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Set HTTPS Redirection State
|
||||||
|
*/
|
||||||
|
async setHTTPSRedirection (obj, args, context) {
|
||||||
|
_.set(WIKI.config, 'server.sslRedir', args.enabled)
|
||||||
|
await WIKI.configSvc.saveToDb(['server'])
|
||||||
|
return {
|
||||||
|
responseResult: graphHelper.generateSuccess('HTTP Redirection state set successfully.')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Renew SSL Certificate
|
||||||
|
*/
|
||||||
|
async renewHTTPSCertificate (obj, args, context) {
|
||||||
|
try {
|
||||||
|
if (!WIKI.config.ssl.enabled) {
|
||||||
|
throw new WIKI.Error.SystemSSLDisabled()
|
||||||
|
} else if (WIKI.config.ssl.provider !== `letsencrypt`) {
|
||||||
|
throw new WIKI.Error.SystemSSLRenewInvalidProvider()
|
||||||
|
} else if (!WIKI.servers.le) {
|
||||||
|
throw new WIKI.Error.SystemSSLLEUnavailable()
|
||||||
|
} else {
|
||||||
|
await WIKI.servers.le.requestCertificate()
|
||||||
|
await WIKI.servers.restartServer('https')
|
||||||
|
return {
|
||||||
|
responseResult: graphHelper.generateSuccess('SSL Certificate renewed successfully.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return graphHelper.generateError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SystemInfo: {
|
SystemInfo: {
|
||||||
@ -266,6 +298,15 @@ module.exports = {
|
|||||||
hostname () {
|
hostname () {
|
||||||
return os.hostname()
|
return os.hostname()
|
||||||
},
|
},
|
||||||
|
httpPort () {
|
||||||
|
return WIKI.servers.servers.http ? _.get(WIKI.servers.servers.http.address(), 'port', 0) : 0
|
||||||
|
},
|
||||||
|
httpRedirection () {
|
||||||
|
return _.get(WIKI.config, 'server.sslRedir', false)
|
||||||
|
},
|
||||||
|
httpsPort () {
|
||||||
|
return WIKI.servers.servers.https ? _.get(WIKI.servers.servers.https.address(), 'port', 0) : 0
|
||||||
|
},
|
||||||
latestVersion () {
|
latestVersion () {
|
||||||
return WIKI.system.updates.version
|
return WIKI.system.updates.version
|
||||||
},
|
},
|
||||||
@ -293,6 +334,21 @@ module.exports = {
|
|||||||
ramTotal () {
|
ramTotal () {
|
||||||
return filesize(os.totalmem())
|
return filesize(os.totalmem())
|
||||||
},
|
},
|
||||||
|
sslDomain () {
|
||||||
|
return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === `letsencrypt` ? WIKI.config.ssl.domain : null
|
||||||
|
},
|
||||||
|
sslExpirationDate () {
|
||||||
|
return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === `letsencrypt` ? _.get(WIKI.config.letsencrypt, 'payload.expires', null) : null
|
||||||
|
},
|
||||||
|
sslProvider () {
|
||||||
|
return WIKI.config.ssl.enabled ? WIKI.config.ssl.provider : null
|
||||||
|
},
|
||||||
|
sslStatus () {
|
||||||
|
return 'OK'
|
||||||
|
},
|
||||||
|
sslSubscriberEmail () {
|
||||||
|
return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === `letsencrypt` ? WIKI.config.ssl.subscriberEmail : null
|
||||||
|
},
|
||||||
telemetry () {
|
telemetry () {
|
||||||
return WIKI.telemetry.enabled
|
return WIKI.telemetry.enabled
|
||||||
},
|
},
|
||||||
|
@ -40,6 +40,12 @@ type SystemMutation {
|
|||||||
mongoDbConnString: String!
|
mongoDbConnString: String!
|
||||||
groupMode: SystemImportUsersGroupMode!
|
groupMode: SystemImportUsersGroupMode!
|
||||||
): SystemImportUsersResponse @auth(requires: ["manage:system"])
|
): SystemImportUsersResponse @auth(requires: ["manage:system"])
|
||||||
|
|
||||||
|
setHTTPSRedirection(
|
||||||
|
enabled: Boolean!
|
||||||
|
): DefaultResponse @auth(requires: ["manage:system"])
|
||||||
|
|
||||||
|
renewHTTPSCertificate: DefaultResponse @auth(requires: ["manage:system"])
|
||||||
}
|
}
|
||||||
|
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
@ -65,6 +71,9 @@ type SystemInfo {
|
|||||||
dbVersion: String @auth(requires: ["manage:system"])
|
dbVersion: String @auth(requires: ["manage:system"])
|
||||||
groupsTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:groups", "write:groups", "manage:users", "write:users"])
|
groupsTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:groups", "write:groups", "manage:users", "write:users"])
|
||||||
hostname: String @auth(requires: ["manage:system"])
|
hostname: String @auth(requires: ["manage:system"])
|
||||||
|
httpPort: Int @auth(requires: ["manage:system"])
|
||||||
|
httpRedirection: Boolean @auth(requires: ["manage:system"])
|
||||||
|
httpsPort: Int @auth(requires: ["manage:system"])
|
||||||
latestVersion: String @auth(requires: ["manage:system"])
|
latestVersion: String @auth(requires: ["manage:system"])
|
||||||
latestVersionReleaseDate: Date @auth(requires: ["manage:system"])
|
latestVersionReleaseDate: Date @auth(requires: ["manage:system"])
|
||||||
nodeVersion: String @auth(requires: ["manage:system"])
|
nodeVersion: String @auth(requires: ["manage:system"])
|
||||||
@ -72,6 +81,11 @@ type SystemInfo {
|
|||||||
pagesTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:pages", "delete:pages"])
|
pagesTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:pages", "delete:pages"])
|
||||||
platform: String @auth(requires: ["manage:system"])
|
platform: String @auth(requires: ["manage:system"])
|
||||||
ramTotal: String @auth(requires: ["manage:system"])
|
ramTotal: String @auth(requires: ["manage:system"])
|
||||||
|
sslDomain: String @auth(requires: ["manage:system"])
|
||||||
|
sslExpirationDate: Date @auth(requires: ["manage:system"])
|
||||||
|
sslProvider: String @auth(requires: ["manage:system"])
|
||||||
|
sslStatus: String @auth(requires: ["manage:system"])
|
||||||
|
sslSubscriberEmail: String @auth(requires: ["manage:system"])
|
||||||
telemetry: Boolean @auth(requires: ["manage:system"])
|
telemetry: Boolean @auth(requires: ["manage:system"])
|
||||||
telemetryClientId: String @auth(requires: ["manage:system"])
|
telemetryClientId: String @auth(requires: ["manage:system"])
|
||||||
upgradeCapable: Boolean @auth(requires: ["manage:system"])
|
upgradeCapable: Boolean @auth(requires: ["manage:system"])
|
||||||
|
@ -165,6 +165,22 @@ module.exports = {
|
|||||||
message: 'An unexpected error occured during search operation.',
|
message: 'An unexpected error occured during search operation.',
|
||||||
code: 4001
|
code: 4001
|
||||||
}),
|
}),
|
||||||
|
SystemGenericError: CustomError('SystemGenericError', {
|
||||||
|
message: 'An unexpected error occured.',
|
||||||
|
code: 7001
|
||||||
|
}),
|
||||||
|
SystemSSLDisabled: CustomError('SystemSSLDisabled', {
|
||||||
|
message: 'SSL is not enabled.',
|
||||||
|
code: 7002
|
||||||
|
}),
|
||||||
|
SystemSSLLEUnavailable: CustomError('SystemSSLLEUnavailable', {
|
||||||
|
message: 'Let\'s Encrypt is not initialized.',
|
||||||
|
code: 7004
|
||||||
|
}),
|
||||||
|
SystemSSLRenewInvalidProvider: CustomError('SystemSSLRenewInvalidProvider', {
|
||||||
|
message: 'Current provider does not support SSL certificate renewal.',
|
||||||
|
code: 7003
|
||||||
|
}),
|
||||||
UserCreationFailed: CustomError('UserCreationFailed', {
|
UserCreationFailed: CustomError('UserCreationFailed', {
|
||||||
message: 'An unexpected error occured during user creation.',
|
message: 'An unexpected error occured during user creation.',
|
||||||
code: 1009
|
code: 1009
|
||||||
|
@ -59,10 +59,10 @@ module.exports = async () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Let's Encrypt Challenge
|
// SSL Handlers
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
|
|
||||||
app.use('/', ctrl.letsencrypt)
|
app.use('/', ctrl.ssl)
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Passport Authentication
|
// Passport Authentication
|
||||||
|
46
yarn.lock
46
yarn.lock
@ -2052,10 +2052,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz#7a8143fb33f077df3e579dca7f18fea74a02ec8b"
|
resolved "https://registry.yarnpkg.com/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz#7a8143fb33f077df3e579dca7f18fea74a02ec8b"
|
||||||
integrity sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA==
|
integrity sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA==
|
||||||
|
|
||||||
"@mdi/font@4.7.95":
|
"@mdi/font@4.8.95":
|
||||||
version "4.7.95"
|
version "4.8.95"
|
||||||
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-4.7.95.tgz#46fddf35aad64dd623a8b1837f78ca4ed7bc48b1"
|
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-4.8.95.tgz#e026255815fbac2d5155fdf5cd3069b8dc599900"
|
||||||
integrity sha512-/SWooHIFz2dXkQJk3VhEXSbBplOU1lIkGSELAmw0peFEgR8KPqyM//M3vD8WDZETuEOSRVhVqLevP3okrsM5dw==
|
integrity sha512-mfEjd6kkuheZ15CBU7g/q+De9+dah/SEgVH0uZsgCJTSYa+CkXIen35aNyHoixgcEfPV4Or0NLJvyYM5CXUnbQ==
|
||||||
|
|
||||||
"@opencensus/web-types@0.0.7":
|
"@opencensus/web-types@0.0.7":
|
||||||
version "0.0.7"
|
version "0.0.7"
|
||||||
@ -5821,6 +5821,11 @@ date-utils@*:
|
|||||||
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
|
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
|
||||||
integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=
|
integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=
|
||||||
|
|
||||||
|
db-errors@^0.2.3:
|
||||||
|
version "0.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/db-errors/-/db-errors-0.2.3.tgz#a6a38952e00b20e790f2695a6446b3c65497ffa2"
|
||||||
|
integrity sha512-OOgqgDuCavHXjYSJoV2yGhv6SeG8nk42aoCSoyXLZUH7VwFG27rxbavU1z+VrZbZjphw5UkDQwUlD21MwZpUng==
|
||||||
|
|
||||||
de-indent@^1.0.2:
|
de-indent@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||||
@ -6970,13 +6975,13 @@ file-loader@5.0.2:
|
|||||||
loader-utils "^1.2.3"
|
loader-utils "^1.2.3"
|
||||||
schema-utils "^2.5.0"
|
schema-utils "^2.5.0"
|
||||||
|
|
||||||
file-type@13.1.0:
|
file-type@13.1.1:
|
||||||
version "13.1.0"
|
version "13.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-13.1.0.tgz#5cfeade4745fad9504bb1435b5b5003af272b5a8"
|
resolved "https://registry.yarnpkg.com/file-type/-/file-type-13.1.1.tgz#439ceea3a50a3929b21d18d9c1c77fd7f2a63aa8"
|
||||||
integrity sha512-nr4fSvwYSlQl7YmaWS8rsvDrAm6VgCeb2ysHh18+YBSH4RxewhPKUQrj2XRuEMBNnH6E4xw+yWTL7+jiMrh6GA==
|
integrity sha512-HEb3tepyq8KzKSFEGMJSIxqn8uC1n3AM8OKME5+BIgq0bErRzcDPOdmnyPKtfjStSpIvuk0Rle8mvuG4824caQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
readable-web-to-node-stream "^2.0.0"
|
readable-web-to-node-stream "^2.0.0"
|
||||||
strtok3 "^5.0.1"
|
strtok3 "^5.0.2"
|
||||||
token-types "^2.0.0"
|
token-types "^2.0.0"
|
||||||
typedarray-to-buffer "^3.1.5"
|
typedarray-to-buffer "^3.1.5"
|
||||||
|
|
||||||
@ -10648,14 +10653,13 @@ object.values@^1.1.0:
|
|||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
|
|
||||||
objection@1.6.11:
|
objection@2.1.2:
|
||||||
version "1.6.11"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/objection/-/objection-1.6.11.tgz#6755c15300277eee76c44faf4295704d8e2e02e2"
|
resolved "https://registry.yarnpkg.com/objection/-/objection-2.1.2.tgz#da42e743ef69eabbb29bbf50efbe6f49acc854ba"
|
||||||
integrity sha512-/W6iR6+YvFg1U4k5DyX1MrY+xqodDM8AAOU1J0b3HlptsNw8V3uDHjZgTi1cFPPe5+ZeTTMvhIFhNiUP6+nqYQ==
|
integrity sha512-55tkg1C8iFfsEz07N3peKXU4COve+jRTaUlSXAGlcC2Kk/7ONntREnwErQp+0483g7eexEbc8EJ7CDPu/RmYoQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "^6.10.0"
|
ajv "^6.10.2"
|
||||||
bluebird "^3.5.5"
|
db-errors "^0.2.3"
|
||||||
lodash "^4.17.11"
|
|
||||||
|
|
||||||
offline-plugin@5.0.7:
|
offline-plugin@5.0.7:
|
||||||
version "5.0.7"
|
version "5.0.7"
|
||||||
@ -13813,10 +13817,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||||
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
||||||
|
|
||||||
simple-git@1.129.0:
|
simple-git@1.130.0:
|
||||||
version "1.129.0"
|
version "1.130.0"
|
||||||
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.129.0.tgz#eddd2611d2bf41c77e1d08cd70c0b7f3af785040"
|
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.130.0.tgz#b689c4163bc021df563a81f256de54482005195d"
|
||||||
integrity sha512-XbzNmugMTeV2crZnPl+b1ZJn+nqXCUNyrZxDXpLM0kHL3B85sbPlpd8q9I4qtAHI9D2FxTB6w4BuiAGKYtyzKw==
|
integrity sha512-gQsPA1uuAkGUa6S+yG4NRknKHVEV+Vnp437w8dJpDpzjtEH566WRSz5z6DoIxlBFaLC7Xwypznsuf1S/J0gtFg==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.0.1"
|
debug "^4.0.1"
|
||||||
|
|
||||||
@ -14313,7 +14317,7 @@ striptags@3.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd"
|
resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd"
|
||||||
integrity sha1-yMPn/db7S7OjKjt1LltePjgJPr0=
|
integrity sha1-yMPn/db7S7OjKjt1LltePjgJPr0=
|
||||||
|
|
||||||
strtok3@^5.0.1:
|
strtok3@^5.0.2:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-5.0.2.tgz#bb81f1f56742e16f1a30ccce5dc3d9498aa5475a"
|
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-5.0.2.tgz#bb81f1f56742e16f1a30ccce5dc3d9498aa5475a"
|
||||||
integrity sha512-EFeVpFC5qDsqPEJSrIYyS/ueFBknGhgSK9cW+YAJF/cgJG/KSjoK7X6rK5xnpcLe7y1LVkVFCXWbAb+ClNKzKQ==
|
integrity sha512-EFeVpFC5qDsqPEJSrIYyS/ueFBknGhgSK9cW+YAJF/cgJG/KSjoK7X6rK5xnpcLe7y1LVkVFCXWbAb+ClNKzKQ==
|
||||||
|
Loading…
Reference in New Issue
Block a user