feat: admin UI fixes + SAML strategy + dashboard gql
This commit is contained in:
@@ -22,33 +22,77 @@ module.exports = {
|
||||
async system() { return {} }
|
||||
},
|
||||
SystemQuery: {
|
||||
async info(obj, args, context, info) {
|
||||
async info() { return {} }
|
||||
},
|
||||
SystemMutation: { },
|
||||
SystemInfo: {
|
||||
configFile() {
|
||||
return path.join(process.cwd(), 'config.yml')
|
||||
},
|
||||
currentVersion() {
|
||||
return WIKI.version
|
||||
},
|
||||
dbType() {
|
||||
return _.get(dbTypes, WIKI.config.db.type, 'Unknown DB')
|
||||
},
|
||||
dbVersion() {
|
||||
return _.get(WIKI.models, 'knex.client.version', 'Unknown version')
|
||||
},
|
||||
dbHost() {
|
||||
return WIKI.config.db.host
|
||||
},
|
||||
latestVersion() {
|
||||
return '2.0.0' // TODO
|
||||
},
|
||||
latestVersionReleaseDate() {
|
||||
return new Date() // TODO
|
||||
},
|
||||
async operatingSystem() {
|
||||
let osLabel = `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}`
|
||||
if (os.platform() === 'linux') {
|
||||
const osInfo = await getos()
|
||||
osLabel = `${os.type()} - ${osInfo.dist} (${osInfo.codename || os.platform()}) ${osInfo.release || os.release()} ${os.arch()}`
|
||||
}
|
||||
|
||||
return {
|
||||
configFile: path.join(process.cwd(), 'config.yml'),
|
||||
currentVersion: WIKI.version,
|
||||
dbType: _.get(dbTypes, WIKI.config.db.type, 'Unknown DB'),
|
||||
dbVersion: _.get(WIKI.models, 'knex.client.version', 'Unknown version'),
|
||||
dbHost: WIKI.config.db.host,
|
||||
latestVersion: WIKI.version, // TODO
|
||||
latestVersionReleaseDate: new Date(), // TODO
|
||||
operatingSystem: osLabel,
|
||||
hostname: os.hostname(),
|
||||
cpuCores: os.cpus().length,
|
||||
ramTotal: filesize(os.totalmem()),
|
||||
workingDirectory: process.cwd(),
|
||||
nodeVersion: process.version.substr(1),
|
||||
redisVersion: WIKI.redis.serverInfo.redis_version,
|
||||
redisUsedRAM: WIKI.redis.serverInfo.used_memory_human,
|
||||
redisTotalRAM: _.get(WIKI.redis.serverInfo, 'total_system_memory_human', 'N/A'),
|
||||
redisHost: WIKI.redis.options.host
|
||||
}
|
||||
return osLabel
|
||||
},
|
||||
hostname() {
|
||||
return os.hostname()
|
||||
},
|
||||
cpuCores() {
|
||||
return os.cpus().length
|
||||
},
|
||||
ramTotal() {
|
||||
return filesize(os.totalmem())
|
||||
},
|
||||
workingDirectory() {
|
||||
return process.cwd()
|
||||
},
|
||||
nodeVersion() {
|
||||
return process.version.substr(1)
|
||||
},
|
||||
redisVersion() {
|
||||
return WIKI.redis.serverInfo.redis_version
|
||||
},
|
||||
redisUsedRAM() {
|
||||
return WIKI.redis.serverInfo.used_memory_human
|
||||
},
|
||||
redisTotalRAM() {
|
||||
return _.get(WIKI.redis.serverInfo, 'total_system_memory_human', 'N/A')
|
||||
},
|
||||
redisHost() {
|
||||
return WIKI.redis.options.host
|
||||
},
|
||||
async groupsTotal() {
|
||||
const total = await WIKI.models.groups.query().count('* as total').first().pluck('total')
|
||||
return _.toSafeInteger(total)
|
||||
},
|
||||
async pagesTotal() {
|
||||
const total = await WIKI.models.pages.query().count('* as total').first().pluck('total')
|
||||
return _.toSafeInteger(total)
|
||||
},
|
||||
async usersTotal() {
|
||||
const total = await WIKI.models.users.query().count('* as total').first().pluck('total')
|
||||
return _.toSafeInteger(total)
|
||||
}
|
||||
},
|
||||
SystemMutation: { }
|
||||
}
|
||||
}
|
||||
|
@@ -37,15 +37,18 @@ type SystemInfo {
|
||||
dbHost: String
|
||||
dbType: String
|
||||
dbVersion: String
|
||||
groupsTotal: Int
|
||||
hostname: String
|
||||
latestVersion: String
|
||||
latestVersionReleaseDate: Date
|
||||
nodeVersion: String
|
||||
operatingSystem: String
|
||||
pagesTotal: Int
|
||||
ramTotal: String
|
||||
redisHost: String
|
||||
redisTotalRAM: String
|
||||
redisUsedRAM: String
|
||||
redisVersion: String
|
||||
usersTotal: Int
|
||||
workingDirectory: String
|
||||
}
|
||||
|
40
server/modules/authentication/saml/authentication.js
Normal file
40
server/modules/authentication/saml/authentication.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const _ = require('lodash')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
// ------------------------------------
|
||||
// SAML Account
|
||||
// ------------------------------------
|
||||
|
||||
const SAMLStrategy = require('passport-saml').Strategy
|
||||
|
||||
module.exports = {
|
||||
init (passport, conf) {
|
||||
passport.use('saml',
|
||||
new SAMLStrategy({
|
||||
callbackURL: conf.callbackURL,
|
||||
entryPoint: conf.entryPoint,
|
||||
issuer: conf.issuer,
|
||||
audience: conf.audience,
|
||||
cert: _.split(conf.cert, '|'),
|
||||
privateCert: conf.privateCert,
|
||||
decryptionPvk: conf.decryptionPvk,
|
||||
signatureAlgorithm: conf.signatureAlgorithm,
|
||||
identifierFormat: conf.identifierFormat,
|
||||
acceptedClockSkewMs: _.toSafeInteger(conf.acceptedClockSkewMs),
|
||||
disableRequestedAuthnContext: conf.disableRequestedAuthnContext,
|
||||
authnContext: conf.authnContext,
|
||||
forceAuthn: conf.forceAuthn,
|
||||
providerName: conf.providerName,
|
||||
skipRequestCompression: conf.skipRequestCompression,
|
||||
authnRequestBinding: conf.authnRequestBinding
|
||||
}, (profile, cb) => {
|
||||
WIKI.models.users.processProfile(profile).then((user) => {
|
||||
return cb(null, user) || true
|
||||
}).catch((err) => {
|
||||
return cb(err, null) || true
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
83
server/modules/authentication/saml/definition.yml
Normal file
83
server/modules/authentication/saml/definition.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
key: saml
|
||||
title: SAML 2.0
|
||||
description: Security Assertion Markup Language 2.0 (SAML 2.0) is a version of the SAML standard for exchanging authentication and authorization data between security domains.
|
||||
author: requarks.io
|
||||
logo: https://static.requarks.io/logo/saml.svg
|
||||
website: https://wiki.oasis-open.org/security/FrontPage
|
||||
useForm: false
|
||||
props:
|
||||
entryPoint:
|
||||
type: String
|
||||
title: Entry Point
|
||||
hint: Identity provider entrypoint (URL)
|
||||
issuer:
|
||||
type: String
|
||||
title: Issuer
|
||||
hint: Issuer string to supply to Identity Provider
|
||||
audience:
|
||||
type: String
|
||||
title: Audience
|
||||
hint: Expected SAML response Audience (if not provided, Audience won't be verified)
|
||||
cert:
|
||||
type: String
|
||||
title: Certificate
|
||||
hint: Public PEM-encoded X.509 signing certificate contents in base64 (e.g. 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqh ... W=='). If the provider has multiple certificates that are valid, join them together using the | pipe symbol.
|
||||
privateCert:
|
||||
type: String
|
||||
title: Private Certificate
|
||||
hint: PEM formatted key used to sign the certificate.
|
||||
decryptionPvk:
|
||||
type: String
|
||||
title: Decryption Private Key
|
||||
hint: (optional) Private key that will be used to attempt to decrypt any encrypted assertions that are received.
|
||||
signatureAlgorithm:
|
||||
type: String
|
||||
title: Signature Algorithm
|
||||
hint: Signature algorithm used for signing requests
|
||||
default: sha1
|
||||
enum:
|
||||
- sha1
|
||||
- sha256
|
||||
- sha512
|
||||
identifierFormat:
|
||||
type: String
|
||||
title: Name Identifier format
|
||||
default: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
|
||||
acceptedClockSkewMs:
|
||||
type: Number
|
||||
title: Accepted Clock Skew Milleseconds
|
||||
hint: Time in milliseconds of skew that is acceptable between client and server when checking OnBefore and NotOnOrAfter assertion condition validity timestamps. Setting to -1 will disable checking these conditions entirely.
|
||||
default: 0
|
||||
disableRequestedAuthnContext:
|
||||
type: Boolean
|
||||
title: Disable Requested Auth Context
|
||||
hint: If enabled, do not request a specific authentication context. This is known to help when authenticating against Active Directory (AD FS) servers.
|
||||
default: false
|
||||
authnContext:
|
||||
type: String
|
||||
title: Auth Context
|
||||
hint: Name identifier format to request auth context.
|
||||
default: urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
|
||||
forceAuthn:
|
||||
type: Boolean
|
||||
title: Force Initial Re-authentication
|
||||
hint: If enabled, the initial SAML request from the service provider specifies that the IdP should force re-authentication of the user, even if they possess a valid session.
|
||||
default: false
|
||||
providerName:
|
||||
type: String
|
||||
title: Provider Name
|
||||
hint: Optional human-readable name of the requester for use by the presenter's user agent or the identity provider.
|
||||
default: wiki.js
|
||||
skipRequestCompression:
|
||||
type: Boolean
|
||||
title: Skip Request Compression
|
||||
hint: If enabled, the SAML request from the service provider won't be compressed.
|
||||
default: false
|
||||
authnRequestBinding:
|
||||
type: String
|
||||
title: Request Binding
|
||||
hint: Binding used for request authentication from IDP.
|
||||
default: 'HTTP-Redirect'
|
||||
enum:
|
||||
- HTTP-Redirect
|
||||
- HTTP-POST
|
Reference in New Issue
Block a user