You are here

function email_confirm_user_change_mail in Email Change Confirmation 7

Same name and namespace in other branches
  1. 5 email_confirm.module \email_confirm_user_change_mail()
  2. 6 email_confirm.module \email_confirm_user_change_mail()

Menu callback; process one time email change confirm.

Parameters

int $uid: Their uid.

int $timestamp: Timestamp the hash was generated.

string $hash: A hash, to validate the change being taken.

Return value

int Returns MENU_ACCESS_DENIED if there is a problem or redirects on success.

1 string reference to 'email_confirm_user_change_mail'
email_confirm_menu in ./email_confirm.module
Implements hook_menu().

File

./email_confirm.module, line 244
The Email Change Confirmation module.

Code

function email_confirm_user_change_mail($uid = NULL, $timestamp = NULL, $hash = NULL) {
  global $user;

  // Check if all required parameters are present.
  if (!isset($uid) || !is_numeric($uid) || !isset($timestamp) || !is_numeric($timestamp) || !isset($hash)) {
    return MENU_ACCESS_DENIED;
  }

  // Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
  $timeout = variable_get('email_confirm_timeout', 86400);
  $current = REQUEST_TIME;

  // Timestamps in the future are invalid.
  if ($timestamp > $current) {
    drupal_set_message(t('There was a problem with your one-time e-mail change link. Please attempt the change again.'), 'error');
    drupal_goto('user/' . $uid . '/edit');
  }

  // Ensure URL is for current user.
  if (!$user->uid || $user->uid != $uid) {
    drupal_set_message(t('You must be logged in to the same account that requested this e-mail change to proceed.'), 'error');
    if (!$user->uid) {
      drupal_goto('user/login');
    }
    else {
      return MENU_ACCESS_DENIED;
    }
  }

  // Load pending email change address.
  if (isset($user->data['email_confirm']['pending_email']) && $user->data['email_confirm']['expiration_time'] > $current) {
    $new_mail = $user->data['email_confirm']['pending_email'];
  }
  else {
    drupal_set_message(t('There was a problem with your one-time e-mail change link. Please attempt the change again.'), 'error');
    drupal_goto('user/' . $uid . '/edit');
  }

  // Check if timestamp provided is too old.
  if ($current - $timestamp > $timeout) {
    drupal_set_message(t('You have tried to use a one-time e-mail change link that has expired. Please attempt the change again.'), 'error');
    drupal_goto('user/' . $uid . '/edit');
  }

  // Ensure no new logins have occurred since the change was made.
  $account = user_load($uid);
  if ($timestamp < $account->login) {
    drupal_set_message(t('There was a problem with your one-time e-mail change link. Please attempt the change again.'), 'error');
    drupal_goto('user/' . $uid . '/edit');
  }

  // Continue with email change if URL hash validates.
  if ($hash === email_confirm_user_email_rehash($new_mail, $timestamp, $uid)) {
    watchdog('user', 'User %name used one-time e-mail change link at time %timestamp.', array(
      '%name' => $user->name,
      '%timestamp' => $timestamp,
    ));
    $old_mail = $user->mail;
    user_save($account, array(
      'mail' => $new_mail,
      'login' => REQUEST_TIME,
      'email_confirmed' => TRUE,
    ));
    module_invoke_all('email_confirm', 'email confirmation', $uid, $old_mail, $new_mail);
    if (module_exists('rules')) {
      rules_invoke_event('email_confirm_email_change_confirmation', $account, $old_mail, $new_mail);
    }
    drupal_set_message(t('Your e-mail address is now %mail.', array(
      '%mail' => $new_mail,
    )));

    // We already validated this uid, so just redirect.
    drupal_goto('user/' . $uid);
  }
  else {
    drupal_set_message(t('There was a problem with your one-time e-mail change link. Please attempt the change again.'), 'error');
    drupal_goto('user/' . $uid . '/edit');
  }
}