2017-09-25 03:22:33 +00:00
< template lang = "pug" >
2018-03-18 02:41:16 +00:00
v - app
2020-07-05 05:36:02 +00:00
. login ( : style = '`background-image: url(` + bgUrl + `);`' )
2020-07-03 23:36:33 +00:00
. login - sd
2020-08-22 23:37:49 +00:00
. d - flex . mb - 5
2020-07-03 23:36:33 +00:00
. login - logo
v - avatar ( tile , size = '34' )
v - img ( : src = 'logoUrl' )
. login - title
. text - h6 { { siteTitle } }
2020-08-22 23:37:49 +00:00
v - alert . mb - 0 (
v - model = 'errorShown'
transition = 'slide-y-reverse-transition'
color = 'red darken-2'
tile
dark
dense
icon = 'mdi-alert'
)
. body - 2 { { errorMessage } }
2020-07-03 23:36:33 +00:00
//-------------------------------------------------
//- PROVIDERS LIST
//-------------------------------------------------
template ( v - if = 'screen === `login` && strategies.length > 1' )
2020-08-22 23:37:49 +00:00
. login - subtitle
2020-07-03 23:36:33 +00:00
. text - subtitle - 1 Select Authentication Provider
. login - list
v - list . elevation - 1. radius - 7 ( nav )
v - list - item - group ( v - model = 'selectedStrategyKey' )
v - list - item (
2020-07-06 03:55:11 +00:00
v - for = '(stg, idx) of filteredStrategies'
2020-07-03 23:36:33 +00:00
: key = 'stg.key'
: value = 'stg.key'
: color = 'stg.strategy.color'
)
v - avatar . mr - 3 ( tile , size = '24' , v - html = 'stg.strategy.icon' )
span . text - none { { stg . displayName } }
//-------------------------------------------------
//- LOGIN FORM
//-------------------------------------------------
template ( v - if = 'screen === `login` && selectedStrategy.strategy.useForm' )
. login - subtitle
. text - subtitle - 1 Enter your credentials
. login - form
v - text - field (
solo
flat
prepend - inner - icon = 'mdi-clipboard-account'
background - color = 'white'
hide - details
ref = 'iptEmail'
v - model = 'username'
2020-07-20 04:22:29 +00:00
: placeholder = 'isUsernameEmail ? $t(`auth:fields.email`) : $t(`auth:fields.username`)'
: type = 'isUsernameEmail ? `email` : `text`'
: autocomplete = 'isUsernameEmail ? `email` : `username`'
2020-07-03 23:36:33 +00:00
)
v - text - field . mt - 2 (
solo
flat
prepend - inner - icon = 'mdi-form-textbox-password'
background - color = 'white'
hide - details
ref = 'iptPassword'
v - model = 'password'
: append - icon = 'hidePassword ? "mdi-eye-off" : "mdi-eye"'
@ click : append = '() => (hidePassword = !hidePassword)'
: type = 'hidePassword ? "password" : "text"'
: placeholder = '$t("auth:fields.password")'
2020-07-20 04:22:29 +00:00
autocomplete = 'current-password'
2020-07-03 23:36:33 +00:00
@ keyup . enter = 'login'
2018-10-08 04:17:31 +00:00
)
2020-07-03 23:36:33 +00:00
v - btn . mt - 2. text - none (
width = '100%'
large
color = 'primary'
dark
@ click = 'login'
: loading = 'isLoading'
) { { $t ( 'auth:actions.login' ) } }
2020-07-20 01:42:20 +00:00
. text - center . mt - 5
2020-07-03 23:36:33 +00:00
v - btn . text - none (
text
rounded
color = 'grey darken-3'
@ click . stop . prevent = 'forgotPassword'
href = '#forgot'
) : . caption { { $t ( 'auth:forgotPasswordLink' ) } }
v - btn . text - none (
2020-07-20 01:42:20 +00:00
v - if = 'selectedStrategyKey === `local` && selectedStrategy.selfRegistration'
2020-07-03 23:36:33 +00:00
color = 'indigo darken-2'
text
rounded
href = '/register'
) : . caption { { $t ( 'auth:switchToRegister.link' ) } }
2020-07-20 01:42:20 +00:00
//-------------------------------------------------
//- FORGOT PASSWORD FORM
//-------------------------------------------------
template ( v - if = 'screen === `forgot`' )
. login - subtitle
. text - subtitle - 1 Forgot your password
. login - info { { $t ( 'auth:forgotPasswordSubtitle' ) } }
. login - form
v - text - field (
solo
flat
prepend - inner - icon = 'mdi-clipboard-account'
background - color = 'white'
hide - details
ref = 'iptForgotPwdEmail'
v - model = 'username'
2020-07-20 04:22:29 +00:00
: placeholder = '$t(`auth:fields.email`)'
type = 'email'
autocomplete = 'email'
2020-07-20 01:42:20 +00:00
)
v - btn . mt - 2. text - none (
width = '100%'
large
color = 'primary'
dark
@ click = 'forgotPasswordSubmit'
: loading = 'isLoading'
) { { $t ( 'auth:sendResetPassword' ) } }
. text - center . mt - 5
v - btn . text - none (
text
rounded
color = 'grey darken-3'
@ click . stop . prevent = 'screen = `login`'
href = '#forgot'
) : . caption { { $t ( 'auth:forgotPasswordCancel' ) } }
//-------------------------------------------------
//- CHANGE PASSWORD FORM
//-------------------------------------------------
template ( v - if = 'screen === `changePwd`' )
. login - subtitle
. text - subtitle - 1 { { $t ( 'auth:changePwd.subtitle' ) } }
. login - form
v - text - field . mt - 2 (
type = 'password'
solo
flat
prepend - inner - icon = 'mdi-form-textbox-password'
background - color = 'white'
hide - details
ref = 'iptNewPassword'
v - model = 'newPassword'
: placeholder = '$t(`auth:changePwd.newPasswordPlaceholder`)'
2020-07-20 04:22:29 +00:00
autocomplete = 'new-password'
2020-07-20 01:42:20 +00:00
)
password - strength ( slot = 'progress' , v - model = 'newPassword' )
v - text - field . mt - 2 (
type = 'password'
solo
flat
prepend - inner - icon = 'mdi-form-textbox-password'
background - color = 'white'
hide - details
v - model = 'newPasswordVerify'
: placeholder = '$t(`auth:changePwd.newPasswordVerifyPlaceholder`)'
2020-07-20 04:22:29 +00:00
autocomplete = 'new-password'
2020-07-20 01:42:20 +00:00
@ keyup . enter = 'changePassword'
)
v - btn . mt - 2. text - none (
width = '100%'
large
color = 'primary'
dark
@ click = 'changePassword'
: loading = 'isLoading'
) { { $t ( 'auth:changePwd.proceed' ) } }
//-------------------------------------------------
//- TFA FORM
//-------------------------------------------------
v - dialog ( v - model = 'isTFAShown' , max - width = '500' , persistent )
v - card
. login - tfa . text - center . pa - 5
img ( src = '_assets/svg/icon-pin-pad.svg' )
. subtitle - 2 Enter the security code generated from your trusted device :
v - text - field . login - tfa - field . mt - 2 (
solo
flat
background - color = 'white'
hide - details
ref = 'iptTFA'
v - model = 'securityCode'
: placeholder = '$t("auth:tfa.placeholder")'
2020-07-20 04:22:29 +00:00
autocomplete = 'one-time-code'
2020-08-22 23:37:49 +00:00
@ keyup . enter = 'verifySecurityCode(false)'
)
v - btn . mt - 2. text - none (
width = '100%'
large
color = 'primary'
dark
@ click = 'verifySecurityCode(false)'
: loading = 'isLoading'
) { { $t ( 'auth:tfa.verifyToken' ) } }
//-------------------------------------------------
//- SETUP TFA FORM
//-------------------------------------------------
v - dialog ( v - model = 'isTFASetupShown' , max - width = '600' , persistent )
v - card
. login - tfa . text - center . pa - 5
. subtitle - 1. primary -- text Your administrator has required Two - Factor Authentication ( 2 FA ) to be enabled on your account .
v - divider . my - 5
. subtitle - 2 1 ) Scan the QR code below from your mobile 2 FA application :
. caption ( e . g . # [ a ( href = 'https://authy.com/' , target = '_blank' , noopener ) Authy ] , # [ a ( href = 'https://support.google.com/accounts/answer/1066447' , target = '_blank' , noopener ) Google Authenticator ] , # [ a ( href = 'https://www.microsoft.com/en-us/account/authenticator' , target = '_blank' , noopener ) Microsoft Authenticator ] , etc . )
. login - tfa - qr . mt - 5 ( v - if = 'isTFASetupShown' , v - html = 'tfaQRImage' )
. subtitle - 2. mt - 5 2 ) Enter the security code generated from your trusted device :
v - text - field . login - tfa - field . mt - 2 (
solo
flat
background - color = 'white'
hide - details
ref = 'iptTFASetup'
v - model = 'securityCode'
: placeholder = '$t("auth:tfa.placeholder")'
autocomplete = 'one-time-code'
@ keyup . enter = 'verifySecurityCode(true)'
2020-07-20 01:42:20 +00:00
)
v - btn . mt - 2. text - none (
width = '100%'
large
color = 'primary'
dark
2020-08-22 23:37:49 +00:00
@ click = 'verifySecurityCode(true)'
2020-07-20 01:42:20 +00:00
: loading = 'isLoading'
) { { $t ( 'auth:tfa.verifyToken' ) } }
2018-12-17 05:51:52 +00:00
loader ( v - model = 'isLoading' , : color = 'loaderColor' , : title = 'loaderTitle' , : subtitle = '$t(`auth:pleaseWait`)' )
2020-08-22 23:37:49 +00:00
notify ( style = 'padding-top: 64px;' )
2017-09-25 03:22:33 +00:00
< / template >
< script >
2018-03-25 02:35:47 +00:00
/* global siteConfig */
2017-10-30 01:36:05 +00:00
2020-07-03 23:36:33 +00:00
// <span>Photo by <a href="https://unsplash.com/@isaacquesada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Isaac Quesada</a> on <a href="/t/textures-patterns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></span>
2018-03-09 05:33:43 +00:00
import _ from 'lodash'
2018-10-08 04:17:31 +00:00
import Cookies from 'js-cookie'
2020-07-03 23:36:33 +00:00
import gql from 'graphql-tag'
import { sync } from 'vuex-pathify'
2018-03-09 05:33:43 +00:00
2017-09-25 03:22:33 +00:00
export default {
2018-06-17 21:29:19 +00:00
i18nOptions : { namespaces : 'auth' } ,
2020-07-05 05:36:02 +00:00
props : {
bgUrl : {
type : String ,
default : ''
} ,
hideLocal : {
type : Boolean ,
default : false
}
} ,
2018-01-10 01:41:53 +00:00
data ( ) {
2017-09-25 03:22:33 +00:00
return {
error : false ,
2017-10-01 03:47:14 +00:00
strategies : [ ] ,
2020-07-06 03:55:11 +00:00
selectedStrategyKey : 'unselected' ,
2020-07-20 04:22:29 +00:00
selectedStrategy : { key : 'unselected' , strategy : { useForm : false , usernameType : 'email' } } ,
2018-01-10 01:41:53 +00:00
screen : 'login' ,
username : '' ,
password : '' ,
2018-03-18 02:41:16 +00:00
hidePassword : true ,
2018-01-10 01:41:53 +00:00
securityCode : '' ,
2019-08-25 02:19:35 +00:00
continuationToken : '' ,
2018-10-08 04:17:31 +00:00
isLoading : false ,
2018-12-17 05:51:52 +00:00
loaderColor : 'grey darken-4' ,
loaderTitle : 'Working...' ,
2019-08-25 02:19:35 +00:00
isShown : false ,
newPassword : '' ,
2020-07-20 01:42:20 +00:00
newPasswordVerify : '' ,
2020-08-22 23:37:49 +00:00
isTFAShown : false ,
isTFASetupShown : false ,
tfaQRImage : '' ,
errorShown : false ,
errorMessage : ''
2017-09-25 03:22:33 +00:00
}
} ,
computed : {
2020-07-03 23:36:33 +00:00
activeModal : sync ( 'editor/activeModal' ) ,
2018-01-10 01:41:53 +00:00
siteTitle ( ) {
2017-09-25 03:22:33 +00:00
return siteConfig . title
2018-10-08 04:17:31 +00:00
} ,
isSocialShown ( ) {
return this . strategies . length > 1
2020-07-03 23:36:33 +00:00
} ,
2020-07-06 03:55:11 +00:00
logoUrl ( ) { return siteConfig . logoUrl } ,
filteredStrategies ( ) {
const qParams = new URLSearchParams ( window . location . search )
if ( this . hideLocal && ! qParams . has ( 'all' ) ) {
return _ . reject ( this . strategies , [ 'key' , 'local' ] )
} else {
return this . strategies
}
2020-07-20 04:22:29 +00:00
} ,
isUsernameEmail ( ) {
return this . selectedStrategy . strategy . usernameType === ` email `
2020-07-06 03:55:11 +00:00
}
2018-10-08 04:17:31 +00:00
} ,
watch : {
2020-07-06 03:55:11 +00:00
filteredStrategies ( newValue , oldValue ) {
if ( _ . head ( newValue ) . strategy . useForm ) {
this . selectedStrategyKey = _ . head ( newValue ) . key
}
2020-07-03 23:36:33 +00:00
} ,
selectedStrategyKey ( newValue , oldValue ) {
this . selectedStrategy = _ . find ( this . strategies , [ 'key' , newValue ] )
this . screen = 'login'
if ( ! this . selectedStrategy . strategy . useForm ) {
this . isLoading = true
window . location . assign ( '/login/' + newValue )
} else {
this . $nextTick ( ( ) => {
this . $refs . iptEmail . focus ( )
} )
}
2017-09-25 03:22:33 +00:00
}
2017-09-30 02:32:43 +00:00
} ,
2018-02-03 21:48:25 +00:00
mounted ( ) {
2018-10-08 04:17:31 +00:00
this . isShown = true
2018-02-03 21:48:25 +00:00
} ,
2017-09-25 03:22:33 +00:00
methods : {
2018-06-17 15:12:11 +00:00
/ * *
* LOGIN
* /
async login ( ) {
2020-08-22 23:37:49 +00:00
this . errorShown = false
2018-01-10 01:41:53 +00:00
if ( this . username . length < 2 ) {
2020-08-22 23:37:49 +00:00
this . errorMessage = this . $t ( 'auth:invalidEmailUsername' )
this . errorShown = true
2018-01-10 01:41:53 +00:00
this . $refs . iptEmail . focus ( )
} else if ( this . password . length < 2 ) {
2020-08-22 23:37:49 +00:00
this . errorMessage = this . $t ( 'auth:invalidPassword' )
this . errorShown = true
2018-01-10 01:41:53 +00:00
this . $refs . iptPassword . focus ( )
} else {
2018-12-17 05:51:52 +00:00
this . loaderColor = 'grey darken-4'
this . loaderTitle = this . $t ( 'auth:signingIn' )
2018-01-10 01:41:53 +00:00
this . isLoading = true
2018-06-17 15:12:11 +00:00
try {
2020-08-22 23:37:49 +00:00
const resp = await this . $apollo . mutate ( {
2020-07-03 23:36:33 +00:00
mutation : gql `
mutation ( $username : String ! , $password : String ! , $strategy : String ! ) {
authentication {
login ( username : $username , password : $password , strategy : $strategy ) {
responseResult {
succeeded
errorCode
slug
message
}
jwt
mustChangePwd
mustProvideTFA
2020-08-22 23:37:49 +00:00
mustSetupTFA
2020-07-03 23:36:33 +00:00
continuationToken
2020-07-19 19:13:35 +00:00
redirect
2020-08-22 23:37:49 +00:00
tfaQRImage
2020-07-03 23:36:33 +00:00
}
}
}
` ,
2018-06-17 15:12:11 +00:00
variables : {
username : this . username ,
password : this . password ,
2018-10-08 04:17:31 +00:00
strategy : this . selectedStrategy . key
2018-06-17 15:12:11 +00:00
}
} )
2018-03-10 05:58:04 +00:00
if ( _ . has ( resp , 'data.authentication.login' ) ) {
2020-08-22 23:37:49 +00:00
const respObj = _ . get ( resp , 'data.authentication.login' , { } )
2018-04-14 19:22:45 +00:00
if ( respObj . responseResult . succeeded === true ) {
2020-08-22 23:37:49 +00:00
this . handleLoginResponse ( respObj )
2018-01-10 01:41:53 +00:00
} else {
2018-04-14 19:22:45 +00:00
throw new Error ( respObj . responseResult . message )
2018-01-10 01:41:53 +00:00
}
} else {
2018-12-17 05:51:52 +00:00
throw new Error ( this . $t ( 'auth:genericError' ) )
2018-01-10 01:41:53 +00:00
}
2018-06-17 15:12:11 +00:00
} catch ( err ) {
2018-01-10 01:41:53 +00:00
console . error ( err )
2018-04-14 19:22:45 +00:00
this . $store . commit ( 'showNotification' , {
style : 'red' ,
message : err . message ,
2019-08-25 02:19:35 +00:00
icon : 'alert'
2018-01-10 01:41:53 +00:00
} )
this . isLoading = false
2018-06-17 15:12:11 +00:00
}
2018-01-10 01:41:53 +00:00
}
} ,
2018-06-17 15:12:11 +00:00
/ * *
* VERIFY TFA CODE
* /
2020-08-22 23:37:49 +00:00
async verifySecurityCode ( setup = false ) {
2018-01-10 01:41:53 +00:00
if ( this . securityCode . length !== 6 ) {
2018-04-14 19:22:45 +00:00
this . $store . commit ( 'showNotification' , {
style : 'red' ,
message : 'Enter a valid security code.' ,
2020-08-22 23:37:49 +00:00
icon : 'alert'
2018-01-10 01:41:53 +00:00
} )
2020-08-22 23:37:49 +00:00
if ( setup ) {
this . $refs . iptTFASetup . focus ( )
} else {
this . $refs . iptTFA . focus ( )
}
2018-01-10 01:41:53 +00:00
} else {
2020-08-22 23:37:49 +00:00
this . loaderColor = 'grey darken-4'
this . loaderTitle = this . $t ( 'auth:signingIn' )
2018-01-10 01:41:53 +00:00
this . isLoading = true
2020-08-22 23:37:49 +00:00
try {
const resp = await this . $apollo . mutate ( {
mutation : gql `
mutation (
$continuationToken : String !
$securityCode : String !
$setup : Boolean
) {
authentication {
loginTFA (
continuationToken : $continuationToken
securityCode : $securityCode
setup : $setup
) {
responseResult {
succeeded
errorCode
slug
message
}
jwt
mustChangePwd
continuationToken
redirect
}
2020-07-04 00:09:22 +00:00
}
}
2020-08-22 23:37:49 +00:00
` ,
variables : {
continuationToken : this . continuationToken ,
securityCode : this . securityCode ,
setup
2020-07-03 23:36:33 +00:00
}
2020-08-22 23:37:49 +00:00
} )
2018-03-10 05:58:04 +00:00
if ( _ . has ( resp , 'data.authentication.loginTFA' ) ) {
let respObj = _ . get ( resp , 'data.authentication.loginTFA' , { } )
2018-04-14 19:22:45 +00:00
if ( respObj . responseResult . succeeded === true ) {
2020-08-22 23:37:49 +00:00
this . handleLoginResponse ( respObj )
2018-01-10 01:41:53 +00:00
} else {
2020-08-22 23:37:49 +00:00
if ( ! setup ) {
this . isTFAShown = false
}
2018-04-14 19:22:45 +00:00
throw new Error ( respObj . responseResult . message )
2018-01-10 01:41:53 +00:00
}
} else {
2018-12-17 05:51:52 +00:00
throw new Error ( this . $t ( 'auth:genericError' ) )
2018-01-10 01:41:53 +00:00
}
2020-08-22 23:37:49 +00:00
} catch ( err ) {
2018-01-10 01:41:53 +00:00
console . error ( err )
2018-04-14 19:22:45 +00:00
this . $store . commit ( 'showNotification' , {
style : 'red' ,
message : err . message ,
2019-08-25 02:19:35 +00:00
icon : 'alert'
2018-01-10 01:41:53 +00:00
} )
this . isLoading = false
2020-08-22 23:37:49 +00:00
}
2018-01-10 01:41:53 +00:00
}
2018-12-21 04:02:17 +00:00
} ,
2019-08-25 02:19:35 +00:00
/ * *
* CHANGE PASSWORD
* /
async changePassword ( ) {
this . loaderColor = 'grey darken-4'
this . loaderTitle = this . $t ( 'auth:changePwd.loading' )
this . isLoading = true
const resp = await this . $apollo . mutate ( {
2020-07-03 23:36:33 +00:00
mutation : gql `
{
2020-07-04 00:09:22 +00:00
authentication {
activeStrategies {
key
}
}
2020-07-03 23:36:33 +00:00
}
` ,
2019-08-25 02:19:35 +00:00
variables : {
continuationToken : this . continuationToken ,
newPassword : this . newPassword
}
} )
if ( _ . get ( resp , 'data.authentication.loginChangePassword.responseResult.succeeded' , false ) === true ) {
this . loaderColor = 'green darken-1'
this . loaderTitle = this . $t ( 'auth:loginSuccess' )
Cookies . set ( 'jwt' , _ . get ( resp , 'data.authentication.loginChangePassword.jwt' , '' ) , { expires : 365 } )
_ . delay ( ( ) => {
window . location . replace ( '/' ) // TEMPORARY - USE RETURNURL
} , 1000 )
} else {
this . $store . commit ( 'showNotification' , {
style : 'red' ,
message : _ . get ( resp , 'data.authentication.loginChangePassword.responseResult.message' , false ) ,
icon : 'alert'
} )
this . isLoading = false
}
} ,
/ * *
* SWITCH TO FORGOT PASSWORD SCREEN
* /
forgotPassword ( ) {
2018-12-21 04:02:17 +00:00
this . screen = 'forgot'
this . $nextTick ( ( ) => {
2020-07-20 04:22:29 +00:00
this . $refs . iptForgotPwdEmail . focus ( )
2018-12-21 04:02:17 +00:00
} )
} ,
2019-08-25 02:19:35 +00:00
/ * *
* FORGOT PASSWORD SUBMIT
* /
async forgotPasswordSubmit ( ) {
2018-12-21 04:02:17 +00:00
this . $store . commit ( 'showNotification' , {
style : 'pink' ,
message : 'Coming soon!' ,
2019-08-25 02:19:35 +00:00
icon : 'ferry'
2018-12-21 04:02:17 +00:00
} )
2020-08-22 23:37:49 +00:00
} ,
handleLoginResponse ( respObj ) {
this . continuationToken = respObj . continuationToken
if ( respObj . mustChangePwd === true ) {
this . screen = 'changePwd'
this . $nextTick ( ( ) => {
this . $refs . iptNewPassword . focus ( )
} )
this . isLoading = false
} else if ( respObj . mustProvideTFA === true ) {
this . securityCode = ''
this . isTFAShown = true
setTimeout ( ( ) => {
this . $refs . iptTFA . focus ( )
} , 500 )
this . isLoading = false
} else if ( respObj . mustSetupTFA === true ) {
this . securityCode = ''
this . isTFASetupShown = true
this . tfaQRImage = respObj . tfaQRImage
setTimeout ( ( ) => {
this . $refs . iptTFASetup . focus ( )
} , 500 )
this . isLoading = false
} else {
this . loaderColor = 'green darken-1'
this . loaderTitle = this . $t ( 'auth:loginSuccess' )
Cookies . set ( 'jwt' , respObj . jwt , { expires : 365 } )
_ . delay ( ( ) => {
const loginRedirect = Cookies . get ( 'loginRedirect' )
if ( loginRedirect ) {
Cookies . remove ( 'loginRedirect' )
window . location . replace ( loginRedirect )
} else if ( respObj . redirect ) {
window . location . replace ( respObj . redirect )
} else {
window . location . replace ( '/' )
}
} , 1000 )
}
2017-09-25 03:22:33 +00:00
}
2018-06-17 15:12:11 +00:00
} ,
apollo : {
strategies : {
2020-07-03 23:36:33 +00:00
query : gql `
{
authentication {
activeStrategies {
key
strategy {
key
logo
color
icon
useForm
2020-07-20 04:22:29 +00:00
usernameType
2020-07-03 23:36:33 +00:00
}
displayName
order
selfRegistration
}
}
}
` ,
update : ( data ) => _ . sortBy ( data . authentication . activeStrategies , [ 'order' ] ) ,
2018-06-17 15:12:11 +00:00
watchLoading ( isLoading ) {
this . $store . commit ( ` loading ${ isLoading ? 'Start' : 'Stop' } ` , 'login-strategies-refresh' )
}
}
2017-09-25 03:22:33 +00:00
}
}
< / script >
2018-01-21 22:54:43 +00:00
< style lang = "scss" >
. login {
2020-07-05 05:36:02 +00:00
// background-image: url('/_assets/img/splash/1.jpg');
background - color : mc ( 'grey' , '900' ) ;
2020-07-03 23:36:33 +00:00
background - size : cover ;
background - position : center center ;
2018-01-21 22:54:43 +00:00
width : 100 % ;
height : 100 % ;
2020-07-03 23:36:33 +00:00
& - sd {
background - color : rgba ( 255 , 255 , 255 , .8 ) ;
backdrop - filter : blur ( 10 px ) ;
- webkit - backdrop - filter : blur ( 10 px ) ;
border - left : 1 px solid rgba ( 255 , 255 , 255 , .85 ) ;
border - right : 1 px solid rgba ( 255 , 255 , 255 , .85 ) ;
width : 450 px ;
height : 100 % ;
margin - left : 5 vw ;
@ at - root . no - backdropfilter & {
background - color : rgba ( 255 , 255 , 255 , .95 ) ;
2018-01-21 22:54:43 +00:00
}
2020-07-03 23:36:33 +00:00
@ include until ( $tablet ) {
margin - left : 0 ;
width : 100 % ;
2018-01-21 22:54:43 +00:00
}
}
2020-07-03 23:36:33 +00:00
& - logo {
padding : 12 px 0 0 12 px ;
width : 58 px ;
height : 58 px ;
background - color : # 222 ;
margin - left : 12 px ;
border - bottom - left - radius : 7 px ;
border - bottom - right - radius : 7 px ;
2018-01-21 22:54:43 +00:00
}
2020-07-03 23:36:33 +00:00
& - title {
height : 58 px ;
padding - left : 12 px ;
2018-01-21 22:54:43 +00:00
display : flex ;
2020-07-03 23:36:33 +00:00
align - items : center ;
text - shadow : .5 px .5 px # FFF ;
2018-01-21 22:54:43 +00:00
}
2020-07-03 23:36:33 +00:00
& - subtitle {
padding : 24 px 12 px 12 px 12 px ;
color : # 111 ;
font - weight : 500 ;
text - shadow : 1 px 1 px rgba ( 255 , 255 , 255 , .5 ) ;
background - image : linear - gradient ( to bottom , rgba ( 0 , 0 , 0 , 0 ) , rgba ( 0 , 0 , 0 , .15 ) ) ;
text - align : center ;
border - bottom : 1 px solid rgba ( 0 , 0 , 0 , .3 ) ;
2018-10-08 04:17:31 +00:00
}
2018-01-21 22:54:43 +00:00
2020-07-20 01:42:20 +00:00
& - info {
border - top : 1 px solid rgba ( 255 , 255 , 255 , .85 ) ;
background - color : rgba ( 255 , 255 , 255 , .15 ) ;
border - bottom : 1 px solid rgba ( 0 , 0 , 0 , .15 ) ;
padding : 12 px ;
font - size : 13 px ;
text - align : center ;
}
2020-07-03 23:36:33 +00:00
& - list {
border - top : 1 px solid rgba ( 255 , 255 , 255 , .85 ) ;
padding : 12 px ;
}
& - form {
padding : 12 px ;
border - top : 1 px solid rgba ( 255 , 255 , 255 , .85 ) ;
}
& - main {
flex : 1 0 100 vw ;
height : 100 vh ;
2018-01-21 22:54:43 +00:00
}
2020-07-20 01:42:20 +00:00
& - tfa {
background - color : # EEE ;
border : 7 px solid # FFF ;
& - field input {
text - align : center ;
}
2020-08-22 23:37:49 +00:00
& - qr {
background - color : # FFF ;
padding : 5 px ;
border - radius : 5 px ;
width : 200 px ;
height : 200 px ;
margin : 0 auto ;
}
2020-07-20 01:42:20 +00:00
}
2018-01-21 22:54:43 +00:00
}
< / style >