Hi, this module is wonderful... it does exactly what I needed as I'm developing a custom RSVP-by-email module, where users can click a yes or no link in an email, and it logs them in and registers their RSVP.

However, I just noticed that whenever a one-time login link is used from this module, the user gets the message "You have just used your one-time login link.". For my use, I really don't want that message there, since my users aren't thinking of the usage of the link in that sense... I'm just wanting to use this module for its API.

I know how to just remove this from your code, but for future updates, I was wondering if you'd consider either removing this behavior, or making it optional.

Thanks!

Comments

danielb’s picture

I think configuration is too much, but I would consider adding a function to put the messages through that allows you to alter and remove them:

<?php

/**
 * Set a message to show the user - allows altering.
 */
function login_one_time_message($situation, $type = 'status') {
  $messages = array(
    'already' => 'It is not necessary to use this link to login anymore. You are already logged in.',
    'blocked' => 'You have tried to use a one-time login for an account which has been blocked.',
    'expired' => 'You have tried to use a one-time login link that has expired. Please use the log in form to supply your username and password.',
    'success' => 'You have just used your one-time login link.',
    'used' => 'You have tried to use a one-time login link which has been used. Please use the log in form to supply your username and password.'
  );
  $msg = $messages[$situation];
  drupal_alter('login_one_time_message', $msg, $situation $type);
  if ($msg) {
    drupal_set_message(t($msg), $type);
  }
}

/**
 * Menu callback; process login one time link and redirect.
 */
function login_one_time_page(&$form_state, $uid, $timestamp, $hashed_pass) {
  global $user;

  // Check if the user is already logged in. The back button is often the culprit here.
  if ($user->uid) {
    login_one_time_message('already');

    $action = login_one_time_get_action_path();

    if (!empty($action)) {
      drupal_goto($action);
    }
    else {
      drupal_goto("<front>");
    }
  }
  else {
    // Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
    $timeout = variable_get('login_one_time_expiry', 86400*14);
    $current = time();
    // Some redundant checks for extra security ?
    if ($timestamp < $current && $account = user_load(array('uid' => $uid, 'status' => 1)) ) {
      // Deny one-time login to blocked accounts.
      if (drupal_is_denied('user', $account->name) || drupal_is_denied('mail', $account->mail)) {
        login_one_time_message('blocked', 'error');
        drupal_goto("<front>");
      }

      // No time out for first time login.
      if ($account->login && $current - $timestamp > $timeout && $timeout) {
        login_one_time_message('expired');
        drupal_goto('user/login');
      }
      else if ($account->uid && $timestamp > $account->login && $timestamp < $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {

        $action = login_one_time_get_action_path();

        watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
        // Set the new user.
        $user = $account;
        // user_authenticate_finalize() also updates the login timestamp of the
        // user, which invalidates further use of the one-time login link.
        user_authenticate_finalize($form_state['values']);
        login_one_time_message('success');
        if (!empty($action)) {
          drupal_goto($action);
        }
        else {
          drupal_goto("<front>");
        }

      }
      else {
        login_one_time_message('used');
        drupal_goto('user/login');
      }
    }
    else {
      // Deny access, no more clues.
      // Everything will be in the watchdog's URL for the administrator to check.
      drupal_access_denied();
    }
  }
}

?>

You can already change the text with string translate, but this will allow you to set the $msg to NULL and prevent it displaying altogether...

Although now that I think of it... you don't need this at all... I'll get back to you with another idea.

danielb’s picture

Category: feature » support
Status: Active » Fixed

The messages are set right before a drupal_goto() which invokes hook_exit()

So you could remove the message like this:

<?php

yourmodule_exit() {
  if (!empty($_SESSION['messages']['status'])) {
    $key = array_search('You have just used your one-time login link.', $_SESSION['messages']['status']);
    if ($key !== FALSE) {
      unset($_SESSION['messages']['status'][$key]);
    }
  }
}

?>

And there are probably other ways to do it, but that's the one that popped into my head.

I just think your use-case is too rare to implement configuration, etc.. for it.

Of course you can always just replace that text with your own using the module: http://drupal.org/project/stringoverrides

Status: Fixed » Closed (fixed)

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

John Carbone’s picture

This module seems promising as one approach to solving this, although I haven't tried it. http://drupal.org/project/disable_messages/
This module basically hijacks the theme_status_messages function which is another approach to solving this as well.

Minor improvement on #2. I had something very similar in hook_init but I must have been hitting some limitations of that function because the same code didn't always work in all situations. The version below seems to work perfectly though.

Anyway, hope this helps someone out.

function mymodue_site_exit() {
  if (!empty($_SESSION['messages']['status'])) {
    $key = array_search('You have just used your one-time login link.', $_SESSION['messages']['status']);
    if ($key !== FALSE) {
      unset($_SESSION['messages']['status'][$key]);
      // Remove the empty status message wrapper if no other messages have been set.
      if (empty($_SESSION['messages']['status'])) {
        unset($_SESSION['messages']['status']);
      }
    }
  }
}
nickau’s picture

Issue summary: View changes

Hi
I am using this module, I am having an issue, when user clicks forget your password , then system sends a new email with link to login, when user clicks the link it gives below message, but password and new password links are disabled.
Can someone please assist?
I want the ability of user to change password.

ou have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password