Azure AD support + defaultReadAccess option + All Pages UI work
This commit is contained in:
parent
5a010f224f
commit
7c1dd8b92a
@ -21,6 +21,7 @@ defaults:
|
||||
lang: en
|
||||
public: false
|
||||
auth:
|
||||
defaultReadAccess: false
|
||||
local:
|
||||
enabled: true
|
||||
microsoft:
|
||||
@ -35,6 +36,8 @@ defaults:
|
||||
enabled: false
|
||||
ldap:
|
||||
enabled: false
|
||||
azure:
|
||||
enabled: false
|
||||
db: mongodb://localhost/wiki
|
||||
sessionSecret: null
|
||||
admin: null
|
||||
@ -55,6 +58,7 @@ defaults:
|
||||
loggly: false
|
||||
papertrail: false
|
||||
rollbar: false
|
||||
sentry: false
|
||||
langs:
|
||||
-
|
||||
id: en
|
||||
|
@ -54,6 +54,7 @@ $(() => {
|
||||
// ====================================
|
||||
|
||||
require('./pages/view.js')(alerts)
|
||||
require('./pages/all.js')(alerts, socket)
|
||||
require('./pages/create.js')(alerts, socket)
|
||||
require('./pages/edit.js')(alerts, socket)
|
||||
require('./pages/source.js')(alerts)
|
||||
|
9
client/js/pages/all.js
Normal file
9
client/js/pages/all.js
Normal file
@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
import $ from 'jquery'
|
||||
|
||||
module.exports = (alerts, socket) => {
|
||||
if ($('#page-type-all').length) {
|
||||
|
||||
}
|
||||
}
|
@ -1,25 +1,52 @@
|
||||
.has-collapsable-nav {
|
||||
background-color: mc('blue-grey', '50');
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.collapsable-nav {
|
||||
width: 300px;
|
||||
background-color: mc($primary, '500');
|
||||
background-color: mc('blue-grey', '900');
|
||||
color: #FFF;
|
||||
min-height: 80vh;
|
||||
transition: all .6s ease;
|
||||
border-left: 1px solid darken(mc('blue-grey', '900'), 5%);
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
&.has-children {
|
||||
width: 50px;
|
||||
background-color: mc($primary, '500');
|
||||
border-left: 1px solid mc($primary, '700');
|
||||
|
||||
&:nth-child(2) {
|
||||
border-left: 1px solid darken(mc('blue-grey', '900'), 5%);
|
||||
}
|
||||
|
||||
li {
|
||||
border-top: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
border-top: 1px solid mc($primary, '700');
|
||||
border-top: 1px solid darken(mc('blue-grey', '900'), 5%);
|
||||
|
||||
&.is-title {
|
||||
background-color: mc('blue-grey', '800');
|
||||
padding: 8px 15px;
|
||||
color: mc('blue-grey', '300');
|
||||
font-size: 13px;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,0.3);
|
||||
margin-right:1px;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
display: flex;
|
||||
@ -32,7 +59,6 @@
|
||||
a {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -61,40 +87,3 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.collapsable-nav-sub {
|
||||
width: 300px;
|
||||
background-color: mc('blue-grey', '800');
|
||||
border-left: 1px solid mc('blue-grey', '900');
|
||||
color: #FFF;
|
||||
min-height: 80vh;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
border-top: 1px solid mc('blue-grey', '900');
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
transition: all .4s ease;
|
||||
background-color: rgba(0,0,0,0);
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,.1);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,10 +87,6 @@
|
||||
width: 50px;
|
||||
|
||||
aside {
|
||||
.sidebar-label {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.sidebar-menu li a {
|
||||
padding: 10px 0;
|
||||
justify-content: center;
|
||||
|
@ -54,6 +54,7 @@ lang: en
|
||||
public: false
|
||||
|
||||
auth:
|
||||
defaultReadAccess: false
|
||||
local:
|
||||
enabled: true
|
||||
google:
|
||||
@ -85,6 +86,12 @@ auth:
|
||||
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
|
||||
|
@ -94,12 +94,14 @@ router.get('/login/google', passport.authenticate('google', { scope: ['profile',
|
||||
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/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: '/' }))
|
||||
|
||||
/**
|
||||
* Logout
|
||||
|
40
libs/auth.js
40
libs/auth.js
@ -2,13 +2,6 @@
|
||||
|
||||
/* global appconfig, appdata, db, winston */
|
||||
|
||||
const LocalStrategy = require('passport-local').Strategy
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy
|
||||
const WindowsLiveStrategy = require('passport-windowslive').Strategy
|
||||
const FacebookStrategy = require('passport-facebook').Strategy
|
||||
const GitHubStrategy = require('passport-github2').Strategy
|
||||
const SlackStrategy = require('passport-slack').Strategy
|
||||
const LdapStrategy = require('passport-ldapauth').Strategy
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = function (passport) {
|
||||
@ -34,6 +27,7 @@ module.exports = function (passport) {
|
||||
// Local Account
|
||||
|
||||
if (!appdata.capabilities.manyAuthProviders || (appconfig.auth.local && appconfig.auth.local.enabled)) {
|
||||
const LocalStrategy = require('passport-local').Strategy
|
||||
passport.use('local',
|
||||
new LocalStrategy({
|
||||
usernameField: 'email',
|
||||
@ -60,6 +54,7 @@ module.exports = function (passport) {
|
||||
// Google ID
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.google && appconfig.auth.google.enabled) {
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy
|
||||
passport.use('google',
|
||||
new GoogleStrategy({
|
||||
clientID: appconfig.auth.google.clientId,
|
||||
@ -79,6 +74,7 @@ module.exports = function (passport) {
|
||||
// Microsoft Accounts
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
|
||||
const WindowsLiveStrategy = require('passport-windowslive').Strategy
|
||||
passport.use('windowslive',
|
||||
new WindowsLiveStrategy({
|
||||
clientID: appconfig.auth.microsoft.clientId,
|
||||
@ -98,6 +94,7 @@ module.exports = function (passport) {
|
||||
// Facebook
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
|
||||
const FacebookStrategy = require('passport-facebook').Strategy
|
||||
passport.use('facebook',
|
||||
new FacebookStrategy({
|
||||
clientID: appconfig.auth.facebook.clientId,
|
||||
@ -118,6 +115,7 @@ module.exports = function (passport) {
|
||||
// GitHub
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.github && appconfig.auth.github.enabled) {
|
||||
const GitHubStrategy = require('passport-github2').Strategy
|
||||
passport.use('github',
|
||||
new GitHubStrategy({
|
||||
clientID: appconfig.auth.github.clientId,
|
||||
@ -138,6 +136,7 @@ module.exports = function (passport) {
|
||||
// Slack
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.slack && appconfig.auth.slack.enabled) {
|
||||
const SlackStrategy = require('passport-slack').Strategy
|
||||
passport.use('slack',
|
||||
new SlackStrategy({
|
||||
clientID: appconfig.auth.slack.clientId,
|
||||
@ -157,6 +156,7 @@ module.exports = function (passport) {
|
||||
// LDAP
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && appconfig.auth.ldap && appconfig.auth.ldap.enabled) {
|
||||
const LdapStrategy = require('passport-ldapauth').Strategy
|
||||
passport.use('ldapauth',
|
||||
new LdapStrategy({
|
||||
server: {
|
||||
@ -187,6 +187,32 @@ module.exports = function (passport) {
|
||||
))
|
||||
}
|
||||
|
||||
// AZURE AD
|
||||
|
||||
if (appdata.capabilities.manyAuthProviders && 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(() => {
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/* global winston */
|
||||
|
||||
const fs = require('fs')
|
||||
const yaml = require('js-yaml')
|
||||
const _ = require('lodash')
|
||||
@ -25,7 +23,7 @@ module.exports = (confPaths) => {
|
||||
appconfig = yaml.safeLoad(fs.readFileSync(confPaths.config, 'utf8'))
|
||||
appdata = yaml.safeLoad(fs.readFileSync(confPaths.data, 'utf8'))
|
||||
} catch (ex) {
|
||||
winston.error(ex)
|
||||
console.error(ex)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
@ -41,7 +39,7 @@ module.exports = (confPaths) => {
|
||||
socialEnabled: (_.chain(appconfig.auth).omit('local').reject({ enabled: false }).value().length > 0)
|
||||
}
|
||||
if (appconfig.authStrategies.list.length < 1) {
|
||||
winston.error(new Error('You must enable at least 1 authentication strategy!'))
|
||||
console.error(new Error('You must enable at least 1 authentication strategy!'))
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
|
@ -2,10 +2,11 @@
|
||||
"providers": {
|
||||
"local": "Local",
|
||||
"windowslive": "Microsoft Account",
|
||||
"azure": "Azure Active Directory",
|
||||
"google": "Google ID",
|
||||
"facebook": "Facebook",
|
||||
"github": "GitHub",
|
||||
"slack": "Slack",
|
||||
"ldap": "LDAP / Active Directory"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,9 +72,8 @@ userSchema.statics.processProfile = (profile) => {
|
||||
}, {
|
||||
new: true
|
||||
}).then((user) => {
|
||||
// LDAP - Handle unregistered accounts
|
||||
// Todo: Allow this behavior for any provider...
|
||||
if (!user && profile.provider === 'ldap') {
|
||||
// Handle unregistered accounts
|
||||
if (!user && profile.provider !== 'local' && (appconfig.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) {
|
||||
let nUsr = {
|
||||
email: primaryEmail,
|
||||
provider: profile.provider,
|
||||
|
@ -70,6 +70,7 @@
|
||||
"image-size": "^0.5.1",
|
||||
"jimp": "github:ngpixel/jimp",
|
||||
"js-yaml": "^3.8.3",
|
||||
"jsonwebtoken": "^7.3.0",
|
||||
"klaw": "^1.3.1",
|
||||
"levelup": "^1.3.5",
|
||||
"lodash": "^4.17.3",
|
||||
@ -91,6 +92,7 @@
|
||||
"multer": "^1.2.1",
|
||||
"ora": "^1.2.0",
|
||||
"passport": "^0.3.2",
|
||||
"passport-azure-ad-oauth2": "0.0.4",
|
||||
"passport-facebook": "^2.1.1",
|
||||
"passport-github2": "^0.1.10",
|
||||
"passport-google-oauth20": "^1.0.0",
|
||||
|
@ -47,6 +47,10 @@ html(data-logic='login')
|
||||
button.ms(onclick='window.location.assign("/login/ms")')
|
||||
i.icon-windows2
|
||||
span Microsoft Account
|
||||
if appconfig.auth.azure && appconfig.auth.azure.enabled
|
||||
button.ms(onclick='window.location.assign("/login/azure")')
|
||||
i.icon-windows2
|
||||
span Azure AD
|
||||
if appconfig.auth.google && appconfig.auth.google.enabled
|
||||
button.google(onclick='window.location.assign("/login/google")')
|
||||
i.icon-google
|
||||
|
@ -36,6 +36,7 @@ block adminContent
|
||||
case user.provider
|
||||
when 'local': i.icon-server
|
||||
when 'windowslive': i.icon-windows2.is-blue
|
||||
when 'azure': i.icon-windows2.is-blue
|
||||
when 'google': i.icon-google.is-blue
|
||||
when 'facebook': i.icon-facebook.is-indigo
|
||||
when 'github': i.icon-github.is-grey
|
||||
|
@ -30,6 +30,9 @@ block adminContent
|
||||
when 'windowslive'
|
||||
i.icon-windows2.is-blue
|
||||
| Microsoft Account
|
||||
when 'azure'
|
||||
i.icon-windows2.is-blue
|
||||
| Azure Active Directory
|
||||
when 'google'
|
||||
i.icon-google.is-blue
|
||||
| Google ID
|
||||
|
@ -37,6 +37,9 @@ block adminContent
|
||||
when 'windowslive'
|
||||
i.icon-windows2.is-blue
|
||||
| Microsoft Account
|
||||
when 'azure'
|
||||
i.icon-windows2.is-blue
|
||||
| Azure Active Directory
|
||||
when 'google'
|
||||
i.icon-google.is-blue
|
||||
| Google ID
|
||||
|
@ -7,61 +7,106 @@ block content
|
||||
|
||||
#page-type-all
|
||||
.container.is-fluid.has-collapsable-nav
|
||||
.columns.is-gapless
|
||||
|
||||
.column.is-narrow.is-hidden-touch.sidebar.is-collapsed
|
||||
|
||||
aside
|
||||
.sidebar-label
|
||||
span NAV
|
||||
ul.sidebar-menu
|
||||
.sidebar.is-collapsed
|
||||
aside
|
||||
.sidebar-label
|
||||
span NAV
|
||||
ul.sidebar-menu
|
||||
li
|
||||
a(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
if !isGuest
|
||||
li
|
||||
a(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
if !isGuest
|
||||
li
|
||||
a(href='/admin')
|
||||
i.icon-head
|
||||
span Account
|
||||
else
|
||||
li
|
||||
a(href='/login')
|
||||
i.icon-unlock
|
||||
span Login
|
||||
|
||||
.column.is-narrow
|
||||
ul.collapsable-nav.has-children
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li.is-active: a
|
||||
i.icon-folder2
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
.column.is-narrow
|
||||
ul.collapsable-nav-sub
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
|
||||
a(href='/admin')
|
||||
i.icon-head
|
||||
span Account
|
||||
else
|
||||
li
|
||||
a(href='/login')
|
||||
i.icon-unlock
|
||||
span Login
|
||||
ul.collapsable-nav.has-children
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li.is-active: a
|
||||
i.icon-folder2
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
ul.collapsable-nav.has-children
|
||||
li.is-title page-4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li.is-active: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
ul.collapsable-nav.has-children
|
||||
li.is-title page-4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li.is-active: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
ul.collapsable-nav.has-children
|
||||
li.is-title page-4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li.is-active: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
ul.collapsable-nav
|
||||
li.is-title Sub-Pages
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 1
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 2
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 3
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 4
|
||||
li: a
|
||||
i.icon-file
|
||||
span Page 5
|
||||
|
Loading…
Reference in New Issue
Block a user