├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── UPGRADE.md ├── composer.json └── src ├── Resources └── translations │ ├── validators.bg.xlf │ ├── validators.cs.xlf │ ├── validators.de.xlf │ ├── validators.en.xlf │ ├── validators.es.xlf │ ├── validators.fr.xlf │ ├── validators.it.xlf │ ├── validators.ja.xlf │ ├── validators.nl.xlf │ ├── validators.pl.xlf │ ├── validators.pt_BR.xlf │ ├── validators.ru.xlf │ ├── validators.sk.xlf │ └── validators.th.xlf └── Validator └── Constraints ├── PasswordRequirements.php ├── PasswordRequirementsValidator.php ├── PasswordStrength.php └── PasswordStrengthValidator.php /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | This project's code-of-conduct can be found at https://github.com/rollerworks/contributing/blob/master/CODE_OF_CONDUCT.md 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-present Sebastiaan Stok 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rollerworks PasswordStrengthValidator 2 | ===================================== 3 | 4 | This package provides various password strength validators for the [Symfony Validator 5 | component](http://symfony.com/doc/current/components/validator.html). 6 | 7 | _To use this bundle with a Symfony application use the [RollerworksPasswordStrengthBundle][1]._ 8 | 9 | Passwords can be validated using either strength-levels (weak, medium, strong etc) 10 | or by configuring explicit requirements (needs letters, numbers etc). 11 | 12 | > This library provides the same level of functionality as the 13 | > [PasswordStrengthBundle](https://github.com/jbafford/PasswordStrengthBundle) created by John Bafford. 14 | 15 | ## Installation 16 | 17 | To install this package, add `rollerworks/password-strength-validator` to your composer.json: 18 | 19 | ```bash 20 | $ php composer.phar require rollerworks/password-strength-validator 21 | ``` 22 | 23 | Now, [Composer][2] will automatically download all required files, and install them 24 | for you. 25 | 26 | ## Requirements 27 | 28 | You need at least PHP PHP 8.2 and Symfony 6, mbstring is recommended but not required. 29 | 30 | ## Basic Usage 31 | 32 | **Caution:** 33 | 34 | > The password validators do not enforce that the field must have a value! 35 | > To make a field "required" use the [NotBlank constraint](http://symfony.com/doc/current/reference/constraints/NotBlank.html) 36 | > in combination with the password validator(s). 37 | 38 | All examples assume you have the Composer autoloader already in your code, 39 | see also [How to Install and Use the Symfony Components](http://symfony.com/doc/current/components/using_components.html) 40 | for more information. 41 | 42 | ### [Strength validation](docs/strength-validation.md) 43 | 44 | Validates the passwords strength-level (weak, medium, strong etc). 45 | 46 | ### [Requirements validation](docs/requirements-validation.md) 47 | 48 | Validates the passwords using explicitly configured requirements (letters, caseDiff, numbers, requireSpecialCharacter). 49 | 50 | ## Versioning 51 | 52 | For transparency and insight into the release cycle, and for striving 53 | to maintain backward compatibility, this package is maintained under 54 | the Semantic Versioning guidelines as much as possible. 55 | 56 | Releases will be numbered with the following format: 57 | 58 | `..` 59 | 60 | And constructed with the following guidelines: 61 | 62 | * Breaking backward compatibility bumps the major (and resets the minor and patch) 63 | * New additions without breaking backward compatibility bumps the minor (and resets the patch) 64 | * Bug fixes and misc changes bumps the patch 65 | 66 | For more information on SemVer, please visit . 67 | 68 | ## License 69 | 70 | This library is released under the [MIT license](LICENSE). 71 | 72 | ## Contributing 73 | 74 | This is an open source project. If you'd like to contribute, 75 | please read the [Contributing Guidelines][3]. If you're submitting 76 | a pull request, please follow the guidelines in the [Submitting a Patch][4] section. 77 | 78 | [1]: https://github.com/rollerworks/PasswordStrengthBundle 79 | [2]: https://getcomposer.org/doc/00-intro.md 80 | [3]: https://github.com/rollerworks/contributing 81 | [4]: https://contributing.readthedocs.org/en/latest/code/patches.html 82 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | UPGRADE 2 | ======= 3 | 4 | ## Upgrade from 1.7 to 2.0 5 | 6 | * The blacklist validator was removed. 7 | 8 | Use the [NotCompromisedPassword](https://symfony.com/doc/current/reference/constraints/NotCompromisedPassword.html) 9 | validator or [PasswordCommonList Validator](https://github.com/rollerworks/password-common-list) instead. 10 | 11 | * The PwnedPassword validator was removed in favor of the Symfon 12 | [NotCompromisedPassword](https://symfony.com/doc/current/reference/constraints/NotCompromisedPassword.html) validator. 13 | 14 | * Support for Symfony 4 and 5 was removed, PHP 8.2 and Symfony 6.0 is now the minimum required version. 15 | 16 | ## Upgrade from 1.6 to 1.7 17 | 18 | * The blacklist validator was deprecated in favor of the [PasswordCommonList Validator](https://github.com/rollerworks/password-common-list). 19 | 20 | ## Upgrade from 1.3 to 1.4 21 | 22 | * The PwnedPassword validator is deprecated in favor of the Symfony [NotCompromisedPassword](https://symfony.com/doc/current/reference/constraints/NotCompromisedPassword.html) validator 23 | 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollerworks/password-strength-validator", 3 | "description": "Password-strength validator for Symfony", 4 | "license": "MIT", 5 | "type": "library", 6 | "keywords": [ 7 | "password", 8 | "validator", 9 | "symfony" 10 | ], 11 | "authors": [ 12 | { 13 | "name": "Sebastiaan Stok", 14 | "email": "s.stok@rollercapes.net" 15 | }, 16 | { 17 | "name": "Community contributions", 18 | "homepage": "https://github.com/rollerworks/PasswordStrengthValidator/contributors" 19 | } 20 | ], 21 | "require": { 22 | "php": ">=8.2", 23 | "symfony/config": "^6.0 || ^7.0", 24 | "symfony/polyfill-mbstring": "^1.5.0", 25 | "symfony/translation": "^6.0 || ^7.0", 26 | "symfony/validator": "^6.0 || ^7.0" 27 | }, 28 | "require-dev": { 29 | "phpstan/phpstan": "^1.10", 30 | "phpstan/phpstan-phpunit": "^1.1", 31 | "phpstan/phpstan-symfony": "^1.2", 32 | "phpunit/phpunit": "^9.5", 33 | "symfony/phpunit-bridge": "^6.0 || ^7.0" 34 | }, 35 | "minimum-stability": "dev", 36 | "prefer-stable": true, 37 | "autoload": { 38 | "psr-4": { 39 | "Rollerworks\\Component\\PasswordStrength\\": "src/" 40 | }, 41 | "exclude-from-classmap": [ 42 | "test/" 43 | ] 44 | }, 45 | "autoload-dev": { 46 | "psr-4": { 47 | "Rollerworks\\Component\\PasswordStrength\\Tests\\": "tests/" 48 | } 49 | }, 50 | "config": { 51 | "sort-packages": true 52 | }, 53 | "extra": { 54 | "branch-alias": { 55 | "dev-main": "2.0-dev" 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.bg.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Паролата трябва да е с дължина най-малко {{length}} знака. 8 | 9 | 10 | Your password must include at least one letter. 11 | Паролата трябва да съдържа поне една буква. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Паролата трябва да съдържа главни и малки букви. 16 | 17 | 18 | Your password must include at least one number. 19 | Паролата трябва да съдържа поне едно число. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Паролата трябва да съдържа поне един специален знак. 24 | 25 | 26 | password_too_weak 27 | Паролата трябва да е поне на ниво "{{ min_strength }}", текущото ниво е "{{ current_strength }}", опитайте това: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Много слабо 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Слабо 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Средно 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Силно 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Много силно 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | добавете букви (главни/малки) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | добавете цифри 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | добавете малки букви 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | добавете главни букви 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | добавете специални знаци 72 | 73 | 74 | rollerworks_password.tip.length 75 | добавете още знаци 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.cs.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Heslo musí mít alespoň {{length}} znaků. 8 | 9 | 10 | Your password must include at least one letter. 11 | Heslo musí obsahovat písmeno. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Heslo musí obsahovat velká i malá písmena. 16 | 17 | 18 | Your password must include at least one number. 19 | Heslo musí obsahovat číslici. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Heslo musí obsahovat speciální znak. 24 | 25 | 26 | password_too_weak 27 | Úroveň hesla musí být alespoň "{{ min_strength }}", současná úroveň je "{{ current_strength }}", zkuste {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | velmi slabé 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | slabé 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | střední 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | silné 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | velmi silné 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | přidat malá/velká písmena 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | přidat číslici 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | přidat malé písmeno 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | přidat velké písmeno 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | přidat speciální znak 72 | 73 | 74 | rollerworks_password.tip.length 75 | delší heslo 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.de.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Das Passwort muss aus mindestens {{length}} Zeichen bestehen. 8 | 9 | 10 | Your password must include at least one letter. 11 | Das Passwort muss mindestens einen Buchstaben enthalten. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Das Passwort muss Groß- und Kleinbuchstaben enthalten. 16 | 17 | 18 | Your password must include at least one number. 19 | Das Passwort muss mindestens eine Ziffer enthalten. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Das Passwort muss mindestens ein Sonderzeichen enthalten. 24 | 25 | 26 | password_too_weak 27 | Die Passwortstärke muss mindestens "{{ min_strength }}" sein, die aktuelle Stärke ist "{{ current_strength }}". Versuchen Sie Folgendes: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Sehr schwach 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Schwach 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Mittel 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Stark 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Sehr stark 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | Buchstaben hinzufügen (Großbuchstaben/Kleinbuchstaben) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | Ziffern hinzufügen 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | Kleinbuchstaben hinzufügen 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | Großbuchstaben hinzufügen 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | Sonderzeichen hinzufügen 72 | 73 | 74 | rollerworks_password.tip.length 75 | Weitere Zeichen hinzufügen 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.en.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Password must be at least {{length}} characters long. 8 | 9 | 10 | Your password must include at least one letter. 11 | Password must include at least one letter. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Password must include both upper and lower case letters. 16 | 17 | 18 | Your password must include at least one number. 19 | Password must include at least one number. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Password must contain at least one special character. 24 | 25 | 26 | password_too_weak 27 | Password needs to be at least at strength level "{{ min_strength }}", current level is "{{ current_strength }}", try the following: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Very Weak 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Weak 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Medium 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Strong 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Very strong 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | add (upper/lowercase) letters 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | add numbers 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | add lowercase letters 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | add uppercase letters 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | add special characters 72 | 73 | 74 | rollerworks_password.tip.length 75 | add more characters 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.es.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | La contraseña debe tener por lo menos {{length}} caracteres. 8 | 9 | 10 | Your password must include at least one letter. 11 | La contraseña debe tener por lo menos una letra. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | La contraseña debe tener mayúsculas y minúsculas. 16 | 17 | 18 | Your password must include at least one number. 19 | La contraseña debe tener por lo menos una cifra. 20 | 21 | 22 | Your password must contain at least one special character. 23 | La contraseña debe tener por lo menos un carácter especial. 24 | 25 | 26 | password_too_weak 27 | La contraseña debe tener una potencia de "{{ min_strength }}" por lo menos. La potencia actual es "{{ current_strength }}". Inténtelo aquí. {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Muy baja 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Baja 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Mediana 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Potente 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Muy potente 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | añadir letras (mayúsculas/minúsculas) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | añadir cifras 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | añadir minúsculas 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | añadir mayúsculas 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | añadir caracteres especiales 72 | 73 | 74 | rollerworks_password.tip.length 75 | añadir más caracteres 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.fr.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Le mot de passe doit faire au moins {{length}} caractères. 8 | 9 | 10 | Your password must include at least one letter. 11 | Le mot de passe doit contenir au moins une lettre. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Le mot de passe doit contenir des majuscules et des minuscules. 16 | 17 | 18 | Your password must include at least one number. 19 | Le mot de passe doit contenir au moins un chiffre. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Le mot de passe doit contenir au moins un caractère spécial. 24 | 25 | 26 | password_too_weak 27 | Le mot de passe doit avoir une force d'au moins "{{ min_strength }}", la force actuelle est "{{ current_strength }}", essayez ceci : {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Très faible 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Faible 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Moyenne 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Forte 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Très forte 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | ajouter des lettres (majuscules/minuscules) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | ajouter des chiffres 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | ajouter des minuscules 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | ajouter des majuscules 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | ajouter des caractères spéciaux 72 | 73 | 74 | rollerworks_password.tip.length 75 | ajouter plus de caractères 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.it.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | La password deve contenere almeno {{length}} caratteri. 8 | 9 | 10 | Your password must include at least one letter. 11 | La password deve contenere almeno una lettera. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | La password deve contenere almeno delle maiuscole e delle minuscole. 16 | 17 | 18 | Your password must include at least one number. 19 | La password deve contenere almeno una cifra. 20 | 21 | 22 | Your password must contain at least one special character. 23 | La password deve contenere almeno un carattere speciale. 24 | 25 | 26 | password_too_weak 27 | La password deve avere una forza di almeno {{ min_strength }}"; la forza attuale è "{{ current_strength }}"; provare quanto segue: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Molto debole 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Debole 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Media 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Forte 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Molto forte 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | aggiungi delle lettere (maiuscole/minuscole) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | aggiungi delle cifre 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | aggiungi delle minuscole 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | aggiungi delle maiuscole 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | aggiungi dei caratteri speciali 72 | 73 | 74 | rollerworks_password.tip.length 75 | aggiungi più caratteri 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.ja.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | パスワードは最低でも {{length}} 文字必要です。 8 | 9 | 10 | Your password must include at least one letter. 11 | パスワードは最低でも1文字必要です。 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | パスワードには大文字と小文字を含む必要があります。 16 | 17 | 18 | Your password must include at least one number. 19 | パスワードには最低でも数字がひとつ必要です。 20 | 21 | 22 | Your password must contain at least one special character. 23 | パスワードは最低でも一つの特殊記号が必要です。 24 | 25 | 26 | password_too_weak 27 | パスワードは最低でも強度"{{ min_strength }}"レベル以上が必要です。現在のレベルは"{{ current_strength }}"なので、こちらをお試しください。 {{ strength_tips }} 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | とても弱い 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | とても強い 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | (大文字/小文字)を追加してください 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | 数字を追加してください。 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | 小文字を追加してください 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | 大文字を追加してください 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | 特殊記号を追加してください 72 | 73 | 74 | rollerworks_password.tip.length 75 | 文字数が足りてません。追加してください 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.nl.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Wachtwoord moet minstens {{length}} tekens lang zijn. 8 | 9 | 10 | Your password must include at least one letter. 11 | Wachtwoord moet ten minste één letter bevatten. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Wachtwoord moet ten minste één hoofdletter en kleine letter bevatten. 16 | 17 | 18 | Your password must include at least one number. 19 | Wachtwoord moet ten minste één nummer bevatten. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Wachtwoord moet ten minste één speciaal teken of leesteken bevatten. 24 | 25 | 26 | password_too_weak 27 | Wachtwoord moet ten minste aan veiligheidsniveau "{{ min_strength }}" voldoen, maar het huidige niveau is "{{ current_strength }}". Probeer het volgende: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Erg zwak 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Zwak 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Gemiddeld 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Sterk 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Zeer sterk 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | voeg (hoofd/kleine) letters toe 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | voeg cijfers toe 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | voeg kleine letters toe 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | voeg hoofdletters toe 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | voeg speciale tekens of leestekens toe 72 | 73 | 74 | rollerworks_password.tip.length 75 | gebruik meer tekens 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.pl.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Hasło musi składać się z przynajmniej {{length}} znaków. 8 | 9 | 10 | Your password must include at least one letter. 11 | Hasło musi zawierać przynajmniej jedną literę. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Hasło musi zawierać duże i małe litery. 16 | 17 | 18 | Your password must include at least one number. 19 | Hasło musi zawierać przynajmniej jedną cyfrę. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Hasło musi zawierać przynajmniej jeden znak specjalny. 24 | 25 | 26 | password_too_weak 27 | Hasło musi być przynajmniej "{{ min_strength }}". Obecny poziom siły hasła to "{{ current_strength }}", spróbuj: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Bardzo słabe 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Słabe 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Średnie 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Silne 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Bardzo silne 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | dodać (małe/duże) litery 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | dodać cyfry 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | dodać małe litery 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | dodać duże litery 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | dodać znaki specjalne 72 | 73 | 74 | rollerworks_password.tip.length 75 | dodać więcej znaków 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.pt_BR.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | A senha deve ter pelo menos {{length}} caracteres de comprimento. 8 | 9 | 10 | Your password must include at least one letter. 11 | A senha deve conter pelo menos uma letra. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | A senha deve conter letras maiúsculas e minúsculas. 16 | 17 | 18 | Your password must include at least one number. 19 | A senha deve conter pelo menos um número. 20 | 21 | 22 | Your password must contain at least one special character. 23 | A senha deve conter pelo menos um caractere especial. 24 | 25 | 26 | password_too_weak 27 | A senha deve ter pelo menos o nível de intensidade "{{ min_strength }}" e o nível atual é "{{ current_strength }}". Tente o seguinte: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Muito fraco 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Fraco 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Médio 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Forte 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Muito forte 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | adicionar letras (maiúsculas/minúsculas) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | adicionar números 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | adicionar letras minúsculas 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | adicionar letras maiúsculas 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | adicionar caracteres especiais 72 | 73 | 74 | rollerworks_password.tip.length 75 | adicionar mais caracteres 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.ru.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Длина пароля должна быть не менее {{length}} символов. 8 | 9 | 10 | Your password must include at least one letter. 11 | Пароль должен содержать, по крайней мере, одну букву. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Пароль должен содержать как прописные, так и строчные буквы. 16 | 17 | 18 | Your password must include at least one number. 19 | Пароль должен содержать, по крайней мере, одну цифру. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Пароль должен содержать, по крайней мере, один специальный символ. 24 | 25 | 26 | password_too_weak 27 | Пароль должен быть как минимум "{{ min_strength }}" уровня сложности, текущий уровень сложности "{{ current_strength }}", обратите внимание на эти советы: {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | Очень слабый 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | Слабый 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | Средний 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | Сильный 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | Очень сильный 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | добавить буквы (прописные / строчные) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | добавить цифры 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | добавить строчные буквы 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | добавить заглавные буквы 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | добавить специальные символы 72 | 73 | 74 | rollerworks_password.tip.length 75 | добавить больше символов 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.sk.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | Heslo musí obsahovať aspoň {{length}} znakov. 8 | 9 | 10 | Your password must include at least one letter. 11 | Heslo musí obsahovať písmeno. 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | Heslo musí obsahovať veľké aj malé písmená. 16 | 17 | 18 | Your password must include at least one number. 19 | Heslo musí obsahovať číslicu. 20 | 21 | 22 | Your password must contain at least one special character. 23 | Heslo musí obsahovať špeciálny znak. 24 | 25 | 26 | password_too_weak 27 | Úroveň hesla musí být aspoň "{{ min_strength }}", súčasná úroveň je "{{ current_strength }}", skúste {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | veľmi slabé 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | slabé 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | priemerné 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | silné 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | veľmi silné 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | pridať malé/veľké písmená 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | pridať číslicu 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | pridať malé písmeno 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | pridať veľké písmeno 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | pridať špeciálny znak 72 | 73 | 74 | rollerworks_password.tip.length 75 | dlhšie heslo 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.th.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Your password must be at least {{length}} characters long. 7 | รหัสผ่านต้องมีความยาวอย่างน้อย {{length}} ตัวอักษร 8 | 9 | 10 | Your password must include at least one letter. 11 | รหัสผ่านต้องมีตัวอักษรอย่างน้อยหนึ่งตัว 12 | 13 | 14 | Your password must include both upper and lower case letters. 15 | รหัสผ่านต้องประกอบด้วยอักษรตัวเล็กและตัวใหญ่ 16 | 17 | 18 | Your password must include at least one number. 19 | รหัสผ่านต้องประกอบด้วยตัวเลขอย่างน้อยหนึ่งตัว 20 | 21 | 22 | Your password must contain at least one special character. 23 | รหัสผ่านต้องประกอบด้วยอักขระพิเศษอย่างน้อยหนึ่งตัว 24 | 25 | 26 | password_too_weak 27 | ความปลอดภัยของรหัสผ่านต้องอยู่ในระดับ "{{ min_strength }}" เป็นอย่างน้อย, ระดับปัจจุบันคือ "{{ current_strength }}", คำแนะนำ {{ strength_tips }}. 28 | 29 | 30 | 31 | 32 | rollerworks_password.strength_level.very_weak 33 | คาดเดาง่ายมาก 34 | 35 | 36 | rollerworks_password.strength_level.weak 37 | คาดเดาง่าย 38 | 39 | 40 | rollerworks_password.strength_level.medium 41 | พอใช้ 42 | 43 | 44 | rollerworks_password.strength_level.strong 45 | เดายาก 46 | 47 | 48 | rollerworks_password.strength_level.very_strong 49 | ดีมาก 50 | 51 | 52 | 53 | 54 | rollerworks_password.tip.letters 55 | เพิ่ม (อักษรตัวใหญ่/ตัวเล็ก) 56 | 57 | 58 | rollerworks_password.tip.numbers 59 | เพิ่ม ตัวเลข 60 | 61 | 62 | rollerworks_password.tip.lowercase_letters 63 | เพิ่ม อักษรตัวเล็ก 64 | 65 | 66 | rollerworks_password.tip.uppercase_letters 67 | เพิ่ม อักษรตัวใหญ่ 68 | 69 | 70 | rollerworks_password.tip.special_chars 71 | เพิ่ม อักขระพิเศษ 72 | 73 | 74 | rollerworks_password.tip.length 75 | เพิ่มความยาวอีก 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Validator/Constraints/PasswordRequirements.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Rollerworks\Component\PasswordStrength\Validator\Constraints; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | 16 | /** 17 | * @Annotation 18 | * 19 | * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) 20 | */ 21 | #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] 22 | class PasswordRequirements extends Constraint 23 | { 24 | public string $tooShortMessage = 'Your password must be at least {{length}} characters long.'; 25 | public string $missingLettersMessage = 'Your password must include at least one letter.'; 26 | public string $requireCaseDiffMessage = 'Your password must include both upper and lower case letters.'; 27 | public string $missingNumbersMessage = 'Your password must include at least one number.'; 28 | public string $missingSpecialCharacterMessage = 'Your password must contain at least one special character.'; 29 | 30 | public int $minLength = 6; 31 | public bool $requireLetters = true; 32 | public bool $requireCaseDiff = false; 33 | public bool $requireNumbers = false; 34 | public bool $requireSpecialCharacter = false; 35 | 36 | public function __construct( 37 | mixed $options = null, 38 | ?array $groups = null, 39 | mixed $payload = null, 40 | ?int $minLength = null, 41 | ?bool $requireLetters = null, 42 | ?bool $requireCaseDiff = null, 43 | ?bool $requireNumbers = null, 44 | ?bool $requireSpecialCharacter = null, 45 | ?string $tooShortMessage = null, 46 | ?string $missingLettersMessage = null, 47 | ?string $requireCaseDiffMessage = null, 48 | ?string $missingNumbersMessage = null, 49 | ?string $missingSpecialCharacterMessage = null 50 | ) { 51 | parent::__construct($options ?? [], $groups, $payload); 52 | 53 | $this->tooShortMessage = $tooShortMessage ?? $this->tooShortMessage; 54 | $this->missingLettersMessage = $missingLettersMessage ?? $this->missingLettersMessage; 55 | $this->requireCaseDiffMessage = $requireCaseDiffMessage ?? $this->requireCaseDiffMessage; 56 | $this->missingNumbersMessage = $missingNumbersMessage ?? $this->missingNumbersMessage; 57 | $this->missingSpecialCharacterMessage = $missingSpecialCharacterMessage ?? $this->missingSpecialCharacterMessage; 58 | 59 | $this->minLength = $minLength ?? $this->minLength; 60 | $this->requireLetters = $requireLetters ?? $this->requireLetters; 61 | $this->requireCaseDiff = $requireCaseDiff ?? $this->requireCaseDiff; 62 | $this->requireNumbers = $requireNumbers ?? $this->requireNumbers; 63 | $this->requireSpecialCharacter = $requireSpecialCharacter ?? $this->requireSpecialCharacter; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Validator/Constraints/PasswordRequirementsValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Rollerworks\Component\PasswordStrength\Validator\Constraints; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | use Symfony\Component\Validator\ConstraintValidator; 16 | use Symfony\Component\Validator\Exception\UnexpectedTypeException; 17 | 18 | class PasswordRequirementsValidator extends ConstraintValidator 19 | { 20 | public function validate(mixed $value, Constraint $constraint): void 21 | { 22 | if ($value === null || $value === '') { 23 | return; 24 | } 25 | 26 | if (! $constraint instanceof PasswordRequirements) { 27 | throw new UnexpectedTypeException($constraint, PasswordRequirements::class); 28 | } 29 | 30 | if (! \is_scalar($value) && ! (\is_object($value) && method_exists($value, '__toString'))) { 31 | throw new UnexpectedTypeException($value, 'string'); 32 | } 33 | 34 | $value = (string) $value; 35 | 36 | if ($constraint->minLength > 0 && (mb_strlen($value) < $constraint->minLength)) { 37 | $this->context->buildViolation($constraint->tooShortMessage) 38 | ->setParameters(['{{length}}' => $constraint->minLength]) 39 | ->setInvalidValue($value) 40 | ->addViolation() 41 | ; 42 | } 43 | 44 | if ($constraint->requireLetters && ! preg_match('/\pL/u', $value)) { 45 | $this->context->buildViolation($constraint->missingLettersMessage) 46 | ->setInvalidValue($value) 47 | ->addViolation() 48 | ; 49 | } 50 | 51 | if ($constraint->requireCaseDiff && ! preg_match('/(\p{Ll}+.*\p{Lu})|(\p{Lu}+.*\p{Ll})/u', $value)) { 52 | $this->context->buildViolation($constraint->requireCaseDiffMessage) 53 | ->setInvalidValue($value) 54 | ->addViolation() 55 | ; 56 | } 57 | 58 | if ($constraint->requireNumbers && ! preg_match('/\pN/u', $value)) { 59 | $this->context->buildViolation($constraint->missingNumbersMessage) 60 | ->setInvalidValue($value) 61 | ->addViolation() 62 | ; 63 | } 64 | 65 | if ($constraint->requireSpecialCharacter && ! preg_match('/[^\p{Ll}\p{Lu}\pL\pN]/u', $value)) { 66 | $this->context->buildViolation($constraint->missingSpecialCharacterMessage) 67 | ->setInvalidValue($value) 68 | ->addViolation() 69 | ; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Validator/Constraints/PasswordStrength.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Rollerworks\Component\PasswordStrength\Validator\Constraints; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | 16 | /** 17 | * @Annotation 18 | * 19 | * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) 20 | */ 21 | #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] 22 | class PasswordStrength extends Constraint 23 | { 24 | public string $tooShortMessage = 'Your password must be at least {{length}} characters long.'; 25 | public string $message = 'password_too_weak'; 26 | public int $minLength = 6; 27 | public int $minStrength; 28 | public bool $unicodeEquality = false; 29 | 30 | public function __construct( 31 | mixed $options = null, 32 | ?array $groups = null, 33 | mixed $payload = null, 34 | ?int $minStrength = null, 35 | ?int $minLength = null, 36 | ?bool $unicodeEquality = null, 37 | ?string $message = null, 38 | ?string $tooShortMessage = null 39 | ) { 40 | $finalOptions = []; 41 | 42 | if (\is_array($options)) { 43 | $finalOptions = $options; 44 | } else { 45 | $finalOptions['minStrength'] = $options; 46 | } 47 | 48 | // The minStrength option is required. 49 | if ($minStrength !== null) { 50 | $finalOptions['minStrength'] = $minStrength; 51 | } 52 | 53 | parent::__construct($finalOptions, $groups, $payload); 54 | 55 | $this->minLength = $minLength ?? $this->minLength; 56 | $this->unicodeEquality = $unicodeEquality ?? $this->unicodeEquality; 57 | $this->message = $message ?? $this->message; 58 | $this->tooShortMessage = $tooShortMessage ?? $this->tooShortMessage; 59 | } 60 | 61 | public function getDefaultOption(): string 62 | { 63 | return 'minStrength'; 64 | } 65 | 66 | public function getRequiredOptions(): array 67 | { 68 | return ['minStrength']; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Validator/Constraints/PasswordStrengthValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Rollerworks\Component\PasswordStrength\Validator\Constraints; 13 | 14 | use Symfony\Component\Translation\Loader\XliffFileLoader; 15 | use Symfony\Component\Translation\Translator; 16 | use Symfony\Component\Validator\Constraint; 17 | use Symfony\Component\Validator\ConstraintValidator; 18 | use Symfony\Component\Validator\Exception\UnexpectedTypeException; 19 | use Symfony\Contracts\Translation\TranslatorInterface; 20 | 21 | /** 22 | * Password strength Validation. 23 | * 24 | * Validates if the password strength is equal or higher 25 | * to the required minimum and the password length is equal 26 | * or longer than the minimum length. 27 | * 28 | * The strength is computed from various measures including 29 | * length and usage of characters. 30 | * 31 | * The strengths are marked up as follow. 32 | * 1: Very Weak 33 | * 2: Weak 34 | * 3: Medium 35 | * 4: Strong 36 | * 5: Very Strong 37 | */ 38 | class PasswordStrengthValidator extends ConstraintValidator 39 | { 40 | private TranslatorInterface $translator; 41 | 42 | /** 43 | * @var array 44 | */ 45 | private static array $levelToLabel = [ 46 | 1 => 'very_weak', 47 | 2 => 'weak', 48 | 3 => 'medium', 49 | 4 => 'strong', 50 | 5 => 'very_strong', 51 | ]; 52 | 53 | public function __construct(?TranslatorInterface $translator = null) 54 | { 55 | // If translator is missing create a new translator. 56 | // With the 'en' locale and 'validators' domain. 57 | if ($translator === null) { 58 | $translator = new Translator('en'); 59 | $translator->addLoader('xlf', new XliffFileLoader()); 60 | $translator->addResource('xlf', \dirname(__DIR__, 2) . '/Resources/translations/validators.en.xlf', 'en', 'validators'); 61 | } 62 | 63 | $this->translator = $translator; 64 | } 65 | 66 | public function validate(mixed $value, Constraint $constraint): void 67 | { 68 | if ($value === null || $value === '') { 69 | return; 70 | } 71 | 72 | if (! $constraint instanceof PasswordStrength) { 73 | throw new UnexpectedTypeException($constraint, PasswordStrength::class); 74 | } 75 | 76 | if (! \is_scalar($value) && ! (\is_object($value) && method_exists($value, '__toString'))) { 77 | throw new UnexpectedTypeException($value, 'string'); 78 | } 79 | 80 | $value = (string) $value; 81 | $passLength = mb_strlen($value); 82 | 83 | if ($passLength < $constraint->minLength) { 84 | $this->context->buildViolation($constraint->tooShortMessage) 85 | ->setParameters(['{{length}}' => $constraint->minLength]) 86 | ->addViolation() 87 | ; 88 | 89 | return; 90 | } 91 | 92 | $tips = []; 93 | 94 | if ($constraint->unicodeEquality) { 95 | $passwordStrength = $this->calculateStrengthUnicode($value, $tips); 96 | } else { 97 | $passwordStrength = $this->calculateStrength($value, $tips); 98 | } 99 | 100 | if ($passLength > 12) { 101 | ++$passwordStrength; 102 | } else { 103 | $tips[] = 'length'; 104 | } 105 | 106 | // There is no decrease of strength on weak combinations. 107 | // Detecting this is tricky and requires a deep understanding of the syntax. 108 | 109 | if ($passwordStrength < $constraint->minStrength) { 110 | $parameters = [ 111 | '{{ length }}' => $constraint->minLength, 112 | '{{ min_strength }}' => $this->translator->trans(/* @Ignore */ 'rollerworks_password.strength_level.' . self::$levelToLabel[$constraint->minStrength], [], 'validators'), 113 | '{{ current_strength }}' => $this->translator->trans(/* @Ignore */ 'rollerworks_password.strength_level.' . self::$levelToLabel[$passwordStrength], [], 'validators'), 114 | '{{ strength_tips }}' => implode(', ', array_map([$this, 'translateTips'], $tips)), 115 | ]; 116 | 117 | $this->context->buildViolation($constraint->message) 118 | ->setParameters($parameters) 119 | ->addViolation() 120 | ; 121 | } 122 | } 123 | 124 | private function translateTips(string $tip): string 125 | { 126 | return $this->translator->trans(/* @Ignore */ 'rollerworks_password.tip.' . $tip, [], 'validators'); 127 | } 128 | 129 | /** 130 | * @param array $tips 131 | */ 132 | private function calculateStrength(string $password, array &$tips): int 133 | { 134 | $passwordStrength = 0; 135 | 136 | if (preg_match('/[a-zA-Z]/', $password)) { 137 | ++$passwordStrength; 138 | 139 | if (! preg_match('/[a-z]/', $password)) { 140 | $tips[] = 'lowercase_letters'; 141 | } elseif (preg_match('/[A-Z]/', $password)) { 142 | ++$passwordStrength; 143 | } else { 144 | $tips[] = 'uppercase_letters'; 145 | } 146 | } else { 147 | $tips[] = 'letters'; 148 | } 149 | 150 | if (preg_match('/\d+/', $password)) { 151 | ++$passwordStrength; 152 | } else { 153 | $tips[] = 'numbers'; 154 | } 155 | 156 | if (preg_match('/[^a-zA-Z0-9]/', $password)) { 157 | ++$passwordStrength; 158 | } else { 159 | $tips[] = 'special_chars'; 160 | } 161 | 162 | return $passwordStrength; 163 | } 164 | 165 | /** 166 | * @param array $tips 167 | */ 168 | private function calculateStrengthUnicode(string $password, array &$tips): int 169 | { 170 | $passwordStrength = 0; 171 | 172 | if (preg_match('/\p{L}/u', $password)) { 173 | ++$passwordStrength; 174 | 175 | if (! preg_match('/\p{Ll}/u', $password)) { 176 | $tips[] = 'lowercase_letters'; 177 | } elseif (preg_match('/\p{Lu}/u', $password)) { 178 | ++$passwordStrength; 179 | } else { 180 | $tips[] = 'uppercase_letters'; 181 | } 182 | } else { 183 | $tips[] = 'letters'; 184 | } 185 | 186 | if (preg_match('/\p{N}/u', $password)) { 187 | ++$passwordStrength; 188 | } else { 189 | $tips[] = 'numbers'; 190 | } 191 | 192 | if (preg_match('/[^\p{L}\p{N}]/u', $password)) { 193 | ++$passwordStrength; 194 | } else { 195 | $tips[] = 'special_chars'; 196 | } 197 | 198 | return $passwordStrength; 199 | } 200 | } 201 | --------------------------------------------------------------------------------