Problem:
One time login process does not require the user to reset their (forgotten) password.
Scenario:
User forgets password, and requests new password. Drupal sends out one time login link. User does not read instructions, and clicks on link and then on Log-in button. User does not reset password. User comes back to site the following week, and again has to follow the "request new password" process, and again does not set a new password. User does the same the following week, and eventually complains to their contact that the system they have been asked to use does not work (and generally give it a bad name).
Fix:
The fix requires the user to set a new password in order to login using the one time password link. Hopefully the user should remember this new password.
I do not expect this fix to be made officially in Drupal 5.x, but I hope this helps anyone who may need this functionality.
robin
The line numbers refer to user.module 5.16
Step 1 - Add new fields to the one time login form
--------------------------------------------------
Go to line 1157 in user.module and change the form
From this:
$form['message'] = array('#value' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date</p><p>Click on this button to login to the site and change your password.</p>', array('%user_name' => $account->name, '%expiration_date' => format_date($timestamp + $timeout))));
$form['help'] = array('#value' => '<p>'. t('This login can be used only once.') .'</p>');
$form['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
$form['#action'] = url("user/reset/$uid/$timestamp/$hashed_pass/login");
return $form;
To this (ie remove #action, add newpass and uid):
$form['message'] = array('#value' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date</p><p>Click on this button to login to the site and change your password.</p>', array('%user_name' => $account->name, '%expiration_date' => format_date($timestamp + $timeout))));
$form['help'] = array('#value' => '<p>'. t('This login can be used only once.') .'</p>');
$form['newpass'] = array('#type' => 'password_confirm',
'#title' => t('New Password'),
'#description' => t('You must set your password now. Enter the password in to both fields.'),
'#required' => TRUE,
'#size' => 25,);
$form['uid'] = array('#type' => 'hidden', '#value' => $account->uid);
$form['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
return $form;
Step 2 - Add function to process form
-------------------------------------
Add the following function to user.module
function user_pass_reset_submit($form_id, $form_values) {
global $user;
$account = user_load(array('uid' => $form_values['uid'], 'status' => 1));
watchdog('user', t('User %name used one-time login link and set a new password at time %timestamp.', array('%name' => "<em>$account->name</em>", '%timestamp' => $timestamp)));
// Update the user table noting user has logged in.
// And this also makes this hashed password a one-time-only login.
$newpass = md5($form_values['newpass']);
db_query("UPDATE {users} SET login = %d, pass = '%s' WHERE uid = %d", time(), $newpass, $account->uid);
// Now we can set the new user.
$user = $account;
// And proceed with normal login, going to user page.
user_module_invoke('login', $edit, $user);
drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please take note of the new password you have just chosen.'));
drupal_goto('user/'. $user->uid .'/edit');
}
Step 3 - Remove redundant code (not required)
---------------------------------------------
You may have noticed that the code for user_pass_reset_submit() is the same logic from line 1144 onwards. You can remove this block of code if you want, although I would recommend leaving it for simplicity in upgrading.