Permalink
Browse files

Change the password forgotten routine to send a personal link to the …

…customer instead of a new password. Here they can enter their own new password or continue with their old password if they remembered it. This prevents abuse of resetting account passwords of known email addresses.
  • Loading branch information...
1 parent 3c02f7e commit 015a96adcc3093297fe48e6e7d4de9c86f172c6b @haraldpdl haraldpdl committed Jul 10, 2012
@@ -42,6 +42,7 @@
define('FILENAME_LOGOFF', 'logoff.php');
define('FILENAME_NEW_PRODUCTS', 'new_products.php');
define('FILENAME_PASSWORD_FORGOTTEN', 'password_forgotten.php');
+ define('FILENAME_PASSWORD_RESET', 'password_reset.php');
define('FILENAME_POPUP_IMAGE', 'popup_image.php');
define('FILENAME_POPUP_SEARCH_HELP', 'popup_search_help.php');
define('FILENAME_PRIVACY', 'privacy.php');
@@ -15,12 +15,12 @@
define('HEADING_TITLE', 'I\'ve Forgotten My Password!');
-define('TEXT_MAIN', 'If you\'ve forgotten your password, enter your e-mail address below and we\'ll send you an e-mail message containing your new password.');
+define('TEXT_MAIN', 'If you\'ve forgotten your password, enter your e-mail address below and we\'ll send you instructions on how to securely change your password.');
-define('TEXT_NO_EMAIL_ADDRESS_FOUND', 'Error: The E-Mail Address was not found in our records, please try again.');
+define('TEXT_PASSWORD_RESET_INITIATED', 'Please check your e-mail for instructions on how to change your password. The instructions contain a link that is valid only for 24 hours or until your password has been updated.');
-define('EMAIL_PASSWORD_REMINDER_SUBJECT', STORE_NAME . ' - New Password');
-define('EMAIL_PASSWORD_REMINDER_BODY', 'A new password was requested from ' . tep_get_ip_address() . '.' . "\n\n" . 'Your new password to \'' . STORE_NAME . '\' is:' . "\n\n" . ' %s' . "\n\n");
+define('TEXT_NO_EMAIL_ADDRESS_FOUND', 'Error: The E-Mail Address was not found in our records, please try again.');
-define('SUCCESS_PASSWORD_SENT', 'Success: A new password has been sent to your e-mail address.');
-?>
+define('EMAIL_PASSWORD_RESET_SUBJECT', STORE_NAME . ' - New Password');
+define('EMAIL_PASSWORD_RESET_BODY', 'A new password has been requested for your account at ' . STORE_NAME . '.' . "\n\n" . 'Please follow this personal link to securely change your password:' . "\n\n" . '%s' . "\n\n" . 'This link will be automatically discarded after 24 hours or after your password has been changed.' . "\n\n" . 'For help with any of our online services, please email the store-owner: ' . STORE_OWNER_EMAIL_ADDRESS . '.' . "\n\n");
+?>
@@ -0,0 +1,24 @@
+<?php
+/*
+ $Id$
+
+ osCommerce, Open Source E-Commerce Solutions
+ http://www.oscommerce.com
+
+ Copyright (c) 2012 osCommerce
+
+ Released under the GNU General Public License
+*/
+
+define('NAVBAR_TITLE_1', 'Login');
+define('NAVBAR_TITLE_2', 'Password Reset');
+
+define('HEADING_TITLE', 'Password Reset');
+
+define('TEXT_MAIN', 'Please enter a new password for your account.');
+
+define('TEXT_NO_RESET_LINK_FOUND', 'Error: The password reset link was not found in our records, please try again by generating a new link.');
+define('TEXT_NO_EMAIL_ADDRESS_FOUND', 'Error: The E-Mail Address was not found in our records, please try again.');
+
+define('SUCCESS_PASSWORD_RESET', 'Your password has been successfully updated. Please login with your new password.');
+?>
@@ -233,6 +233,8 @@ CREATE TABLE customers_info (
customers_info_date_account_created datetime,
customers_info_date_account_last_modified datetime,
global_product_notifications int(1) DEFAULT '0',
+ password_reset_key char(40),
+ password_reset_date datetime,
PRIMARY KEY (customers_info_id)
);
View
@@ -57,7 +57,7 @@
tep_session_register('customer_country_id');
tep_session_register('customer_zone_id');
- tep_db_query("update " . TABLE_CUSTOMERS_INFO . " set customers_info_date_of_last_logon = now(), customers_info_number_of_logons = customers_info_number_of_logons+1 where customers_info_id = '" . (int)$customer_id . "'");
+ tep_db_query("update " . TABLE_CUSTOMERS_INFO . " set customers_info_date_of_last_logon = now(), customers_info_number_of_logons = customers_info_number_of_logons+1, password_reset_key = null, password_reset_date = null where customers_info_id = '" . (int)$customer_id . "'");
// reset session token
$sessiontoken = md5(tep_rand() . tep_rand() . tep_rand() . tep_rand());
@@ -14,23 +14,28 @@
require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_PASSWORD_FORGOTTEN);
+ $password_reset_initiated = false;
+
if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'process') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
$email_address = tep_db_prepare_input($HTTP_POST_VARS['email_address']);
- $check_customer_query = tep_db_query("select customers_firstname, customers_lastname, customers_password, customers_id from " . TABLE_CUSTOMERS . " where customers_email_address = '" . tep_db_input($email_address) . "'");
+ $check_customer_query = tep_db_query("select customers_firstname, customers_lastname, customers_id from " . TABLE_CUSTOMERS . " where customers_email_address = '" . tep_db_input($email_address) . "'");
if (tep_db_num_rows($check_customer_query)) {
$check_customer = tep_db_fetch_array($check_customer_query);
- $new_password = tep_create_random_value(max(ENTRY_PASSWORD_MIN_LENGTH, 12));
- $crypted_password = tep_encrypt_password($new_password);
+ $reset_key = tep_create_random_value(40);
+
+ tep_db_query("update " . TABLE_CUSTOMERS_INFO . " set password_reset_key = '" . tep_db_input($reset_key) . "', password_reset_date = now() where customers_info_id = '" . (int)$check_customer['customers_id'] . "'");
- tep_db_query("update " . TABLE_CUSTOMERS . " set customers_password = '" . tep_db_input($crypted_password) . "' where customers_id = '" . (int)$check_customer['customers_id'] . "'");
+ $reset_key_url = tep_href_link(FILENAME_PASSWORD_RESET, 'account=' . urlencode($email_address) . '&key=' . $reset_key, 'SSL', false);
- tep_mail($check_customer['customers_firstname'] . ' ' . $check_customer['customers_lastname'], $email_address, EMAIL_PASSWORD_REMINDER_SUBJECT, sprintf(EMAIL_PASSWORD_REMINDER_BODY, $new_password), STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
+ if ( strpos($reset_key_url, '&amp;') !== false ) {
+ $reset_key_url = str_replace('&amp;', '&', $reset_key_url);
+ }
- $messageStack->add_session('login', SUCCESS_PASSWORD_SENT, 'success');
+ tep_mail($check_customer['customers_firstname'] . ' ' . $check_customer['customers_lastname'], $email_address, EMAIL_PASSWORD_RESET_SUBJECT, sprintf(EMAIL_PASSWORD_RESET_BODY, $reset_key_url), STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
- tep_redirect(tep_href_link(FILENAME_LOGIN, '', 'SSL'));
+ $password_reset_initiated = true;
} else {
$messageStack->add('password_forgotten', TEXT_NO_EMAIL_ADDRESS_FOUND);
}
@@ -48,6 +53,18 @@
if ($messageStack->size('password_forgotten') > 0) {
echo $messageStack->output('password_forgotten');
}
+
+ if ($password_reset_initiated == true) {
+?>
+
+<div class="contentContainer">
+ <div class="contentText">
+ <?php echo TEXT_PASSWORD_RESET_INITIATED; ?>
+ </div>
+</div>
+
+<?php
+ } else {
?>
<?php echo tep_draw_form('password_forgotten', tep_href_link(FILENAME_PASSWORD_FORGOTTEN, 'action=process', 'SSL'), 'post', '', true); ?>
@@ -74,6 +91,8 @@
</form>
<?php
+ }
+
require(DIR_WS_INCLUDES . 'template_bottom.php');
require(DIR_WS_INCLUDES . 'application_bottom.php');
?>
View
@@ -0,0 +1,127 @@
+<?php
+/*
+ $Id$
+
+ osCommerce, Open Source E-Commerce Solutions
+ http://www.oscommerce.com
+
+ Copyright (c) 2012 osCommerce
+
+ Released under the GNU General Public License
+*/
+
+ require('includes/application_top.php');
+
+ require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_PASSWORD_RESET);
+
+ $error = false;
+
+ if ( !isset($HTTP_GET_VARS['account']) || !isset($HTTP_GET_VARS['key']) ) {
+ $error = true;
+
+ $messageStack->add_session('password_forgotten', TEXT_NO_RESET_LINK_FOUND);
+ }
+
+ if ($error == false) {
+ $email_address = tep_db_prepare_input($HTTP_GET_VARS['account']);
+ $password_key = tep_db_prepare_input($HTTP_GET_VARS['key']);
+
+ if ( (strlen($email_address) < ENTRY_EMAIL_ADDRESS_MIN_LENGTH) || (tep_validate_email($email_address) == false) ) {
+ $error = true;
+
+ $messageStack->add_session('password_forgotten', TEXT_NO_EMAIL_ADDRESS_FOUND);
+ } elseif (strlen($password_key) != 40) {
+ $error = true;
+
+ $messageStack->add_session('password_forgotten', TEXT_NO_RESET_LINK_FOUND);
+ } else {
+ $check_customer_query = tep_db_query("select c.customers_id, c.customers_email_address, ci.password_reset_key, ci.password_reset_date from " . TABLE_CUSTOMERS . " c, " . TABLE_CUSTOMERS_INFO . " ci where c.customers_email_address = '" . tep_db_input($email_address) . "' and c.customers_id = ci.customers_info_id");
+ if (tep_db_num_rows($check_customer_query)) {
+ $check_customer = tep_db_fetch_array($check_customer_query);
+
+ if ( empty($check_customer['password_reset_key']) || ($check_customer['password_reset_key'] != $password_key) || (strtotime($check_customer['password_reset_date'] . ' +1 day') <= time()) ) {
+ $error = true;
+
+ $messageStack->add_session('password_forgotten', TEXT_NO_RESET_LINK_FOUND);
+ }
+ } else {
+ $error = true;
+
+ $messageStack->add_session('password_forgotten', TEXT_NO_EMAIL_ADDRESS_FOUND);
+ }
+ }
+ }
+
+ if ($error == true) {
+ tep_redirect(tep_href_link(FILENAME_PASSWORD_FORGOTTEN));
+ }
+
+ if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'process') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
+ $password_new = tep_db_prepare_input($HTTP_POST_VARS['password']);
+ $password_confirmation = tep_db_prepare_input($HTTP_POST_VARS['confirmation']);
+
+ if (strlen($password_new) < ENTRY_PASSWORD_MIN_LENGTH) {
+ $error = true;
+
+ $messageStack->add('password_reset', ENTRY_PASSWORD_NEW_ERROR);
+ } elseif ($password_new != $password_confirmation) {
+ $error = true;
+
+ $messageStack->add('password_reset', ENTRY_PASSWORD_NEW_ERROR_NOT_MATCHING);
+ }
+
+ if ($error == false) {
+ tep_db_query("update " . TABLE_CUSTOMERS . " set customers_password = '" . tep_encrypt_password($password_new) . "' where customers_id = '" . (int)$check_customer['customers_id'] . "'");
+
+ tep_db_query("update " . TABLE_CUSTOMERS_INFO . " set customers_info_date_account_last_modified = now(), password_reset_key = null, password_reset_date = null where customers_info_id = '" . (int)$check_customer['customers_id'] . "'");
+
+ $messageStack->add_session('login', SUCCESS_PASSWORD_RESET, 'success');
+
+ tep_redirect(tep_href_link(FILENAME_LOGIN, '', 'SSL'));
+ }
+ }
+
+ $breadcrumb->add(NAVBAR_TITLE_1, tep_href_link(FILENAME_LOGIN, '', 'SSL'));
+ $breadcrumb->add(NAVBAR_TITLE_2);
+
+ require(DIR_WS_INCLUDES . 'template_top.php');
+ require('includes/form_check.js.php');
+?>
+
+<h1><?php echo HEADING_TITLE; ?></h1>
+
+<?php
+ if ($messageStack->size('password_reset') > 0) {
+ echo $messageStack->output('password_reset');
+ }
+?>
+
+<?php echo tep_draw_form('password_reset', tep_href_link(FILENAME_PASSWORD_RESET, 'account=' . $email_address . '&key=' . $password_key . '&action=process', 'SSL'), 'post', 'onsubmit="return check_form(password_reset);"', true); ?>
+
+<div class="contentContainer">
+ <div class="contentText">
+ <div><?php echo TEXT_MAIN; ?></div>
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td class="fieldKey"><?php echo ENTRY_PASSWORD; ?></td>
+ <td class="fieldValue"><?php echo tep_draw_password_field('password'); ?></td>
+ </tr>
+ <tr>
+ <td class="fieldKey"><?php echo ENTRY_PASSWORD_CONFIRMATION; ?></td>
+ <td class="fieldValue"><?php echo tep_draw_password_field('confirmation'); ?></td>
+ </tr>
+ </table>
+ </div>
+
+ <div class="buttonSet">
+ <span class="buttonAction"><?php echo tep_draw_button(IMAGE_BUTTON_CONTINUE, 'triangle-1-e', null, 'primary'); ?></span>
+ </div>
+</div>
+
+</form>
+
+<?php
+ require(DIR_WS_INCLUDES . 'template_bottom.php');
+ require(DIR_WS_INCLUDES . 'application_bottom.php');
+?>

0 comments on commit 015a96a

Please sign in to comment.