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:
Igor 2023-05-11 17:20:40 +00:00
commit 384fe16671
6 changed files with 76 additions and 3 deletions

7
public/icons/eye-off.svg Normal file
View 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

View File

@ -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",

View File

@ -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": "Удалить",

View File

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

View File

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

View File

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