Files
wekan/client/components/users/userForm.css
T
Lauri Ojansivu e014d5c816 Fix #4394: Register / Forgot Password links stay hidden after a failed login
Security: with "Self Registration" and "Forgot Password" disabled in the Admin
Panel, the Register (.at-signup-link) and Forgot Password (.at-pwd-link) links
were hidden only by a one-shot jQuery .hide() in userFormsLayout.onRendered.
When a login failed (notably the LDAP "User not Found" path), useraccounts
re-rendered the form and recreated those link nodes without the inline
display:none, so the links reappeared and exposed registration / password-reset
flows that were meant to be off.

The disable state is now also reflected as a class on the stable <body>
ancestor (registration-disabled / forgotpwd-disabled) with matching CSS in
userForm.css. Because the class sits on <body>, the rule re-hides every copy of
the links that useraccounts recreates after a failed login, instead of relying
on a single inline style that the re-render dropped.

Thanks to Alsterdetektive1 and xet7.
2026-07-09 09:45:53 +03:00

184 lines
5.3 KiB
CSS

.auth-layout .at-form-landing-logo {
width: min(249px, 32vw);
margin: auto;
margin-top: 6vh;
margin-bottom: 2.5vh;
}
.auth-layout .auth-dialog {
width: min(275px, 36vw);
padding: 3vh 3vw;
margin: auto;
margin-bottom: 2.5vh;
background: #fff;
border-radius: 0.4vw;
border: 1px solid #dbdbdb;
border-bottom-color: #c2c2c2;
box-shadow: 0 0.2vh 0.8vh rgba(0,0,0,0.3);
}
.auth-layout .auth-dialog .at-form .at-link {
color: #17683a;
}
.auth-layout .auth-dialog .at-form label {
margin-bottom: 0.4vh;
}
.auth-layout .auth-dialog .at-form input {
width: 100%;
}
.password-input-container {
display: flex;
align-self: stretch;
align-items: stretch;
column-gap: 0.5rem;
}
.password-input-container input {
width: 100%;
box-sizing: border-box;
}
/* The show/hide password button is a square: its width and height match the
password input field height, and the field flex-grows to fill the space the
narrower button frees up on the right. */
.password-input-container .password-field {
flex: 1 1 auto;
min-width: 0;
}
.auth-layout .auth-dialog .at-form .password-input-container .password-toggle-btn {
position: static;
transform: none;
flex: 0 0 auto;
align-self: stretch;
aspect-ratio: 1 / 1;
width: auto;
height: auto;
min-width: 0;
padding: 0;
border: 0;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
line-height: 1;
}
.auth-layout .auth-dialog .at-form .password-input-container .password-toggle-btn .fa {
display: block;
margin: 0;
padding: 0;
line-height: 1;
vertical-align: middle;
}
.auth-layout .auth-dialog .at-form .password-input-container .password-field {
padding-inline-end: 0;
}
body.mobile-mode .password-input-container {
flex-direction: column;
align-items: stretch;
}
body.mobile-mode .auth-layout .auth-dialog .at-form .password-input-container .password-toggle-btn {
aspect-ratio: auto;
width: 100%;
}
.auth-layout .auth-dialog .at-form button {
width: 100%;
background: #216694;
color: #fff;
}
.auth-layout .auth-dialog .at-form .at-title {
background: #f7f7f7;
margin: -3vh -3vw;
padding: 2vh 3vw 0.7vh;
margin-bottom: 2.5vh;
border-bottom: 1px solid #dcdcdc;
color: #4d4d4d;
font-weight: bold;
}
.auth-layout .auth-dialog .at-form .at-signup-link,
.auth-layout .auth-dialog .at-form .at-signin-link,
.auth-layout .auth-dialog .at-form .at-forgotPwd {
font-size: 0.9em;
margin-top: 2vh;
color: #4d4d4d;
}
/* #4394 (security): when registration / forgot-password are disabled in the
Admin Panel, keep the corresponding links hidden even after useraccounts
re-renders the form on a failed login. The class lives on the stable <body>
ancestor (set in layouts.js), so this rule re-hides every recreated copy of
the link — unlike a one-shot inline display:none that the re-render dropped. */
body.registration-disabled .at-signup-link,
body.registration-disabled .at-signUp {
display: none !important;
}
body.forgotpwd-disabled .at-pwd-link,
body.forgotpwd-disabled .at-forgotPwd {
display: none !important;
}
.auth-layout .auth-dialog .at-form .at-signup-link .at-signUp,
.auth-layout .auth-dialog .at-form .at-signin-link .at-signUp,
.auth-layout .auth-dialog .at-form .at-forgotPwd .at-signUp,
.auth-layout .auth-dialog .at-form .at-signup-link .at-signIn,
.auth-layout .auth-dialog .at-form .at-signin-link .at-signIn,
.auth-layout .auth-dialog .at-form .at-forgotPwd .at-signIn {
font-weight: bold;
}
.auth-layout .auth-dialog .at-form-lang {
margin-top: 0px;
}
.auth-layout .auth-dialog .at-form-lang .select-lang {
width: 100%;
margin-top: 10px;
}
/* Auth pages (login / register) must scroll as a normal document on mobile so
the content below the form — the sign-up / sign-in link, legal notice and
language selector — is reachable, including when the on-screen keyboard is
open. body.mobile-mode otherwise locks <body> to position:fixed + 100vh (an
iOS board-view anti-bounce fix); the auth layout has no inner #content
scroller, so that lock traps the page at viewport height and the on-screen
keyboard hides the bottom. .userform-layout is added by userFormsLayout while
these pages are mounted (see layouts.js). */
body.mobile-mode.userform-layout {
position: static !important;
height: auto !important;
min-height: 100vh;
overflow-y: auto !important;
}
@media screen and (max-width: 800px) {
.auth-layout {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
/* Let the auth layout/dialog grow to their content instead of being pinned to
the viewport height, so everything below the form scrolls into view. */
body.userform-layout .auth-layout {
height: auto;
}
body.userform-layout .auth-layout .auth-dialog {
height: auto;
}
.auth-layout .at-form-landing-logo {
width: 125px;
position: absolute;
top: 0px;
inset-inline-end: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
.auth-layout .at-form-landing-logo img {
width: 125px;
}
.auth-layout .auth-dialog {
width: calc(100% - 50px);
height: calc(100% - 50px);
padding: 25px;
min-height: 380px;
margin: 0px;
margin-bottom: 0px;
border: 0px;
}
.auth-layout .auth-dialog .at-form .at-title h3 {
width: calc(100% - 125px);
overflow-x: hidden;
}
}