diff --git a/assets/svg/auth-icon-azure.svg b/assets/svg/auth-icon-azure.svg
new file mode 100644
index 00000000..cf13b912
--- /dev/null
+++ b/assets/svg/auth-icon-azure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/svg/auth-icon-facebook.svg b/assets/svg/auth-icon-facebook.svg
new file mode 100644
index 00000000..fa706aa2
--- /dev/null
+++ b/assets/svg/auth-icon-facebook.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/assets/svg/auth-icon-github.svg b/assets/svg/auth-icon-github.svg
new file mode 100644
index 00000000..18e9450e
--- /dev/null
+++ b/assets/svg/auth-icon-github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/svg/auth-icon-google.svg b/assets/svg/auth-icon-google.svg
new file mode 100644
index 00000000..06dc52f0
--- /dev/null
+++ b/assets/svg/auth-icon-google.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/svg/auth-icon-ldap.svg b/assets/svg/auth-icon-ldap.svg
new file mode 100644
index 00000000..679fc237
--- /dev/null
+++ b/assets/svg/auth-icon-ldap.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/assets/svg/auth-icon-microsoft.svg b/assets/svg/auth-icon-microsoft.svg
new file mode 100644
index 00000000..0d47e89a
--- /dev/null
+++ b/assets/svg/auth-icon-microsoft.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/svg/auth-icon-slack.svg b/assets/svg/auth-icon-slack.svg
new file mode 100644
index 00000000..47232d6d
--- /dev/null
+++ b/assets/svg/auth-icon-slack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/client/scss/login.scss b/client/scss/login.scss
deleted file mode 100644
index 725ce498..00000000
--- a/client/scss/login.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-@charset "utf-8";
-
-$primary: 'indigo';
-
-@import "base/variables";
-@import "base/colors";
-@import "base/reset";
-@import "base/mixins";
-@import "base/fonts";
-@import "base/base";
-
-@import "libs/animate";
-@import 'pages/login';
diff --git a/client/scss/pages/_login.scss b/client/scss/pages/_login.scss
index 284bf7f6..440148c0 100644
--- a/client/scss/pages/_login.scss
+++ b/client/scss/pages/_login.scss
@@ -9,23 +9,65 @@
justify-content: center;
&-container {
+ position: relative;
display: flex;
- width: 650px;
+ width: 450px;
align-items: stretch;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
+
+ &.is-expanded {
+ width: 650px;
+ }
+
+ @include until($tablet) {
+ width: 350px;
+
+ &.is-expanded {
+ width: 400px;
+ }
+ }
+ }
+
+ &-error {
+ position: absolute;
+ bottom: 100%;
+ width: 100%;
+ min-height: 50px;
+ background-image: radial-gradient(ellipse at top left, rgba(mc('red', '900'),.9) 0%,rgba(mc('red', '400'),.8) 100%);
+ border: 1px solid #FFF;
+ color: #FFF;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ strong {
+ font-weight: 600;
+ text-transform: uppercase;
+ display: block;
+ padding: 0 1rem 0 0;
+ border-right: 1px solid #FFF;
+ }
+ span {
+ padding: 0 0 0 1rem;
+ display: block;
+ }
}
&-providers {
display: flex;
flex-direction: column;
- width: 200px;
+ width: 250px;
border: 1px solid #FFF;
background-color: mc('grey', '900');
z-index: 1;
+ @include until($tablet) {
+ width: 50px;
+ }
+
button {
flex: 1 1;
- padding: 0 15px;
+ padding: 5px 15px;
border: none;
color: #FFF;
background-color: mc('grey', '800');
@@ -34,6 +76,18 @@
font-weight: 600;
text-align: left;
min-height: 40px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ transition: all .4s ease;
+
+ @include until($tablet) {
+ justify-content: center;
+ }
+
+ &:hover {
+ background-color: mc('grey', '600');
+ }
&:first-child {
border-top: none;
@@ -48,10 +102,36 @@
i {
margin-right: 10px;
font-size: 16px;
+
+ @include until($tablet) {
+ margin-right: 0;
+ font-size: 20px;
+ }
+ }
+
+ svg {
+ margin-right: 10px;
+ width: auto;
+ height: 20px;
+ max-width: 18px;
+ max-height: 20px;
+
+ path {
+ fill: #FFF;
+ }
+
+ @include until($tablet) {
+ margin-right: 0;
+ font-size: 20px;
+ }
}
span {
font-weight: 600;
+
+ @include until($tablet) {
+ display: none;
+ }
}
}
}
@@ -59,7 +139,7 @@
&-frame {
background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%);
border: 1px solid #FFF;
- width: 450px;
+ width: 400px;
padding: 1rem;
color: mc('grey', '700');
display: flex;
@@ -67,6 +147,10 @@
flex-direction: column;
text-align: center;
+ @include until($tablet) {
+ width: 350px;
+ }
+
h1 {
font-size: 2rem;
font-weight: 600;
@@ -83,29 +167,6 @@
margin: 0 0 25px 0;
}
- h3 {
- font-size: 1.25rem;
- font-weight: normal;
- color: #FB8C00;
- padding: 0;
- margin: 0;
- animation: shake 1s ease;
-
- > .fa {
- margin-right: 7px;
- }
-
- }
-
- h4 {
- font-size: .8rem;
- font-weight: normal;
- color: rgba(255,255,255,0.7);
- padding: 0;
- margin: 0 0 15px 0;
- animation: fadeIn 3s ease;
- }
-
form {
display: flex;
flex-direction: column;
@@ -147,14 +208,10 @@
font-weight: 400;
text-shadow: 1px 1px 0 #000;
- .icon {
- font-size: 1.2rem;
- margin: 0 8px;
- }
-
a {
font-weight: 600;
color: #FFF;
+ margin-left: .25rem;
}
}
diff --git a/server/authentication/azure.js b/server/authentication/azure.js
index c54830ef..c6d71b4d 100644
--- a/server/authentication/azure.js
+++ b/server/authentication/azure.js
@@ -8,24 +8,29 @@
const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy
-module.exports = (passport, conf) => {
- const jwt = require('jsonwebtoken')
- passport.use('azure_ad_oauth2',
- new AzureAdOAuth2Strategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL,
- resource: conf.resource,
- tenant: conf.tenant
- }, (accessToken, refreshToken, params, profile, cb) => {
- let waadProfile = jwt.decode(params.id_token)
- waadProfile.id = waadProfile.oid
- waadProfile.provider = 'azure'
- wiki.db.User.processProfile(waadProfile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'azure',
+ title: 'Azure Active Directory',
+ props: ['clientId', 'clientSecret', 'callbackURL', 'resource', 'tenant'],
+ init (passport, conf) {
+ const jwt = require('jsonwebtoken')
+ passport.use('azure_ad_oauth2',
+ new AzureAdOAuth2Strategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL,
+ resource: conf.resource,
+ tenant: conf.tenant
+ }, (accessToken, refreshToken, params, profile, cb) => {
+ let waadProfile = jwt.decode(params.id_token)
+ waadProfile.id = waadProfile.oid
+ waadProfile.provider = 'azure'
+ wiki.db.User.processProfile(waadProfile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/facebook.js b/server/authentication/facebook.js
index 1a1d3822..03375dac 100644
--- a/server/authentication/facebook.js
+++ b/server/authentication/facebook.js
@@ -8,19 +8,24 @@
const FacebookStrategy = require('passport-facebook').Strategy
-module.exports = (passport, conf) => {
- passport.use('facebook',
- new FacebookStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL,
- profileFields: ['id', 'displayName', 'email']
- }, function (accessToken, refreshToken, profile, cb) {
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'facebook',
+ title: 'Facebook',
+ props: ['clientId', 'clientSecret', 'callbackURL'],
+ init (passport, conf) {
+ passport.use('facebook',
+ new FacebookStrategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL,
+ profileFields: ['id', 'displayName', 'email']
+ }, function (accessToken, refreshToken, profile, cb) {
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/github.js b/server/authentication/github.js
index 7c225e6a..ff3aec3b 100644
--- a/server/authentication/github.js
+++ b/server/authentication/github.js
@@ -8,19 +8,24 @@
const GitHubStrategy = require('passport-github2').Strategy
-module.exports = (passport, conf) => {
- passport.use('github',
- new GitHubStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL,
- scope: ['user:email']
- }, (accessToken, refreshToken, profile, cb) => {
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'github',
+ title: 'GitHub',
+ props: ['clientId', 'clientSecret', 'callbackURL'],
+ init (passport, conf) {
+ passport.use('github',
+ new GitHubStrategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL,
+ scope: ['user:email']
+ }, (accessToken, refreshToken, profile, cb) => {
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/google.js b/server/authentication/google.js
index 9531f4a8..371f4c30 100644
--- a/server/authentication/google.js
+++ b/server/authentication/google.js
@@ -8,18 +8,23 @@
const GoogleStrategy = require('passport-google-oauth20').Strategy
-module.exports = (passport, conf) => {
- passport.use('google',
- new GoogleStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL
- }, (accessToken, refreshToken, profile, cb) => {
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'google',
+ title: 'Google ID',
+ props: ['clientId', 'clientSecret', 'callbackURL'],
+ init (passport, conf) {
+ passport.use('google',
+ new GoogleStrategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL
+ }, (accessToken, refreshToken, profile, cb) => {
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/ldap.js b/server/authentication/ldap.js
index 0eb4ccbe..c7a993db 100644
--- a/server/authentication/ldap.js
+++ b/server/authentication/ldap.js
@@ -9,32 +9,37 @@
const LdapStrategy = require('passport-ldapauth').Strategy
const fs = require('fs')
-module.exports = (passport, conf) => {
- passport.use('ldapauth',
- new LdapStrategy({
- server: {
- url: conf.url,
- bindDn: conf.bindDn,
- bindCredentials: conf.bindCredentials,
- searchBase: conf.searchBase,
- searchFilter: conf.searchFilter,
- searchAttributes: ['displayName', 'name', 'cn', 'mail'],
- tlsOptions: (conf.tlsEnabled) ? {
- ca: [
- fs.readFileSync(conf.tlsCertPath)
- ]
- } : {}
- },
- usernameField: 'email',
- passReqToCallback: false
- }, (profile, cb) => {
- profile.provider = 'ldap'
- profile.id = profile.dn
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'ldap',
+ title: 'LDAP / Active Directory',
+ props: ['url', 'bindDn', 'bindCredentials', 'searchBase', 'searchFilter', 'tlsEnabled', 'tlsCertPath'],
+ init (passport, conf) {
+ passport.use('ldapauth',
+ new LdapStrategy({
+ server: {
+ url: conf.url,
+ bindDn: conf.bindDn,
+ bindCredentials: conf.bindCredentials,
+ searchBase: conf.searchBase,
+ searchFilter: conf.searchFilter,
+ searchAttributes: ['displayName', 'name', 'cn', 'mail'],
+ tlsOptions: (conf.tlsEnabled) ? {
+ ca: [
+ fs.readFileSync(conf.tlsCertPath)
+ ]
+ } : {}
+ },
+ usernameField: 'email',
+ passReqToCallback: false
+ }, (profile, cb) => {
+ profile.provider = 'ldap'
+ profile.id = profile.dn
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/local.js b/server/authentication/local.js
index ae00171b..1c4c7c07 100644
--- a/server/authentication/local.js
+++ b/server/authentication/local.js
@@ -8,25 +8,30 @@
const LocalStrategy = require('passport-local').Strategy
-module.exports = (passport, conf) => {
- passport.use('local',
- new LocalStrategy({
- usernameField: 'email',
- passwordField: 'password'
- }, (uEmail, uPassword, done) => {
- wiki.db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
- if (user) {
- return user.validatePassword(uPassword).then(() => {
- return done(null, user) || true
- }).catch((err) => {
- return done(err, null)
- })
- } else {
- return done(new Error('INVALID_LOGIN'), null)
- }
- }).catch((err) => {
- done(err, null)
- })
- }
- ))
+module.exports = {
+ key: 'local',
+ title: 'Local',
+ props: [],
+ init (passport, conf) {
+ passport.use('local',
+ new LocalStrategy({
+ usernameField: 'email',
+ passwordField: 'password'
+ }, (uEmail, uPassword, done) => {
+ wiki.db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
+ if (user) {
+ return user.validatePassword(uPassword).then(() => {
+ return done(null, user) || true
+ }).catch((err) => {
+ return done(err, null)
+ })
+ } else {
+ return done(new Error('INVALID_LOGIN'), null)
+ }
+ }).catch((err) => {
+ done(err, null)
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/microsoft.js b/server/authentication/microsoft.js
index 6ccd1b88..e8069de2 100644
--- a/server/authentication/microsoft.js
+++ b/server/authentication/microsoft.js
@@ -8,18 +8,23 @@
const WindowsLiveStrategy = require('passport-windowslive').Strategy
-module.exports = (passport, conf) => {
- passport.use('windowslive',
- new WindowsLiveStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL
- }, function (accessToken, refreshToken, profile, cb) {
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'microsoft',
+ title: 'Microsoft Account',
+ props: ['clientId', 'clientSecret', 'callbackURL'],
+ init (passport, conf) {
+ passport.use('windowslive',
+ new WindowsLiveStrategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL
+ }, function (accessToken, refreshToken, profile, cb) {
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/authentication/slack.js b/server/authentication/slack.js
index 778d6abf..17b7e0ae 100644
--- a/server/authentication/slack.js
+++ b/server/authentication/slack.js
@@ -8,18 +8,23 @@
const SlackStrategy = require('passport-slack').Strategy
-module.exports = (passport, conf) => {
- passport.use('slack',
- new SlackStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL
- }, (accessToken, refreshToken, profile, cb) => {
- wiki.db.User.processProfile(profile).then((user) => {
- return cb(null, user) || true
- }).catch((err) => {
- return cb(err, null) || true
- })
- }
- ))
+module.exports = {
+ key: 'slack',
+ title: 'Slack',
+ props: ['clientId', 'clientSecret', 'callbackURL'],
+ init (passport, conf) {
+ passport.use('slack',
+ new SlackStrategy({
+ clientID: conf.clientId,
+ clientSecret: conf.clientSecret,
+ callbackURL: conf.callbackURL
+ }, (accessToken, refreshToken, profile, cb) => {
+ wiki.db.User.processProfile(profile).then((user) => {
+ return cb(null, user) || true
+ }).catch((err) => {
+ return cb(err, null) || true
+ })
+ }
+ ))
+ }
}
diff --git a/server/controllers/auth.js b/server/controllers/auth.js
index a29e2873..179dbae8 100644
--- a/server/controllers/auth.js
+++ b/server/controllers/auth.js
@@ -37,7 +37,8 @@ const bruteforce = new ExpressBrute(EBstore, {
*/
router.get('/login', function (req, res, next) {
res.render('auth/login', {
- usr: res.locals.usr
+ authStrategies: wiki.auth.strategies,
+ hasMultipleStrategies: Object.keys(wiki.config.auth.strategies).length > 0
})
})
diff --git a/server/master.js b/server/master.js
index 844eee05..9199bc71 100644
--- a/server/master.js
+++ b/server/master.js
@@ -16,6 +16,7 @@ module.exports = Promise.join(
// Load global modules
// ----------------------------------------
+ wiki.auth = require('./modules/auth').init()
wiki.disk = require('./modules/disk').init()
wiki.docs = require('./modules/documents').init()
wiki.git = require('./modules/git').init(false)
@@ -38,7 +39,6 @@ module.exports = Promise.join(
const http = require('http')
const i18nBackend = require('i18next-node-fs-backend')
const path = require('path')
- const passport = require('passport')
const passportSocketIo = require('passport.socketio')
const session = require('express-session')
const SessionRedisStore = require('connect-redis')(session)
@@ -78,10 +78,6 @@ module.exports = Promise.join(
// Passport Authentication
// ----------------------------------------
- require('./modules/auth').init(passport)
- wiki.rights = require('./modules/rights')
- // wiki.rights.init()
-
let sessionStore = new SessionRedisStore({
client: wiki.redis
})
@@ -95,8 +91,8 @@ module.exports = Promise.join(
saveUninitialized: false
}))
app.use(flash())
- app.use(passport.initialize())
- app.use(passport.session())
+ app.use(wiki.auth.passport.initialize())
+ app.use(wiki.auth.passport.session())
// ----------------------------------------
// SEO
@@ -135,6 +131,7 @@ module.exports = Promise.join(
// View accessible data
// ----------------------------------------
+ app.locals.basedir = wiki.ROOTPATH
app.locals._ = require('lodash')
app.locals.t = wiki.lang.t.bind(wiki.lang)
app.locals.moment = require('moment')
diff --git a/server/middlewares/flash.js b/server/middlewares/flash.js
index 98182b47..09e4adf0 100644
--- a/server/middlewares/flash.js
+++ b/server/middlewares/flash.js
@@ -9,7 +9,7 @@
* @return {any} void
*/
module.exports = (req, res, next) => {
- res.locals.appflash = req.flash('alert')
+ res.locals.flash = req.flash('alert')
next()
}
diff --git a/server/modules/auth.js b/server/modules/auth.js
index 2fd96206..95befaeb 100644
--- a/server/modules/auth.js
+++ b/server/modules/auth.js
@@ -3,10 +3,16 @@
/* global wiki */
const _ = require('lodash')
+const passport = require('passport')
+const fs = require('fs-extra')
+const path = require('path')
module.exports = {
- init(passport) {
- // Serialization user methods
+ strategies: {},
+ init() {
+ this.passport = passport
+
+ // Serialization user methods
passport.serializeUser(function (user, done) {
done(null, user._id)
@@ -27,20 +33,26 @@ module.exports = {
// Load authentication strategies
- wiki.config.authStrategies = {
- list: _.pickBy(wiki.config.auth, strategy => strategy.enabled),
- socialEnabled: (_.chain(wiki.config.auth).omit('local').filter(['enabled', true]).value().length > 0)
- }
-
- _.forOwn(wiki.config.authStrategies.list, (strategyConfig, strategyName) => {
- strategyConfig.callbackURL = `${wiki.config.site.host}/login/${strategyName}/callback`
- require(`../authentication/${strategyName}`)(passport, strategyConfig)
- wiki.logger.info(`Authentication Provider ${_.upperFirst(strategyName)}: OK`)
+ _.forOwn(wiki.config.auth.strategies, (strategyConfig, strategyKey) => {
+ strategyConfig.callbackURL = `${wiki.config.site.host}${wiki.config.site.path}/login/${strategyKey}/callback`
+ let strategy = require(`../authentication/${strategyKey}`)
+ strategy.init(passport, strategyConfig)
+ fs.readFile(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${strategyKey}.svg`), 'utf8').then(iconData => {
+ strategy.icon = iconData
+ }).catch(err => {
+ if (err.code === 'ENOENT') {
+ strategy.icon = '[missing icon]'
+ } else {
+ wiki.logger.error(err)
+ }
+ })
+ this.strategies[strategy.key] = strategy
+ wiki.logger.info(`Authentication Provider ${strategyKey}: OK`)
})
// Create Guest account for first-time
- return wiki.db.User.findOne({
+ wiki.db.User.findOne({
where: {
provider: 'local',
email: 'guest@example.com'
@@ -88,5 +100,7 @@ module.exports = {
// })
// } else { return true }
// })
+
+ return this
}
}
diff --git a/server/views/auth/login.pug b/server/views/auth/login.pug
index 14105179..fad51aff 100644
--- a/server/views/auth/login.pug
+++ b/server/views/auth/login.pug
@@ -3,52 +3,30 @@ extends ../master.pug
block body
body
.login#root
- .login-container
- if config.authStrategies.socialEnabled
+ .login-container(:class={ "is-expanded": hasMultipleStrategies })
+ if flash.length > 0
+ .login-error
+ strong
+ i.icon-warning-outline
+ = flash[0].title
+ span= flash[0].message
+ if hasMultipleStrategies
.login-providers
- button.is-active(onclick='window.location.assign("/login/ms")')
+ button.is-active(title=t('auth:providers.local'))
i.nc-icon-outline.ui-1_database
span= t('auth:providers.local')
- if config.auth.microsoft && config.auth.microsoft.enabled
- button(onclick='window.location.assign("/login/ms")')
- i.icon-windows2
- span= t('auth:providers.windowslive')
- if config.auth.azure && config.auth.azure.enabled
- button(onclick='window.location.assign("/login/azure")')
- i.icon-windows2
- span= t('auth:providers.azure')
- if config.auth.google && config.auth.google.enabled
- button(onclick='window.location.assign("/login/google")')
- i.icon-google
- span= t('auth:providers.google')
- if config.auth.facebook && config.auth.facebook.enabled
- button(onclick='window.location.assign("/login/facebook")')
- i.icon-facebook
- span= t('auth:providers.facebook')
- if config.auth.github && config.auth.github.enabled
- button(onclick='window.location.assign("/login/github")')
- i.icon-github
- span= t('auth:providers.github')
- if config.auth.slack && config.auth.slack.enabled
- button(onclick='window.location.assign("/login/slack")')
- i.icon-slack
- span= t('auth:providers.slack')
+ each strategy in authStrategies
+ button(onclick='window.location.assign("/login/' + strategy.key + '")', title=strategy.title)
+ != strategy.icon
+ span= strategy.title
.login-frame
h1= config.site.title
h2= t('auth:loginrequired')
- if appflash.length > 0
- h3
- i.icon-warning-outline
- = appflash[0].title
- h4= appflash[0].message
- if config.auth.local.enabled
- form(method='post', action='/login')
- input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
- input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
- button.button.is-light-green.is-fullwidth(type='submit')
- span= t('auth:actions.login')
+ form(method='post', action='/login')
+ input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
+ input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
+ button.button.is-light-green.is-fullwidth(type='submit')
+ span= t('auth:actions.login')
.login-copyright
- = t('footer.poweredby') + ' '
- a.icon(href='https://github.com/Requarks/wiki')
- i.icon-github
- a(href='https://wiki.requarks.io/') Wiki.js
+ = t('footer.poweredby')
+ a(href='https://wiki.js.org', rel='external', title='Wiki.js') Wiki.js