瀏覽代碼

Merge branch 'master' of https://github.com/unaio/una

AntonLV 8 年之前
父節點
當前提交
aeb986c93b

+ 6 - 0
inc/classes/BxDolAccount.php

@@ -154,6 +154,12 @@ class BxDolAccount extends BxDolFactory implements iBxDolSingleton
         return false;
     }
     
+    public function isLocked($iAccountId = false)
+    {
+        $a = $this->getInfo((int)$iAccountId);
+        return $a['locked'] ? true : false;
+    }
+    
     //
 
     /**

+ 34 - 1
inc/classes/BxDolAccountQuery.php

@@ -168,7 +168,40 @@ class BxDolAccountQuery extends BxDolDb implements iBxDolSingleton
      */
     public function updateLoggedIn($iID)
     {
-        $sQuery = $this->prepare("UPDATE `sys_accounts` SET `logged` = ?, `ip` = ? WHERE `id`= ?", time(), getVisitorIP(), $iID);
+        $sQuery = $this->prepare("UPDATE `sys_accounts` SET `logged` = ?, `ip` = ?, `login_attempts` = 0 WHERE `id`= ?", time(), getVisitorIP(), $iID);
+        return $this->query($sQuery);
+    }
+    
+    /**
+     * Update login attempts counter
+     * @param  int    $iID account id
+     * @return number of affected rows
+     */
+    public function updateAttemptsCounter($iID)
+    {
+        $sQuery = $this->prepare("UPDATE `sys_accounts` SET `login_attempts` = `login_attempts` + 1 WHERE `id`= ?", $iID);
+        return $this->query($sQuery);
+    }
+    
+    /**
+     * Lock account
+     * @param  int    $iID account id
+     * @return number of affected rows
+     */
+    public function lockAccount($iID)
+    {
+        $sQuery = $this->prepare("UPDATE `sys_accounts` SET `locked` = 1 WHERE `id`= ?", $iID);
+        return $this->query($sQuery);
+    }
+    
+    /**
+     * Unlock account
+     * @param  int    $iID account id
+     * @return number of affected rows
+     */
+    public function unlockAccount($iID)
+    {
+        $sQuery = $this->prepare("UPDATE `sys_accounts` SET `locked` = 0, `login_attempts` = 0 WHERE `id`= ?", $iID);
         return $this->query($sQuery);
     }
 

+ 17 - 3
inc/profiles.inc.php

@@ -184,10 +184,23 @@ function bx_check_password($sLogin, $sPassword, $iRole = BX_DOL_ROLE_MEMBER)
             'info' => $aAccountInfo,
 			'pwd' => $sPassword,
             'password' => &$sPassCheck,
-        ));		
-	
-    if ($sErrorMsg = bx_check_login($aAccountInfo['id'], $sPassCheck, $iRole))
+        ));
+    
+    if ($sErrorMsg = bx_check_login($aAccountInfo['id'], $sPassCheck, $iRole)){
+        $iMaxLoginAttempts = getParam('sys_account_limit_incorrect_login_attempts');
+        if ($iMaxLoginAttempts >0){
+            $oAccountQuery = BxDolAccountQuery::getInstance();
+            if ($aAccountInfo['login_attempts'] >= $iMaxLoginAttempts){
+                $oAccountQuery->lockAccount($aAccountInfo['id'], 1);
+                bx_import('BxDolLanguages');
+                return _t("_sys_txt_login_locked", BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=forgot-password'));
+            }
+            else{
+                $oAccountQuery->updateAttemptsCounter($aAccountInfo['id']);
+            }
+        }
         return $sErrorMsg;
+    }
 
     // Admin can always login even if he is blocked/banned/suspended/etc
     if (isAdmin($aAccountInfo['id']))
@@ -195,6 +208,7 @@ function bx_check_password($sLogin, $sPassword, $iRole = BX_DOL_ROLE_MEMBER)
 
     $sErrorMsg = '';
     bx_alert('account', 'check_login',  $aAccountInfo['id'], false, array('error_msg' => &$sErrorMsg));
+    
     return $sErrorMsg;
 }
 

+ 5 - 2
install/sql/system.sql

@@ -476,7 +476,8 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'sys_account_activation_2fa_enable', '_adm_stg_cpt_option_sys_account_2fa_enable', '', 'checkbox', '', '', '', 13),
 (@iCategoryId, 'sys_account_auto_profile_creation', '_adm_stg_cpt_option_sys_account_auto_profile_creation', 'on', 'checkbox', '', '', '', 15),
 (@iCategoryId, 'sys_account_default_profile_type', '_adm_stg_cpt_option_sys_account_default_profile_type', '', 'select', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:17:"get_profile_types";s:5:"class";s:20:"TemplServiceProfiles";}', '', '', 20),
-(@iCategoryId, 'sys_account_limit_profiles_number', '_adm_stg_cpt_option_sys_account_limit_profiles_number', '0', 'digit', '', '', '', 21);
+(@iCategoryId, 'sys_account_limit_profiles_number', '_adm_stg_cpt_option_sys_account_limit_profiles_number', '0', 'digit', '', '', '', 21),
+(@iCategoryId, 'sys_account_limit_incorrect_login_attempts', '_adm_stg_cpt_option_sys_account_limit_incorrect_login_attempts', '6', 'digit', '', '', '', 22);
 
 --
 -- CATEGORY: ACL
@@ -911,6 +912,8 @@ CREATE TABLE `sys_accounts` (
   `logged` int(11) NOT NULL DEFAULT '0',
   `ip` varchar(40) NOT NULL DEFAULT '',
   `reffered` varchar(255) NOT NULL DEFAULT '',
+  `login_attempts` tinyint(4) NOT NULL DEFAULT '0',
+  `locked` tinyint(4) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`),
   UNIQUE KEY `email` (`email`(191)),
   KEY `added` (`added`)
@@ -2900,7 +2903,7 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 ('sys_login', 'system', 'do_sendsms', '_sys_form_login_input_sendsms', '', 0, 'submit', '_sys_form_login_input_caption_system_sendsms', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 
 ('sys_account', 'system', 'email', '', '', 0, 'text', '_sys_form_login_input_caption_system_email', '_sys_form_account_input_email', '', 1, 0, 0, '', '', '', 'EmailUniq', '', '_sys_form_account_input_email_error', 'Xss', '', 0, 0),
-('sys_account', 'system', 'password', '', '', 0, 'password', '_sys_form_login_input_caption_system_password', '_sys_form_account_input_password', '', 1, 0, 0, '', '', '', 'Length', 'a:2:{s:3:"min";i:6;s:3:"max";i:1024;}', '_sys_form_account_input_password_error', '', '', 0, 0),
+('sys_account', 'system', 'password', '', '', 0, 'password', '_sys_form_login_input_caption_system_password', '_sys_form_account_input_password', '', 1, 0, 0, '', '', '', 'Preg', 'a:1:{s:4:"preg";s:38:"~^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}~";}', '_sys_form_account_input_password_error', '', '', 0, 0),
 ('sys_account', 'system', 'password_confirm', '', '', 0, 'password', '_sys_form_login_input_caption_system_password_confirm', '_sys_form_account_input_password_confirm', '', 1, 0, 0, '', '', '', 'PasswordConfirm', '', '_sys_form_account_input_password_confirm_error', '', '', 0, 0),
 ('sys_account', 'system', 'do_submit', '_sys_form_account_input_submit', '', 0, 'submit', '_sys_form_login_input_caption_system_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('sys_account', 'system', 'name', '', '', 0, 'text', '_sys_form_login_input_caption_system_name', '_sys_form_account_input_name', '', 1, 0, 0, '', '', '', 'Avail', '', '_sys_form_account_input_name_error', 'Xss', '', 1, 0),

+ 1 - 0
modules/boonex/accounts/classes/BxAccntConfig.php

@@ -40,6 +40,7 @@ class BxAccntConfig extends BxBaseModGeneralConfig
                 'filter_item_operators' => '_bx_accnt_grid_filter_item_title_adm_operators',
             	'filter_item_pending' => '_bx_accnt_grid_filter_item_title_adm_pending',
             	'filter_item_suspended' => '_bx_accnt_grid_filter_item_title_adm_suspended',
+                'filter_item_locked' => '_bx_accnt_grid_filter_item_title_adm_locked',
             	'filter_item_select_one_filter1' => '_bx_accnt_grid_filter_item_title_adm_select_one_filter1',
                 'filter_item_select_one_filter2' => '_bx_accnt_grid_filter_item_title_adm_select_one_filter2',
         	)

+ 36 - 5
modules/boonex/accounts/classes/BxAccntGridAdministration.php

@@ -19,8 +19,10 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
     {
     	$this->MODULE = 'bx_accounts';
         parent::__construct ($aOptions, $oTemplate);
-
+        
         $CNF = &$this->_oModule->_oConfig->CNF;
+        $this->_aFilter1Values['locked'] = $CNF['T']['filter_item_locked'];
+       
         $this->_sFilter2Name = 'filter2';
         $this->_aFilter2Values = array(
             'operators' => $CNF['T']['filter_item_operators']
@@ -38,8 +40,12 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
         if(strpos($sFilter, $this->_sParamsDivider) !== false)
             list($this->_sFilter1Value, $this->_sFilter2Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
 
-    	if(!empty($this->_sFilter1Value))
-        	$this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `tp`.`status`=?", $this->_sFilter1Value);
+    	if(!empty($this->_sFilter1Value)){
+            if ($this->_sFilter1Value != 'locked')
+        	    $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `tp`.`status`=?", $this->_sFilter1Value);
+            else
+                $this->_aOptions['source'] .= " AND `ta`.`locked` = 1";
+        }
         
         if(!empty($this->_sFilter2Value))
         	$this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `ta`.`role` & " . BX_DOL_ROLE_ADMIN ." = " . BX_DOL_ROLE_ADMIN);
@@ -183,6 +189,26 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
 
         return echoJson($aRes);
     }
+    
+    public function performActionUnlockAccount()
+    {
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+		$oAccountQuery = BxDolAccountQuery::getInstance();
+		foreach($aIds as $iId){
+			$oAccount = BxDolAccount::getInstance($iId);
+			if(!$oAccount)
+				continue;
+			if ($oAccount->isLocked()){
+				$oAccountQuery->unlockAccount($iId);
+			}
+		}
+		$aRes = array('grid' => $this->getCode(false), 'blink' => $aIds);
+        return echoJson($aRes);
+    }
 
 	public function performActionMakeOperator()
     {
@@ -259,7 +285,7 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
     {
         return '';
     }
-
+    
     protected function _getCellEmailConfirmed($mixedValue, $sKey, $aField, $aRow)
     {
     	$mixedValue = (int)$mixedValue == 1 ? '_Yes' : '_No';
@@ -270,12 +296,17 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
     {
         return '';
     }
+    
+    protected function _getActionUnlockAccount($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
 
     protected function _getCellName($mixedValue, $sKey, $aField, $aRow)
     {
         $oAccount = BxDolAccount::getInstance($aRow['id']);
         if ($oAccount)
-            $s = $oAccount->getDisplayName();
+            $s = ($aRow['locked'] == 1 ? $this->_oTemplate->parseIcon("lock col-red1") . ' ' : '') . $oAccount->getDisplayName();
         return parent::_getCellDefault ($s, $sKey, $aField, $aRow);
     }
     

+ 3 - 0
modules/boonex/accounts/classes/BxAccntMenuManageTools.php

@@ -47,6 +47,9 @@ class BxAccntMenuManageTools extends BxBaseModGeneralMenuManageTools
             case 'unmake-operator':
             	$sCheckFuncName = 'checkAllowedUnmakeOperator';
             	break;
+            case 'unlock-account':
+            	$sCheckFuncName = 'checkAllowedUnlockAccount';
+            	break;
         }
 
         if(!$sCheckFuncName || !method_exists($this->_oModule, $sCheckFuncName))

+ 8 - 0
modules/boonex/accounts/classes/BxAccntModule.php

@@ -81,6 +81,14 @@ class BxAccntModule extends BxBaseModGeneralModule
 
     	return CHECK_ACTION_RESULT_ALLOWED;
     }
+    
+    public function checkAllowedUnlockAccount(&$aDataEntry, $isPerformAction = false)
+    {
+    	if((int)$aDataEntry['locked'] != 1)
+    		return _t('_sys_txt_access_denied');
+
+    	return CHECK_ACTION_RESULT_ALLOWED;
+    }
 }
 
 /** @} */

+ 2 - 2
modules/boonex/accounts/classes/BxAccntStudioPage.php

@@ -39,8 +39,8 @@ class BxAccntStudioPage extends BxTemplStudioModule
         if(!$oGrid)
             return '';
 
-        $this->_oModule->_oTemplate->addStudioCss(array('manage_tools.css'));
-        $this->_oModule->_oTemplate->addStudioJs(array('manage_tools.js'));
+        $this->_oModule->_oTemplate->addStudioCss(array('manage_tools.css', 'main.css'));
+        $this->_oModule->_oTemplate->addStudioJs(array('manage_tools.js', 'main.js'));
         $this->_oModule->_oTemplate->addStudioJsTranslation(array('_sys_grid_search'));
         return $this->_oModule->_oTemplate->getJsCode('manage_tools', array('sObjNameGrid' => $sGrid)) . $oGrid->getCode();
     }

+ 7 - 2
modules/boonex/accounts/install/langs/en.xml

@@ -21,6 +21,8 @@
     <string name="_bx_accnt_menu_item_title_edit_email"><![CDATA[Edit Email]]></string>
     <string name="_bx_accnt_menu_item_title_system_reset_password"><![CDATA[Reset Password]]></string>
     <string name="_bx_accnt_menu_item_title_reset_password"><![CDATA[Reset Password]]></string>
+    <string name="_bx_accnt_menu_item_title_system_unlock_account"><![CDATA[Unlock]]></string>
+    <string name="_bx_accnt_menu_item_title_unlock_account"><![CDATA[Unlock]]></string>
     <string name="_bx_accnt_menu_item_title_system_delete"><![CDATA[Delete]]></string>
     <string name="_bx_accnt_menu_item_title_delete"><![CDATA[Delete]]></string>
     <string name="_bx_accnt_menu_item_title_system_delete_with_content"><![CDATA[Delete With Content]]></string>
@@ -41,6 +43,7 @@
   <string name="_bx_accnt_grid_filter_item_title_adm_operators"><![CDATA[Operators]]></string>
 	<string name="_bx_accnt_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
 	<string name="_bx_accnt_grid_filter_item_title_adm_suspended"><![CDATA[Suspended]]></string>
+  <string name="_bx_accnt_grid_filter_item_title_adm_locked"><![CDATA[Locked]]></string>
 	<string name="_bx_accnt_grid_column_title_adm_active"><![CDATA[Active]]></string>
     <string name="_bx_accnt_grid_column_title_adm_name"><![CDATA[Name]]></string>
     <string name="_bx_accnt_grid_column_title_adm_email"><![CDATA[Email]]></string>
@@ -54,13 +57,15 @@
 	<string name="_bx_accnt_grid_action_title_adm_edit_email"><![CDATA[Edit Email]]></string>
     <string name="_bx_accnt_grid_action_title_adm_resend_cemail"><![CDATA[Resend Confirmation]]></string>
     <string name="_bx_accnt_grid_action_title_adm_reset_password"><![CDATA[Reset Password]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_unlock_account"><![CDATA[Unlock]]></string>
     <string name="_bx_accnt_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
     <string name="_bx_accnt_grid_action_title_adm_delete_with_content"><![CDATA[Delete With Content]]></string>
     <string name="_bx_accnt_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
     <string name="_bx_accnt_grid_action_err_delete"><![CDATA[Cannot delete the selected account(s).]]></string>
     <string name="_bx_accnt_grid_action_err_perform"><![CDATA[Cannot perform the action for selected account(s).]]></string>
-
-    <string name="_bx_accnt_grid_confirmation_status_none"><![CDATA[No]]></string>
+    <string name="_bx_accnt_grid_action_unlock_successed"><![CDATA[Successfully unlocked]]></string>
+    <string name="_bx_accnt_grid_action_unlock_error"><![CDATA[Account is not blocked]]></string>
+  <string name="_bx_accnt_grid_confirmation_status_none"><![CDATA[No]]></string>
     <string name="_bx_accnt_grid_confirmation_status_email"><![CDATA[Email]]></string>
     <string name="_bx_accnt_grid_confirmation_status_phone"><![CDATA[Phone]]></string>
     <string name="_bx_accnt_grid_confirmation_status_email_and_phone"><![CDATA[All]]></string>

+ 7 - 5
modules/boonex/accounts/install/sql/enable.sql

@@ -20,10 +20,11 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('bx_accounts_menu_manage_tools', @sName, 'edit-email', '_bx_accnt_menu_item_title_system_edit_email', '_bx_accnt_menu_item_title_edit_email', 'javascript:void(0)', 'javascript:{js_object}.onClickEditEmail({content_id}, this);', '_self', 'at', '', 192, 1, 0, 1),
 ('bx_accounts_menu_manage_tools', @sName, 'resend-cemail', '_bx_accnt_menu_item_title_system_resend_cemail', '_bx_accnt_menu_item_title_resend_cemail', 'javascript:void(0)', 'javascript:{js_object}.onClickResendCemail({content_id}, this);', '_self', 'envelope-o', '', 192, 1, 0, 2),
 ('bx_accounts_menu_manage_tools', @sName, 'reset-password', '_bx_accnt_menu_item_title_system_reset_password', '_bx_accnt_menu_item_title_reset_password', 'javascript:void(0)', 'javascript:{js_object}.onClickResetPassword({content_id}, this);', '_self', 'eraser', '', 192, 1, 0, 3),
-('bx_accounts_menu_manage_tools', @sName, 'delete', '_bx_accnt_menu_item_title_system_delete', '_bx_accnt_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id}, this);', '_self', 'trash-o', '', 192, 1, 0, 4),
-('bx_accounts_menu_manage_tools', @sName, 'delete-with-content', '_bx_accnt_menu_item_title_system_delete_with_content', '_bx_accnt_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id}, this);', '_self', 'trash-o', '', 192, 1, 0, 5),
-('bx_accounts_menu_manage_tools', @sName, 'make-operator', '_bx_accnt_menu_item_title_system_make_operator', '_bx_accnt_menu_item_title_make_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickMakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 6),
-('bx_accounts_menu_manage_tools', @sName, 'unmake-operator', '_bx_accnt_menu_item_title_system_unmake_operator', '_bx_accnt_menu_item_title_unmake_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickUnmakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 7);
+('bx_accounts_menu_manage_tools', @sName, 'unlock-account', '_bx_accnt_menu_item_title_system_unlock_account', '_bx_accnt_menu_item_title_unlock_account', 'javascript:void(0)', 'javascript:{js_object}.onClickUnlockAccount({content_id}, this);', '_self', 'unlock', '', 192, 1, 0, 4),
+('bx_accounts_menu_manage_tools', @sName, 'delete', '_bx_accnt_menu_item_title_system_delete', '_bx_accnt_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id}, this);', '_self', 'trash-o', '', 192, 1, 0, 5),
+('bx_accounts_menu_manage_tools', @sName, 'delete-with-content', '_bx_accnt_menu_item_title_system_delete_with_content', '_bx_accnt_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id}, this);', '_self', 'trash-o', '', 192, 1, 0, 6),
+('bx_accounts_menu_manage_tools', @sName, 'make-operator', '_bx_accnt_menu_item_title_system_make_operator', '_bx_accnt_menu_item_title_make_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickMakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 7),
+('bx_accounts_menu_manage_tools', @sName, 'unmake-operator', '_bx_accnt_menu_item_title_system_unmake_operator', '_bx_accnt_menu_item_title_unmake_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickUnmakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 8);
 
 -- MENU: dashboard manage tools
 SET @iManageMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard_manage_tools' LIMIT 1);
@@ -75,4 +76,5 @@ INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon
 ('bx_accounts_administration', 'bulk', 'delete_with_content', '_bx_accnt_grid_action_title_adm_delete_with_content', '', 0, 1, 5),
 ('bx_accounts_administration', 'single', 'edit_email', '_bx_accnt_grid_action_title_adm_edit_email', '', 0, 0, 0),
 ('bx_accounts_administration', 'single', 'reset_password', '_bx_accnt_grid_action_title_adm_reset_password', '', 0, 0, 0),
-('bx_accounts_administration', 'single', 'settings', '_bx_accnt_grid_action_title_adm_more_actions', 'cog', 1, 0, 1);
+('bx_accounts_administration', 'single', 'unlock_account', '_bx_accnt_grid_action_title_adm_unlock_account', '', 0, 0, 0),
+('bx_accounts_administration', 'single', 'settings', '_bx_accnt_grid_action_title_adm_more_actions', 'cog', 1, 0, 2);

+ 8 - 0
modules/boonex/accounts/js/manage_tools.js

@@ -74,6 +74,14 @@ BxAccntManageTools.prototype.onClickResetPassword = function(iContentId, oLink)
 	oGrid.actionWithId(iContentId, 'reset_password', oData, '', false, 0);
 };
 
+BxAccntManageTools.prototype.onClickUnlockAccount = function (iContentId, oLink) {
+    $('.bx-popup-applied:visible').dolPopupHide();
+
+    var oGrid = glGrids[this._sObjNameGrid];
+    var oData = oGrid._checkAppend(oLink, oGrid._getActionDataForReload());
+    oGrid.actionWithId(iContentId, 'unlock_account', oData, '', false, 0);
+};
+
 BxAccntManageTools.prototype.onClickDelete = function(iContentId, oLink) {
 	$('.bx-popup-applied:visible').dolPopupHide();
 

+ 4 - 1
modules/boonex/english/data/langs/system/en.xml

@@ -1265,6 +1265,7 @@
     <string name="_adm_stg_err_option_sys_account_online_time"><![CDATA[You need to enter a value greater than zero.]]></string>
     <string name="_adm_stg_cpt_option_sys_account_default_profile_type"><![CDATA[Default profile type]]></string>
 	<string name="_adm_stg_cpt_option_sys_account_limit_profiles_number"><![CDATA[Limit number of profiles (0 - no limit)]]></string>
+  <string name="_adm_stg_cpt_option_sys_account_limit_incorrect_login_attempts"><![CDATA[Max number of logins attempts (0 - no limit)]]></string>
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notification_days"><![CDATA[Number of days before membership expiration to notify members (-1 = after expiration)]]></string>
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notify_once"><![CDATA[Notify members about membership expiration only once (every day otherwise)]]></string>
 	<string name="_adm_stg_cpt_option_sys_add_nofollow"><![CDATA[Add "nofollow" attribute for external links]]></string>
@@ -1892,7 +1893,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_form_account_input_password_confirm_error"><![CDATA[Password confirmation failed]]></string>
 	<string name="_sys_form_account_input_password_current"><![CDATA[Current Password]]></string>
 	<string name="_sys_form_account_input_password_current_error"><![CDATA[Current password isn't correct, please enter password you are using to login to this site.]]></string>
-	<string name="_sys_form_account_input_password_error"><![CDATA[Password must at least 6 characters long.]]></string>
+	<string name="_sys_form_account_input_password_error"><![CDATA[The password must at least 8 characters long and contain at least 1 uppercase letter, 1 lowercase letter and 1 digit.]]></string>
 	<string name="_sys_form_account_input_receive_news"><![CDATA[Receive Newsletters]]></string>
 	<string name="_sys_form_account_input_receive_updates"><![CDATA[Receive Site Updates]]></string>
 	<string name="_sys_form_account_input_submit"><![CDATA[Submit]]></string>
@@ -2596,6 +2597,8 @@ If it is not enabled then please consider implement this optimization, since it
     <string name="_sys_txt_join_description"><![CDATA[Already a member? <a href="{0}">Log in.</a>]]></string>
 	<string name="_sys_txt_login_description"><![CDATA[Not a member yet? <a href="{0}">Sign up.</a>]]></string>
 	<string name="_sys_txt_login_error"><![CDATA[Entered email or password is incorrect. Please try again.]]></string>
+  <string name="_sys_txt_login_locked"><![CDATA[Your account is locked and needs to be unlocked using <a href="{0}">forgot password page</a>.]]></string>
+  
 	<string name="_sys_txt_login_invalid_role"><![CDATA[Access denied]]></string>
     <string name="_sys_txt_my_profiles"><![CDATA[Create a new profile]]></string>
     <string name="_sys_txt_new_picture"><![CDATA[New Picture]]></string>

+ 9 - 3
modules/boonex/russian/data/langs/bx_accounts/ru.xml

@@ -21,6 +21,8 @@
     <string name="_bx_accnt_menu_item_title_resend_cemail"><![CDATA[Переслать подтверждение]]></string>
     <string name="_bx_accnt_menu_item_title_system_reset_password"><![CDATA[Сбросить пароль]]></string>
     <string name="_bx_accnt_menu_item_title_reset_password"><![CDATA[Сбросить пароль]]></string>
+    <string name="_bx_accnt_menu_item_title_system_unlock_account"><![CDATA[Разблокировать]]></string>
+    <string name="_bx_accnt_menu_item_title_unlock_account"><![CDATA[Разблокировать]]></string>
     <string name="_bx_accnt_menu_item_title_system_delete"><![CDATA[Удалить]]></string>
     <string name="_bx_accnt_menu_item_title_delete"><![CDATA[Удалить]]></string>
     <string name="_bx_accnt_menu_item_title_system_delete_with_content"><![CDATA[Удалить вместе с содержимым]]></string>
@@ -36,8 +38,10 @@
 	<string name="_bx_accnt_grid_filter_item_title_adm_active"><![CDATA[Активный]]></string>
   <string name="_bx_accnt_grid_filter_item_title_adm_operators"><![CDATA[Операторы]]></string>
 	<string name="_bx_accnt_grid_filter_item_title_adm_pending"><![CDATA[Неактивный]]></string>
-	<string name="_bx_accnt_grid_filter_item_title_adm_suspended"><![CDATA[Заблокированный]]></string>
-	<string name="_bx_accnt_grid_column_title_adm_active"><![CDATA[Активный]]></string>
+	<string name="_bx_accnt_grid_filter_item_title_adm_suspended"><![CDATA[Приостановленный]]></string>
+  <string name="_bx_accnt_grid_filter_item_title_adm_locked"><![CDATA[Заблокированный]]></string>
+  
+  <string name="_bx_accnt_grid_column_title_adm_active"><![CDATA[Активный]]></string>
     <string name="_bx_accnt_grid_column_title_adm_name"><![CDATA[Имя]]></string>
     <string name="_bx_accnt_grid_column_title_adm_email"><![CDATA[Имейл]]></string>
   <string name="_bx_accnt_grid_column_title_adm_ip"><![CDATA[IP]]></string>
@@ -49,12 +53,14 @@
 	<string name="_bx_accnt_grid_action_title_adm_edit_email"><![CDATA[Изменить имейл]]></string>
     <string name="_bx_accnt_grid_action_title_adm_resend_cemail"><![CDATA[Переслать подтверждение]]></string>
     <string name="_bx_accnt_grid_action_title_adm_reset_password"><![CDATA[Сбросить пароль]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_unlock_account"><![CDATA[Разблокировать]]></string>
     <string name="_bx_accnt_grid_action_title_adm_delete"><![CDATA[Удалить]]></string>
     <string name="_bx_accnt_grid_action_title_adm_delete_with_content"><![CDATA[Удалить вместе с содержимым]]></string>
     <string name="_bx_accnt_grid_action_title_adm_more_actions"><![CDATA[Дополнительно]]></string>
     <string name="_bx_accnt_grid_action_err_delete"><![CDATA[Невозможно удалить выбранный(ные) аккаунт(ы).]]></string>
     <string name="_bx_accnt_grid_action_err_perform"><![CDATA[Невозможно выполнить действие для выбранного(ных) аккаунта(ов).]]></string>
-
+    <string name="_bx_accnt_grid_action_unlock_successed"><![CDATA[Успешно разблокирован]]></string>
+    <string name="_bx_accnt_grid_action_unlock_error"><![CDATA[Аккаунт не является заблокированным]]></string>
     <string name="_bx_accnt_grid_confirmation_status_none"><![CDATA[Нет]]></string>
     <string name="_bx_accnt_grid_confirmation_status_email"><![CDATA[Email]]></string>
     <string name="_bx_accnt_grid_confirmation_status_phone"><![CDATA[Телефон]]></string>

+ 4 - 2
modules/boonex/russian/data/langs/system/ru.xml

@@ -1262,7 +1262,8 @@
 	<string name="_adm_stg_cpt_option_sys_account_online_time"><![CDATA[Временные рамки статуса "онлайн" (минуты)]]></string>
     <string name="_adm_stg_err_option_sys_account_online_time"><![CDATA[Вам необходимо ввести значение больше нуля.]]></string>
     <string name="_adm_stg_cpt_option_sys_account_default_profile_type"><![CDATA[Тип профиля по умолчанию]]></string>
-    <string name="_adm_stg_cpt_option_sys_account_limit_profiles_number"><![CDATA[Ограничить число профилей (0 - без ограничений)]]></string>
+  <string name="_adm_stg_cpt_option_sys_account_limit_profiles_number"><![CDATA[Ограничить число профилей (0 - без ограничений)]]></string>
+  <string name="_adm_stg_cpt_option_sys_account_limit_incorrect_login_attempts"><![CDATA[Количество попыток ввода пароля (0 - без ограничений)]]></string>
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notification_days"><![CDATA[За сколько дней до окончания членства оповестить пользователя об окончании (-1 = после окончания)]]></string>
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notify_once"><![CDATA[Оповещать пользователей об окончании членства только одинажды (каждый день в противном случае)]]></string>
 	<string name="_adm_stg_cpt_option_sys_add_nofollow"><![CDATA[Добавить атрибут "nofollow" для внешних ссылок]]></string>
@@ -1891,7 +1892,7 @@
 	<string name="_sys_form_account_input_password_confirm_error"><![CDATA[Не удалось подтвердить пароль]]></string>
 	<string name="_sys_form_account_input_password_current"><![CDATA[Текущий пароль]]></string>
 	<string name="_sys_form_account_input_password_current_error"><![CDATA[Неправильный текущий пароль. Введите пароль, который Вы используете для доступа к этому сайту.]]></string>
-	<string name="_sys_form_account_input_password_error"><![CDATA[Пароль должен иметь как минимум 6 символов.]]></string>
+	<string name="_sys_form_account_input_password_error"><![CDATA[Пароль должен иметь как минимум 8 символов, и содержать по крайней мере 1 прописную латинскую букву, 1 строчную латинскую букву и 1 число.]]></string>
 	<string name="_sys_form_account_input_phone_error"><![CDATA[Это обязательное поле.]]></string>
 	<string name="_sys_form_account_input_receive_news"><![CDATA[Получать новости]]></string>
 	<string name="_sys_form_account_input_receive_updates"><![CDATA[Получать обновления сайта]]></string>
@@ -2594,6 +2595,7 @@
 	<string name="_sys_txt_join_description"><![CDATA[Уже зарегистрировались? <a href="{0}">Заходите.</a>]]></string>
 	<string name="_sys_txt_login_description"><![CDATA[Ещё нет аккаунта? <a href="{0}">Зарегистрируйтесь.</a>]]></string>
 	<string name="_sys_txt_login_error"><![CDATA[Введённый имейл или пароль неправильны. Пожалуйста, попытайтесь снова.]]></string>
+  <string name="_sys_txt_login_locked"><![CDATA[Ваш аккаунт заблокирован, для разблокировки, пожалуйста, используйте  <a href="{0}">страницу сброса пароля</a>.]]></string>
 	<string name="_sys_txt_login_invalid_role"><![CDATA[Доступ запрещён]]></string>
     <string name="_sys_txt_my_profiles"><![CDATA[Создать новый профайл]]></string>
     <string name="_sys_txt_new_picture"><![CDATA[Новая картинка]]></string>

+ 0 - 1
template/scripts/BxBaseFormAccount.php

@@ -59,7 +59,6 @@ class BxFormAccountCheckerHelper extends BxDolFormCheckerHelper
 
         return BxDolAccountQuery::getInstance()->getIdByEmail($s) ? _t('_sys_form_account_input_email_uniq_error', BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=forgot-password')) : true;
     }
-
 }
 
 /**

+ 3 - 0
template/scripts/BxBaseServiceAccount.php

@@ -436,6 +436,9 @@ class BxBaseServiceAccount extends BxDol
 
         $aTemplate = BxDolEmailTemplates::getInstance() -> parseTemplate('t_PasswordReset', $aPlus, $iAccountId);
 
+		$oAccountQuery = BxDolAccountQuery::getInstance();
+		$oAccountQuery->unlockAccount($iAccountId);
+		
         if ($aTemplate && sendMail($aData['email'], $aTemplate['Subject'], $aTemplate['Body'], 0, $aPlus, BX_EMAIL_SYSTEM))
             return _t("_sys_txt_reset_pasword_email_sent", $sPassword);
         else