Jump to content

  • You cannot start a new topic
  • You cannot reply to this topic

Force All Users To Change Password On Next Login Rate Topic   * * * * * 2 votes

 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 30 May 2014 - 07:17 PM #1

The following code will force users to change their passwords on their next login attempt and will set the lifetime of a password to 365 days (only if it is currently set to zero).

These changes only apply to users who are NOT admin users with the "is_root" property == 'Y'. I.e. the primary admin should be unaffected.

This same code will work on all versions but needs to be installed in different locations depending on whether you are V4 or earlier.

Follow the instructions in the comments.
It is reasonably well tested and should work in PRO, ULTIMATE and MVE environments.

<?php

/*
 * For V4, copy this file to app/addons/my_changes/controllers/backend/my_changes.php
 * Make sure the My Changes addon is active
 * Then run this url: [your_domain_admin.php]?dispatch=my_changes.reset_user_passwords
 *
 * For V2/V3, copy this file to addons/my_changes/controllers/admin/my_changes.php
 * Make sure the My Changes addon is active
 * Then run this url: [your_domain_admin.php]?dispatch=my_changes.reset_user_passwords
 *
 * What will it do?
 *    - Changes the last password change timestamp to 1969 for all "Non admin root" users.
 *    - Changes the required password change time to 1 year if it is set to zero.  If set to some other
 *      value then it leaves this alone.
 *    - Any user (admin, supplier, vendor or customer other than a root-admin-user) will be required to
 *      change their password.
 *    - You will see a yellow warning message after this completes.
 *
 * You might see a message indicating that you need to change your password.  You can close that message
 * and ignore it if you are logged in as the root admin.
 */

if( !defined('PRODUCT_VERSION') ) die('Access denied');

if( version_compare(PRODUCT_VERSION, '4.0.0', '<') )
    if( !defined('AREA') ) die('Access denied');
else
    if( !defined('BOOTSTRAP') ) die('Access denied');
    
switch($mode) {
    case 'reset_user_passwords':
        $user_ids = db_get_fields("SELECT user_id FROM ?:users WHERE is_root != 'Y'");
        $user_count = count($user_ids);
        db_query("UPDATE ?:users SET password_change_timestamp=1 WHERE is_root != 'Y'");
        db_query("UPDATE ?:users SET password_change_timestamp=?i WHERE is_root = 'Y'", TIME);
        $msg = "<br/>Your previous password expiration was set to zero.  It has been reset to 365.";
        if( version_compare(PRODUCT_VERSION, '3.0.0', '<') ) {
            $cur_days = db_get_field("SELECT value FROM ?:settings WHERE option_name='admin_password_expiration_period'");
            if( !$cur_days ) {
                db_query("UPDATE ?:settings SET value = 365 WHERE option_name = 'admin_password_expiration_period' AND value = 0");
            } else {
                $msg = '';
            }
        } else {
            $cur_days = db_get_field("SELECT value FROM ?:settings_objects WHERE name='admin_password_expiration_period'");
            if( !$cur_days ) {
                db_query("UPDATE ?:settings_objects SET value = 365 WHERE name = 'admin_password_expiration_period' AND value = 0");
            } else {
                $msg = '';
            }
        }

        fn_set_notification('W', "Force password change", "'$user_count' users will be asked to change their passwords next time they login.$msg", true');
        fn_redirect(empty($index_script) ? "/" : $index_script);
        break;
}
return array(CONTROLLER_STATUS_OK);

?>

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 11 March 2015 - 02:36 PM #2

Thank you for this code! There is a small typo in the fn_set_notification, this is the correct code:

<?php

/*
* For V4, copy this file to app/addons/my_changes/controllers/backend/my_changes.php
* Make sure the My Changes addon is active
* Then run this url: [your_domain_admin.php]?dispatch=my_changes.reset_user_passwords
*
* For V2/V3, copy this file to addons/my_changes/controllers/admin/my_changes.php
* Make sure the My Changes addon is active
* Then run this url: [your_domain_admin.php]?dispatch=my_changes.reset_user_passwords
*
* What will it do?
*	- Changes the last password change timestamp to 1969 for all "Non admin root" users.
*	- Changes the required password change time to 1 year if it is set to zero.  If set to some other
*	  value then it leaves this alone.
*	- Any user (admin, supplier, vendor or customer other than a root-admin-user) will be required to
*	  change their password.
*	- You will see a yellow warning message after this completes.
*
* You might see a message indicating that you need to change your password.  You can close that message
* and ignore it if you are logged in as the root admin.
*/

if( !defined('PRODUCT_VERSION') ) die('Access denied');

if( version_compare(PRODUCT_VERSION, '4.0.0', '<') )
	if( !defined('AREA') ) die('Access denied');
else
	if( !defined('BOOTSTRAP') ) die('Access denied');
	
switch($mode) {
	case 'reset_user_passwords':
		$user_ids = db_get_fields("SELECT user_id FROM ?:users WHERE is_root != 'Y'");
		$user_count = count($user_ids);
		db_query("UPDATE ?:users SET password_change_timestamp=1 WHERE is_root != 'Y'");
		db_query("UPDATE ?:users SET password_change_timestamp=?i WHERE is_root = 'Y'", TIME);
		$msg = "<br/>Your previous password expiration was set to zero.  It has been reset to 365.";
		if( version_compare(PRODUCT_VERSION, '3.0.0', '<') ) {
			$cur_days = db_get_field("SELECT value FROM ?:settings WHERE option_name='admin_password_expiration_period'");
			if( !$cur_days ) {
				db_query("UPDATE ?:settings SET value = 365 WHERE option_name = 'admin_password_expiration_period' AND value = 0");
			} else {
				$msg = '';
			}
		} else {
			$cur_days = db_get_field("SELECT value FROM ?:settings_objects WHERE name='admin_password_expiration_period'");
			if( !$cur_days ) {
				db_query("UPDATE ?:settings_objects SET value = 365 WHERE name = 'admin_password_expiration_period' AND value = 0");
			} else {
				$msg = '';
			}
		}

		fn_set_notification('W', "Force password change", "$user_count users will be asked to change their passwords next time they login. $msg", true);
		fn_redirect(empty($index_script) ? "/" : $index_script);
		break;
}
return array(CONTROLLER_STATUS_OK);
?>

Unfortunately after testing in version 4.2.3 I noticed it's not working. At least. After logging in with a customer account it doesn't tell me to change the password. So I searched the CS-Cart files for the lang var "error_password_expired" and it only appears in \app\controllers\backend\init.php and \design\backend\templates\views\auth\password_change.tpl.

So I'm guessing more code changes need to be made to make it work with customers in the front-end.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 11 March 2015 - 07:45 PM #3

It should work in V4.x. Verify that the change_password_timestamp field in the cscart_users table has been correctly set to 1 for non-primary-admin users.

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 12 March 2015 - 08:49 AM #4

Thank you for your reply! Yes, all users except the admin are set to 1. But after logging in as a customer to the front end it only shows "logged in successfully".

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 12 March 2015 - 06:51 PM #5

Then I think something else is wrong. The code clearly checks to see if the change_password_timestamp is less than TIME (current timestamp) and if so, should force a change. Maybe they broke it in this version. Might want to submit a bug in bugtracker.

And is the error you mentioned in fn_set_notification the missing space between the notice of the number of users changed and the $msg variable?

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 13 March 2015 - 08:47 AM #6

I checked with CS-Cart support and it seems to be a bug. As soon as I have a working solution, I'll post it here.

As for the code correction. I changed:
fn_set_notification('W', "Force password change", "'$user_count' users will be asked to change their passwords next time they login.$msg", true');
to
fn_set_notification('W', "Force password change", "$user_count users will be asked to change their passwords next time they login.$msg", true);

So I removed the ' after "true". As you can see it's messing up the code coloring.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 13 March 2015 - 04:22 PM #7

Okay, didn't catch that. Old eyes don't see single quotes very well here....:-)

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 16 March 2015 - 09:50 AM #8

:grin: no problem.

CS-Cart told me to change some code:

The issue may be caused by a bug in the current version of Multi-Vendor.

In order to fix it, open the app/functions/fn.users.php file of your installation and replace this line:

$has_permissions = false;

with this part of code:
if ($auth['user_id'] != $user_data['user_id']) {
	$has_permissions = false;
}

The $has_permissions = false; line is used two times. You will need to replace the one which is after the following line:
} elseif ($auth['user_type'] == 'V' && $user_data['is_root'] == 'Y') {


Unfortunately after this, still only users in the back-end will have to change their password. I'm guessing they removed this function for front-end users, since I only see After logging in with a customer account it doesn't tell me to change the password. the lang var "error_password_expired" in \app\controllers\backend\init.php and \design\backend\templates\views\auth\password_change.tpl.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 16 March 2015 - 06:18 PM #9

Not sure why they would remove a functioning feature that lets an administrator tighten the security of their site by forcing users to change their passwords at some administrator defined frequency.

The change you list above seems to only applies to Vendors, not Customers.

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 18 March 2015 - 10:44 AM #10

As expected I got this answer from CS-Cart:

My name is Timur Mestan-zade. I am a technical support engineer at CS-Cart. I will continue communicating with you in this ticket.

I should inform you that there was no such feature as forcing customers to change their passwords in default CS-Cart. This functionality requires an additional code modification.

I am afraid, it cannot be made as a part of our technical support service, so we can offer you the customization services offered by our affiliate company Simtech Development Ltd (reorganization took place in our company and now our Custom Development department acts as a separate legal entity. Their company name is Simtech Development Ltd and the website is http://www.simtechdev.com ).

For your convenience we can forward your request to Simtech Development Ltd for an estimation, please let me know if you are interested in it.


Do you have a working "demo" of the force password change for customers? Would like to show them.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 18 March 2015 - 06:07 PM #11

Just tell them the password_change_timestamp was set to 1 in the DB and when a user logs in to your site it does not ask them to change the password. Obviously 1 is less than the current timestamp (TIME). I.e. the password has expired.

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 20 March 2015 - 10:09 AM #12

I did, but still.. offering Simtech to make the changes.
I see no other option than having someone customize the code to make it work in Multi-Vendor 4.2.4, but not by Simtech. You can PM me if you are interrested. My client needs it next week.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 21 March 2015 - 11:38 PM #13

You can request a quote by using the link in my signature. I.e. "get a quote".

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • scooterlord
  • Advanced Member
  • Members
  • Join Date: 29-Jun 13
  • 111 posts

Posted 18 April 2015 - 08:07 PM #14

Hello. Have you found a solution to this? Also, will this work for the free version of cscart?

 
  • maxam
  • Junior Member
  • Members
  • Join Date: 20-Apr 11
  • 72 posts

Posted 19 April 2015 - 10:15 AM #15

I checked with CS-Cart support and it seems to be a bug. As soon as I have a working solution, I'll post it here.

As for the code correction. I changed:

fn_set_notification('W', "Force password change", "'$user_count' users will be asked to change their passwords next time they login.$msg", true');
to
fn_set_notification('W', "Force password change", "$user_count users will be asked to change their passwords next time they login.$msg", true);

So I removed the ' after "true". As you can see it's messing up the code coloring.

Looks like you also removed the ' before and after $user_count in the code (not sure if that was intended)

 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 12091 posts

Posted 20 April 2015 - 07:46 PM #16

Line should read:
fn_set_notification('W', "Force password change", "'$user_count' users will be asked to change their passwords next time they login.$msg", true);
This simply puts the number of affected users in single quotes. I.e.

'3929 users will be asked to change their passwords next time they login

If the previous setting of the password expiration setting was zero (no reset of passwords), it is changed to 365 days and the notification has

Your previous password expiration was set to zero. It has been reset to 365.

appended to the message. If it was not zero, it is left alone.

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Webrunner
  • Member
  • Members
  • Join Date: 06-Dec 06
  • 70 posts

Posted 21 April 2015 - 07:49 AM #17

Hello. Have you found a solution to this? Also, will this work for the free version of cscart?


Unfortunately, no. Still no solution.
My client decided not to spend too much time on this, because in the end it isn't that important for them.

Authorized Reseller Bitcoin accepted!
CS-Cart $345 - Ultimate $775 - Multi-Vendor $1250 https://sprintweb.nl
 


 
  • Dexterflamez
  • Senior Member
  • Trial users
  • Join Date: 08-Jan 18
  • 339 posts

Posted 25 June 2021 - 02:29 AM #18

How to check previous 4 passwords for both vendor and customers

 

The code below checks the previous 4 password for vendor account only I want to extend it to include the customers as well

// Check last 4 passwords
                if (!empty($user_id)) {
                        $current_user_data = db_get_row(
            "SELECT user_id, company_id, is_root, status, user_type, email, user_login, lang_code, password, salt, last_passwords"
            . " FROM ?:users WHERE user_id = ?i",
            $user_id
        );
                    $prev_passwords = !empty($current_user_data['last_passwords']) ? explode(',', $current_user_data['last_passwords']) : array();

                    if (!empty(Tygh::$app['session']['auth']['forced_password_change'])) {
                        // if forced password change - new password can't be equal to current password.
                        $prev_passwords[] = $current_user_data['password'];
                    }

                    if (in_array(fn_generate_salted_password($user_data['password1'], $current_user_data['salt']), $prev_passwords)) {
                        $valid_passwords = false;
                        fn_set_notification('E', __('error'), __('error_password_was_used'));
                    } else {
                        if (count($prev_passwords) >= 5) {
                            array_shift($prev_passwords);
                        }
                        $user_data['last_passwords'] = implode(',', $prev_passwords);
                    }
                }