feat: admin ssl - renew cert + toggle redirection btn
This commit is contained in:
@@ -54,6 +54,8 @@ defaults:
|
||||
securityHSTSDuration: 300
|
||||
securityCSP: false
|
||||
securityCSPDirectives: ''
|
||||
server:
|
||||
sslRedir: false
|
||||
flags:
|
||||
ldapdebug: false
|
||||
sqllog: false
|
||||
|
@@ -1,6 +1,7 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const _ = require('lodash')
|
||||
const qs = require('querystring')
|
||||
|
||||
/* 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
|
@@ -46,7 +46,7 @@ module.exports = {
|
||||
})
|
||||
|
||||
this.servers.http.on('connection', conn => {
|
||||
let connKey = `${conn.remoteAddress}:${conn.remotePort}`
|
||||
let connKey = `http:${conn.remoteAddress}:${conn.remotePort}`
|
||||
this.connections.set(connKey, conn)
|
||||
conn.on('close', () => {
|
||||
this.connections.delete(connKey)
|
||||
@@ -108,7 +108,7 @@ module.exports = {
|
||||
})
|
||||
|
||||
this.servers.https.on('connection', conn => {
|
||||
let connKey = `${conn.remoteAddress}:${conn.remotePort}`
|
||||
let connKey = `https:${conn.remoteAddress}:${conn.remotePort}`
|
||||
this.connections.set(connKey, conn)
|
||||
conn.on('close', () => {
|
||||
this.connections.delete(connKey)
|
||||
@@ -135,11 +135,17 @@ module.exports = {
|
||||
/**
|
||||
* Close all active connections
|
||||
*/
|
||||
closeConnections () {
|
||||
for (const conn of this.connections.values()) {
|
||||
closeConnections (mode = 'all') {
|
||||
for (const [key, conn] of this.connections) {
|
||||
if (mode !== `all` && key.indexOf(`${mode}:`) !== 0) {
|
||||
continue
|
||||
}
|
||||
conn.destroy()
|
||||
this.connections.delete(key)
|
||||
}
|
||||
if (mode === 'all') {
|
||||
this.connections.clear()
|
||||
}
|
||||
this.connections.clear()
|
||||
},
|
||||
/**
|
||||
* Stop all servers
|
||||
@@ -155,5 +161,29 @@ module.exports = {
|
||||
this.servers.https = 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) {
|
||||
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: {
|
||||
@@ -266,6 +298,15 @@ module.exports = {
|
||||
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 () {
|
||||
return WIKI.system.updates.version
|
||||
},
|
||||
@@ -293,6 +334,21 @@ module.exports = {
|
||||
ramTotal () {
|
||||
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 () {
|
||||
return WIKI.telemetry.enabled
|
||||
},
|
||||
|
@@ -40,6 +40,12 @@ type SystemMutation {
|
||||
mongoDbConnString: String!
|
||||
groupMode: SystemImportUsersGroupMode!
|
||||
): 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"])
|
||||
groupsTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:groups", "write:groups", "manage:users", "write:users"])
|
||||
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"])
|
||||
latestVersionReleaseDate: Date @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"])
|
||||
platform: 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"])
|
||||
telemetryClientId: String @auth(requires: ["manage:system"])
|
||||
upgradeCapable: Boolean @auth(requires: ["manage:system"])
|
||||
|
@@ -165,6 +165,22 @@ module.exports = {
|
||||
message: 'An unexpected error occured during search operation.',
|
||||
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', {
|
||||
message: 'An unexpected error occured during user creation.',
|
||||
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
|
||||
|
Reference in New Issue
Block a user