mirror of
https://github.com/plankanban/planka.git
synced 2025-07-18 20:59:44 +02:00
feat: Stronger password policy
This commit is contained in:
parent
9ef9c00040
commit
799f34ab68
7 changed files with 33 additions and 10 deletions
|
@ -7,6 +7,7 @@ import { useDidUpdate, usePrevious, useToggle } from '../../lib/hooks';
|
|||
import { Input, Popup } from '../../lib/custom-ui';
|
||||
|
||||
import { useForm } from '../../hooks';
|
||||
import { isPassword } from '../../utils/validator';
|
||||
|
||||
import styles from './UserPasswordEditStep.module.scss';
|
||||
|
||||
|
@ -56,7 +57,7 @@ const UserPasswordEditStep = React.memo(
|
|||
const currentPasswordField = useRef(null);
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
if (!data.password) {
|
||||
if (!data.password || !isPassword(data.password)) {
|
||||
passwordField.current.select();
|
||||
return;
|
||||
}
|
||||
|
@ -112,14 +113,18 @@ const UserPasswordEditStep = React.memo(
|
|||
)}
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<div className={styles.text}>{t('common.newPassword')}</div>
|
||||
<Input.Password
|
||||
fluid
|
||||
ref={passwordField}
|
||||
name="password"
|
||||
value={data.password}
|
||||
className={styles.field}
|
||||
onChange={handleFieldChange}
|
||||
/>
|
||||
<div className={styles.field}>
|
||||
<Input.Password
|
||||
fluid
|
||||
ref={passwordField}
|
||||
name="password"
|
||||
value={data.password}
|
||||
onChange={handleFieldChange}
|
||||
/>
|
||||
<div className={styles.note}>
|
||||
{t('common.mustBeAtLeast6CharactersLongAndContainAtLeastOneLetterAndNumber')}
|
||||
</div>
|
||||
</div>
|
||||
{usePasswordConfirmation && (
|
||||
<>
|
||||
<div className={styles.text}>{t('common.currentPassword')}</div>
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.note {
|
||||
font-size: 11px;
|
||||
margin-top: 4px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #444444;
|
||||
font-size: 12px;
|
||||
|
|
|
@ -105,6 +105,8 @@ export default {
|
|||
members: 'Members',
|
||||
minutes: 'Minutes',
|
||||
moveCard_title: 'Move Card',
|
||||
mustBeAtLeast6CharactersLongAndContainAtLeastOneLetterAndNumber:
|
||||
'Must be at least 6 characters long and contain at least one letter and number',
|
||||
name: 'Name',
|
||||
newEmail: 'New e-mail',
|
||||
newPassword: 'New password',
|
||||
|
|
|
@ -100,6 +100,8 @@ export default {
|
|||
members: 'Участники',
|
||||
minutes: 'Минуты',
|
||||
moveCard: 'Перемещение карточки',
|
||||
mustBeAtLeast6CharactersLongAndContainAtLeastOneLetterAndNumber:
|
||||
'Должен быть не менее 6 символов и содержать хотя бы одну букву и цифру',
|
||||
name: 'Имя',
|
||||
newEmail: 'Новый e-mail',
|
||||
newPassword: 'Новый пароль',
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
const PASSWORD_REGEX = /^(?=.*[A-Za-z])(?=.*\d).+$/;
|
||||
const USERNAME_REGEX = /^[a-zA-Z0-9]+((_|\.)?[a-zA-Z0-9])*$/;
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const isPassword = (string) => {
|
||||
return string.length >= 3 && PASSWORD_REGEX.test(string);
|
||||
};
|
||||
|
||||
export const isUsername = (string) => {
|
||||
return string.length >= 3 && string.length <= 16 && USERNAME_REGEX.test(string);
|
||||
};
|
||||
|
|
|
@ -16,6 +16,8 @@ module.exports = {
|
|||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
minLength: 6,
|
||||
regex: /^(?=.*[A-Za-z])(?=.*\d).+$/,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
|
|
|
@ -18,6 +18,8 @@ module.exports = {
|
|||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
minLength: 6,
|
||||
regex: /^(?=.*[A-Za-z])(?=.*\d).+$/,
|
||||
required: true,
|
||||
},
|
||||
currentPassword: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue