0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

Merge pull request #4444 from logto-io/gao-sync-latest-content

This commit is contained in:
Gao Sun 2023-09-07 21:20:44 +08:00 committed by GitHub
commit ae262d77e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
69 changed files with 455 additions and 306 deletions

View file

@ -271,18 +271,11 @@ const traverseNode = async (
if (Array.isArray(value)) {
const [phrase] = value;
// If the key exists in the target language and the value is a string,
// use the value of the target language and inherit the untranslated
// mark; otherwise, use the value of the baseline language and add a
// comment to indicate that the phrase is untranslated to help identify
// missing translations.
if (Array.isArray(existingValue)) {
if (!existingValue[1]) {
await fs.appendFile(
targetFilePath,
`${' '.repeat(tabSize)}/** ${untranslatedMark} */\n`
);
}
// If the key exists in the target language and the value is a translated
// string, use the value of the target language; otherwise, use the value
// of the baseline language and add a comment to indicate that the phrase
// is untranslated to help identify missing translations.
if (Array.isArray(existingValue) && existingValue[1]) {
await fs.appendFile(
targetFilePath,
`${' '.repeat(tabSize)}${key}: ${existingValue[0]},\n`

View file

@ -2,7 +2,7 @@ import { PasswordPolicyChecker } from '@logto/core-kit';
import { cond } from '@silverhand/essentials';
import { type ChangeEvent, type ReactNode } from 'react';
import { Controller, type FieldPath, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import PageMeta from '@/components/PageMeta';
import Card from '@/ds-components/Card';
@ -11,6 +11,7 @@ import FormField from '@/ds-components/FormField';
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
import TabWrapper from '@/ds-components/TabWrapper';
import NumericInput from '@/ds-components/TextInput/NumericInput';
import TextLink from '@/ds-components/TextLink';
import Textarea from '@/ds-components/Textarea';
import { type SignInExperienceForm } from '../../types';
@ -76,7 +77,13 @@ function PasswordPolicy({ isActive }: Props) {
<div className={commonStyles.title}>{t('password_requirements')}</div>
<FormField title="sign_in_exp.password_policy.minimum_length">
<div className={commonStyles.formFieldDescription}>
{t('minimum_length_description', { max })}
<Trans
components={{
a: <TextLink href="https://pages.nist.gov/800-63-3/sp800-63b.html#sec5" />,
}}
>
{t('minimum_length_description', { max })}
</Trans>
</div>
<Controller
name="passwordPolicy.length.min"
@ -143,23 +150,26 @@ function PasswordPolicy({ isActive }: Props) {
</Card>
<Card>
<div className={commonStyles.title}>{t('password_rejection')}</div>
<FormField title="sign_in_exp.password_policy.forbidden_passwords">
<FormField title="sign_in_exp.password_policy.compromised_passwords">
<PasswordOption
name="passwordPolicy.rejects.pwned"
title={t('breached_passwords')}
description={t('breached_passwords_description')}
/>
</FormField>
<FormField title="sign_in_exp.password_policy.restricted_phrases_in_passwords">
<FormField
title="sign_in_exp.password_policy.restricted_phrases"
tip={t('restricted_phrases_tooltip')}
>
<PasswordOption
name="passwordPolicy.rejects.repetitionAndSequence"
title={t('repetitive_or_sequential_characters')}
description={t('repetitive_or_sequential_characters_description')}
/>
<PasswordOption
name="passwordPolicy.rejects.personalInfo"
title={t('personal_information')}
description={t('personal_information_description')}
name="passwordPolicy.rejects.userInfo"
title={t('user_information')}
description={t('user_information_description')}
/>
<PasswordOption
name="passwordPolicy.isCustomWordsEnabled"

View file

@ -63,10 +63,17 @@ const description = {
verify_email: 'Bestätige deine E-Mail-Adresse',
verify_phone: 'Bestätige deine Telefonnummer',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -59,9 +59,13 @@ const description = {
no_region_code_found: 'No region code found',
verify_email: 'Verify your email',
verify_phone: 'Verify your phone number',
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
password_requirements: 'Password {{items, list}}.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -9,7 +9,7 @@ const password_rejected = {
restricted_found: 'Avoid overusing {{list, list}}.',
'restricted.repetition': 'repeated characters',
'restricted.sequence': 'sequential characters',
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
'restricted.words': 'product context',
} satisfies Record<PasswordRejectionCode, string> & {
// Use for displaying a list of restricted issues

View file

@ -61,10 +61,17 @@ const description = {
verify_email: 'Verificar su correo electrónico',
verify_phone: 'Verificar su número de teléfono',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -63,10 +63,17 @@ const description = {
verify_email: 'Vérifiez votre e-mail',
verify_phone: 'Vérifiez votre numéro de téléphone',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -59,10 +59,17 @@ const description = {
verify_email: 'Verifica la tua email',
verify_phone: 'Verifica il tuo numero di telefono',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -61,10 +61,17 @@ const description = {
verify_email: 'Eメールを確認する',
verify_phone: '電話番号を確認する',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -56,10 +56,17 @@ const description = {
verify_email: '이메일 인증',
verify_phone: '휴대전화번호 인증',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -59,10 +59,17 @@ const description = {
verify_email: 'Potwierdź swój email',
verify_phone: 'Potwierdź swój numer telefonu',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -58,10 +58,17 @@ const description = {
verify_email: 'Verificar e-mail',
verify_phone: 'Verificar número de telefone',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -58,10 +58,17 @@ const description = {
verify_email: 'Verifique o seu email',
verify_phone: 'Verifique o seu número de telefone',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -62,10 +62,17 @@ const description = {
verify_email: 'Подтвердите Ваш электронный адрес',
verify_phone: 'Подтвердите свой номер телефона',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -59,10 +59,17 @@ const description = {
verify_email: 'E-postanızın doğrulanması',
verify_phone: 'Telefon numaranızın doğrulanması',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -52,10 +52,17 @@ const description = {
verify_email: '验证你的邮箱',
verify_phone: '验证你的手机号',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -52,10 +52,17 @@ const description = {
verify_email: '驗證你的郵箱',
verify_phone: '驗證你的手機號',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -52,10 +52,17 @@ const description = {
verify_email: '驗證你的郵箱',
verify_phone: '驗證你的手機號碼',
/** UNTRANSLATED */
password_requirements_with_type_one: 'Password requires a minimum of {{min}} characters.',
password_requirements: 'Password {{items, list}}.',
/** UNTRANSLATED */
password_requirements_with_type_other:
'Password requires a minimum of {{min}} characters, and contains {{count}} of the following: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and symbols.',
'password_requirement.length_one': 'requires a minimum of {{count}} character',
/** UNTRANSLATED */
'password_requirement.length_other': 'requires a minimum of {{count}} characters',
/** UNTRANSLATED */
'password_requirement.character_types_one':
'should contain at least {{count}} type of uppercase letters, lowercase letters, digits, and symbols',
/** UNTRANSLATED */
'password_requirement.character_types_other':
'should contain at least {{count}} types of uppercase letters, lowercase letters, digits, and symbols',
};
export default Object.freeze(description);

View file

@ -16,7 +16,7 @@ const password_rejected = {
/** UNTRANSLATED */
'restricted.sequence': 'sequential characters',
/** UNTRANSLATED */
'restricted.personal_info': 'your personal information',
'restricted.user_info': 'your personal information',
/** UNTRANSLATED */
'restricted.words': 'product context',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'Die Verschlüsselungsmethode {{name}} wird nicht unterstützt.',
pepper_not_found: 'Password pepper not found. Please check your core envs.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -1,7 +1,7 @@
const password = {
unsupported_encryption_method: 'The encryption method {{name}} is not supported.',
pepper_not_found: 'Password pepper not found. Please check your core envs.',
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -2,25 +2,25 @@ const password_policy = {
password_requirements: 'Password requirements',
minimum_length: 'Minimum length',
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
minimum_required_char_types: 'Minimum required character types',
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
password_rejection: 'Password rejection',
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
breached_passwords: 'Breached passwords',
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
restricted_phrases: 'Restrict low-security phrases',
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
personal_information: 'Personal information',
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
user_information: 'User information',
user_information_description: 'E.g., email address, phone number, username, etc.',
custom_words: 'Custom words',
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'El método de encriptación {{name}} no es compatible.',
pepper_not_found: 'No se encontró el password pepper. Por favor revisa tus variables de entorno.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -3,7 +3,7 @@ const password = {
pepper_not_found:
'Mot de passe pepper non trouvé. Veuillez vérifier votre environnement de base.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'Il metodo di crittografia {{name}} non è supportato.',
pepper_not_found: 'Pepper password non trovato. Per favore controlla le tue env di core.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '暗号化方式 {{name}} はサポートされていません。',
pepper_not_found: 'パスワードペッパーが見つかりません。コアの環境を確認してください。',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '{{name}} 암호화 방법을 지원하지 않아요.',
pepper_not_found: '비밀번호 Pepper를 찾을 수 없어요. Core 환경설정을 확인해 주세요.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'Metoda szyfrowania {{name}} nie jest obsługiwana.',
pepper_not_found: 'Nie znaleziono wartości pepper dla hasła. Sprawdź swoje zmienne środowiskowe.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'O método de criptografia {{name}} não é suportado.',
pepper_not_found: 'Password pepper não encontrada. Por favor, verifique seus envs principais.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'O método de enncriptação {{name}} não é suportado.',
pepper_not_found: 'pepper da Password não encontrada. Por favor, verifique os envs.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: 'Метод шифрования {{name}} не поддерживается.',
pepper_not_found: 'Не найден пепер пароля. Пожалуйста, проверьте ваши основные envs.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '{{name}} şifreleme metodu desteklenmiyor.',
pepper_not_found: 'Şifre pepperı bulunamadı. Lütfen core envs.i kontrol edin.',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '不支持的加密方法 {{name}}',
pepper_not_found: '密码 pepper 未找到。请检查 core 的环境变量。',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '不支持的加密方法 {{name}}',
pepper_not_found: '密碼 pepper 未找到。請檢查 core 的環境變量。',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -2,7 +2,7 @@ const password = {
unsupported_encryption_method: '不支持的加密方法 {{name}}',
pepper_not_found: '密碼 pepper 未找到。請檢查 core 的環境變數。',
/** UNTRANSLATED */
rejected: 'Password rejected. Please check your password meets the requirements.',
rejected: 'Password rejected. Please check if your password meets the requirements.',
};
export default Object.freeze(password);

View file

@ -5,39 +5,40 @@ const password_policy = {
minimum_length: 'Minimum length',
/** UNTRANSLATED */
minimum_length_description:
'NIST recommends a minimum of 8 characters for web products. The maximum length is fixed at {{max}} characters.',
'NIST suggests using <a>at least 8 characters</a> for web products. The maximum length is {{max}}.',
/** UNTRANSLATED */
minimum_length_error: 'Minimum length must be between {{min}} and {{max}} (inclusive).',
/** UNTRANSLATED */
minimum_required_char_types: 'Minimum required character types',
/** UNTRANSLATED */
minimum_required_char_types_description:
'The four character types are lowercase letters (a-z), uppercase letters (A-Z), numbers (0-9), and special characters ({{symbols}}).',
'Lowercase letters (A-Z), uppercase letters (a-z), numbers (0-9), and special characters ({{symbols}}) are all.',
/** UNTRANSLATED */
password_rejection: 'Password rejection',
/** UNTRANSLATED */
forbidden_passwords: 'Forbidden passwords',
compromised_passwords: 'Reject compromised password',
/** UNTRANSLATED */
breached_passwords: 'Breached passwords',
/** UNTRANSLATED */
breached_passwords_description:
'Prevent users from using passwords that have been breached in other systems.',
breached_passwords_description: 'Reject passwords previously found in breach databases.',
/** UNTRANSLATED */
restricted_phrases_in_passwords: 'Restricted phrases in passwords',
restricted_phrases: 'Restrict low-security phrases',
/** UNTRANSLATED */
restricted_phrases_tooltip:
'Users cannot use passwords that are exactly the same as or made up of the listed phrases below. The addition of 3 or more non-consecutive characters is allowed to increase password complexity.',
/** UNTRANSLATED */
repetitive_or_sequential_characters: 'Repetitive or sequential characters',
/** UNTRANSLATED */
repetitive_or_sequential_characters_description: "For example, 'aaaaa' or '12345'",
repetitive_or_sequential_characters_description: 'E.g., "AAAA", "1234", and "abcd".',
/** UNTRANSLATED */
personal_information: 'Personal information',
user_information: 'User information',
/** UNTRANSLATED */
personal_information_description:
'Email address, phone number, username, first name, last name, etc.',
user_information_description: 'E.g., email address, phone number, username, etc.',
/** UNTRANSLATED */
custom_words: 'Custom words',
/** UNTRANSLATED */
custom_words_description:
'Customize the list of words to reject. Enter one word per line. Words are case-insensitive.',
'Personalize context-specific words, case-insensitive, and one per line.',
/** UNTRANSLATED */
custom_words_placeholder: 'Your service name, company name, etc.',
};

View file

@ -39,7 +39,7 @@ describe('PasswordPolicyChecker -> check()', () => {
rejects: {
pwned: true,
repetitionAndSequence: true,
personalInfo: true,
userInfo: true,
words: ['test', 'aaaa'],
},
});
@ -60,7 +60,7 @@ describe('PasswordPolicyChecker -> check()', () => {
{ code: 'password_rejected.character_types', interpolation: { min: 2 } },
{ code: 'password_rejected.pwned' },
{ code: 'password_rejected.restricted.sequence' },
{ code: 'password_rejected.restricted.personal_info' },
{ code: 'password_rejected.restricted.user_info' },
]);
expect(await checker.check('aaaaaatest😀', {})).toEqual([
@ -79,12 +79,12 @@ describe('PasswordPolicyChecker -> checkCharTypes()', () => {
const checker1 = new PasswordPolicyChecker({
length: { min: 1, max: 256 },
characterTypes: { min: 2 },
rejects: { pwned: false, repetitionAndSequence: false, personalInfo: false, words: [] },
rejects: { pwned: false, repetitionAndSequence: false, userInfo: false, words: [] },
});
const checker2 = new PasswordPolicyChecker({
length: { min: 1, max: 256 },
characterTypes: { min: 4 },
rejects: { pwned: false, repetitionAndSequence: false, personalInfo: false, words: [] },
rejects: { pwned: false, repetitionAndSequence: false, userInfo: false, words: [] },
});
it('should reject unsupported characters', () => {
@ -108,7 +108,7 @@ describe('PasswordPolicyChecker -> hasBeenPwned()', () => {
const checker = new PasswordPolicyChecker({
length: { min: 1, max: 256 },
characterTypes: { min: 2 },
rejects: { pwned: true, repetitionAndSequence: false, personalInfo: false, words: [] },
rejects: { pwned: true, repetitionAndSequence: false, userInfo: false, words: [] },
});
mockPwnResponse();
@ -141,33 +141,33 @@ describe('PasswordPolicyChecker -> hasRepetition()', () => {
});
});
describe('PasswordPolicyChecker -> hasPersonalInfo()', () => {
describe('PasswordPolicyChecker -> hasUserInfo()', () => {
const checker = new PasswordPolicyChecker({
rejects: { pwned: false, repetitionAndSequence: false, personalInfo: true, words: [] },
rejects: { pwned: false, repetitionAndSequence: false, userInfo: true, words: [] },
});
it('should reject password with name', () => {
expect(checker.hasPersonalInfo('test', { name: 'test' })).toBe(true);
expect(checker.hasPersonalInfo('test', { name: 'test2' })).toBe(false);
expect(checker.hasPersonalInfo('FOO', { name: 'Foo bar' })).toBe(true);
expect(checker.hasPersonalInfo('Foo', { name: 'bar fOo' })).toBe(true);
expect(checker.hasUserInfo('test', { name: 'test' })).toBe(true);
expect(checker.hasUserInfo('test', { name: 'test2' })).toBe(false);
expect(checker.hasUserInfo('FOO', { name: 'Foo bar' })).toBe(true);
expect(checker.hasUserInfo('Foo', { name: 'bar fOo' })).toBe(true);
});
it('should reject password with username', () => {
expect(checker.hasPersonalInfo('123.456!test', { username: 'teST' })).toBe(true);
expect(checker.hasPersonalInfo('test', { username: 'test2' })).toBe(false);
expect(checker.hasUserInfo('123.456!test', { username: 'teST' })).toBe(true);
expect(checker.hasUserInfo('test', { username: 'test2' })).toBe(false);
});
it('should reject password with email', () => {
expect(checker.hasPersonalInfo('teST', { email: 'test@foo.com' })).toBe(true);
expect(checker.hasPersonalInfo('TEST', { email: 'test1@foo.com' })).toBe(false);
expect(checker.hasPersonalInfo('FOO', { email: 'test@foo.com' })).toBe(false);
expect(checker.hasPersonalInfo('Foo', { email: 'fOO@foo.com' })).toBe(true);
expect(checker.hasUserInfo('teST', { email: 'test@foo.com' })).toBe(true);
expect(checker.hasUserInfo('TEST', { email: 'test1@foo.com' })).toBe(false);
expect(checker.hasUserInfo('FOO', { email: 'test@foo.com' })).toBe(false);
expect(checker.hasUserInfo('Foo', { email: 'fOO@foo.com' })).toBe(true);
});
it('should reject password with phone number', () => {
expect(checker.hasPersonalInfo('teST1234567890.', { phoneNumber: '123456789' })).toBe(true);
expect(checker.hasPersonalInfo('TEST12345678', { phoneNumber: '123456789' })).toBe(false);
expect(checker.hasUserInfo('teST1234567890.', { phoneNumber: '123456789' })).toBe(true);
expect(checker.hasUserInfo('TEST12345678', { phoneNumber: '123456789' })).toBe(false);
});
});
@ -178,7 +178,7 @@ describe('PasswordPolicyChecker -> hasWords()', () => {
rejects: {
pwned: false,
repetitionAndSequence: false,
personalInfo: false,
userInfo: false,
words: ['test', 'teSt2', 'TesT3'],
},
});
@ -199,7 +199,7 @@ describe('PasswordPolicyChecker -> hasSequentialChars()', () => {
const checker = new PasswordPolicyChecker({
length: { min: 1, max: 256 },
characterTypes: { min: 2 },
rejects: { pwned: false, repetitionAndSequence: true, personalInfo: false, words: [] },
rejects: { pwned: false, repetitionAndSequence: true, userInfo: false, words: [] },
});
it('should reject password with too many sequential characters', () => {

View file

@ -28,8 +28,8 @@ export type PasswordPolicy = {
pwned: boolean;
/** Whether to reject passwords that like '123456' or 'aaaaaa'. */
repetitionAndSequence: boolean;
/** Whether to reject passwords that include personal information. */
personalInfo: boolean;
/** Whether to reject passwords that include current user information. */
userInfo: boolean;
/** Whether to reject passwords that include specific words. */
words: string[];
};
@ -52,7 +52,7 @@ export const passwordPolicyGuard = z.object({
.object({
pwned: z.boolean().default(true),
repetitionAndSequence: z.boolean().default(true),
personalInfo: z.boolean().default(true),
userInfo: z.boolean().default(true),
words: z.string().array().default([]),
})
.default({}),
@ -67,7 +67,7 @@ export type PasswordRejectionCode =
| 'pwned'
| 'restricted.repetition'
| 'restricted.sequence'
| 'restricted.personal_info'
| 'restricted.user_info'
| 'restricted.words';
/** A password issue that does not meet the policy. */
@ -78,8 +78,8 @@ export type PasswordIssue<Code extends PasswordRejectionCode = PasswordRejection
interpolation?: Record<string, unknown>;
};
/** Personal information to check. */
export type PersonalInfo = Partial<{
/** User information to check. */
export type UserInfo = Partial<{
name: string;
username: string;
email: string;
@ -125,15 +125,15 @@ export class PasswordPolicyChecker {
* Check if a password meets all the policy requirements.
*
* @param password - Password to check.
* @param personalInfo - Personal information to check. Required if the policy
* requires to reject passwords that include personal information.
* @param userInfo - User information to check. Required if the policy
* requires to reject passwords that include user information.
* @returns An array of issues. If the password meets the policy, an empty array will be returned.
* @throws TypeError - If the policy requires to reject passwords that include personal information
* but the personal information is not provided.
* @throws TypeError - If the policy requires to reject passwords that include user information
* but the user information is not provided.
*/
/* eslint-disable @silverhand/fp/no-mutating-methods */
async check(password: string, personalInfo?: PersonalInfo): Promise<PasswordIssue[]> {
async check(password: string, userInfo?: UserInfo): Promise<PasswordIssue[]> {
const issues: PasswordIssue[] = this.fastCheck(password);
if (this.policy.rejects.pwned && (await this.hasBeenPwned(password))) {
@ -165,14 +165,14 @@ export class PasswordPolicyChecker {
});
}
if (this.policy.rejects.personalInfo) {
if (!personalInfo) {
throw new TypeError('Personal information is required to check personal information.');
if (this.policy.rejects.userInfo) {
if (!userInfo) {
throw new TypeError('User information is required to check user information.');
}
if (this.hasPersonalInfo(password, personalInfo)) {
if (this.hasUserInfo(password, userInfo)) {
issues.push({
code: 'password_rejected.restricted.personal_info',
code: 'password_rejected.restricted.user_info',
});
}
}
@ -283,15 +283,15 @@ export class PasswordPolicyChecker {
}
/**
* Check if the given password contains personal information.
* Check if the given password contains user information.
*
* @param password - Password to check.
* @param personalInfo - Personal information to check.
* @returns Whether the password contains personal information.
* @param userInfo - User information to check.
* @returns Whether the password contains user information.
*/
hasPersonalInfo(password: string, personalInfo: PersonalInfo): boolean {
hasUserInfo(password: string, userInfo: UserInfo): boolean {
const lowercasedPassword = password.toLowerCase();
const { name, username, email, phoneNumber } = personalInfo;
const { name, username, email, phoneNumber } = userInfo;
if (
name

View file

@ -1,4 +1,5 @@
import type { TFuncKey } from 'i18next';
import { type ReactElement } from 'react';
import DynamicT from '@/components/DynamicT';
import NavBar from '@/components/NavBar';
@ -11,7 +12,7 @@ import * as styles from './index.module.scss';
type Props = {
title: TFuncKey;
description?: TFuncKey;
description?: TFuncKey | ReactElement;
titleProps?: Record<string, unknown>;
descriptionProps?: Record<string, unknown>;
notification?: TFuncKey;
@ -42,7 +43,11 @@ const SecondaryPageLayout = ({
</div>
{description && (
<div className={styles.description}>
<DynamicT forKey={description} interpolation={descriptionProps} />
{typeof description === 'string' ? (
<DynamicT forKey={description} interpolation={descriptionProps} />
) : (
description
)}
</div>
)}
</div>

View file

@ -1,5 +1,6 @@
import { PasswordPolicyChecker, passwordPolicyGuard } from '@logto/core-kit';
import { SignInIdentifier } from '@logto/schemas';
import { condArray } from '@silverhand/essentials';
import { useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@ -39,9 +40,30 @@ export const usePasswordPolicy = () => {
);
const policyChecker = useMemo(() => new PasswordPolicyChecker(policy), [policy]);
const requirementsDescription = useMemo(
() =>
t('description.password_requirements', {
items: condArray(
// There's no need to show the length requirement if it can be satisfied by the character types
policy.length.min > policy.characterTypes.min &&
t('description.password_requirement.length', { count: policy.length.min }),
// Show the character types requirement if:
// - It's greater than 1, or;
// - The length requirement is equal to or less than 1 (since the length requirement will be hidden in this case)
(policy.characterTypes.min > 1 || policy.length.min <= 1) &&
t('description.password_requirement.character_types', {
count: policy.characterTypes.min,
})
),
}),
[t, policy.length.min, policy.characterTypes.min]
);
return {
policy,
policyChecker,
/** The localized description of the password policy. */
requirementsDescription,
};
};

View file

@ -47,12 +47,13 @@ const SetPassword = () => {
length: { min },
characterTypes: { min: count },
},
requirementsDescription,
} = usePasswordPolicy();
return (
<SecondaryPageLayout
title="description.set_password"
description="description.password_requirements_with_type"
description={<span>{requirementsDescription}</span>}
descriptionProps={{ min, count }}
>
<SetPasswordForm

View file

@ -49,6 +49,7 @@ const RegisterPassword = () => {
length: { min },
characterTypes: { min: count },
},
requirementsDescription,
} = usePasswordPolicy();
if (!signUpMethods.includes(SignInIdentifier.Username)) {
@ -58,7 +59,7 @@ const RegisterPassword = () => {
return (
<SecondaryPageLayout
title="description.new_password"
description="description.password_requirements_with_type"
description={<span>{requirementsDescription}</span>}
descriptionProps={{ min, count }}
>
<SetPassword

View file

@ -53,12 +53,13 @@ const ResetPassword = () => {
length: { min },
characterTypes: { min: count },
},
requirementsDescription,
} = usePasswordPolicy();
return (
<SecondaryPageLayout
title="description.new_password"
description="description.password_requirements_with_type"
description={<span>{requirementsDescription}</span>}
descriptionProps={{ min, count }}
>
<SetPassword