@ -21,11 +21,12 @@
< template >
< form ref = "loginForm"
class = "login-form"
method = "post"
name = "login"
: action = "loginActionUrl"
@ submit = "submit" >
< fieldset >
< fieldset class = "login-form__fieldset" >
< div v -if = " apacheAuthFailed "
class = "warning" >
{ { t ( 'core' , 'Server side authentication failed!' ) } } < br >
@ -52,65 +53,36 @@
<!-- the following div ensures that the spinner is always inside the # message div -- >
< div style = "clear: both;" / >
< / div >
< p class = "grouptop"
: class = "{shake: invalidPassword}" >
< input id = "user"
ref = "user"
v - model = "user"
type = "text"
name = "user"
autocapitalize = "none"
autocorrect = "off"
: autocomplete = "autoCompleteAllowed ? 'on' : 'off'"
: placeholder = "t('core', 'Username or email')"
: aria - label = "t('core', 'Username or email')"
required
@ change = "updateUsername" >
< label for = "user" class = "infield" > { { t ( 'core' , 'Username or email' ) } } < / label >
< / p >
< p class = "groupbottom"
: class = "{shake: invalidPassword}" >
< input id = "password"
ref = "password"
: type = "passwordInputType"
class = "password-with-toggle"
name = "password"
autocorrect = "off"
autocapitalize = "none"
: autocomplete = "autoCompleteAllowed ? 'current-password' : 'off'"
: placeholder = "t('core', 'Password')"
: aria - label = "t('core', 'Password')"
required >
< label for = "password"
class = "infield" > { { t ( 'core' , 'Password' ) } } < / label >
< NcButton class = "toggle-password"
type = "tertiary-no-background"
: aria - label = "isPasswordHidden ? t('core', 'Show password') : t('core', 'Hide password')"
@ click . stop . prevent = "togglePassword" >
< template # icon >
< Eye v -if = " isPasswordHidden " :size ="20" / >
< EyeOff v -else :size ="20" / >
< / template >
< / NcButton >
< / p >
< NcTextField id = "user"
: label = "t('core', 'Username or email')"
: labelVisible = "true"
ref = "user"
name = "user"
: class = "{shake: invalidPassword}"
: value . sync = "user"
autocapitalize = "none"
: spellchecking = "false"
: autocomplete = "autoCompleteAllowed ? 'username' : 'off'"
: aria - label = "t('core', 'Username or email')"
required
@ change = "updateUsername" / >
< NcPasswordField id = "password"
ref = "password"
name = "password"
: labelVisible = "true"
: class = "{shake: invalidPassword}"
: value . sync = "password"
: spellchecking = "false"
autocapitalize = "none"
: autocomplete = "autoCompleteAllowed ? 'current-password' : 'off'"
: label = "t('core', 'Password')"
: helperText = "errorLabel"
: error = "isError"
required / >
< LoginButton :loading ="loading" / >
< p v -if = " invalidPassword "
class = "warning wrongPasswordMsg" >
{ { t ( 'core' , 'Wrong username or password.' ) } }
< / p >
< p v -else -if = " userDisabled "
class = "warning userDisabledMsg" >
{ { t ( 'core' , 'User disabled' ) } }
< / p >
< p v -if = " throttleDelay & & throttleDelay > 5000 "
class = "warning throttledMsg" >
{ { t ( 'core' , 'We have detected multiple invalid login attempts from your IP. Therefore your next login is throttled up to 30 seconds.' ) } }
< / p >
< input v -if = " redirectUrl "
type = "hidden"
name = "redirect_url"
@ -136,7 +108,9 @@
import jstz from 'jstimezonedetect'
import { generateUrl , imagePath } from '@nextcloud/router'
import NcButton from '@nextcloud/vue/dist/Components/NcButton'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcPasswordField from '@nextcloud/vue/dist/Components/NcPasswordField.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import Eye from 'vue-material-design-icons/Eye'
import EyeOff from 'vue-material-design-icons/EyeOff'
@ -150,6 +124,8 @@ export default {
Eye ,
EyeOff ,
LoginButton ,
NcPasswordField ,
NcTextField ,
} ,
props : {
@ -190,11 +166,26 @@ export default {
timezoneOffset : ( - new Date ( ) . getTimezoneOffset ( ) / 60 ) ,
user : this . username ,
password : '' ,
passwordInputType : 'password' ,
}
} ,
computed : {
isError ( ) {
return this . invalidPassword || this . userDisabled
|| ( this . throttleDelay && this . throttleDelay > 5000 )
} ,
errorLabel ( ) {
if ( this . invalidPassword ) {
return t ( 'core' , 'Wrong username or password.' )
}
if ( this . userDisabled ) {
return t ( 'core' , 'User disabled' )
}
if ( this . throttleDelay && this . throttleDelay > 5000 ) {
return t ( 'core' , 'We have detected multiple invalid login attempts from your IP. Therefore your next login is throttled up to 30 seconds.' )
}
return undefined ;
} ,
apacheAuthFailed ( ) {
return this . errors . indexOf ( 'apacheAuthFailed' ) !== - 1
} ,
@ -213,9 +204,6 @@ export default {
loginActionUrl ( ) {
return generateUrl ( 'login' )
} ,
isPasswordHidden ( ) {
return this . passwordInputType === 'password'
} ,
} ,
mounted ( ) {
@ -227,13 +215,6 @@ export default {
} ,
methods : {
togglePassword ( ) {
if ( this . passwordInputType === 'password' ) {
this . passwordInputType = 'text'
} else {
this . passwordInputType = 'password'
}
} ,
updateUsername ( ) {
this . $emit ( 'update:username' , this . user )
} ,
@ -246,10 +227,15 @@ export default {
< / script >
< style lang = "scss" scoped >
. toggle - password {
position : absolute ;
top : 2 px ;
right : 10 px ;
color : var ( -- color - text - lighter ) ;
. login - form {
text - align : left ;
font - size : 1 rem ;
& _ _fieldset {
width : 100 % ;
display : flex ;
flex - direction : column ;
gap : 1 rem ;
}
}
< / style >