feat: self-contained auth modules + login UI + icons

pull/621/head
NGPixel 7 years ago
parent 52630127cd
commit cac3d21c6e

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

@ -0,0 +1,3 @@
<svg width="100%" height="100%" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
<path fill="#3B5998" d="M288.714,500l0,-228.073l76.554,0l11.461,-88.885l-88.017,0l0,-56.749c0,-25.735 7.145,-43.271 44.049,-43.271l47.067,-0.022l0,-79.498c-8.141,-1.081 -36.082,-3.502 -68.584,-3.502c-67.862,0 -114.321,41.422 -114.321,117.492l0,65.55l-76.751,0l0,88.885l76.751,0l0,228.071l91.791,0l0,0.002Z" style="fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 434 B

@ -0,0 +1 @@
<svg width="2500" height="2432" viewBox="0 0 256 249" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#161614"><path d="M127.505 0C57.095 0 0 57.085 0 127.505c0 56.336 36.534 104.13 87.196 120.99 6.372 1.18 8.712-2.766 8.712-6.134 0-3.04-.119-13.085-.173-23.739-35.473 7.713-42.958-15.044-42.958-15.044-5.8-14.738-14.157-18.656-14.157-18.656-11.568-7.914.872-7.752.872-7.752 12.804.9 19.546 13.14 19.546 13.14 11.372 19.493 29.828 13.857 37.104 10.6 1.144-8.242 4.449-13.866 8.095-17.05-28.32-3.225-58.092-14.158-58.092-63.014 0-13.92 4.981-25.295 13.138-34.224-1.324-3.212-5.688-16.18 1.235-33.743 0 0 10.707-3.427 35.073 13.07 10.17-2.826 21.078-4.242 31.914-4.29 10.836.048 21.752 1.464 31.942 4.29 24.337-16.497 35.029-13.07 35.029-13.07 6.94 17.563 2.574 30.531 1.25 33.743 8.175 8.929 13.122 20.303 13.122 34.224 0 48.972-29.828 59.756-58.22 62.912 4.573 3.957 8.648 11.717 8.648 23.612 0 17.06-.148 30.791-.148 34.991 0 3.393 2.295 7.369 8.759 6.117 50.634-16.879 87.122-64.656 87.122-120.973C255.009 57.085 197.922 0 127.505 0"/><path d="M47.755 181.634c-.28.633-1.278.823-2.185.389-.925-.416-1.445-1.28-1.145-1.916.275-.652 1.273-.834 2.196-.396.927.415 1.455 1.287 1.134 1.923M54.027 187.23c-.608.564-1.797.302-2.604-.589-.834-.889-.99-2.077-.373-2.65.627-.563 1.78-.3 2.616.59.834.899.996 2.08.36 2.65M58.33 194.39c-.782.543-2.06.034-2.849-1.1-.781-1.133-.781-2.493.017-3.038.792-.545 2.05-.055 2.85 1.07.78 1.153.78 2.513-.019 3.069M65.606 202.683c-.699.77-2.187.564-3.277-.488-1.114-1.028-1.425-2.487-.724-3.258.707-.772 2.204-.555 3.302.488 1.107 1.026 1.445 2.496.7 3.258M75.01 205.483c-.307.998-1.741 1.452-3.185 1.028-1.442-.437-2.386-1.607-2.095-2.616.3-1.005 1.74-1.478 3.195-1.024 1.44.435 2.386 1.596 2.086 2.612M85.714 206.67c.036 1.052-1.189 1.924-2.705 1.943-1.525.033-2.758-.818-2.774-1.852 0-1.062 1.197-1.926 2.721-1.951 1.516-.03 2.758.815 2.758 1.86M96.228 206.267c.182 1.026-.872 2.08-2.377 2.36-1.48.27-2.85-.363-3.039-1.38-.184-1.052.89-2.105 2.367-2.378 1.508-.262 2.857.355 3.049 1.398"/></g></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1 @@
<svg width="2443" height="2500" viewBox="0 0 256 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"/><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"/><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"/><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"/></svg>

After

Width:  |  Height:  |  Size: 1018 B

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="48px" height="48px" viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
<path fill="#458BC4" d="M44.804,30.404l-20-27C24.615,3.15,24.308,3.023,24,3.023V46c0.2,0,0.401-0.061,0.573-0.181l20-14
c0.222-0.155,0.37-0.393,0.414-0.659C45.03,30.895,44.964,30.622,44.804,30.404z"/>
<path fill="#43A6DD" d="M23.196,3.405l-20,27c-0.16,0.218-0.227,0.49-0.184,0.756c0.044,0.267,0.192,0.504,0.414,0.659l20,14
C23.599,45.939,23.8,46,24,46V3.023C23.692,3.023,23.385,3.15,23.196,3.405z"/>
</svg>

After

Width:  |  Height:  |  Size: 872 B

@ -0,0 +1 @@
<svg width="2490" height="2500" viewBox="0 0 256 257" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M0 36.357L104.62 22.11l.045 100.914-104.57.595L0 36.358zm104.57 98.293l.08 101.002L.081 221.275l-.006-87.302 104.494.677zm12.682-114.405L255.968 0v121.74l-138.716 1.1V20.246zM256 135.6l-.033 121.191-138.716-19.578-.194-101.84L256 135.6z" fill="#00ADEF"/></svg>

After

Width:  |  Height:  |  Size: 389 B

@ -0,0 +1 @@
<svg width="2500" height="2500" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M165.964 15.838c-3.89-11.975-16.752-18.528-28.725-14.636-11.975 3.89-18.528 16.752-14.636 28.725l58.947 181.365c4.048 11.187 16.132 17.473 27.732 14.135 12.1-3.483 19.475-16.334 15.614-28.217L165.964 15.838" fill="#DFA22F"/><path d="M74.626 45.516C70.734 33.542 57.873 26.989 45.9 30.879 33.924 34.77 27.37 47.631 31.263 59.606l58.948 181.366c4.047 11.186 16.132 17.473 27.732 14.132 12.099-3.481 19.474-16.332 15.613-28.217L74.626 45.516" fill="#3CB187"/><path d="M240.162 166.045c11.975-3.89 18.526-16.75 14.636-28.726-3.89-11.973-16.752-18.527-28.725-14.636L44.708 181.632c-11.187 4.046-17.473 16.13-14.135 27.73 3.483 12.099 16.334 19.475 28.217 15.614l181.372-58.93" fill="#CE1E5B"/><path d="M82.508 217.27l43.347-14.084-14.086-43.352-43.35 14.09 14.089 43.347" fill="#392538"/><path d="M173.847 187.591c16.388-5.323 31.62-10.273 43.348-14.084l-14.088-43.36-43.35 14.09 14.09 43.354" fill="#BB242A"/><path d="M210.484 74.706c11.974-3.89 18.527-16.751 14.637-28.727-3.89-11.973-16.752-18.526-28.727-14.636L15.028 90.293C3.842 94.337-2.445 106.422.896 118.022c3.481 12.098 16.332 19.474 28.217 15.613l181.371-58.93" fill="#72C5CD"/><path d="M52.822 125.933c11.805-3.836 27.025-8.782 43.354-14.086-5.323-16.39-10.273-31.622-14.084-43.352l-43.36 14.092 14.09 43.346" fill="#248C73"/><path d="M144.16 96.256l43.356-14.088a546179.21 546179.21 0 0 0-14.089-43.36L130.07 52.9l14.09 43.356" fill="#62803A"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -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';

@ -9,23 +9,65 @@
justify-content: center; justify-content: center;
&-container { &-container {
position: relative;
display: flex; display: flex;
width: 650px; width: 450px;
align-items: stretch; align-items: stretch;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); 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 { &-providers {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 200px; width: 250px;
border: 1px solid #FFF; border: 1px solid #FFF;
background-color: mc('grey', '900'); background-color: mc('grey', '900');
z-index: 1; z-index: 1;
@include until($tablet) {
width: 50px;
}
button { button {
flex: 1 1; flex: 1 1;
padding: 0 15px; padding: 5px 15px;
border: none; border: none;
color: #FFF; color: #FFF;
background-color: mc('grey', '800'); background-color: mc('grey', '800');
@ -34,6 +76,18 @@
font-weight: 600; font-weight: 600;
text-align: left; text-align: left;
min-height: 40px; 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 { &:first-child {
border-top: none; border-top: none;
@ -48,10 +102,36 @@
i { i {
margin-right: 10px; margin-right: 10px;
font-size: 16px; 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 { span {
font-weight: 600; font-weight: 600;
@include until($tablet) {
display: none;
}
} }
} }
} }
@ -59,7 +139,7 @@
&-frame { &-frame {
background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%); background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%);
border: 1px solid #FFF; border: 1px solid #FFF;
width: 450px; width: 400px;
padding: 1rem; padding: 1rem;
color: mc('grey', '700'); color: mc('grey', '700');
display: flex; display: flex;
@ -67,6 +147,10 @@
flex-direction: column; flex-direction: column;
text-align: center; text-align: center;
@include until($tablet) {
width: 350px;
}
h1 { h1 {
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
@ -83,29 +167,6 @@
margin: 0 0 25px 0; 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 { form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -147,14 +208,10 @@
font-weight: 400; font-weight: 400;
text-shadow: 1px 1px 0 #000; text-shadow: 1px 1px 0 #000;
.icon {
font-size: 1.2rem;
margin: 0 8px;
}
a { a {
font-weight: 600; font-weight: 600;
color: #FFF; color: #FFF;
margin-left: .25rem;
} }
} }

@ -8,7 +8,11 @@
const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'azure',
title: 'Azure Active Directory',
props: ['clientId', 'clientSecret', 'callbackURL', 'resource', 'tenant'],
init (passport, conf) {
const jwt = require('jsonwebtoken') const jwt = require('jsonwebtoken')
passport.use('azure_ad_oauth2', passport.use('azure_ad_oauth2',
new AzureAdOAuth2Strategy({ new AzureAdOAuth2Strategy({
@ -29,3 +33,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const FacebookStrategy = require('passport-facebook').Strategy const FacebookStrategy = require('passport-facebook').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'facebook',
title: 'Facebook',
props: ['clientId', 'clientSecret', 'callbackURL'],
init (passport, conf) {
passport.use('facebook', passport.use('facebook',
new FacebookStrategy({ new FacebookStrategy({
clientID: conf.clientId, clientID: conf.clientId,
@ -24,3 +28,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const GitHubStrategy = require('passport-github2').Strategy const GitHubStrategy = require('passport-github2').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'github',
title: 'GitHub',
props: ['clientId', 'clientSecret', 'callbackURL'],
init (passport, conf) {
passport.use('github', passport.use('github',
new GitHubStrategy({ new GitHubStrategy({
clientID: conf.clientId, clientID: conf.clientId,
@ -24,3 +28,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const GoogleStrategy = require('passport-google-oauth20').Strategy const GoogleStrategy = require('passport-google-oauth20').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'google',
title: 'Google ID',
props: ['clientId', 'clientSecret', 'callbackURL'],
init (passport, conf) {
passport.use('google', passport.use('google',
new GoogleStrategy({ new GoogleStrategy({
clientID: conf.clientId, clientID: conf.clientId,
@ -23,3 +27,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -9,7 +9,11 @@
const LdapStrategy = require('passport-ldapauth').Strategy const LdapStrategy = require('passport-ldapauth').Strategy
const fs = require('fs') const fs = require('fs')
module.exports = (passport, conf) => { module.exports = {
key: 'ldap',
title: 'LDAP / Active Directory',
props: ['url', 'bindDn', 'bindCredentials', 'searchBase', 'searchFilter', 'tlsEnabled', 'tlsCertPath'],
init (passport, conf) {
passport.use('ldapauth', passport.use('ldapauth',
new LdapStrategy({ new LdapStrategy({
server: { server: {
@ -38,3 +42,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const LocalStrategy = require('passport-local').Strategy const LocalStrategy = require('passport-local').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'local',
title: 'Local',
props: [],
init (passport, conf) {
passport.use('local', passport.use('local',
new LocalStrategy({ new LocalStrategy({
usernameField: 'email', usernameField: 'email',
@ -30,3 +34,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const WindowsLiveStrategy = require('passport-windowslive').Strategy const WindowsLiveStrategy = require('passport-windowslive').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'microsoft',
title: 'Microsoft Account',
props: ['clientId', 'clientSecret', 'callbackURL'],
init (passport, conf) {
passport.use('windowslive', passport.use('windowslive',
new WindowsLiveStrategy({ new WindowsLiveStrategy({
clientID: conf.clientId, clientID: conf.clientId,
@ -23,3 +27,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -8,7 +8,11 @@
const SlackStrategy = require('passport-slack').Strategy const SlackStrategy = require('passport-slack').Strategy
module.exports = (passport, conf) => { module.exports = {
key: 'slack',
title: 'Slack',
props: ['clientId', 'clientSecret', 'callbackURL'],
init (passport, conf) {
passport.use('slack', passport.use('slack',
new SlackStrategy({ new SlackStrategy({
clientID: conf.clientId, clientID: conf.clientId,
@ -23,3 +27,4 @@ module.exports = (passport, conf) => {
} }
)) ))
} }
}

@ -37,7 +37,8 @@ const bruteforce = new ExpressBrute(EBstore, {
*/ */
router.get('/login', function (req, res, next) { router.get('/login', function (req, res, next) {
res.render('auth/login', { res.render('auth/login', {
usr: res.locals.usr authStrategies: wiki.auth.strategies,
hasMultipleStrategies: Object.keys(wiki.config.auth.strategies).length > 0
}) })
}) })

@ -16,6 +16,7 @@ module.exports = Promise.join(
// Load global modules // Load global modules
// ---------------------------------------- // ----------------------------------------
wiki.auth = require('./modules/auth').init()
wiki.disk = require('./modules/disk').init() wiki.disk = require('./modules/disk').init()
wiki.docs = require('./modules/documents').init() wiki.docs = require('./modules/documents').init()
wiki.git = require('./modules/git').init(false) wiki.git = require('./modules/git').init(false)
@ -38,7 +39,6 @@ module.exports = Promise.join(
const http = require('http') const http = require('http')
const i18nBackend = require('i18next-node-fs-backend') const i18nBackend = require('i18next-node-fs-backend')
const path = require('path') const path = require('path')
const passport = require('passport')
const passportSocketIo = require('passport.socketio') const passportSocketIo = require('passport.socketio')
const session = require('express-session') const session = require('express-session')
const SessionRedisStore = require('connect-redis')(session) const SessionRedisStore = require('connect-redis')(session)
@ -78,10 +78,6 @@ module.exports = Promise.join(
// Passport Authentication // Passport Authentication
// ---------------------------------------- // ----------------------------------------
require('./modules/auth').init(passport)
wiki.rights = require('./modules/rights')
// wiki.rights.init()
let sessionStore = new SessionRedisStore({ let sessionStore = new SessionRedisStore({
client: wiki.redis client: wiki.redis
}) })
@ -95,8 +91,8 @@ module.exports = Promise.join(
saveUninitialized: false saveUninitialized: false
})) }))
app.use(flash()) app.use(flash())
app.use(passport.initialize()) app.use(wiki.auth.passport.initialize())
app.use(passport.session()) app.use(wiki.auth.passport.session())
// ---------------------------------------- // ----------------------------------------
// SEO // SEO
@ -135,6 +131,7 @@ module.exports = Promise.join(
// View accessible data // View accessible data
// ---------------------------------------- // ----------------------------------------
app.locals.basedir = wiki.ROOTPATH
app.locals._ = require('lodash') app.locals._ = require('lodash')
app.locals.t = wiki.lang.t.bind(wiki.lang) app.locals.t = wiki.lang.t.bind(wiki.lang)
app.locals.moment = require('moment') app.locals.moment = require('moment')

@ -9,7 +9,7 @@
* @return {any} void * @return {any} void
*/ */
module.exports = (req, res, next) => { module.exports = (req, res, next) => {
res.locals.appflash = req.flash('alert') res.locals.flash = req.flash('alert')
next() next()
} }

@ -3,9 +3,15 @@
/* global wiki */ /* global wiki */
const _ = require('lodash') const _ = require('lodash')
const passport = require('passport')
const fs = require('fs-extra')
const path = require('path')
module.exports = { module.exports = {
init(passport) { strategies: {},
init() {
this.passport = passport
// Serialization user methods // Serialization user methods
passport.serializeUser(function (user, done) { passport.serializeUser(function (user, done) {
@ -27,20 +33,26 @@ module.exports = {
// Load authentication strategies // Load authentication strategies
wiki.config.authStrategies = { _.forOwn(wiki.config.auth.strategies, (strategyConfig, strategyKey) => {
list: _.pickBy(wiki.config.auth, strategy => strategy.enabled), strategyConfig.callbackURL = `${wiki.config.site.host}${wiki.config.site.path}/login/${strategyKey}/callback`
socialEnabled: (_.chain(wiki.config.auth).omit('local').filter(['enabled', true]).value().length > 0) 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)
} }
})
_.forOwn(wiki.config.authStrategies.list, (strategyConfig, strategyName) => { this.strategies[strategy.key] = strategy
strategyConfig.callbackURL = `${wiki.config.site.host}/login/${strategyName}/callback` wiki.logger.info(`Authentication Provider ${strategyKey}: OK`)
require(`../authentication/${strategyName}`)(passport, strategyConfig)
wiki.logger.info(`Authentication Provider ${_.upperFirst(strategyName)}: OK`)
}) })
// Create Guest account for first-time // Create Guest account for first-time
return wiki.db.User.findOne({ wiki.db.User.findOne({
where: { where: {
provider: 'local', provider: 'local',
email: 'guest@example.com' email: 'guest@example.com'
@ -88,5 +100,7 @@ module.exports = {
// }) // })
// } else { return true } // } else { return true }
// }) // })
return this
} }
} }

@ -3,52 +3,30 @@ extends ../master.pug
block body block body
body body
.login#root .login#root
.login-container .login-container(:class={ "is-expanded": hasMultipleStrategies })
if config.authStrategies.socialEnabled if flash.length > 0
.login-error
strong
i.icon-warning-outline
= flash[0].title
span= flash[0].message
if hasMultipleStrategies
.login-providers .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 i.nc-icon-outline.ui-1_database
span= t('auth:providers.local') span= t('auth:providers.local')
if config.auth.microsoft && config.auth.microsoft.enabled each strategy in authStrategies
button(onclick='window.location.assign("/login/ms")') button(onclick='window.location.assign("/login/' + strategy.key + '")', title=strategy.title)
i.icon-windows2 != strategy.icon
span= t('auth:providers.windowslive') span= strategy.title
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')
.login-frame .login-frame
h1= config.site.title h1= config.site.title
h2= t('auth:loginrequired') 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') form(method='post', action='/login')
input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser')) input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
input#login-pass(type='password', name='password', placeholder=t('auth:fields.password')) input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
button.button.is-light-green.is-fullwidth(type='submit') button.button.is-light-green.is-fullwidth(type='submit')
span= t('auth:actions.login') span= t('auth:actions.login')
.login-copyright .login-copyright
= t('footer.poweredby') + ' ' = t('footer.poweredby')
a.icon(href='https://github.com/Requarks/wiki') a(href='https://wiki.js.org', rel='external', title='Wiki.js') Wiki.js
i.icon-github
a(href='https://wiki.requarks.io/') Wiki.js

Loading…
Cancel
Save