├── .github ├── PULL_REQUEST_TEMPLATE.md ├── stale.yml ├── ISSUE_TEMPLATE.md └── CONTRIBUTING.md ├── src ├── StrengthValidatorAsset.php ├── PasswordInputAsset.php ├── presets.php ├── messages │ ├── en │ │ └── kvpwdstrength.php │ ├── zh-TW │ │ └── kvpwdstrength.php │ ├── zh-CN │ │ └── kvpwdstrength.php │ ├── vi │ │ └── kvpwdstrength.php │ ├── et │ │ └── kvpwdstrength.php │ ├── sr │ │ └── kvpwdstength.php │ ├── config.php │ ├── nl │ │ └── kvpwdstrength.php │ ├── it │ │ └── kvpwdstrength.php │ ├── pt-BR │ │ └── kvpwdstrength.php │ ├── hu │ │ └── kvpwdstrength.php │ ├── el │ │ └── kvpwdstrength.php │ ├── lt │ │ └── kvpwdstrength.php │ ├── de │ │ └── kvpwdstrength.php │ ├── es │ │ └── kvpwdstrength.php │ ├── pl │ │ └── kvpwdstrength.php │ ├── fr │ │ └── kvpwdstrength.php │ ├── ru │ │ └── kvpwdstrength.php │ ├── uk │ │ └── kvpwdstrength.php │ └── cs │ │ └── kvpwdstrength.php ├── assets │ └── js │ │ ├── strength-validation.min.js │ │ └── strength-validation.js ├── PasswordInput.php └── StrengthValidator.php ├── composer.json ├── LICENSE.md ├── CHANGE.md └── README.md /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Scope 2 | This pull request includes a 3 | 4 | - [ ] Bug fix 5 | - [ ] New feature 6 | - [ ] Translation 7 | 8 | ## Changes 9 | The following changes were made (this change is also documented in the [change log](https://github.com/kartik-v/yii2-password/blob/master/CHANGE.md)): 10 | 11 | - 12 | - 13 | - 14 | 15 | ## Related Issues 16 | If this is related to an existing ticket, include a link to it as well. -------------------------------------------------------------------------------- /src/StrengthValidatorAsset.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 7 | * @version 1.5.8 8 | */ 9 | 10 | namespace kartik\password; 11 | 12 | use kartik\base\AssetBundle; 13 | 14 | /** 15 | * Asset bundle for StrengthValidator 16 | * 17 | * @author Kartik Visweswaran 18 | * @since 1.0 19 | */ 20 | class StrengthValidatorAsset extends AssetBundle 21 | { 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function init() 26 | { 27 | $this->setSourcePath(__DIR__.'/assets'); 28 | $this->setupAssets('js', ['js/strength-validation']); 29 | parent::init(); 30 | } 31 | } -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - bug 8 | - enhancement 9 | - pinned 10 | - security 11 | # Label to use when marking an issue as stale 12 | staleLabel: wontfix 13 | # Comment to post when marking an issue as stale. Set to `false` to disable 14 | markComment: > 15 | This issue has been automatically marked as stale because it has not had 16 | recent activity. It will be closed if no further activity occurs. Thank you 17 | for your contributions. 18 | # Comment to post when closing a stale issue. Set to `false` to disable 19 | closeComment: false -------------------------------------------------------------------------------- /src/PasswordInputAsset.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 7 | * @version 1.5.8 8 | */ 9 | 10 | namespace kartik\password; 11 | 12 | use kartik\base\AssetBundle; 13 | 14 | /** 15 | * Asset bundle for the [[PasswordInput]] widget. 16 | * 17 | * @author Kartik Visweswaran 18 | * @since 1.0 19 | */ 20 | class PasswordInputAsset extends AssetBundle 21 | { 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function init() 26 | { 27 | $this->setSourcePath('@vendor/kartik-v/strength-meter'); 28 | $this->setupAssets('css', ['css/strength-meter']); 29 | $this->setupAssets('js', ['js/strength-meter']); 30 | parent::init(); 31 | } 32 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kartik-v/yii2-password", 3 | "description": "Useful password strength validation utilities for Yii Framework 2.0", 4 | "keywords": [ 5 | "yii", 6 | "yii2", 7 | "extension", 8 | "password", 9 | "strength", 10 | "auth", 11 | "input", 12 | "form", 13 | "bootstrap", 14 | "jquery" 15 | ], 16 | "homepage": "https://github.com/kartik-v/yii2-password", 17 | "type": "yii2-extension", 18 | "license": "BSD-3-Clause", 19 | "authors": [ 20 | { 21 | "name": "Kartik Visweswaran", 22 | "email": "kartikv2@gmail.com", 23 | "homepage": "http://www.krajee.com/" 24 | } 25 | ], 26 | "require": { 27 | "kartik-v/strength-meter": "~1.1", 28 | "kartik-v/yii2-krajee-base": ">=3.0.4" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "kartik\\password\\": "src" 33 | } 34 | }, 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "1.5.x-dev" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Prerequisites 2 | 3 | - [ ] I have searched for similar issues in both open and closed tickets and cannot find a duplicate. 4 | - [ ] The issue still exists against the latest `master` branch of yii2-password. 5 | - [ ] This is not an usage question. I confirm having gone through and read the [documentation and demos](http://demos.krajee.com/password-details/password-input). 6 | - [ ] This is not a general programming / coding question. (Those should be directed to the [webtips Q & A forum](http://webtips.krajee.com/questions)). 7 | - [ ] I have attempted to find the simplest possible steps to reproduce the issue. 8 | - [ ] I have included a failing test as a pull request (Optional). 9 | 10 | ## Steps to reproduce the issue 11 | 12 | 1. 13 | 2. 14 | 3. 15 | 16 | ## Expected behavior and actual behavior 17 | 18 | When I follow those steps, I see... 19 | 20 | I was expecting... 21 | 22 | ## Environment 23 | 24 | #### Browsers 25 | 26 | - [ ] Google Chrome 27 | - [ ] Mozilla Firefox 28 | - [ ] Internet Explorer 29 | - [ ] Safari 30 | 31 | #### Operating System 32 | 33 | - [ ] Windows 34 | - [ ] Mac OS X 35 | - [ ] Linux 36 | - [ ] Mobile 37 | 38 | #### Libraries 39 | 40 | - jQuery version: 41 | - yii2-password version: 42 | 43 | ## Isolating the problem 44 | 45 | - [ ] This bug happens [on the demos page](http://demos.krajee.com/password-details/password-input) 46 | - [ ] The bug happens consistently across all tested browsers 47 | - [ ] This bug happens when using yii2-password without other plugins. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 - 2022, Kartik Visweswaran 2 | Krajee.com 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | * Neither the names of Kartik Visweswaran or Krajee nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /src/presets.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 6 | * @version 1.5.8 7 | */ 8 | 9 | namespace kartik\password; 10 | 11 | /** 12 | * List of password rule presets 13 | */ 14 | return [ 15 | StrengthValidator::SIMPLE => [ 16 | 'min' => 6, 17 | 'upper' => 0, 18 | 'lower' => 1, 19 | 'digit' => 1, 20 | 'special' => 0, 21 | 'repeat' => 6, 22 | 'hasUser' => false, 23 | 'hasEmail' => false, 24 | 'haveIBeenPwned' => false, 25 | ], 26 | StrengthValidator::NORMAL => [ 27 | 'min' => 8, 28 | 'upper' => 1, 29 | 'lower' => 1, 30 | 'digit' => 1, 31 | 'special' => 0, 32 | 'repeat' => 5, 33 | 'hasUser' => true, 34 | 'hasEmail' => true, 35 | 'haveIBeenPwned' => false, 36 | ], 37 | StrengthValidator::FAIR => [ 38 | 'min' => 10, 39 | 'upper' => 1, 40 | 'lower' => 1, 41 | 'digit' => 1, 42 | 'special' => 1, 43 | 'repeat' => 4, 44 | 'hasUser' => true, 45 | 'hasEmail' => true, 46 | 'haveIBeenPwned' => false, 47 | ], 48 | StrengthValidator::MEDIUM => [ 49 | 'min' => 10, 50 | 'upper' => 1, 51 | 'lower' => 1, 52 | 'digit' => 2, 53 | 'special' => 1, 54 | 'repeat' => 3, 55 | 'hasUser' => true, 56 | 'hasEmail' => true, 57 | 'haveIBeenPwned' => false, 58 | ], 59 | StrengthValidator::STRONG => [ 60 | 'min' => 12, 61 | 'upper' => 2, 62 | 'lower' => 2, 63 | 'digit' => 2, 64 | 'special' => 2, 65 | 'repeat' => 2, 66 | 'hasUser' => true, 67 | 'hasEmail' => true, 68 | 'haveIBeenPwned' => false, 69 | ], 70 | ]; 71 | -------------------------------------------------------------------------------- /src/messages/en/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '', 21 | '{attribute} cannot contain any spaces' => '', 22 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 23 | '{attribute} cannot contain the username' => '', 24 | '{attribute} is present in compromised password list' => '', 25 | '{attribute} must be a string' => '', 26 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '', 27 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '', 28 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '', 29 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '', 30 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '', 31 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '', 32 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/assets/js/strength-validation.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 3 | * @package yii2-password 4 | * @version 1.5.8 5 | * 6 | * Password Strength Validation 7 | * Built for Yii Framework 2.0 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014, Kartik Visweswaran, Krajee.com 10 | * For more Yii related demos visit http://demos.krajee.com 11 | */var kvStrengthValidator={};!function(r){"use strict";var e=/^([\w!#$%&'\*\+\-\/=\?\^`{\|}~]+\.)*[\w!#$%&'\*\+\-\/=\?\^`{\|}~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(:\d{1,5})?)$/i;kvStrengthValidator={isEmpty:function(e,a){return null===e||void 0===e||0===e.length||a&&""===r.trim(e)},addMessage:function(r,e,a){var t=this.isEmpty(a)?"none":a;r.push(e.replace(/\{value}/g,t))},addError:function(r,e,a,t){var i=this,o=e.replace(/\{found}/g,t);i.addMessage(r,o,a)},findPatterns:function(r,e){var a=this,t=a.isEmpty,i=new RegExp("(\\w)\\1{"+e.repeat+",}"),o=r.match(/[a-z]/g),d=r.match(/[A-Z]/g),n=r.match(/\d/g),s=r.match(i),l=r.match(/\W/g);return{lower:t(o)?0:o.length,upper:t(d)?0:d.length,digit:t(n)?0:n.length,repeat:t(s)?0:s.length,special:t(l)?0:l.length}},compare:function(r,e,a){var t=void 0!==r&&void 0!==a;return"<"===e?t&&a>r:">"===e?t&&r>a:t&&r===a},validate:function(a,t,i){var o=this,d=o.compare;if(!o.isEmpty(a)){if("string"!=typeof a)return void o.addMessage(t,i.strError,a);var n=o.findPatterns(a,i),s=a.length||0,l=r(i.userField).val();d(s,"<",i.min)&&o.addError(t,i.minError,i.min,s),d(s,">",i.max)&&o.addError(t,i.maxError,i.max,s),d(s,">",i.length)&&o.addError(t,i.lengthError,i.length,s),i.allowSpaces===!1&&-1!==a.indexOf(" ")&&o.addMessage(t,i.allowSpacesError,a),i.hasUser&&l&&a.toLowerCase().match(l.toLowerCase())&&o.addMessage(t,i.hasUserError,a),i.hasEmail&&a.match(e)&&o.addMessage(t,i.hasEmailError,a),d(n.lower,"<",i.lower)&&o.addError(t,i.lowerError,i.lower,n.lower),d(n.upper,"<",i.upper)&&o.addError(t,i.upperError,i.upper,n.upper),d(n.digit,"<",i.digit)&&o.addError(t,i.digitError,i.digit,n.digit),console.log("KV SAYS",n.repeat,d(n.repeat,">",0)),d(n.repeat,">",0)&&o.addError(t,i.repeatError,i.repeat,s),d(n.special,"<",i.special)&&o.addError(t,i.specialError,i.special,n.special)}}}}(window.jQuery); -------------------------------------------------------------------------------- /src/messages/zh-TW/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} 至少要有 {n} 個字元,目前是 {found} 個字元!', 21 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} 最多能有 {n} 個字元,目前是 {found} 個字元!', 22 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} 必須剛好是 {n} 個字元,目前是 {found} 個字元!', 23 | '{attribute} cannot contain any spaces' => "{attribute} 不能有任何空白字元", 24 | '{attribute} cannot contain the username' => '{attribute} 不能包含用戶名稱', 25 | '{attribute} cannot contain an email address' => '{attribute} 不能包含電子郵件', 26 | '{attribute} must be a string' => '{attribute} 必須是字串', 27 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} 至少要有 {n} 個小寫字母,目前是 {found} 個!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} 至少要有 {n} 個大寫字母,目前是 {found} 個!', 29 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} 至少要有 {n} 個數字,目前是 {found} 個!', 30 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} 至少要有 {n} 個特殊符號,目前是 {found} 個!', 31 | ]; 32 | -------------------------------------------------------------------------------- /src/messages/zh-CN/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} 不能包含Email', 21 | '{attribute} cannot contain any spaces' => '{attribute} 不能包含任何空格', 22 | '{attribute} cannot contain the username' => '{attribute} 不能包含用户名', 23 | '{attribute} must be a string' => '{attribute} 必须是个字符串', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} 必须至少包含 {n} 个字符, 实际存在{found}个!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} 必须至少包含 {n} 个小写字符, 实际存在{found}个!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} 必须至少包含 {n} 个数字, 实际存在{found}个!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} 必须至少包含 {n} 个特殊字符, 实际存在{found}个!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} 必须至少包含 {n} 个大写字符, 实际存在{found}个!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} 必须最多包含 {n} 个字符, 实际存在{found}个!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} 必须正好包含 {n} 个字符, 实际存在{found}个!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/vi/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} nên chứa ít nhất {n, plural, one{một ký tự} other{# ký tự}} ({found} tìm thấy)!', 21 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} nên chứa nhiều nhất {n, plural, one{một ký tự} other{# ký tự}} ({found} tìm thấy)!', 22 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} nên chứa chính xác {n, plural, one{một ký tự} other{# ký tự}} ({found} tìm thấy)!', 23 | '{attribute} cannot contain any spaces' => '{attribute} không được chứa khoảng trắng', 24 | '{attribute} cannot contain the username' => "{attribute} không được chứa tên đăng nhập", 25 | '{attribute} cannot contain an email address' => "{attribute} không được chứa địa chỉ email", 26 | '{attribute} must be a string' => '{attribute} phải là chuỗi ký tự', 27 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} nên chứa ít nhất {n, plural, one{một ký tự in thường} other{# ký tự in thường}} ({found} tìm thấy)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} nên chứa ít nhất {n, plural, one{một ký tự in hoa} other{# ký tự in hoa}} ({found} tìm thấy)!', 29 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} nên chứa ít nhất {n, plural, one{một số / ký tự số} other{# số / ký tự số}} ({found} tìm thấy)!', 30 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} nên chứa ít nhất {n, plural, one{một ký tự đặc biệt} other{# ký tự đặc biệt}} ({found} tìm thấy)!', 31 | ]; 32 | -------------------------------------------------------------------------------- /src/messages/et/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} peab sisaldama vähemalt {n, plural, one{ühte tähemärki} other{# tähemärki}} ({found} leitud)!', 21 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} võib sisaldada kõige enam {n, plural, one{ühte tähemärki} other{# tähemärki}} ({found} leitud)!', 22 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} peaks sisaldama täpselt {n, plural, one{ühte tähemärki} other{# täehemärki}} ({found} leitud)!', 23 | '{attribute} cannot contain any spaces' => '{attribute} ei tohi sisaldada tühikuid', 24 | '{attribute} cannot contain the username' => '{attribute} ei tohi sisaldada kasutajanime', 25 | '{attribute} cannot contain an email address' => '{attribute} ei tohi sisaldada e-posti aadressi', 26 | '{attribute} must be a string' => '{attribute} peab olema tekst', 27 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} peaks sisaldama vähemalt {n, plural, one{ühte väiketähte} other{# väiketeähte}} ({found} leitud)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} peaks sisaldama vähemalt {n, plural, one{ühte suurtähte} other{# suurtähte}} ({found} leitud)!', 29 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} peaks sisaldama vähemalt {n, plural, one{ühte numbrit} other{# numbrit}} ({found} leitud)!', 30 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} pesks sisaldama vähemalt {n, plural, one{ühte erimärki} other{# erimärki}} ({found} leitud)!', 31 | ]; 32 | -------------------------------------------------------------------------------- /src/messages/sr/kvpwdstength.php: -------------------------------------------------------------------------------- 1 | 21 | '{attribute} treba da sadrži najmanje {n, plural, one{jedan karakter} other{# karaktera}} ({found} pronađeno)!', 22 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => 23 | '{attribute} treba da sadrži najviše {n, plural, one{jedan karakter} other{# karaktera}} ({found} pronađeno)!', 24 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => 25 | '{attribute} treba da sadrži tačno {n, plural, one{jedan karakter} other{# karaktera}} ({found} pronađeno)!', 26 | '{attribute} cannot contain any spaces' => '{attribute} ne može da sadrži razmake', 27 | '{attribute} cannot contain the username' => "{attribute} ne može da sadrži korisničko ime", 28 | '{attribute} cannot contain an email address' => "{attribute} ne može da sadrži email", 29 | '{attribute} must be a string' => '{attribute} mora da bude skup karaktera', 30 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => 31 | '{attribute} mora da sadrži bar {n, plural, one{jedno malo slovo} other{# mala slova}} ({found} pronađeno)!', 32 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => 33 | '{attribute} mora da sadrži bar {n, plural, one{jedno veliko slovo} other{# velika slova}} ({found} pronađeno)!', 34 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => 35 | '{attribute} mora da sadrži bar {n, plural, one{jedan broj} other{# broja}} ({found} pronađeno)!', 36 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => 37 | '{attribute} mora da sadrži bar {n, plural, one{jedan specijalni karakter} other{# specijalna karaktera}} ({found} pronađeno)!', 38 | ]; 39 | -------------------------------------------------------------------------------- /src/messages/config.php: -------------------------------------------------------------------------------- 1 | __DIR__ . DIRECTORY_SEPARATOR . '..', 5 | // string, required, root directory containing message translations. 6 | 'messagePath' => __DIR__, 7 | // array, required, list of language codes that the extracted messages 8 | // should be translated to. For example, ['zh-CN', 'de']. 9 | 'languages' => ['cs', 'de', 'el', 'en', 'es', 'fr', 'hu', 'it', 'lt', 'nl', 'pl', 'pt-BR', 'ru', 'uk', 'zh-CN'], 10 | // string, the name of the function for translating messages. 11 | // Defaults to 'Yii::t'. This is used as a mark to find the messages to be 12 | // translated. You may use a string for single function name or an array for 13 | // multiple function names. 14 | 'translator' => 'Yii::t', 15 | // boolean, whether to sort messages by keys when merging new messages 16 | // with the existing ones. Defaults to false, which means the new (untranslated) 17 | // messages will be separated from the old (translated) ones. 18 | 'sort' => false, 19 | // boolean, whether the message file should be overwritten with the merged messages 20 | 'overwrite' => true, 21 | // boolean, whether to remove messages that no longer appear in the source code. 22 | // Defaults to false, which means each of these messages will be enclosed with a pair of '' marks. 23 | 'removeUnused' => false, 24 | // array, list of patterns that specify which files/directories should NOT be processed. 25 | // If empty or not set, all files/directories will be processed. 26 | // A path matches a pattern if it contains the pattern string at its end. For example, 27 | // '/a/b' will match all files and directories ending with '/a/b'; 28 | // the '*.svn' will match all files and directories whose name ends with '.svn'. 29 | // and the '.svn' will match all files and directories named exactly '.svn'. 30 | // Note, the '/' characters in a pattern matches both '/' and '\'. 31 | // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. 32 | 'only' => ['*.php'], 33 | // array, list of patterns that specify which files (not directories) should be processed. 34 | // If empty or not set, all files will be processed. 35 | // Please refer to "except" for details about the patterns. 36 | // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. 37 | 'except' => [ 38 | '.svn', 39 | '.git', 40 | '.gitignore', 41 | '.gitkeep', 42 | '.hgignore', 43 | '.hgkeep', 44 | '/messages', 45 | ], 46 | // Generated file format. Can be either "php", "po" or "db". 47 | 'format' => 'php', 48 | // When format is "db", you may specify the following two options 49 | //'db' => 'db', 50 | //'sourceMessageTable' => '{{%source_message}}', 51 | ]; -------------------------------------------------------------------------------- /src/messages/nl/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} mag niet het email-adres bevatten', 21 | '{attribute} cannot contain any spaces' => '{attribute} mag geen spaties bevatten', 22 | '{attribute} cannot contain the username' => '{attribute} mag niet de gebruikersnaam bevatten', 23 | '{attribute} is present in compromised password list' => '{attribute} is gevonden in een lijst met gekraakte wachtwoorden', 24 | '{attribute} must be a string' => '{attribute} moet een string zijn', 25 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} moet minstens {n, plural, one{één karakter} other{# karakters}} bevatten ({found} gevonden)!', 26 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} moet minstens {n, plural, one{één kleine letter} other{# kleine letters}} bevatten ({found} gevonden)!', 27 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} moet minstens {n, plural, one{één cijfer} other{# cijfers}} bevatten ({found} gevonden)!', 28 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} moet minstens {n, plural, one{één speciaal teken} other{# speciale tekens}} bevatten ({found} gevonden)!', 29 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} moet minstens {n, plural, one{één hoofdletter} other{# hoofdletters}} bevatten ({found} gevonden)!', 30 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} mag maximaal {n, plural, one{één karakter} other{# karakters}} bevatten ({found} gevonden)!', 31 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} moet precies {n, plural, one{één karakter} other{# karakters}} bevatten ({found} gevonden)!', 32 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/it/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} non può contenere un indirizzo email', 21 | '{attribute} cannot contain any spaces' => '{attribute} non può contenere spazi', 22 | '{attribute} cannot contain the username' => '{attribute} non può contenere il nome utente', 23 | '{attribute} must be a string' => '{attribute} deve essere una stringa', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} dovrebbe contenere almeno {n, plural, one{un carattere} other{# caratteri}} ({found} trovati)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} deve contenere almeno {n, plural, one{un carattere minuscolo} other{# caratteri minuscoli}} ({found} trovati)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} deve contenere almeno {n, plural, one{un carattere numerico / cifre} other{# caratteri numerico / cifre}} ({found} trovati)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} deve contenere almeno {n, plural, one{un carattere speciale} other{# caratteri speciale}} ({found} trovati)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} deve contenere almeno {n, plural, one{un carattere maiuscolo} other{# caratteri maiuscoli}} ({found} trovati)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} dovrebbe contenere al massimo {n, plural, one{un carattere} other{# caratteri}} ({found} trovati)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} dovrebbe contenere esattamente {n, plural, one{un carattere} other{# caratteri}} ({found} trovati)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/pt-BR/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} não pode conter o endereço de e-mail', 21 | '{attribute} cannot contain any spaces' => '{attribute} não pode conter espaços', 22 | '{attribute} cannot contain the username' => '{attribute} não pode conter o nome de usuário', 23 | '{attribute} must be a string' => '{attribute} deve ter apenas letras', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} deve conter ao menos {n, plural, one{one caracter} other{# caracteres}} (encontrado {found})!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} deve conter ao menos {n, plural, one{um caracter em minúsculo} other{# caracteres em minúsculo}} (encontrado {found})!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} deve ter ao menos {n, plural, one{um dígito numérico/caracter} other{# dígitos numéricos/caracteres}} (encontrado {found})!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} deve conter ao menos {n, plural, one{um caracter especial} other{# caracteres especiais}} (encontrado {found})!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} deve conter ao menos {n, plural, one{um caracter em maiúsculo} other{# caracteres em maiúsculo}} (encontrado {found})!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} deve conter no máximo {n, plural, one{one caracter} other{# caracteres}} (encontrado {found})!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} deve conter exatamente {n, plural, one{um caracter} other{# caracteres}} (encontrado {found})!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/hu/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} mező nem tartalmazhat email címet', 21 | '{attribute} cannot contain any spaces' => '{attribute} nem tartalmazhat szóközt', 22 | '{attribute} cannot contain the username' => '{attribute} mező nem tartalmazhatja a felhasználónevet', 23 | '{attribute} must be a string' => '{attribute} mező csak szöveges lehet', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} mezőnek legalább {n, plural, one{egy} other{#}} karaktert kell tartalmaznia (most {found} darabot tartalmaz)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} mezőnek legalább {n, plural, one{egy} other{#}} kisbetűt kell tartalmaznia (most {found} darabot tartalmaz)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} mezőnek legalább {n, plural, one{egy} other{#}} számot kell tartalmaznia (most {found} darabot tartalmaz)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} mezőnek legalább {n, plural, one{egy} other{#}} speciális karaktert kell tartalmaznia (most {found} darabot tartalmaz)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} mezőnek legalább {n, plural, one{egy} other{#}} nagybetűt kell tartalmaznia (most {found} darabot tartalmaz)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} mező legfeljebb {n, plural, one{egy} other{#}} karaktert tartalmazhat (most {found} darabot tartalmaz)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} mező pontosan {n, plural, one{egy} other{#}} karaktert tartalmazhat (most {found} darabot tartalmaz)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/el/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} δεν μπορεί να περιέχει διεύθυνση email', 21 | '{attribute} cannot contain any spaces' => '{attribute} δεν μπορεί να περιέχει καθόλου κενά', 22 | '{attribute} cannot contain the username' => '{attribute} δεν μπορεί να περιέχει το όνομα χρήστη', 23 | '{attribute} must be a string' => '{attribute} πρέπει να είναι κείμενο', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει τουλάχιστο {n, plural, one{ένα χαρακτήρα} other{# χαρακτήρες}} ({found} βρέθηκαν)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει τουλάχιστο {n, plural, one{ένα πεζό χαρακτήρα} other{# πεζούς χαρακτήρες}} ({found} βρέθηκαν)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει τουλάχιστο {n, plural, one{ένα αριθμητικό ψηφίο} other{# αριθμητικά ψηφία}} ({found} βρέθηκαν)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει τουλάχιστο {n, plural, one{ένα ειδικό χαρακτήρα} other{# ειδικούς χαρακτήρες}} ({found} βρέθηκαν)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει τουλάχιστο {n, plural, one{ένα κεφαλαίο χαρακτήρα} other{# κεφαλαίους χαρακτήρες}} ({found} βρέθηκαν)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει το πολύ {n, plural, one{ένα χαρακτήρα} other{# χαρακτήρες}} ({found} βρέθηκαν)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} πρέπει να περιέχει ακριβώς {n, plural, one{ένα χαρακτήρα} other{# χαρακτήρες}} ({found} βρέθηκαν)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/lt/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} negali atkartoti slaptažodį', 21 | '{attribute} cannot contain any spaces' => '{attribute} negali turėti tarpų', 22 | '{attribute} cannot contain the username' => '{attribute} negali atkartoti vartotojo vardą', 23 | '{attribute} must be a string' => '{attribute} privalo būti eilutė', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} turėtų sudaryti bent jau {n, plural, one{simbolis} few{# simboliai} other{# simbolių}}! (Rasta: {found})!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} turėtų sudaryti bent {n, plural, one{1 mažoji raidė} few{# mažosios raidės} other{# mažųjų raidžių}}! (Rasta: {found})!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} turėtų sudaryti bent {n, plural, one{1 skaitmuo} few{# skaitmenys} other{# skaitmenų}}! (Rasta: {found})!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} turėtų sudaryti bent {n, plural, one{1 skiriamasis ženklas} few{# skiriamieji ženklai} other{# skiriamųjų ženklų}} ({found} trouvé)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} turėtų sudaryti bent {n, plural, one{1 didžioji raidė} few{# didžiosios raidės} other{# didžiųjų raidžių}}! (Rasta: {found})!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} turėtų sudaryti ne daugiau nei {n, plural, one{simbolis} few{# simboliai} other{# simbolių}}! (Rasta: {found})!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} turėtų sudaryti lygiai {n, plural, one{vienas simbolis} few{# simboliai} other{# simbolių}}! (Rasta: {found})!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/de/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} darf keine E-Mail-Adresse enthalten', 21 | '{attribute} cannot contain any spaces' => '{attribute} darf keine Leerzeichen enthalten', 22 | '{attribute} cannot contain the username' => '{attribute} darf den Benutzernamen nicht enthalten', 23 | '{attribute} is present in compromised password list' => '{attribute} befindet sich auf der Liste bereits kompromittierter Passwörter', 24 | '{attribute} must be a string' => '{attribute} muss eine Zeichenfolge sein', 25 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} muss mindestens {n, plural, one{ein Zeichen} other{# Zeichen}} enthalten ({found} gefunden)!', 26 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} muss mindestens {n, plural, one{einen Kleinbuchstaben enthalten} other{# Kleinbuchstaben enthalten}} ({found} gefunden)!', 27 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} muss mindestens {n, plural, one{eine Ziffer enthalten} other{# Ziffern enthalten}} ({found} gefunden)!', 28 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} muss mindestens {n, plural, one{ein Sonderzeichen enthalten} other{# Sonderzeichen enthalten}} ({found} gefunden)!', 29 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} muss mindestens {n, plural, one{einen Großbuchstaben enthalten} other{# Großbuchstaben enthalten}} ({found} gefunden)!', 30 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} darf höchstens {n, plural, one{ein Zeichen} other{# Zeichen}} enthalten ({found} gefunden)!', 31 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} muss genau {n, plural, one{ein Zeichen} other{# Zeichen}} enthalten ({found} gefunden)!', 32 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/es/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} no puede contener una dirección de correo electrónico', 21 | '{attribute} cannot contain any spaces' => '{attribute} no puede contener ningún espacio', 22 | '{attribute} cannot contain the username' => '{attribute} no puede contener el nombre de usuario', 23 | '{attribute} must be a string' => '{attribute} debe ser una cadena de texto', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} debe contener al menos {n, plural, one{un carácter} other{# caracteres}} ({found} encontrados)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} debe contener al menos {n, plural, one{un carácter en minúscula} other{# caracteres en minúscula}} ({found} encontrados)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} debe contener al menos {n, plural, one{un carácter numérico / dígito} other{# caracteres numéricos / dígitos}} ({found} encontrados)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} debe contener al menos {n, plural, one{un carácter especial} other{# caracteres especiales}} ({found} encontrados)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} debe contener al menos {n, plural, one{un carácter en mayúscula} other{# caracteres en mayúscula}} ({found} encontrados)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} debe contener como máximo {n, plural, one{un carácter} other{# caracteres}} ({found} encontrados)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} debe contener exactamente {n, plural, one{un carácter} other{# caracteres}} ({found} encontrados)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/pl/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} nie może zawierać adresu e-mail', 21 | '{attribute} cannot contain any spaces' => '{attribute} nie może zawierać żadnych spacji', 22 | '{attribute} cannot contain the username' => '{attribute} nie może zawierać nazwy użytkownika', 23 | '{attribute} must be a string' => '{attribute} musi być ciągiem znaków', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} powinno zawierać przynajmniej {n, plural, one{jeden znak} few{# znaki} other{# znaków}} (wpisano {found})!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} powinno zawierać przynajmniej {n, plural, one{jedną małą literę} few{# małe litery} other{# małych liter}} ({found} znaleziono)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} powinno zawierać przynajmniej {n, plural, one{jedną cyfrę} few{# cyfry} other{# cyfr}} ({found} znaleziono)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} powinno zawierać przynajmniej {n, plural, one{jeden znak specjalny} few{# znaki specjalne} other{# znaków specjalnych}} ({found} znaleziono)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} powinno zawierać przynajmniej {n, plural, one{jedną wielką literę} few{# wielkie litery} other{# wielkich liter}} ({found} znaleziono)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} powinno zawierać najwyżej {n, plural, one{jeden znak} few{# znaki} other{# znaków}} (wpisano {found})!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} powinno zawierać dokładnie {n, plural, one{jeden znak} few{# znaki} other{# znaków}} (wpisano {found})!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/fr/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} ne peut pas contenir l\'adresse e-mail', 21 | '{attribute} cannot contain any spaces' => '{attribute} ne peut pas contenir d\'espaces', 22 | '{attribute} cannot contain the username' => '{attribute} ne peut pas contenir le nom d\'utilisateur', 23 | '{attribute} must be a string' => '{attribute} doit être une chaîne', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} devrait contenir au moins {n, plural, one{un caractère} other{# caractères}}! ({found} trouvé)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} {n, plural, one{devrait contenir au moins un caractère en minuscule} other{# doit contenir au moins caractères minuscules}}! ({found} trouvé)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} {n, plural, one{devrait contenir au moins un caractère numérique / chiffres} other{# doit contenir au moins caractères numérique / chiffres}}! ({found} trouvé)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} {n, plural, one{devrait contenir au moins un caractère spécial} other{# doit contenir au moins caractères spéciaux}} ({found} trouvé)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} {n, plural, one{devrait contenir au moins une lettre majuscule} other{# doit contenir au moins caractères majuscules}}! ({found} trouvé)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} devrait contenir au plus {n, plural, one{un caractère} other{# caractères}}! ({found} trouvé)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} devrait contenir exactly {n, plural, one{un caractère} other{# caractères}}! ({found} trouvé)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/ru/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} не может содержать адрес электронной почты', 21 | '{attribute} cannot contain any spaces' => '{attribute} не может содержать никаких пробелов', 22 | '{attribute} cannot contain the username' => '{attribute} не может содержать имя пользователя', 23 | '{attribute} must be a string' => '{attribute} должен быть строкой', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} должен содержать {n, plural, =1{хотя бы один символ} one{минимум # символ} few{минимум # символа} many{минимум # символов} other{минимум # символов}} ({found} найдено)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} должен содержать минимум {n, plural, one{# строчный символ} few{# строчных символа} many{# строчных символов} other{# строчных символов}} ({found} найдено)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} должен содержать минимум {n, plural, one{# цифру} few{# цифры} many{# цифр} other{# цифр}} ({found} найдено)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} должен содержать минимум {n, plural, one{# специальный символ} few{# специальных символа} many{# специальных символов} other{# специальных символов}} ({found} найдено)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} должен содержать минимум {n, plural, one{# символ верхнего регистра} few{# символа верхнего регистра} many{# символов верхнего регистра} other{# символов верхнего регистра}} ({found} найдено)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} должен содержать не более {n, plural, one{# символа} other{# символов}} ({found} найдено)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} должен содержать ровно {n, plural, one{# символ} few{# символа} many{# символов} other{# символов}} ({found} найдено)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/uk/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} не може містити адресу електронної пошти', 21 | '{attribute} cannot contain any spaces' => '{attribute} не може містити ніяких пробілів', 22 | '{attribute} cannot contain the username' => '{attribute} не може містити ім’я користувача', 23 | '{attribute} must be a string' => '{attribute} має бути рядком', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} повинен містити {n, plural, =1{хоча б один символ} one{мінімум # символ} few{мінімум # символа} many{мінімум # символів} other{мінімум # символів}} ({found} знайдено)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} повинен містити мінімум {n, plural, one{# рядковий символ} few{# рядкових символів} many{# рядкових символів} other{# рядкових символів}} ({found} знайдено)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} повинен містити мінімум {n, plural, one{# цифру} few{# цифр} many{# цифр} many{# цифр} other{# цифр}} ({found} знайдено)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} повинен містити мінімум {n, plural, one{# спеціальний символ} few{# спеціальних символів} many{# спеціальних символів} other{# спеціальних символів}} ({found} знайдено)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} повинен містити мінімум {n, plural, one{# символ верхнього регістру} few{# символів верхнього регістру } many{# символів верхнього регістру} other{# символів верхнього регістру}} ({found} знайдено)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} повинен містити не більш як {n, plural, one{# символа} other{# символів}} ({found} знайдено)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} повинен містити рівно {n, plural, one{# символ} few{# символів} many{# символів} other{# символів}} ({found} знайдено)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/messages/cs/kvpwdstrength.php: -------------------------------------------------------------------------------- 1 | '{attribute} nemůže obsahovat emailovou adresu', 21 | '{attribute} cannot contain any spaces' => '{attribute} nemůže obsahovat žádné mezery', 22 | '{attribute} cannot contain the username' => '{attribute} nemůže obsahovat uživatelské jméno', 23 | '{attribute} must be a string' => '{attribute} must be a string', 24 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} musí obsahovat minimálně {n, plural, one{jeden znak} two{2 znaky} three{3 znaky} four{4 znaky} other{# znaků}} ({found} nalezeno)!', 25 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' => '{attribute} musí obsahovat minimálně {n, plural, one{jedno malé písmeno} two{2 malá písmena} three{3 malá písmena} four{4 malá písmena} other{# malých písmen}} ({found} nalezeno)!', 26 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' => '{attribute} musí obsahovat minimálně {n, plural, one{jeden numerický / číselný znak} two{2 numerické / číselné znaky} three{3 numerické / číselné znaky} four{4 numerické / číselné znaky} other{# numerických / číselných znaků}} ({found} nalezeno)!', 27 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' => '{attribute} musí obsahovat minimálně {n, plural, one{1 speciální znak} two{2 speciální znaky} three{3 speciální znaky} four{4 speciální znak} other{# speciálních znaků}} ({found} nalezeno)!', 28 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' => '{attribute} musí obsahovat minimálně {n, plural, one{jedno velké písmeno} two{2 velká písmena} three{3 velká písmena} four{4 velká písmena} other{# velkých písmen}} ({found} nalezeno)!', 29 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} musí obsahovat maximálně {n, plural, one{jeden znak} two{2 znaky} three{3 znaky} four{4 znaky} other{# znaků}} ({found} nalezeno)!', 30 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' => '{attribute} musí obsahovat přesně {n, plural, one{jeden znak} two{2 znaky} three{3 znaky} four{4 znaky} other{# znaků}} ({found} nalezeno)!', 31 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' => '', 32 | '{attribute} is present in compromised password list' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/PasswordInput.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 7 | * @version 1.5.8 8 | */ 9 | 10 | namespace kartik\password; 11 | 12 | use Exception; 13 | use kartik\base\InputWidget; 14 | use ReflectionException; 15 | use Yii; 16 | use yii\helpers\Html; 17 | use yii\helpers\ArrayHelper; 18 | 19 | /** 20 | * PasswordInput widget is a wrapper for the JQuery Strength meter plugin by Krajee. The plugin converts a password 21 | * input into a widget with an advanced strength validation meter and toggle mask to show/hide the password. The 22 | * password strength is validated as you type. 23 | * 24 | * For example, 25 | * 26 | * ```php 27 | * // add this in your view 28 | * use kartik\password\PasswordInput; 29 | * use kartik\widgets\ActiveForm; // optional 30 | * 31 | * $form = ActiveForm::begin(['id' => 'login-form']); 32 | * echo $form->field($model,'username'); 33 | * echo $form->field($model, 'password')->widget(PasswordInput::classname(), [ 34 | * 'pluginOptions' => [ 35 | * 'showMeter' => true, 36 | * 'toggleMask' => false 37 | * ] 38 | * ]); 39 | * ``` 40 | * 41 | * @author Kartik Visweswaran 42 | * @since 1.0 43 | * @see http://plugins.krajee.com/strength-meter 44 | */ 45 | class PasswordInput extends InputWidget 46 | { 47 | /** 48 | * @var string the password strength meter language. If not provided or no translation is available, this will 49 | * default to `en` (US English). 50 | */ 51 | public $language; 52 | 53 | /** 54 | * @var string the password input size. Defaults to medium size ('md'). Can be set 'lg' for large size or 'sm' for 55 | * small size. 56 | */ 57 | public $size = 'md'; 58 | 59 | /** 60 | * @var string the toggle mask placement with respect to the password input. Should be 'left' or 'right'. Defaults 61 | * to 'right'. 62 | */ 63 | public $togglePlacement = 'right'; 64 | 65 | /** 66 | * @inheritdoc 67 | */ 68 | public $pluginName = 'strength'; 69 | 70 | /** 71 | * @inheritdoc 72 | * @throws ReflectionException 73 | * @throws Exception 74 | */ 75 | public function run() 76 | { 77 | $this->initLanguage(); 78 | if ($this->hasModel()) { 79 | $this->name = ArrayHelper::remove( 80 | $this->options, 81 | 'name', 82 | Html::getInputName($this->model, $this->attribute) 83 | ); 84 | $this->value = Html::getAttributeValue($this->model, $this->attribute); 85 | } 86 | echo $this->getInput('passwordInput'); 87 | if (empty($this->pluginOptions['inputTemplate'])) { 88 | $this->pluginOptions['inputTemplate'] = $this->renderInputTemplate(); 89 | } 90 | $this->registerAssets(); 91 | parent::run(); 92 | } 93 | 94 | /** 95 | * Renders the input template 96 | * 97 | * @return string 98 | * @throws Exception 99 | */ 100 | protected function renderInputTemplate() 101 | { 102 | $isLeft = $this->togglePlacement === 'left'; 103 | $css = $this->isBs(5) ? 'input-group-text' : 'input-group-addon'; 104 | $tog = '{toggle}'; 105 | if ($this->isBs(4)) { 106 | $css = $isLeft ? 'input-group-prepend' : 'input-group-append'; 107 | $tog = '{toggle}'; 108 | } 109 | $groupOptions = ['class' => 'input-group']; 110 | $toggle = Html::tag('span', $tog, ['class' => $css]); 111 | if ($this->size === 'lg' || $this->size === 'sm') { 112 | Html::addCssClass($groupOptions, 'input-group-'.$this->size); 113 | } 114 | $content = $isLeft ? $toggle.'{input}' : '{input}'.$toggle; 115 | 116 | return Html::tag('div', $content, $groupOptions); 117 | } 118 | 119 | /** 120 | * Registers the needed assets 121 | * 122 | * @throws Exception 123 | */ 124 | public function registerAssets() 125 | { 126 | $view = $this->getView(); 127 | $path = Yii::getAlias("@vendor/kartik-v/strength-meter"); 128 | $this->setLanguage('strength-meter-', $path, 'js/locales'); 129 | if (!empty($this->_langFile)) { 130 | PasswordInputAsset::register($view)->js[] = $this->_langFile; 131 | } else { 132 | PasswordInputAsset::register($view); 133 | } 134 | $this->registerPlugin($this->pluginName); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /CHANGE.md: -------------------------------------------------------------------------------- 1 | Change Log: `yii2-password` 2 | =========================== 3 | 4 | ## Version 1.5.8 5 | 6 | **Date:** _under development_ 7 | 8 | - (enh #80): Add new password validation for checking repeating characters. 9 | 10 | ## Version 1.5.7 11 | 12 | **Date:** 16-May-2022 13 | 14 | - PHP 8.1 enhancements for native functions. 15 | - (enh #79): Enhancement to input group addons for Bootstrap 5.x. 16 | 17 | ## Version 1.5.6 18 | 19 | **Date:** 15-Jun-2020 20 | 21 | - (bug #73, #74): Validate `haveIBeenPwned` correctly and default to `false` for BC. 22 | 23 | ## Version 1.5.5 24 | 25 | **Date:** 08-Jun-2020 26 | 27 | - (enh #72): Add support to check password in haveibeenpwned.com online lists. 28 | - (enh #71): Correct German Translations. 29 | - (bug #70): Correct `allowSpaces`. 30 | - (bug #69): Correct code bug (multiple and conditions). 31 | - (enh #66, #67, #68): Correct `allowSpaces`. 32 | 33 | ## Version 1.5.4 34 | 35 | **Date:** 07-Sep-2018 36 | 37 | - Add github contribution and issue/PR log templates. 38 | - Updates for Bootstrap v4.x. 39 | - Reorganize source code in `src` directory. 40 | - (enh #61): Update Russian Translations. 41 | - (enh #60): Add Greek Translations. 42 | - (enh #58): Add Ukranian Translations. 43 | - (enh #56): Update Portugese BR Translations. 44 | - (enh #54): Add Lithuanian Translations. 45 | - (enh #53): Add Vietnamese Translations. 46 | - (enh #49): Correct Html::getAttributeValue. 47 | - (enh #45): Add Traditional Chinese Translations. 48 | - (enh #44): Add Estonian Translations. 49 | - (enh #42): Add Serbian Translations. 50 | - (enh #39): Update Spanish Translations. 51 | 52 | ## Version 1.5.3 53 | 54 | **Date:** 10-Jan-2016 55 | 56 | - (enh #37): Enhance code to generate Yii localization messages via config 57 | - (enh #37): Validate username without attribute 58 | - New `usernameValue` property that will be used without model or `usernameAttribute`. If this is provided the `usernameAttribute` will be skipped. 59 | - Eliminate `StrengthValidator::strError` property (BC Breaking). Use the `StrengthValidator::message` property instead. 60 | - (enh #36): Add Czech translations 61 | - (enh #35): Model is required to have a username attribute (or userAttribute) 62 | - (enh #34): Enhance StrengthValidator to support `validateValue` 63 | - (enh #33): Update Russian Translations 64 | - (enh #32): Correct Polish Translations 65 | - (enh #31): Fix for short-long language code conflict 66 | - (enh #30): Add Hungarian Translations 67 | - (enh #29): Add Simplified Chinese translation 68 | - (enh #28): Spaces validation via new properties `allowSpaces` and `allowSpacesError`. 69 | 70 | ## Version 1.5.2 71 | 72 | **Date:** 14-Jul-2015 73 | 74 | - (enh #27): Add ability to configure multi-language widgets on same page. 75 | 76 | ## Version 1.5.1 77 | 78 | **Date:** 17-Jun-2015 79 | 80 | - (enh #26): Set composer ## Version dependencies. 81 | - (bug #25): Fix strength validator callback. 82 | - (enh #24): Improve validation to retrieve the right translation messages folder. 83 | - Set copyright year to current. 84 | - (enh #22, #23): Updated German Translations. 85 | 86 | ## Version 1.5.0 87 | 88 | **Date:** 12-Jan-2015 89 | 90 | - (bug #21): Ensure empty username check when `hasUser` is true. 91 | - Code formatting updates as per Yii2 coding style. 92 | - Change message file category name to begin with `kv` prefix. 93 | - (enh #17): StrengthValidator client validation fix when not using username validation. 94 | - (bug #16): StrengthValidator strpos empty needle error fix. 95 | - (enh #15): Added Portugese Brazilian translations. 96 | 97 | ## Version 1.4.0 98 | 99 | **Date:** 20-Nov-2014 100 | 101 | - (enh #14): Enhance strength client validation plugin as a better reusable component. 102 | - (bug #13): Fix errors in client side validation of patterns (digit, special etc.) 103 | 104 | ## Version 1.3.0 105 | 106 | **Date:** 10-Nov-2014 107 | 108 | - Set dependency on Krajee base components 109 | - Set release to stable 110 | 111 | 112 | ## Version 1.2.0 113 | 114 | **Date:** 31-Oct-2014 115 | 116 | - (enh #10): Spanish translations. 117 | - (enh #9): Polish translations. 118 | - (enh #8): Dutch translations. 119 | - (enh #7, enh #11): Validate if translation locale file exists. 120 | 121 | ## Version 1.1.0 122 | 123 | **Date:** 28-Feb-2014 124 | 125 | - (enh #6): PasswordInput widget now wraps the enhanced [JQuery Strength Meter Plugin](http://github.com/kartik-v/strength-meter). 126 | - (enh #4): Fix German translations. 127 | - The strength meter validation routines and rendering have been enhanced and offers ability to configure most options, call events, and methods. 128 | - PSR4 alias change 129 | 130 | ## Version 1.0.0 131 | 132 | Initial release -------------------------------------------------------------------------------- /src/assets/js/strength-validation.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 3 | * @package yii2-password 4 | * @version 1.5.8 5 | * 6 | * Password Strength Validation 7 | * Built for Yii Framework 2.0 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014, Kartik Visweswaran, Krajee.com 10 | * For more Yii related demos visit http://demos.krajee.com 11 | */ 12 | var kvStrengthValidator = {}; 13 | (function ($) { 14 | "use strict"; 15 | var emailRegExp = /^([\w!#$%&'\*\+\-\/=\?\^`{\|}~]+\.)*[\w!#$%&'\*\+\-\/=\?\^`{\|}~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(:\d{1,5})?)$/i; 16 | kvStrengthValidator = { 17 | isEmpty: function (value, trim) { 18 | return value === null || value === undefined || value.length === 0 || trim && $.trim(value) === ''; 19 | }, 20 | addMessage: function (messages, message, value) { 21 | var val = this.isEmpty(value) ? 'none' : value; 22 | messages.push(message.replace(/\{value}/g, val)); 23 | }, 24 | addError: function (messages, message, valueRequired, valueFound) { 25 | var self = this, msg = message.replace(/\{found}/g, valueFound); 26 | self.addMessage(messages, msg, valueRequired); 27 | }, 28 | findPatterns: function (str, options) { 29 | var self = this, isEmpty = self.isEmpty, 30 | repRegex = new RegExp("(\\w)\\1{" + options.repeat + ",}"), 31 | lower = str.match(/[a-z]/g), 32 | upper = str.match(/[A-Z]/g), 33 | digit = str.match(/\d/g), 34 | repeat = str.match(repRegex), 35 | special = str.match(/\W/g); 36 | return { 37 | lower: isEmpty(lower) ? 0 : lower.length, 38 | upper: isEmpty(upper) ? 0 : upper.length, 39 | digit: isEmpty(digit) ? 0 : digit.length, 40 | repeat: isEmpty(repeat) ? 0 : repeat.length, 41 | special: isEmpty(special) ? 0 : special.length 42 | }; 43 | }, 44 | compare: function (from, operator, to) { 45 | var chk = (from !== undefined) && (to !== undefined); 46 | if (operator === '<') { 47 | return chk && (from < to); 48 | } 49 | if (operator === '>') { 50 | return chk && (from > to); 51 | } 52 | return chk && (from === to); 53 | }, 54 | validate: function (value, messages, options) { 55 | var self = this, compare = self.compare; 56 | /** @namespace options.minError */ 57 | /** @namespace options.maxError */ 58 | /** @namespace options.lengthError */ 59 | /** @namespace options.allowSpaces */ 60 | /** @namespace options.allowSpacesError */ 61 | /** @namespace options.userField */ 62 | /** @namespace options.hasUser */ 63 | /** @namespace options.hasUserError */ 64 | /** @namespace options.hasEmail */ 65 | /** @namespace options.hasEmailError */ 66 | /** @namespace options.lowerError */ 67 | /** @namespace options.upperError */ 68 | /** @namespace options.digitError */ 69 | /** @namespace options.specialError */ 70 | /** @namespace options.strError */ 71 | if (self.isEmpty(value)) { 72 | return; 73 | } 74 | if (typeof value !== 'string') { 75 | self.addMessage(messages, options.strError, value); 76 | return; 77 | } 78 | var patterns = self.findPatterns(value, options), len = value.length || 0, 79 | username = $(options.userField).val(); 80 | if (compare(len, '<', options.min)) { 81 | self.addError(messages, options.minError, options.min, len); 82 | } 83 | if (compare(len, '>', options.max)) { 84 | self.addError(messages, options.maxError, options.max, len); 85 | } 86 | if (compare(len, '>', options['length'])) { // jshint ignore:line 87 | self.addError(messages, options.lengthError, options['length'], len); // jshint ignore:line 88 | } 89 | if (options.allowSpaces === false && value.indexOf(' ') !== -1) { 90 | self.addMessage(messages, options.allowSpacesError, value); 91 | } 92 | if (options.hasUser && username && value.toLowerCase().match(username.toLowerCase())) { 93 | self.addMessage(messages, options.hasUserError, value); 94 | } 95 | if (options.hasEmail && value.match(emailRegExp)) { 96 | self.addMessage(messages, options.hasEmailError, value); 97 | } 98 | if (compare(patterns.lower, '<', options.lower)) { 99 | self.addError(messages, options.lowerError, options.lower, patterns.lower); 100 | } 101 | if (compare(patterns.upper, '<', options.upper)) { 102 | self.addError(messages, options.upperError, options.upper, patterns.upper); 103 | } 104 | if (compare(patterns.digit, '<', options.digit)) { 105 | self.addError(messages, options.digitError, options.digit, patterns.digit); 106 | } 107 | console.log('KV SAYS', patterns.repeat, compare(patterns.repeat, '>', 0)); 108 | if (compare(patterns.repeat, '>', 0)) { 109 | self.addError(messages, options.repeatError, options.repeat, len); 110 | } 111 | if (compare(patterns.special, '<', options.special)) { 112 | self.addError(messages, options.specialError, options.special, patterns.special); 113 | } 114 | } 115 | }; 116 | })(window.jQuery); -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to yii2-password 2 | ============================= 3 | Looking to contribute something to yii2-password? **Here's how you can help.** 4 | 5 | Please take a moment to review this document in order to make the contribution 6 | process easy and effective for everyone involved. 7 | 8 | Following these guidelines helps to communicate that you respect the time of 9 | the developers managing and developing this open source project. In return, 10 | they should reciprocate that respect in addressing your issue or assessing 11 | patches and features. 12 | 13 | Using the issue tracker 14 | ----------------------- 15 | When [reporting bugs][reporting-bugs] or 16 | [requesting features][requesting-features], the 17 | [issue tracker on GitHub][issue-tracker] is the recommended channel to use. 18 | 19 | The issue tracker **is not** a place for support requests. Refer the 20 | [extension documentation and demos](http://demos.krajee.com/password) and/or refer to the 21 | [webtips Q & A forum](http://webtips.krajee.com/questions) which are the better places to get help. 22 | 23 | Reporting bugs with yii2-password 24 | --------------------------------- 25 | We really appreciate clear bug reports that _consistently_ show an issue 26 | _within yii2-password_. 27 | 28 | The ideal bug report follows these guidelines: 29 | 30 | 1. **Use the [GitHub issue search][issue-search]** — Check if the issue 31 | has already been reported. 32 | 2. **Check if the issue has been fixed** — Try to reproduce the problem 33 | using the code in the `master` branch. 34 | 3. **Isolate the problem** — Try to share a demo or a test case that 35 | consistently reproduces the problem. 36 | 37 | Please try to be as detailed as possible in your bug report, especially if an 38 | isolated test case cannot be made. Some useful questions to include the answer 39 | to are: 40 | 41 | - What steps can be used to reproduce the issue? 42 | - What is the bug and what is the expected outcome? 43 | - What browser(s) and Operating System have you tested with? 44 | - Does the bug happen consistently across all tested browsers? 45 | - What version of jQuery are you using? And what version of yii2-password? 46 | - Are you using yii2-password with other plugins? 47 | 48 | All of these questions will help others fix and identify any potential bugs. 49 | 50 | Requesting features in yii2-password 51 | ------------------------------------ 52 | Before starting work on a major feature for yii2-password, **read the 53 | [documentation](http://demos.krajee.com/password) first** or you may risk spending a considerable amount of 54 | time on something which the project developers are not interested in bringing into the project. 55 | 56 | ### Submitting a pull request 57 | 58 | We use GitHub's pull request system for submitting patches. Here are some 59 | guidelines to follow when creating the pull request for your fix. 60 | 61 | 1. Make sure to create a ticket for your pull request. This will serve as the 62 | bug ticket, and any discussion about the bug will take place there. Your pull 63 | request will be focused on the specific changes that fix the bug. 64 | 2. Make sure to reference the ticket you are fixing within your pull request. 65 | This will allow us to close off the ticket once we merge the pull request, or 66 | follow up on the ticket if there are any related blocking issues. 67 | 3. Explain why the specific change was made. Not everyone who is reviewing your 68 | pull request will be familiar with the problem it is fixing. 69 | 4. Run your tests first. If your tests aren't passing, the pull request won't 70 | be able to be merged. If you're breaking existing tests, make sure that you 71 | aren't causing any breaking changes. 72 | 5. Only include source changes. While it's not required, only including changes 73 | from the `src` directory will prevent merge conflicts from occuring. Making 74 | this happen can be as a simple as not committing changes from the `dist` 75 | directory. 76 | 77 | By following these steps, you will make it easier for your pull request to be 78 | reviewed and eventually merged. 79 | 80 | Triaging issues and pull requests 81 | --------------------------------- 82 | Anyone can help the project maintainers triage issues and review pull requests. 83 | 84 | ### Handling new issues 85 | 86 | yii2-password regularly receives new issues which need to be tested and organized. 87 | 88 | When a new issue that comes in that is similar to another existing issue, it 89 | should be checked to make sure it is not a duplicate. Duplicates issues should 90 | be marked by replying to the issue with "Duplicate of #[issue number]" where 91 | `[issue number]` is the url or issue number for the existing issue. This will 92 | allow the project maintainers to quickly close off additional issues and keep 93 | the discussion focused within a single issue. 94 | 95 | If you can test issues that are reported to yii2-password that contain test cases and 96 | confirm under what conditions bugs happen, that will allow others to identify 97 | what causes a bug quicker. 98 | 99 | ### Reviewing pull requests 100 | 101 | It is very common for pull requests to be opened for issues that contain a clear 102 | solution to the problem. These pull requests should be rigorously reviewed by 103 | the community before being accepted. If you are not sure about a piece of 104 | submitted code, or know of a better way to do something, do not hesitate to make 105 | a comment on the pull request. 106 | 107 | ### Reviving old tickets 108 | 109 | If you come across tickets which have not been updated for a while, you are 110 | encouraged to revive them. While this can be as simple as saying `:+1:`, it is 111 | best if you can include more information on the issue. Common bugs and feature 112 | requests are more likely to be fixed, whether it is by the community or the 113 | developers, so keeping tickets up to date is encouraged. 114 | 115 | Licensing 116 | --------- 117 | 118 | It should also be made clear that **all code contributed to yii2-password** must be 119 | licensable under the [BSD-3 license][licensing]. Code that cannot be released 120 | under this license **cannot be accepted** into the project. 121 | 122 | [issue-search]: https://github.com/kartik-v/yii2-password/search?q=&type=Issues 123 | [issue-tracker]: https://github.com/kartik-v/yii2-password/issues 124 | [licensing]: https://github.com/kartik-v/yii2-password/blob/master/LICENSE.md 125 | [reporting-bugs]: #reporting-bugs-with-yii2-password 126 | [requesting-features]: #requesting-features-in-yii2-password -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Krajee Logo 4 | 5 |
6 | yii2-password 7 |
8 | Donate 10 |       11 | kartikv 12 |

13 | 14 |
15 | 16 | [![Stable Version](https://poser.pugx.org/kartik-v/yii2-password/v/stable)](https://packagist.org/packages/kartik-v/yii2-password) 17 | [![Untable Version](https://poser.pugx.org/kartik-v/yii2-password/v/unstable)](https://packagist.org/packages/kartik-v/yii2-password) 18 | [![License](https://poser.pugx.org/kartik-v/yii2-password/license)](https://packagist.org/packages/kartik-v/yii2-password) 19 | [![Total Downloads](https://poser.pugx.org/kartik-v/yii2-password/downloads)](https://packagist.org/packages/kartik-v/yii2-password) 20 | [![Monthly Downloads](https://poser.pugx.org/kartik-v/yii2-password/d/monthly)](https://packagist.org/packages/kartik-v/yii2-password) 21 | [![Daily Downloads](https://poser.pugx.org/kartik-v/yii2-password/d/daily)](https://packagist.org/packages/kartik-v/yii2-password) 22 | 23 |
24 | 25 | This extension provides a couple of great password management utilities for Yii Framework 2.0. The extension allows password strength validation through your model. In addition, it provides an advanced password input widget, that allows you to display/hide text and show the password strength. 26 | 27 | ### Release Changes 28 | Refer the [CHANGE LOG](https://github.com/kartik-v/yii2-password/blob/master/CHANGE.md) for details of various releases. 29 | 30 | ### Prerequisites 31 | 32 | - Ensure you have the right version of jQuery loaded (> v1.9.0). 33 | - In case you are upgrading from an older release, its recommended that you clean up your web assets, local browser cache, and restart your browsers before using the extension. 34 | 35 | ### StrengthValidator 36 | [```VIEW DEMO```](http://demos.krajee.com/password-details/strength-validator) 37 | This is a password strength validator for your model attributes. The strength validator allows you to configure the following parameters for validating passwords or strings. 38 | 39 | 1. Whether password contains an username 40 | 2. Whether password contains an email string 41 | 3. Minimum number of characters 42 | 4. Maximum number of characters 43 | 5. Whether spaces are allowed 44 | 6. Minimum number of lower space characters 45 | 7. Minimum number of upper space characters 46 | 8. Minimum number of numeric / digit characters 47 | 9. Minimum number of special characters 48 | 10. Whether password is compromised and part of [Have I Been Pwned](https://haveibeenpwned.com/) lists. 49 | 50 | Other features: 51 | 52 | 1. Includes 5 presets (simple, normal, fair, medium, and strong). Instead of setting each parameter above, you can call a preset which will auto-set each of the parameters above. 53 | 2. It includes both server and client validation. 54 | 3. This can work with the PasswordInput widget (described next) as per your needs. The strength validation routines for both are a bit different. The PasswordInput widget focuses on displaying the strength only, and does not restrict the user input in any way. 55 | 56 | > NOTE: The StrengthValidator does not validate if the password field is required. You need to use Yii's ```required``` rule for this. 57 | 58 | ### PasswordInput 59 | [```VIEW DEMO```](http://demos.krajee.com/password-details/password-input) 60 | This is an advanced password input widget with configurable options and a dynamic strength meter based on the [Strength Meter JQuery Plugin](http://plugins.krajee.com/strength-meter) by Krajee. The widget provides various features as mentioned below: 61 | 62 | 1. Allows you to show/ hide a password text (using bootstrap styled input addons). You can configure this option to be shown or not. 63 | 2. Allows you to display an advanced password strength meter to calculate and show your password strength as you type. 64 | 3. Allows you to control and position/style your meter based on templates. 65 | 4. A password strength meter consists of the meter bar, the score, and the verdict. 66 | 5. Uses Bootstrap 3.0 styling wherever possible with inbuilt Yii 2.0 ActiveField functionality. 67 | 6. Works independent and complements the StrengthValidator. 68 | 69 | ### Demo 70 | You can see a [demonstration here](http://demos.krajee.com/password) on usage of these functions with documentation and examples. 71 | 72 | ## Installation 73 | 74 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 75 | 76 | > Note: Check the [composer.json](https://github.com/kartik-v/yii2-password/blob/master/composer.json) for this extension's requirements and dependencies. 77 | Read this [web tip /wiki](http://webtips.krajee.com/setting-composer-minimum-stability-application/) on setting the `minimum-stability` settings for your application's composer.json. 78 | 79 | Either run 80 | 81 | ``` 82 | $ php composer.phar require kartik-v/yii2-password "@dev" 83 | ``` 84 | 85 | or add 86 | 87 | ``` 88 | "kartik-v/yii2-password": "@dev" 89 | ``` 90 | 91 | to the ```require``` section of your `composer.json` file. 92 | 93 | ## Usage 94 | 95 | ### StrengthValidator 96 | ```php 97 | // add this in your model 98 | use kartik\password\StrengthValidator; 99 | 100 | // use the validator in your model rules 101 | public function rules() { 102 | return [ 103 | [['username', 'password'], 'required'], 104 | [['password'], StrengthValidator::className(), 'preset'=>'normal', 'userAttribute'=>'username'] 105 | ]; 106 | } 107 | ``` 108 | 109 | ### PasswordInput 110 | ```php 111 | // add this in your view 112 | use kartik\password\PasswordInput; 113 | use kartik\widgets\ActiveForm; // optional 114 | 115 | $form = ActiveForm::begin(['id' => 'login-form']); 116 | echo $form->field($model,'username'); 117 | echo $form->field($model, 'password')->widget(PasswordInput::classname(), [ 118 | 'pluginOptions' => [ 119 | 'showMeter' => true, 120 | 'toggleMask' => false 121 | ] 122 | ]); 123 | ``` 124 | 125 | ## License 126 | 127 | **yii2-password** is released under the BSD-3-Clause License. See the bundled `LICENSE.md` for details. -------------------------------------------------------------------------------- /src/StrengthValidator.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2022 7 | * @version 1.5.8 8 | */ 9 | 10 | namespace kartik\password; 11 | 12 | use kartik\base\Lib; 13 | use ReflectionException; 14 | use Yii; 15 | use yii\base\Model; 16 | use yii\base\InvalidConfigException; 17 | use yii\helpers\Html; 18 | use yii\helpers\Json; 19 | use yii\validators\Validator; 20 | use kartik\base\TranslationTrait; 21 | 22 | /** 23 | * StrengthValidator validates if the attribute value matches a specified set of password strength rules. You can 24 | * use this validator to validate the password strength as part of your model's validation rules. 25 | * 26 | * For example, 27 | * 28 | * ```php 29 | * // add this in your model 30 | * use kartik\password\StrengthValidator; 31 | * 32 | * // use the validator in your model rules 33 | * public function rules() { 34 | * return [ 35 | * [['username', 'password'], 'required'], 36 | * [['password'], StrengthValidator::className(), 'preset'=>'normal', 'userAttribute'=>'username'] 37 | * ]; 38 | * } 39 | * ``` 40 | * 41 | * @author Kartik Visweswaran 42 | * @since 1.0 43 | */ 44 | class StrengthValidator extends Validator 45 | { 46 | use TranslationTrait; 47 | 48 | /** 49 | * @var string the simple password strength configuration preset 50 | */ 51 | const SIMPLE = 'simple'; 52 | /** 53 | * @var string the normal password strength configuration preset 54 | */ 55 | const NORMAL = 'normal'; 56 | /** 57 | * @var string the fair password strength configuration preset 58 | */ 59 | const FAIR = 'fair'; 60 | /** 61 | * @var string the medium password strength configuration preset 62 | */ 63 | const MEDIUM = 'medium'; 64 | /** 65 | * @var string the strong password strength configuration preset 66 | */ 67 | const STRONG = 'strong'; 68 | /** 69 | * @var string rule to check the minimum length of the password 70 | */ 71 | const RULE_MIN = 'min'; 72 | /** 73 | * @var string rule to check the maximum length of the password 74 | */ 75 | const RULE_MAX = 'max'; 76 | /** 77 | * @var string rule to check the password string length 78 | */ 79 | const RULE_LEN = 'length'; 80 | /** 81 | * @var string rule to check whether to allow spaces in the password 82 | */ 83 | const RULE_SPACES = 'allowSpaces'; 84 | /** 85 | * @var string rule to check whether the password contains the username 86 | */ 87 | const RULE_USER = 'hasUser'; 88 | /** 89 | * @var string rule to check whether the password contains the email 90 | */ 91 | const RULE_EMAIL = 'hasEmail'; 92 | /** 93 | * @var string rule to check whether the password contains lower case characters 94 | */ 95 | const RULE_LOW = 'lower'; 96 | /** 97 | * @var string rule to check whether the password contains upper case characters 98 | */ 99 | const RULE_UP = 'upper'; 100 | /** 101 | * @var string rule to check whether the password contains numeric digit characters 102 | */ 103 | const RULE_NUM = 'digit'; 104 | /** 105 | * @var string rule to check whether the password contains special characters 106 | */ 107 | const RULE_SPL = 'special'; 108 | /** 109 | * @var string rule to check whether the password has repeating characters 110 | */ 111 | const RULE_REP = 'repeat'; 112 | /** 113 | * @var string rule to check whether the password is part of `HaveIBeenPwned` database 114 | */ 115 | const RULE_HIBP = 'haveIBeenPwned'; 116 | /** 117 | * @var string regex to match email pattern 118 | */ 119 | const EMAIL_MATCH = '/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i'; 120 | 121 | /** 122 | * @var bool check whether password contains the username 123 | */ 124 | public $hasUser = true; 125 | 126 | /** 127 | * @var bool check whether password contains an email string 128 | */ 129 | public $hasEmail = true; 130 | 131 | /** 132 | * @var int minimum number of characters. If not set, defaults to 4. 133 | */ 134 | public $min = 4; 135 | 136 | /** 137 | * @var int maximum length. If not set, it means no maximum length limit. 138 | */ 139 | public $max; 140 | 141 | /** 142 | * @var int|array specifies the length limit of the value to be validated. This can be specified in one of the 143 | * following forms: 144 | * - an integer: the exact length that the value should be of; 145 | * - an array of one element: the minimum length that the value should be of. For example, `[8]`. 146 | * This will overwrite [[min]]. 147 | * - an array of two elements: the minimum and maximum lengths that the value should be of. 148 | * For example, `[8, 128]`. This will overwrite both [[min]] and [[max]]. 149 | * @see minError for the customized message for a too short string. 150 | * @see maxError for the customized message for a too long string. 151 | * @see notEqual for the customized message for a string that does not match desired length. 152 | */ 153 | public $length; 154 | 155 | /** 156 | * @var bool whether to allow spaces in the input. Defaults to `false`. 157 | */ 158 | public $allowSpaces = false; 159 | 160 | /** 161 | * @var int minimal number of lower case characters 162 | */ 163 | public $lower = 2; 164 | 165 | /** 166 | * @var int minimal number of upper case characters 167 | */ 168 | public $upper = 2; 169 | 170 | /** 171 | * @var int minimal number of numeric digit characters 172 | */ 173 | public $digit = 2; 174 | 175 | /** 176 | * @var int minimal number of special characters 177 | */ 178 | public $special = 2; 179 | 180 | /** 181 | * @var int maximum number of same characters that can be repeated 182 | */ 183 | public $repeat = 2; 184 | 185 | /** 186 | * @var bool whether to check the online database of "Have I Been Pwned" 187 | */ 188 | public $haveIBeenPwned = false; 189 | 190 | /** 191 | * @var string the api for "Have I Been Pwned" check with trailing slash 192 | * @see https://haveibeenpwned.com/API/v3#SearchingPwnedPasswordsByRange 193 | */ 194 | public $apiHIBP = 'https://api.pwnedpasswords.com/range/'; 195 | 196 | /** 197 | * @var string the name of the username attribute 198 | */ 199 | public $userAttribute = 'username'; 200 | 201 | /** 202 | * @var string the value of the username to cross check for `hasUser` rule. This will override the userAttribute 203 | * setting if this is set. 204 | */ 205 | public $usernameValue; 206 | 207 | /** 208 | * @var string user-defined error message used when the value is not a string 209 | */ 210 | public $message; 211 | 212 | /** 213 | * @var string user-defined error message used when the length of the value is smaller than [[min]]. 214 | */ 215 | public $minError; 216 | 217 | /** 218 | * @var string user-defined error message used when the length of the value is greater than [[max]]. 219 | */ 220 | public $maxError; 221 | 222 | /** 223 | * @var string user-defined error message used when the length of the value is not equal to [[length]]. 224 | */ 225 | public $lengthError; 226 | 227 | /** 228 | * @var string user-defined error message used when [[allowSpaces]] is `false` and spaces are found in input 229 | */ 230 | public $allowSpacesError; 231 | 232 | /** 233 | * @var string user-defined error message used when [[hasUser]] is true and value contains the username 234 | */ 235 | public $hasUserError; 236 | 237 | /** 238 | * @var string user-defined error message used [[hasEmail]] is true and value contains an email 239 | */ 240 | public $hasEmailError; 241 | 242 | /** 243 | * @var string user-defined error message used when value contains less than [[lower]] characters 244 | */ 245 | public $lowerError; 246 | 247 | /** 248 | * @var string user-defined error message used when value contains less than [[upper]] characters 249 | */ 250 | public $upperError; 251 | 252 | /** 253 | * @var string user-defined error message used when value contains less than [[digit]] characters 254 | */ 255 | public $digitError; 256 | 257 | /** 258 | * @var string user-defined error message used when value contains more than [[special]] characters 259 | */ 260 | public $specialError; 261 | 262 | /** 263 | * @var string user-defined error message used when the number of characters repeated exceeds [[repeat]]. 264 | */ 265 | public $repeatError; 266 | 267 | /** 268 | * @var string user-defined error message used when password is found in Have I Been Pwned 269 | */ 270 | public $haveIBeenPwnedError; 271 | 272 | /** 273 | * @var string preset - one of the preset constants. If this is not null, the preset parameters will override the 274 | * validator level params 275 | */ 276 | public $preset; 277 | 278 | /** 279 | * @var string presets configuration source file defaults to [[presets.php]] in the current directory 280 | */ 281 | public $presetsSource; 282 | 283 | /** 284 | * @var array the target strength rule requirements that will be evaluated for displaying the strength meter 285 | */ 286 | public $strengthTarget = [ 287 | 'min' => 8, 288 | 'lower' => 3, 289 | 'upper' => 3, 290 | 'digit' => 3, 291 | 'special' => 3 292 | ]; 293 | 294 | /** 295 | * @var string the encoding of the string value to be validated (e.g. 'UTF-8'). If this property is not set, 296 | * [[\yii\base\Application::charset]] will be used. 297 | */ 298 | public $encoding; 299 | 300 | /** 301 | * @var array the default rule settings 302 | */ 303 | protected static $_rules = [ 304 | self::RULE_MIN => ['int' => true], 305 | self::RULE_MAX => ['int' => true], 306 | self::RULE_LEN => ['int' => true], 307 | self::RULE_SPACES => ['bool' => true], 308 | self::RULE_USER => ['bool' => true], 309 | self::RULE_EMAIL => ['match' => self::EMAIL_MATCH, 'bool' => true], 310 | self::RULE_LOW => ['match' => '![a-z]!', 'int' => true], 311 | self::RULE_UP => ['match' => '![A-Z]!', 'int' => true], 312 | self::RULE_NUM => ['match' => '![\d]!', 'int' => true], 313 | self::RULE_SPL => ['match' => '![\W]!', 'int' => true], 314 | self::RULE_REP => ['match' => '/(\w)\1{,}/'], // flag will be replaced with $repeat 315 | self::RULE_HIBP => ['bool' => true], 316 | ]; 317 | 318 | /** 319 | * @var string curl http adapter for HIBP 320 | */ 321 | private $_adapter; 322 | 323 | /** 324 | * @inheritdoc 325 | * @throws ReflectionException 326 | * @throws InvalidConfigException 327 | */ 328 | public function init() 329 | { 330 | parent::init(); 331 | if ($this->encoding === null) { 332 | $this->encoding = Yii::$app->charset; 333 | } 334 | $this->_msgCat = 'kvpwdstrength'; 335 | $this->initI18N(__DIR__); 336 | $this->applyPreset(); 337 | $this->checkParams(); 338 | $this->setRuleMessages(); 339 | } 340 | 341 | /** 342 | * Apply preset parameter if set 343 | * 344 | * @return void 345 | * @throws InvalidConfigException if [[preset]] value is invalid. 346 | */ 347 | protected function applyPreset() 348 | { 349 | if (!isset($this->preset)) { 350 | return; 351 | } 352 | if (!isset($this->presetsSource)) { 353 | $this->presetsSource = __DIR__.'/presets.php'; 354 | } 355 | $presets = require($this->presetsSource); 356 | if (isset($this->preset) && array_key_exists($this->preset, $presets)) { 357 | foreach ($presets[$this->preset] as $param => $value) { 358 | $this->$param = $value; 359 | } 360 | } else { 361 | throw new InvalidConfigException("Invalid preset '{$this->preset}'."); 362 | } 363 | } 364 | 365 | /** 366 | * Validates the provided parameters for valid data type and the right threshold for 'max' chars. 367 | * 368 | * @throws InvalidConfigException if validation is invalid 369 | */ 370 | protected function checkParams() 371 | { 372 | foreach (self::$_rules as $rule => $setup) { 373 | if (isset($this->$rule) && !empty($setup['int']) && (!is_int($this->$rule) || $this->$rule < 0)) { 374 | throw new InvalidConfigException("The property '{$rule}' must be a positive integer."); 375 | } 376 | if (isset($this->$rule) && !empty($setup['bool']) && !is_bool($this->$rule)) { 377 | throw new InvalidConfigException("The property '{$rule}' must be either true or false."); 378 | } 379 | } 380 | if (isset($this->max)) { 381 | $chars = $this->lower + $this->upper + $this->digit + $this->special; 382 | if ($chars > $this->max) { 383 | throw new InvalidConfigException( 384 | "Total number of required characters {$chars} is greater than maximum allowed {$this->max}. ". 385 | "Validation is not possible!" 386 | ); 387 | } 388 | } 389 | } 390 | 391 | /** 392 | * Sets the rule message for each rule 393 | */ 394 | protected function setRuleMessages() 395 | { 396 | if ($this->message === null) { 397 | $this->message = Yii::t('kvpwdstrength', '{attribute} must be a string'); 398 | } 399 | foreach (self::$_rules as $rule => $setup) { 400 | $param = "{$rule}Error"; 401 | if ($this->$rule !== null) { 402 | $message = !isset($this->$param) ? static::getRuleMessage($rule) : $this->$param; 403 | $this->$param = Yii::t('kvpwdstrength', $message, ['n' => $this->$rule]); 404 | } 405 | } 406 | } 407 | 408 | /** 409 | * Gets the localized rule message 410 | * 411 | * @param string $rule the rule to parse 412 | * 413 | * @return string 414 | */ 415 | protected static function getRuleMessage($rule) 416 | { 417 | switch ($rule) { 418 | case self::RULE_MIN: 419 | return Yii::t( 420 | 'kvpwdstrength', 421 | '{attribute} should contain at least {n, plural, one{one character} other{# characters}} ({found} found)!' 422 | ); 423 | case self::RULE_MAX: 424 | return Yii::t( 425 | 'kvpwdstrength', 426 | '{attribute} should contain at most {n, plural, one{one character} other{# characters}} ({found} found)!' 427 | ); 428 | case self::RULE_LEN: 429 | return Yii::t( 430 | 'kvpwdstrength', 431 | '{attribute} should contain exactly {n, plural, one{one character} other{# characters}} ({found} found)!' 432 | ); 433 | case self::RULE_SPACES: 434 | return Yii::t('kvpwdstrength', '{attribute} cannot contain any spaces'); 435 | case self::RULE_USER: 436 | return Yii::t('kvpwdstrength', '{attribute} cannot contain the username'); 437 | case self::RULE_EMAIL: 438 | return Yii::t('kvpwdstrength', '{attribute} cannot contain an email address'); 439 | case self::RULE_LOW: 440 | return Yii::t( 441 | 'kvpwdstrength', 442 | '{attribute} should contain at least {n, plural, one{one lower case character} other{# lower case characters}} ({found} found)!' 443 | ); 444 | case self::RULE_UP: 445 | return Yii::t( 446 | 'kvpwdstrength', 447 | '{attribute} should contain at least {n, plural, one{one upper case character} other{# upper case characters}} ({found} found)!' 448 | ); 449 | case self::RULE_NUM: 450 | return Yii::t( 451 | 'kvpwdstrength', 452 | '{attribute} should contain at least {n, plural, one{one numeric / digit character} other{# numeric / digit characters}} ({found} found)!' 453 | ); 454 | case self::RULE_SPL: 455 | return Yii::t( 456 | 'kvpwdstrength', 457 | '{attribute} should contain at least {n, plural, one{one special character} other{# special characters}} ({found} found)!' 458 | ); 459 | case self::RULE_REP: 460 | return Yii::t( 461 | 'kvpwdstrength', 462 | '{attribute} cannot contain more than {n, plural, one{one repeating character} other{# repeating characters}}!' 463 | ); 464 | case self::RULE_HIBP: 465 | return Yii::t('kvpwdstrength', '{attribute} is present in compromised password list'); 466 | } 467 | 468 | return null; 469 | } 470 | 471 | /** 472 | * The main password validation routine 473 | * 474 | * @param array $params of model, attribute, and value 475 | * 476 | * @return array|null the validated result 477 | */ 478 | protected function performValidation($params = []) 479 | { 480 | /** @var Model $model */ 481 | $model = $attribute = $value = $label = null; 482 | extract($params); 483 | $hasModel = $model !== null; 484 | if ($hasModel) { 485 | $value = Html::getAttributeValue($model, $attribute); 486 | if (!is_string($value)) { 487 | $this->addError($model, $attribute, $this->message); 488 | 489 | return null; 490 | } 491 | $label = $model->getAttributeLabel($attribute); 492 | $username = !$this->hasUser ? '' : (isset($this->usernameValue) ? $this->usernameValue : 493 | Html::getAttributeValue($model, $this->userAttribute)); 494 | } else { 495 | if (!is_string($value)) { 496 | return [$this->message, []]; 497 | } 498 | $username = !$this->hasUser ? '' : $this->usernameValue; 499 | } 500 | $temp = []; 501 | foreach (self::$_rules as $rule => $setup) { 502 | $param = "{$rule}Error"; 503 | $ruleValue = isset($this->$rule) ? $this->$rule : null; 504 | $chkUser = $rule === self::RULE_USER && $ruleValue && !empty($value) && !empty($username) && 505 | Lib::strpos($value, $username) !== false; 506 | $chkEmail = $rule === self::RULE_EMAIL && $ruleValue && Lib::preg_match($setup['match'], $value, $matches); 507 | $chkSpaces = $rule === self::RULE_SPACES && !$ruleValue && Lib::strpos($value, ' ') !== false; 508 | if ($rule === self::RULE_REP && $ruleValue && !empty($setup['match'])) { 509 | 510 | $count = Lib::preg_match_all($match, $value, $temp); 511 | if ($count > $ruleValue) { 512 | if ($hasModel) { 513 | $this->addError($model, $attribute, $this->$param, ['attribute' => $label, 'found' => $count]); 514 | } 515 | return [$this->$param, ['found' => $count]]; 516 | } 517 | } 518 | if ($chkUser || $chkEmail || $chkSpaces) { 519 | if ($hasModel) { 520 | $this->addError($model, $attribute, $this->$param, ['attribute' => $label]); 521 | } else { 522 | return [$this->$param, []]; 523 | } 524 | } elseif ($rule !== self::RULE_EMAIL && $rule !== self::RULE_USER && !empty($setup['match'])) { 525 | $match = $setup['match']; 526 | if ($rule === self::RULE_REP) { 527 | $match = Lib::str_replace('', $ruleValue, $setup['match']); 528 | } 529 | $count = Lib::preg_match_all($match, $value, $temp); 530 | $failed = $rule === self::RULE_REP ? $count > 0 : $count < $ruleValue; 531 | if ($failed) { 532 | if ($hasModel) { 533 | $this->addError($model, $attribute, $this->$param, ['attribute' => $label, 'found' => $count]); 534 | } else { 535 | return [$this->$param, ['found' => $count]]; 536 | } 537 | } 538 | } elseif ($rule === self::RULE_HIBP && $ruleValue) { 539 | $hash = isset($value) ? sha1($value) : ''; 540 | $range = Lib::substr($hash, 0, 5); 541 | $needle = Lib::strtoupper(substr($hash, 5)); 542 | $url = $this->apiHIBP.Lib::urlencode($range); 543 | $result = empty($url) ? '' : file_get_contents($url); 544 | $result = empty($result) && $result !== '0' ? '' : 545 | Lib::preg_replace('/^([0-9A-Z]+:0)$/m', '', $result); 546 | if (Lib::strpos($result, $needle) !== false) { 547 | if ($hasModel) { 548 | $this->addError($model, $attribute, $this->$param, ['attribute' => $label]); 549 | } else { 550 | return [$this->$param, []]; 551 | } 552 | } 553 | } else { 554 | $length = isset($value) ? mb_strlen($value, $this->encoding) : 0; 555 | $test = false; 556 | if ($rule === self::RULE_LEN) { 557 | $test = ($length !== $ruleValue); 558 | } elseif ($rule === self::RULE_MIN) { 559 | $test = ($length < $ruleValue); 560 | } elseif ($rule === self::RULE_MAX) { 561 | $test = ($length > $ruleValue); 562 | } 563 | if ($ruleValue !== null && $rule !== self::RULE_REP && $test) { 564 | if ($hasModel) { 565 | $this->addError($model, $attribute, $this->$param, [ 566 | 'attribute' => $label.' ('.$rule.' , '.$ruleValue.')', 567 | 'found' => $length, 568 | ]); 569 | } else { 570 | return [$this->$param, ['found' => $length]]; 571 | } 572 | } 573 | } 574 | } 575 | return null; 576 | } 577 | 578 | /** 579 | * @inheritdoc 580 | */ 581 | public function validateAttribute($model, $attribute) 582 | { 583 | $this->performValidation(['model' => $model, 'attribute' => $attribute]); 584 | } 585 | 586 | /** 587 | * @inheritdoc 588 | */ 589 | protected function validateValue($value) 590 | { 591 | return $this->performValidation(['value' => $value]); 592 | } 593 | 594 | /** 595 | * @inheritdoc 596 | */ 597 | public function clientValidateAttribute($model, $attribute, $view) 598 | { 599 | $label = $model->getAttributeLabel($attribute); 600 | $options = [ 601 | 'strError' => Html::encode(Yii::t('kvpwdstrength', $this->message, ['attribute' => $label])), 602 | 'userField' => '#'.Html::getInputId($model, $this->userAttribute), 603 | ]; 604 | foreach (self::$_rules as $rule => $setup) { 605 | $param = "{$rule}Error"; 606 | if ($this->$rule !== null) { 607 | $options[$rule] = $this->$rule; 608 | $options[$param] = Html::encode(Yii::t('kvpwdstrength', $this->$param, ['attribute' => $label])); 609 | } 610 | } 611 | StrengthValidatorAsset::register($view); 612 | 613 | return "kvStrengthValidator.validate(value, messages, ".Json::encode($options).");"; 614 | } 615 | } 616 | --------------------------------------------------------------------------------