feat: ldap module + deps upgrade

This commit is contained in:
Nick 2019-04-26 23:59:35 -04:00
parent db14239eba
commit 26c7d49a78
9 changed files with 2673 additions and 1723 deletions

View File

@ -168,6 +168,7 @@ export default {
return {
analyticsServices: [
{ text: 'None', value: '' },
{ text: 'Elasticsearch APM', value: 'elk' },
{ text: 'Google Analytics', value: 'ga' },
{ text: 'Google Tag Manager', value: 'gtm' }
],

View File

@ -15,7 +15,7 @@
v-toolbar(color='primary', flat, dense, dark)
v-spacer
.subheading(v-if='screen === "tfa"') {{ $t('auth:tfa.subtitle') }}
.subheading(v-else-if='selectedStrategy.key !== "local"') {{ $t('auth:loginUsingStrategy', { strategy: selectedStrategy.title }) }}
.subheading(v-else-if='selectedStrategy.key !== "local"') {{ $t('auth:loginUsingStrategy', { strategy: selectedStrategy.title, interpolation: { escapeValue: false } }) }}
.subheading(v-else) {{ $t('auth:loginRequired') }}
v-spacer
v-card-text.text-xs-center

View File

@ -40,24 +40,24 @@
},
"dependencies": {
"@aoberoi/passport-slack": "1.0.5",
"@bugsnag/js": "5.2.0",
"@bugsnag/js": "6.2.0",
"algoliasearch": "3.32.1",
"apollo-fetch": "0.7.0",
"apollo-server": "2.3.3",
"apollo-server-express": "2.3.3",
"apollo-server": "2.4.8",
"apollo-server-express": "2.4.8",
"auto-load": "3.0.4",
"aws-sdk": "2.420.0",
"aws-sdk": "2.444.0",
"axios": "0.18.0",
"azure-search-client": "3.1.5",
"bcryptjs-then": "1.0.1",
"bluebird": "3.5.3",
"body-parser": "1.18.3",
"bluebird": "3.5.4",
"body-parser": "1.19.0",
"chalk": "2.4.2",
"cheerio": "1.0.0-rc.2",
"chokidar": "2.0.4",
"cheerio": "1.0.0-rc.3",
"chokidar": "2.1.5",
"clean-css": "4.2.1",
"compression": "1.7.3",
"cookie-parser": "1.4.3",
"compression": "1.7.4",
"cookie-parser": "1.4.4",
"cors": "2.8.5",
"custom-error-instance": "2.1.1",
"dependency-graph": "0.8.0",
@ -69,33 +69,33 @@
"express": "4.16.4",
"express-brute": "1.0.1",
"express-session": "1.16.1",
"file-type": "10.7.1",
"filesize": "4.0.0",
"file-type": "10.11.0",
"filesize": "4.1.2",
"fs-extra": "7.0.1",
"getos": "3.1.1",
"graphql": "14.1.1",
"graphql": "14.2.1",
"graphql-list-fields": "2.0.2",
"graphql-rate-limit-directive": "0.1.0",
"graphql-subscriptions": "1.0.0",
"graphql-rate-limit-directive": "1.0.1",
"graphql-subscriptions": "1.1.0",
"graphql-tools": "4.0.4",
"graphql-upload": "8.0.5",
"highlight.js": "9.14.2",
"i18next": "14.0.1",
"i18next-express-middleware": "1.7.1",
"graphql-upload": "8.0.6",
"highlight.js": "9.15.6",
"i18next": "15.1.0",
"i18next-express-middleware": "1.8.0",
"i18next-localstorage-cache": "1.1.1",
"i18next-node-fs-backend": "2.1.1",
"image-size": "0.7.1",
"i18next-node-fs-backend": "2.1.3",
"image-size": "0.7.4",
"js-base64": "2.5.1",
"js-binary": "1.2.0",
"js-yaml": "3.12.1",
"jsonwebtoken": "8.4.0",
"js-yaml": "3.13.1",
"jsonwebtoken": "8.5.1",
"klaw": "3.0.0",
"knex": "0.16.3",
"knex": "0.16.5",
"lodash": "4.17.11",
"markdown-it": "8.4.2",
"markdown-it-abbr": "1.0.4",
"markdown-it-anchor": "5.0.2",
"markdown-it-attrs": "2.3.2",
"markdown-it-attrs": "2.3.3",
"markdown-it-emoji": "1.4.0",
"markdown-it-expand-tabs": "1.0.13",
"markdown-it-external-links": "0.0.6",
@ -107,19 +107,19 @@
"markdown-it-sup": "1.0.0",
"markdown-it-task-lists": "2.1.1",
"mathjax-node": "2.1.1",
"mime-types": "2.1.21",
"mime-types": "2.1.24",
"moment": "2.24.0",
"moment-timezone": "0.5.23",
"mongodb": "3.1.13",
"mssql": "5.0.0-beta.1",
"moment-timezone": "0.5.25",
"mongodb": "3.2.3",
"mssql": "5.1.0",
"multer": "1.4.1",
"mysql2": "1.6.4",
"mysql2": "1.6.5",
"nanoid": "2.0.1",
"node-2fa": "1.1.2",
"node-cache": "4.2.0",
"nodemailer": "5.1.1",
"objection": "1.5.3",
"ora": "3.0.0",
"nodemailer": "6.1.1",
"objection": "1.6.8",
"ora": "3.4.0",
"passport": "0.4.0",
"passport-auth0": "1.1.0",
"passport-azure-ad-oauth2": "0.0.4",
@ -128,52 +128,52 @@
"passport-dropbox-oauth2": "1.1.0",
"passport-facebook": "3.0.0",
"passport-github2": "0.1.11",
"passport-google-oauth20": "1.0.0",
"passport-google-oauth20": "2.0.0",
"passport-jwt": "4.0.0",
"passport-ldapauth": "2.1.1",
"passport-ldapauth": "2.1.3",
"passport-local": "1.0.0",
"passport-oauth2": "1.4.0",
"passport-microsoft": "0.0.5",
"passport-oauth2": "1.5.0",
"passport-okta-oauth": "0.0.1",
"passport-openidconnect": "0.0.2",
"passport-saml": "1.0.0",
"passport-twitch": "1.0.3",
"passport-windowslive": "1.0.2",
"pem-jwk": "2.0.0",
"pg": "7.8.0",
"pg": "7.10.0",
"pg-hstore": "2.3.2",
"pg-query-stream": "2.0.0",
"pg-tsquery": "8.0.3",
"pm2": "3.2.9",
"pg-tsquery": "8.0.4",
"pm2": "3.5.0",
"pug": "2.0.3",
"qr-image": "3.2.0",
"raven": "2.6.4",
"remove-markdown": "0.3.0",
"request": "2.88.0",
"request-promise": "4.2.2",
"safe-regex": "2.0.1",
"request-promise": "4.2.4",
"safe-regex": "2.0.2",
"scim-query-filter-parser": "1.1.0",
"semver": "5.6.0",
"semver": "6.0.0",
"serve-favicon": "2.5.0",
"simple-git": "1.107.0",
"simple-git": "1.110.0",
"solr-node": "1.1.3",
"sqlite3": "4.0.6",
"striptags": "3.1.1",
"subscriptions-transport-ws": "0.9.15",
"subscriptions-transport-ws": "0.9.16",
"tar-fs": "2.0.0",
"twemoji": "11.3.0",
"twemoji": "12.0.1",
"uslug": "1.0.4",
"uuid": "3.3.2",
"validate.js": "0.12.0",
"validator": "10.11.0",
"validator-as-promised": "1.0.2",
"winston": "3.2.1",
"yargs": "12.0.5"
"yargs": "13.2.2"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/plugin-proposal-decorators": "^7.3.0",
"@babel/cli": "^7.4.3",
"@babel/core": "^7.4.3",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-proposal-decorators": "^7.4.0",
"@babel/plugin-proposal-export-namespace-from": "^7.2.0",
"@babel/plugin-proposal-function-sent": "^7.2.0",
"@babel/plugin-proposal-json-strings": "^7.2.0",
@ -181,62 +181,62 @@
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/polyfill": "^7.2.5",
"@babel/preset-env": "^7.3.1",
"@babel/polyfill": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"@panter/vue-i18next": "0.15.0",
"animate-sass": "0.8.2",
"animated-number-vue": "0.1.4",
"apollo-cache-inmemory": "1.4.2",
"animated-number-vue": "0.1.5",
"apollo-cache-inmemory": "1.5.1",
"apollo-client": "2.4.12",
"apollo-link": "1.2.8",
"apollo-link-batch-http": "1.2.8",
"apollo-link-error": "1.1.7",
"apollo-link-http": "1.5.11",
"apollo-link": "1.2.11",
"apollo-link-batch-http": "1.2.11",
"apollo-link-error": "1.1.10",
"apollo-link-http": "1.5.14",
"apollo-link-persisted-queries": "0.2.2",
"apollo-link-ws": "1.0.14",
"apollo-link-ws": "1.0.17",
"apollo-upload-client": "10.0.0",
"apollo-utilities": "1.1.2",
"autoprefixer": "9.4.7",
"apollo-utilities": "1.2.1",
"autoprefixer": "9.5.1",
"babel-eslint": "10.0.1",
"babel-jest": "24.0.0",
"babel-jest": "24.7.1",
"babel-loader": "^8.0.5",
"babel-plugin-graphql-tag": "1.6.0",
"babel-plugin-graphql-tag": "2.1.0",
"babel-plugin-lodash": "3.3.4",
"babel-plugin-transform-imports": "1.5.1",
"brace": "0.11.1",
"cache-loader": "2.0.1",
"chart.js": "2.7.3",
"clean-webpack-plugin": "1.0.1",
"copy-webpack-plugin": "4.6.0",
"cache-loader": "3.0.0",
"chart.js": "2.8.0",
"clean-webpack-plugin": "2.0.1",
"copy-webpack-plugin": "5.0.3",
"core-js": "2.6.3",
"css-loader": "2.1.0",
"cssnano": "4.1.8",
"css-loader": "2.1.1",
"cssnano": "4.1.10",
"duplicate-package-checker-webpack-plugin": "3.0.0",
"epic-spinners": "1.0.4",
"eslint": "5.13.0",
"eslint": "5.16.0",
"eslint-config-requarks": "1.0.7",
"eslint-config-standard": "12.0.0",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-import": "2.17.2",
"eslint-plugin-node": "8.0.1",
"eslint-plugin-promise": "4.0.1",
"eslint-plugin-promise": "4.1.1",
"eslint-plugin-standard": "4.0.0",
"eslint-plugin-vue": "5.1.0",
"eslint-plugin-vue": "5.2.2",
"file-loader": "3.0.1",
"filepond": "4.2.0",
"filepond-plugin-file-validate-type": "1.2.2",
"filepond": "4.4.0",
"filepond-plugin-file-validate-type": "1.2.4",
"filesize.js": "1.0.2",
"grapesjs": "0.14.52",
"graphiql": "0.12.0",
"grapesjs": "0.14.57",
"graphiql": "0.13.0",
"graphql-persisted-document-loader": "1.0.1",
"graphql-tag": "^2.10.1",
"graphql-voyager": "1.0.0-rc.26",
"graphql-voyager": "1.0.0-rc.27",
"hammerjs": "2.0.8",
"html-webpack-plugin": "3.2.0",
"html-webpack-pug-plugin": "0.3.0",
"i18next-xhr-backend": "1.5.1",
"i18next-xhr-backend": "2.0.1",
"ignore-loader": "0.1.2",
"js-cookie": "2.2.0",
"mini-css-extract-plugin": "0.5.0",
"mini-css-extract-plugin": "0.6.0",
"moment-duration-format": "2.2.2",
"node-sass": "4.11.0",
"offline-plugin": "5.0.6",
@ -246,15 +246,15 @@
"postcss-flexibility": "2.0.0",
"postcss-import": "12.0.1",
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.5.0",
"postcss-selector-parser": "5.0.0",
"postcss-preset-env": "6.6.0",
"postcss-selector-parser": "6.0.2",
"pug-lint": "2.5.0",
"pug-loader": "2.4.0",
"pug-plain-loader": "1.0.0",
"raw-loader": "1.0.0",
"react": "16.7.0",
"react-dom": "16.7.0",
"resolve-url-loader": "3.0.0",
"raw-loader": "2.0.0",
"react": "16.8.6",
"react-dom": "16.8.6",
"resolve-url-loader": "3.1.0",
"sass-loader": "7.1.0",
"sass-resources-loader": "2.0.0",
"script-ext-html-webpack-plugin": "2.1.3",
@ -264,41 +264,41 @@
"stylus-loader": "3.0.2",
"twemoji-awesome": "1.0.6",
"url-loader": "1.1.2",
"vee-validate": "2.1.7",
"vee-validate": "2.2.5",
"velocity-animate": "1.5.2",
"viz.js": "2.1.2",
"vue": "2.5.22",
"vue-apollo": "3.0.0-beta.27",
"vue-chartjs": "3.4.0",
"vue": "2.6.10",
"vue-apollo": "3.0.0-beta.28",
"vue-chartjs": "3.4.2",
"vue-clipboards": "1.2.4",
"vue-codemirror": "4.0.6",
"vue-filepond": "5.0.0",
"vue-hot-reload-api": "2.3.1",
"vue-loader": "15.6.2",
"vue-material-design-icons": "3.0.0",
"vue-filepond": "5.1.0",
"vue-hot-reload-api": "2.3.3",
"vue-loader": "15.7.0",
"vue-material-design-icons": "3.2.0",
"vue-moment": "4.0.0",
"vue-router": "3.0.2",
"vue-router": "3.0.6",
"vue-simple-breakpoints": "1.0.3",
"vue-status-indicator": "1.1.1",
"vue-template-compiler": "2.5.22",
"vue-template-compiler": "2.6.10",
"vue-tour": "1.1.0",
"vue2-animate": "2.1.0",
"vuedraggable": "2.17.0",
"vuescroll": "4.10.2",
"vuetify": "1.4.4",
"vuedraggable": "2.20.0",
"vuescroll": "4.12.2",
"vuetify": "1.5.13",
"vuex": "3.1.0",
"vuex-pathify": "1.1.3",
"vuex-pathify": "1.2.2",
"vuex-persistedstate": "2.5.4",
"webpack": "4.29.0",
"webpack-bundle-analyzer": "3.0.3",
"webpack-cli": "3.2.1",
"webpack-dev-middleware": "3.5.1",
"webpack-hot-middleware": "2.24.3",
"webpack": "4.30.0",
"webpack-bundle-analyzer": "3.3.2",
"webpack-cli": "3.3.1",
"webpack-dev-middleware": "3.6.2",
"webpack-hot-middleware": "2.24.4",
"webpack-merge": "4.2.1",
"webpack-subresource-integrity": "1.3.2",
"whatwg-fetch": "3.0.0",
"write-file-webpack-plugin": "4.5.0",
"xterm": "3.11.0",
"xterm": "3.12.2",
"zxcvbn": "4.4.2"
},
"resolutions": {

View File

@ -17,7 +17,6 @@ router.get('/login/:strategy', async (req, res, next) => {
const authResult = await WIKI.models.users.login({
strategy: req.params.strategy
}, { req, res })
console.info(authResult)
} catch (err) {
next(err)
}

View File

@ -5,6 +5,8 @@ const crypto = require('crypto')
const localeSegmentRegex = /^[A-Z]{2}(-[A-Z]{2})?$/gi
const systemSegmentRegex = /^[A-Z]\//gi
/* global WIKI */
module.exports = {
/**
* Parse raw url path and make it safe
@ -63,7 +65,10 @@ module.exports = {
/**
* Check if path is a reserved path
*/
isReservedPath(rawPath)  {
return _.some(WIKI.data.reservedPaths, p => _.startsWith(rawPath, p)) || systemSegmentRegex.test(rawPath)
isReservedPath(rawPath) {
const firstSection = _.head(rawPath.split('/'))
return _.some(WIKI.data.reservedPaths, p => {
return p === firstSection || systemSegmentRegex.test(rawPath)
})
}
}

View File

@ -6,10 +6,11 @@
const LdapStrategy = require('passport-ldapauth').Strategy
const fs = require('fs')
const _ = require('lodash')
module.exports = {
init (passport, conf) {
passport.use('ldapauth',
passport.use('ldap',
new LdapStrategy({
server: {
url: conf.url,
@ -17,7 +18,6 @@ module.exports = {
bindCredentials: conf.bindCredentials,
searchBase: conf.searchBase,
searchFilter: conf.searchFilter,
searchAttributes: ['displayName', 'name', 'cn', 'mail'],
tlsOptions: (conf.tlsEnabled) ? {
ca: [
fs.readFileSync(conf.tlsCertPath)
@ -25,15 +25,28 @@ module.exports = {
} : {}
},
usernameField: 'email',
passwordField: 'password',
passReqToCallback: false
}, (profile, cb) => {
profile.provider = 'ldap'
profile.id = profile.dn
WIKI.models.users.processProfile(profile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true
}, async (profile, cb) => {
try {
const userId = _.get(profile, conf.mappingUID, null)
if (!userId) {
throw new Error('Invalid Unique ID field mapping!')
}
const user = await WIKI.models.users.processProfile({
profile: {
id: userId,
email: _.get(profile, conf.mappingEmail, ''),
displayName: _.get(profile, conf.mappingDisplayName, '???'),
picture: _.get(profile, conf.mappingPicture, '')
},
providerKey: 'ldap'
})
cb(null, user)
} catch (err) {
cb(err, null)
}
}
))
}

View File

@ -5,33 +5,69 @@ author: requarks.io
logo: https://static.requarks.io/logo/active-directory.svg
color: blue darken-3
website: https://www.microsoft.com/windowsserver
isAvailable: true
useForm: true
props:
url:
title: URL
title: LDAP URL
type: String
default: 'ldap://serverhost:389'
hint: (e.g. ldap://serverhost:389)
hint: (e.g. ldap://serverhost:389 or ldaps://serverhost:636)
order: 1
bindDn:
title: Bind DN
title: Admin Bind DN
type: String
default: cn='root'
hint: The dstinguished name (dn) of the account used for binding.
order: 2
bindCredentials:
title: Admin Bind Credentials
type: String
hint: The password of the account used for binding.
hint: The password of the account used above for binding.
order: 3
searchBase:
title: Search Base
type: String
default: 'o=users,o=example.com'
hint: The base DN from which to search for users.
order: 4
searchFilter:
title: Search Filter
type: String
default: '(uid={{username}})'
hint: The query to use to match username. {{username}} must be present.
hint: The query to use to match username. {{username}} must be present and will be interpolated with the user provided username when performing the LDAP search.
order: 5
tlsEnabled:
title: Use TLS
type: Boolean
default: false
order: 6
tlsCertPath:
title: TLS Certificate Path
type: String
hint: Absolute path to the TLS certificate on the server.
order: 7
mappingUID:
title: Unique ID Field Mapping
type: String
default: 'uid'
hint: The field storing the user unique identifier. Usually "uid" or "sAMAccountName".
order: 8
mappingEmail:
title: Email Field Mapping
type: String
default: 'mail'
hint: The field storing the user email. Usually "mail".
order: 9
mappingDisplayName:
title: Display Name Field Mapping
type: String
default: 'displayName'
hint: The field storing the user display name. Usually "displayName" or "cn".
order: 10
mappingPicture:
title: Avatar Picture Field Mapping
type: String
default: 'jpegPhoto'
hint: The field storing the user avatar picture. Usually "jpegPhoto" or "thumbnailPhoto".
order: 11

View File

@ -4,7 +4,8 @@
// Microsoft Account
// ------------------------------------
const WindowsLiveStrategy = require('passport-windowslive').Strategy
const WindowsLiveStrategy = require('passport-microsoft').Strategy
const _ = require('lodash')
module.exports = {
init (passport, conf) {
@ -12,7 +13,8 @@ module.exports = {
new WindowsLiveStrategy({
clientID: conf.clientId,
clientSecret: conf.clientSecret,
callbackURL: conf.callbackURL
callbackURL: conf.callbackURL,
scope: ['User.Read', 'email', 'openid', 'profile']
}, async (accessToken, refreshToken, profile, cb) => {
console.info(profile)
try {

4084
yarn.lock

File diff suppressed because it is too large Load Diff