The one-time-login link can be used more that once. (in all versions)

Only a small change is needed to fix this:

In function logintoboggan_validate_email() add empty($account->login) to this line:

if ($account->uid && !empty($account) && $timestamp < $current &&

So line becomes:

if (empty($account->login) && $account->uid && !empty($account) && $timestamp < $current &&

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hunmonk’s picture

Version: 5.x-1.3 » 7.x-1.x-dev
Status: Needs review » Fixed

fixed in 5.x, 6.x-1.x, and HEAD

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

jonathan_hunt’s picture

Version: 7.x-1.x-dev » 5.x-1.3
Status: Closed (fixed) » Active

I tried making this patch on 5.x-1.3 and ran into an issue. I have the option 'Set password & Immediate login' enabled - this means when a user tries to validate they are coming from a state where they were logged in and the $account->login value has a timestamp.

This logic needs to take account of that scenario: (pseudo code)
If (user_email_verification && !account->login || !user_email_verification && user_role=pre-authorized) {
//validate hash
}

hunmonk’s picture

Version: 5.x-1.3 » 7.x-1.x-dev
Status: Active » Fixed
FileSize
1.72 KB

the previous solution was very broken -- applied the attached to 6.x, and similar to 5.x, which should fix this once and for all.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

Triskelion’s picture

Title: Allow One Time Login To Be Used Only Once » Allow One Time Login To Be Used Only Once - Patch Breaks Email Validation
Version: 7.x-1.x-dev » 6.x-1.3
Status: Closed (fixed) » Active
hunmonk’s picture

Status: Active » Fixed

this patch only changed the logic to determine if the validation link was already used. the problem at #372884: Validation email links always result in Access Denied message appears to be that the validation function is being called twice, which is a different problem. i still believe this is the correct solution for this particular problem.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Weka’s picture

Version: 6.x-1.3 » 6.x-1.6
Status: Closed (fixed) » Active

I just tested LoginToboggan 6.x-1.6 on a fresh install of Drupal 6.16 and the one-time-login link can be used more that once. No other modules installed.

LT Settings:

  • Allow users to login using their e-mail address: [enabled]
  • Immediate login: [unchecked]

User settings (core):

  • Visitors can create accounts and no administrator approval is required.
  • Require e-mail verification when a visitor creates an account [checked]

Let me know if you need more information.

hunmonk’s picture

Title: Allow One Time Login To Be Used Only Once - Patch Breaks Email Validation » Allow One Time Login To Be Used Only Once
Status: Active » Postponed (maintainer needs more info)

i cannot reproduce this locally using logintoboggan 6.x-1.x-dev. please re-test using the latest 6.x-1.x-dev snapshot -- if it's not present there, then there's really no bug to fix.

Weka’s picture

Tested using LoginToboggan 6.x-1.x-dev (2010-Mar-26).
Still able to reuse the one-time login link over and over even after logging out.
Very easy to replicate using fresh install of D6 and LT.

hunmonk’s picture

dunno what to tell you. i cannot reproduce. i can't fix a bug i can't reproduce. one thing you can check: is the login column for the users table being populated with a timestamp after the first use of the validation link? it should be 0 before the first use, then a Unix timestamp value after the first use.

the line of code in question is very specific:

if (((variable_get('user_email_verification', TRUE) && empty($account->login)) || array_key_exists(logintoboggan_validating_id(), $account->roles)) && $hashed_pass == logintoboggan_eml_rehash($account->pass, $timestamp, $account->mail)) {

if $account->login is populated, then the login link attempt will fail. this value is clearly populated in logintoboggan_process_login():

  // Update the user table timestamp noting user has logged in.
  db_query("UPDATE {users} SET login = %d WHERE uid = %d", time(), $user->uid);
Weka’s picture

Yes, the login column in the users table is 0 before the first use. It gets correctly populated with time stamp value after the first use and updated after each use of the one-time login link.

hunmonk’s picture

check the code you have against the code i pasted in #12. make sure there's not some other module install overriding the one you think is running. try putting in some var_dump() calls in logintoboggan_validate_email() to see what weirdness you can catch. there's really nothing else i can do to help you, as the code makes perfect sense, and is behaving correctly in my test install.

Weka’s picture

Status: Postponed (maintainer needs more info) » Active

I checked the logintoboggan.module file for the code you pasted in #12 and it does match. I don't see why it would not as I did not modify anything and the LT module was downloaded from the LT project page..

As I said before, I did a fresh install of D6 and LT just to test this issue. LT is the only contrib module installed. There are no other modules installed or enabled just a straight fresh D6.16 configuration.

I sent you a link to the test installation so you can see I am not making this up. The test site is using LT 6.x-1.x-dev.

hunmonk’s picture

Status: Active » Postponed (maintainer needs more info)

you can try the var_dump() calls i suggested in #14.

Weka’s picture

FileSize
64.09 KB
19.45 KB
22 KB
41.25 KB

Sorry, I am not a programmer and don't know how to 'putting in some var_dump() calls'.
Here is a list of steps I took to replicate this:

  1. Fresh install of Drupal 6.16. Leave all settings at default.
  2. Install LoginToboggan 6.x-1.x-dev (2010-Mar-26) Leave settings at default.
  3. Visit http://example.com/user/register and create a new account
  4. Use the one-time login link you receive in the e-mail message
    Link I received: http://example.com/user/validate/4/1271180132/6433f1318fbc0ef7d525a00034...
    Redirected to: http://example.com/user/4
    Status Message: 'You have just used your one-time login link. It is no longer possible to use this link to login. Please change your password.' (LTLogin.png)
  5. Log Out
  6. Use the same link again
    Same results as in step 4. above
  7. Repeat steps 5 and 6 as many times you want

See screen shot of Recent Log Entries (LogEntries.png)

Before installing LT in step 2. I tested the default Drupal install and the one-time login link worked fine:
Link received: http://www.example.com/user/reset/3/1271178464/6a243e594466f2c8a0600ec9b...

Using the link, user is greeted with'You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.' (D6default1stLogin.png)

Trying to use the one-time login link after logging out, user receives the message:

'You have tried to use a one-time login link which has either been used or is no longer valid. Please request a new one using the form below.'

Everything else in LT is working just fine and I appreciate having this module available. I am not asking for help here, I am just reporting what I see and trying to provide as much detail as possible. Thank you for your time, you don't need to reply.

hunmonk’s picture

is the 'Set password' checkbox on the LT settings page checked or unchecked? what is the value of the 'Non-authenticated role' on that settings page as well?

Weka’s picture

The 'Set password' checkbox on the LT settings page is unchecked.
The value of the 'Non-authenticated role' is by default set to 'authenticated user'. This does not apply since the "Set password" is not checked.

hunmonk’s picture

i'm officially stumped. it should work as coded.

jjchinquist’s picture

I believe that I have a VERY HUGE REASON as to why everyone is having this problem. Our setup is the following.

We have Drupal 6, logintoboggan and mimemail modules installed.

1) User Registration: Username*, Email*, Password*, Terms of Use*
2) User sent a mail for validation.
3) User opens the mail in his/her mail program (this example is from hotmail.com, but gmail.com & yahoo.com have the same results) and receives the following:


Hello ABC,
Thank you for your interest in XYZ.com.
Click the following link to finish your registration process:
<i>Note: our linked url but the url is cut off by hotmail.com!</i>
http://www.quax.at/user/validate/1872/1271321873/6dbf7f0869f1f2b04520a78... [1]
This is a one time link [and the e-mail goes on, until the footer of the mail is reached]
------------------------------------------------------------------------------

[1] http://www.xyz.com/user/validate/1872/1271321873/6dbf7f0869f1f2b04520a7826e928232

The key here is the automatic generation of a footnote by the e-mail program (in this case hotmail) cuts off the URL link for security reasons. The reader reads "click on the following link" and does not go further. Clicks on the link and receives the message:

t("Sorry, you can only use your validation link once for security reasons. Please !login with your username and password instead now.", array('!login' => l(t('login'),'user/login'))),'error')

The message that logintoboggan gives to the user is misleading and not user-friendly. I suggest providing a mailto link so that the user is prompted to send an e-mail to a predefined account such as "customerservice@xyz.com" and then one can set up an automatic job to run when the subject line is correct.

Another idea is for the website maintainer to redirect to a FAQ page and provide further instructions.

I will try to post our solution as soon as we have one.

hunmonk’s picture

@jjchinquist: the issue you're trying to address is not the issue being discussed in this thread. your issue is covered here: #557102: Issues with validating with Hotmail accounts!

jjchinquist’s picture

My apologies, thank you.

AaronELBorg’s picture

subscribing

Weka’s picture

Hi Aaron,
Are you subscribing because you are experiencing the same problem?

JoelD’s picture

I was just troubleshooting an issue we were having with the email that gets sent on our registration and my search found this issue. I checked to see if my one-time link would work more than once because we just enabled LT yesterday. The link worked more than once when I was both logged in and not logged in. We disabled LT, registered a new user and the login process worked as expected. And the one-time use now yells if you try and use it more than once.

Ours is not a clean install, but the symptoms were the same. Hope it helps,
Joel

hunmonk’s picture

@JoelD: i've looked over this issue several times, looked at the code, and tested it. it works in my testing and i discuss the code that makes it work in #12. my guess is this is interference from some other module during the registration process, but i don't know for sure. i've done all i can for this issue given the information i've seen, so unless somebody comes up with something new it's not going to make any progress ;)

JThan’s picture

I have this issue also. In my case the login value is not beeing set to "0". The value is not changed when using the link (sometimes it is changed when logging in, but most of the time not - I did not find a pattern to this by now). I am still investigating.

John Morahan’s picture

Status: Postponed (maintainer needs more info) » Active

This seems to happen when the preauth role is set to authenticated user. Because then array_key_exists(logintoboggan_validating_id(), $account->roles) is always TRUE and the empty($account->login) check on the other side of the || makes no difference.

hunmonk’s picture

Assigned: Unassigned » hunmonk
Status: Active » Needs review
FileSize
2.05 KB

pretty sure the attached patch addresses the issue in #29 -- can you give it a test run to make sure it still works properly in both the auth role pre-auth case and non-auth role pre-auth case?

greg.harvey’s picture

Status: Needs review » Needs work

SUMMARY

If you don't want to read the whole test, highlights are:

- Patch broadly functions fine
- There is a small UX issue in TEST 4 - no message after account creation
- Otherwise, review the experienced behaviour - if this is by design, then the point above is the only item that "needs work"

Tested with PHP 5.3 and Apache2, for reference. Test plan was as follows:

SETUP

- Almost blank Drupal 6 install (CCK, Ctools, Permissions API, Secure Permissions, SMTP and Views were also enabled)
- Checked out LT 6.x-1.x-dev from Git
- Applied patch in #30
- Enabled LT
- Create a custom role, 'non-auth'

(- Set up SMTP to send mails, if necessary)

TEST 1 - using 'authenticated user' as the pre-auth role

1. Go to LT settings, check 'Set password', set 'Non-authenticated role' to 'authenticated user'
2. Make sure 'Immediate login' is checked and click Save
3. Logout and create a new user
4. Was logged in immediately (worked as expected)
5. Received auth email
6. Logged out the test user
7. Clicked the verification link in the email

RESULT

Received this message:
Sorry, you can only use your validation link once for security reasons. Please log in with your username and password instead now.

NOTE: If you do not carry out step 6 then the message is subtly different, it just takes you to your user page and only says:
Sorry, you can only use your validation link once for security reasons.

But regardless, the verification link was not valid. I don't know if this is expected behaviour or not? Either way, it certainly seems "safe" and administrators should edit the body of the core "Welcome, no approval required" email template and remove the one-time login URL if they have set things up like this, since it is not required. (Perhaps LT could do this automagically, but that would be a separate feature request.)

TEST 2 - using a custom role as the pre-auth

1. Go to LT settings, check 'Set password', set 'Non-authenticated role' to custom 'non-auth'
2. Make sure 'Immediate login' is checked and click Save
3. Logout and create a new user
4. Was logged in immediately (worked as expected)
5. Logout and login as an administrator
6. Check the roles of the user you just created (confirmed, user is not 'authenticated user' yet)
7. Logout as administrator again
8. Open received auth email and click the verification link

RESULT

Logged in as expected, message reads:
You have successfully validated your e-mail address.

Logged out and tried the link again, just in case, got this message on the login page:
Sorry, you can only use your validation link once for security reasons. Please log in with your username and password instead now.

Logged in as admin and verified user roles for test user - 'non-auth' role gone (and form altered away too) and user now default 'authenticated user', as expected.

TEST 3 - using a custom role as the pre-auth without immediate login

1. Go to LT settings, check 'Set password', set 'Non-authenticated role' to custom 'non-auth'
2. Make sure 'Immediate login' is *not* checked and click Save
3. Logout and create a new user
4. Get message saying I need to verify email before full access (as expected)
5. Logout and login as an administrator
6. Check the roles of the user you just created (confirmed, user is not 'authenticated user' yet)
7. Logout as administrator again
8. Open received auth email and click the verification link

RESULT

Logged in, successful validation, roles changed as expected. Tried the link again, received this:
Sorry, you can only use your validation link once for security reasons.

TEST 4 - using 'authenticated user' as the pre-auth role without immediate login

1. Go to LT settings, check 'Set password', set 'Non-authenticated role' to default 'authenticated user'
2. Make sure 'Immediate login' is *not* checked and click Save
3. Logout and create a new user
4. Get no confirmation message (!!)
5. Logout and login as an administrator
6. Check the roles of the user you just created (confirmed, user is 'authenticated user' as expected)
7. Logout as administrator again
8. Attempt to login as user (works fine) then logout again
9. Open received auth email and click the verification link

RESULT

No messages after submitting the user register form, but email arrived as normal. User can login, but there is no feedback from the system. Clicking the validation link results in:
Sorry, you can only use your validation link once for security reasons. Please log in with your username and password instead now.

While this is the 'correct' behaviour (the link cannot be used, because effectively the user is already registered, and the link can be removed from the mail template), the lack of message when the account is created is a UX bug, for sure.

TEST 5 - using 'authenticated user' as the pre-auth role with immediate login, with Drupal core set to require verification

1. Go to LT settings, check 'Set password', set 'Non-authenticated role' to default 'authenticated user'
2. Make sure 'Immediate login' is checked and click Save
3. Go to core user settings, check the 'Require e-mail verification when a visitor creates an account' and Save
4. Go back and check LT settings (correctly reverted to not permitting the password to be set)
4. Logout and create a new user (set password boxes are missing from user register form, as expected)
5. Confirmation message received
6. Attempt to login as test user (correctly fails)
7. Open received auth email and click the verification link

RESULT

Successful login from verification link. Attempt to logout and use the link again failed correctly. 'Set password' behaviour correctly overridden.

TEST 6 - no pre-auth

1. Go to LT settings, *remove* 'Set password' and 'Immediate login' options
2. Logout as admin
3. Try to create new user account

RESULT

Drupal core behaves normally, no side-effects, everything works.

hunmonk’s picture

Status: Needs work » Fixed

committed #30 to 6.x-1.x-dev and 7.x-1.x-dev, and moved the UI issue to #1077704: new user gets no confirmation message when pre-auth==auth user and immediate login disabled.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.