Merge branch 'feature/62-auth-v10' into 'main'
Added a hide/show password button, password complexity check See merge request discoursio/discoursio-webapp!86
This commit is contained in:
commit
384fe16671
7
public/icons/eye-off.svg
Normal file
7
public/icons/eye-off.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="512px" height="512px" viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M255.66,112c-77.94,0-157.89,45.11-220.83,135.33a16,16,0,0,0-.27,17.77C82.92,340.8,161.8,400,255.66,400,348.5,400,429,340.62,477.45,264.75a16.14,16.14,0,0,0,0-17.47C428.89,172.28,347.8,112,255.66,112Z"
|
||||
style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px" />
|
||||
<circle cx="256" cy="256" r="80" style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px" />
|
||||
<line x1="100" y1="400" x2="400" y2="100" style="stroke:#000;stroke-width:32px"/>
|
||||
</svg>
|
After Width: | Height: | Size: 618 B |
|
@ -46,6 +46,9 @@
|
|||
"Create Chat": "Create Chat",
|
||||
"Create Group": "Create a group",
|
||||
"Create account": "Create an account",
|
||||
"Password should be at least 8 characters": "Password should be at least 8 characters",
|
||||
"Password should contain at least one number": "Password should contain at least one number",
|
||||
"Password should contain at least one special character: !@#$%^&*": "Password should contain at least one special character: !@#$%^&*",
|
||||
"Create post": "Create post",
|
||||
"Date of Birth": "Date of Birth",
|
||||
"Delete": "Delete",
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
"Create Chat": "Создать чат",
|
||||
"Create Group": "Создать группу",
|
||||
"Create account": "Создать аккаунт",
|
||||
"Password should be at least 8 characters": "Пароль должен быть не менее 8 символов",
|
||||
"Password should contain at least one number": "Пароль должен содержать хотя бы одну цифру",
|
||||
"Password should contain at least one special character: !@#$%^&*": "Пароль должен содержать хотя бы один специальный символ: !@#$%^&*",
|
||||
"Create post": "Создать публикацию",
|
||||
"Date of Birth": "Дата рождения",
|
||||
"Delete": "Удалить",
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
font-weight: 700;
|
||||
padding: 1.6rem !important;
|
||||
width: 100%;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.authControl {
|
||||
|
@ -148,6 +149,10 @@
|
|||
line-height: 16px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&.registerPassword {
|
||||
margin-bottom: -32px;
|
||||
}
|
||||
|
||||
/* Red/500 */
|
||||
color: #d00820;
|
||||
|
||||
|
@ -162,6 +167,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
.passwordToggle {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.passwordToggleIcon {
|
||||
height: 1.6em;
|
||||
display: inline-block;
|
||||
margin-right: 0.2em;
|
||||
max-width: 1.4em;
|
||||
max-height: 1.4em;
|
||||
transition: filter 0.2s;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
line-height: 32px;
|
||||
|
|
|
@ -13,6 +13,7 @@ import { signSendLink } from '../../../stores/auth'
|
|||
|
||||
import { useSnackbar } from '../../../context/snackbar'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { Icon } from '../../_shared/Icon'
|
||||
|
||||
type FormFields = {
|
||||
email: string
|
||||
|
@ -30,6 +31,7 @@ export const LoginForm = () => {
|
|||
// TODO: better solution for interactive error messages
|
||||
const [isEmailNotConfirmed, setIsEmailNotConfirmed] = createSignal(false)
|
||||
const [isLinkSent, setIsLinkSent] = createSignal(false)
|
||||
const [showPassword, setShowPassword] = createSignal(false)
|
||||
|
||||
const {
|
||||
actions: { showSnackbar }
|
||||
|
@ -143,17 +145,26 @@ export const LoginForm = () => {
|
|||
<Show when={validationErrors().email}>
|
||||
<div class={styles.validationError}>{validationErrors().email}</div>
|
||||
</Show>
|
||||
|
||||
<div class="pretty-form__item">
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="password"
|
||||
type="password"
|
||||
type={showPassword() ? 'text' : 'password'}
|
||||
placeholder={t('Password')}
|
||||
onInput={(event) => handlePasswordInput(event.currentTarget.value)}
|
||||
/>
|
||||
<label for="password">{t('Password')}</label>
|
||||
<button
|
||||
type="button"
|
||||
class={styles.passwordToggle}
|
||||
onClick={() => setShowPassword(!showPassword())}
|
||||
>
|
||||
<Icon class={styles.passwordToggleIcon} name={showPassword() ? 'eye-off' : 'eye'} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Show when={validationErrors().password}>
|
||||
<div class={styles.validationError}>{validationErrors().password}</div>
|
||||
</Show>
|
||||
|
|
|
@ -44,8 +44,30 @@ export const RegisterForm = () => {
|
|||
}
|
||||
}
|
||||
|
||||
function isValidPassword(password) {
|
||||
const minLength = 8
|
||||
const hasNumber = /\d/
|
||||
const hasSpecial = /[!@#$%^&*]/
|
||||
|
||||
if (password.length < minLength) {
|
||||
return t('Password should be at least 8 characters')
|
||||
}
|
||||
if (!hasNumber.test(password)) {
|
||||
return t('Password should contain at least one number')
|
||||
}
|
||||
if (!hasSpecial.test(password)) {
|
||||
return t('Password should contain at least one special character: !@#$%^&*')
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const handlePasswordInput = (newPassword: string) => {
|
||||
setValidationErrors(({ password: _notNeeded, ...rest }) => rest)
|
||||
const passwordError = isValidPassword(newPassword)
|
||||
if (passwordError) {
|
||||
setValidationErrors((errors) => ({ ...errors, password: passwordError }))
|
||||
} else {
|
||||
setValidationErrors(({ password: _notNeeded, ...rest }) => rest)
|
||||
}
|
||||
setPassword(newPassword)
|
||||
}
|
||||
|
||||
|
@ -176,7 +198,9 @@ export const RegisterForm = () => {
|
|||
<label for="password">{t('Password')}</label>
|
||||
</div>
|
||||
<Show when={validationErrors().password}>
|
||||
<div class={styles.validationError}>{validationErrors().password}</div>
|
||||
<div class={clsx(styles.registerPassword, styles.validationError)}>
|
||||
{validationErrors().password}
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user