View source
<?php
function email_confirm_help($path, $arg) {
switch ($path) {
case 'admin/modules#description':
return t('Configuration of confirmation email sent to users who attempt to change their email address.');
case 'admin/help#email_confirm':
return t('<p>The Email Change Confirmation module addresses missing functionality in the core distribution of Drupal. With this module enabled, a user who attempts to change the email address associated with their account must confirm that change by clicking a confirmation link that is sent to the new email address. The confirmation link must be clicked with a certain time period after which the pending update to their email address will expire and they will have to attempt to update their account again. This module was based on code from <a href="!url">this issue</a></p>', array(
'!url' => 'http://drupal.org/node/85494',
));
case 'admin/settings/email_confirm':
return t('When the Email Change Confirmation module is enabled, users who attempt to update their email address will be required to confirm their changes by clicking a confirmation link in an email sent to the new email address. The settings below determine the subject and body of the confirmation email sent to the user. A copy is sent to both the user\'s original email address and the new address.');
}
}
function email_confirm_menu() {
$items = array();
$items['user/change-mail'] = array(
'title' => 'Change e-mail',
'page callback' => 'email_confirm_user_change_mail',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['admin/settings/email_confirm'] = array(
'title' => 'Email change confirmation settings',
'description' => 'Configuration of confirmation email sent to users who attempt to change their email address.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'email_confirm_admin_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function email_confirm_admin_settings() {
$form = array();
$form['email_confirm_confirmation_email_subject'] = array(
'#type' => 'textfield',
'#title' => t('Email address change request email subject'),
'#description' => t('The above text will be the subject for the email sent to a user that is attempting to update their email address. The placeholders !username and !site will be replaced by the username and the site name.'),
'#default_value' => email_confirm_mail_text('email_confirm_confirmation_email_subject'),
'#size' => 60,
'#maxlength' => 256,
'#required' => TRUE,
);
$form['email_confirm_confirmation_email_author'] = array(
'#type' => 'textfield',
'#title' => t('Email address change request email author'),
'#default_value' => variable_get('email_confirm_confirmation_email_author', ''),
'#size' => 60,
'#description' => t('The above address will be the \'From\' email address for the confirmation email for an email address change request. If no address is supplied the default site email address will be used.'),
);
$form['email_confirm_confirmation_email_bcc'] = array(
'#type' => 'textfield',
'#title' => t('Email address change request email BCC email address'),
'#default_value' => variable_get('email_confirm_confirmation_email_bcc', ''),
'#size' => 60,
'#description' => t('The above address will receive a BCC email copy of the confirmation email for an email address change request.'),
);
$form['email_confirm_confirmation_email_body'] = array(
'#type' => 'textarea',
'#title' => t('Email address change request email body'),
'#description' => t("The above text will be the body for the email sent to a user that is attempting to update their email address. The text here will be sent to the user's new email address. The placeholders !username and !site will be replaced by the username and the site name."),
'#default_value' => email_confirm_mail_text('email_confirm_confirmation_email_body'),
'#cols' => 80,
'#rows' => 10,
'#required' => TRUE,
);
$form['email_confirm_confirmation_original_email_body'] = array(
'#type' => 'textarea',
'#title' => t('Email address change request email body (Original)'),
'#description' => t("The above text will be the body for the email sent to a user that is attempting to update their email address. The text here will be sent to the user's original email address. The placeholders !username and !site will be replaced by the username and the site name."),
'#default_value' => email_confirm_mail_text('email_confirm_confirmation_original_email_body'),
'#cols' => 80,
'#rows' => 10,
'#required' => TRUE,
);
return system_settings_form($form);
}
function email_confirm_admin_settings_validate($form, $form_state) {
if (!empty($form_state['values']['email_confirm_confirmation_email_author']) && !valid_email_address($form_state['values']['email_confirm_confirmation_email_author'])) {
form_set_error('email_confirm_confirmation_email_author', t('You must enter a valid email address for the "Email address change request email author" setting.'));
}
if (!empty($form_state['values']['email_confirm_confirmation_email_bcc']) && !valid_email_address($form_state['values']['email_confirm_confirmation_email_bcc'])) {
form_set_error('email_confirm_confirmation_email_bcc', t('You must enter a valid email address for the "Email address change request email BCC email address" setting.'));
}
}
function email_confirm_user($op, &$edit, &$account) {
switch ($op) {
case 'submit':
if (!empty($edit['mail']) && $account->mail != $edit['mail'] && !user_access('administer users')) {
email_confirm_build_mail($edit);
module_invoke_all('email_confirm', 'email change', $account->uid, $account->mail, $edit['mail']);
if (module_exists('rules')) {
rules_invoke_event('email_confirm_email_change_request', $account, $account->mail, $edit['mail']);
}
unset($edit['mail']);
}
break;
}
}
function email_confirm_user_change_mail($uid = NULL, $timestamp = NULL, $new_mail = NULL, $hash = NULL) {
global $user;
if (!isset($uid) || !is_numeric($uid) || !isset($timestamp) || !is_numeric($timestamp) || !isset($new_mail) || !isset($hash)) {
drupal_access_denied();
return;
}
$account = user_load(array(
'uid' => $uid,
'status' => 1,
));
$new_mail = str_replace(' ', '+', $new_mail);
$timeout = 86400;
$current = time();
if ($timestamp < $current && $account) {
if ($current - $timestamp > $timeout) {
drupal_set_message(t('You have tried to use a one-time e-mail change link for %account that has expired--your change of e-mail request was not completed. Please visit your account edit page if you wish to attempt the change again.', array(
'%account' => $account->name,
)), 'error');
if ($account->uid == $user->uid) {
drupal_goto('user/' . $account->uid . '/edit');
}
else {
drupal_goto();
}
}
else {
if ($user->uid && $user->uid != $account->uid) {
drupal_set_message(t('You are currently logged in as %user, and are attempting to confirm an e-mail change for %account, which is not allowed. Please log in as %account and initiate a new change of e-mail request.', array(
'%user' => $user->name,
'%account' => $account->name,
)), 'error');
drupal_goto();
}
else {
if ($hash != email_confirm_user_email_rehash($account->pass, $new_mail)) {
drupal_set_message(t('There was a problem verifying your change of e-mail request--please visit your account edit page and attempt the change again'), 'error');
if ($user->uid) {
drupal_goto('user/' . $user->uid . '/edit');
}
else {
drupal_goto('user/login', 'destination=user/' . $user->uid . '/edit');
}
}
else {
if ($timestamp > $account->login && $timestamp < $current) {
watchdog('user', 'User %name used one-time e-mail change link at time %timestamp.', array(
'%name' => $account->name,
'%timestamp' => $timestamp,
));
$old_mail = $account->mail;
user_save($account, array(
'mail' => $new_mail,
'login' => time(),
));
module_invoke_all('email_confirm', 'email confirmation', $account->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,
)));
if ($user->uid) {
drupal_goto('user/' . $user->uid);
}
else {
drupal_goto('user');
}
}
else {
drupal_set_message(t('You have tried to use a one-time e-mail change link which has either been used or has expired. Please request a new one.'), 'error');
if ($user->uid) {
drupal_goto('user/' . $user->uid . '/edit');
}
else {
drupal_goto('user/login', 'destination=user/' . $user->uid . '/edit');
}
}
}
}
}
}
else {
drupal_access_denied();
}
}
function email_confirm_mail($key, &$message, $params) {
$language = $message['language'];
$account = $params['account'];
$context = $params['context'];
$variables = user_mail_tokens($account, $language);
$variables += array(
'!email_url' => $context['url'],
);
$message['subject'] = strtr($context['subject'], $variables);
$message['body'][] = strtr($context['body'], $variables);
if ($params['headers']['bcc']) {
$message['headers']['bcc'] = $params['headers']['bcc'];
}
}
function email_confirm_build_mail($edit) {
global $user;
$params = array();
$params['account'] = $user;
$timestamp = time();
$pass = $edit['pass'] ? md5($edit['pass']) : $user->pass;
$hash = email_confirm_user_email_rehash($pass, $edit['mail']);
$params['context']['url'] = url('user/change-mail/' . $user->uid . '/' . $timestamp . '/' . $edit['mail'] . '/' . $hash, array(
'absolute' => TRUE,
));
if (module_exists('smtp') && variable_get('smtp_from', '') != '') {
$default_from = $smtp_from;
}
else {
$default_from = variable_get('site_mail', ini_get('sendmail_from'));
}
$from = variable_get('email_confirm_confirmation_email_author', $default_from);
$bcc = variable_get('email_confirm_confirmation_email_bcc', '');
$params['context']['subject'] = email_confirm_mail_text('email_confirm_confirmation_email_subject');
$params['context']['body'] = email_confirm_mail_text('email_confirm_confirmation_email_body');
$params['headers'] = array();
if ($bcc) {
$params['headers']['bcc'] = $bcc;
}
if ($message['result'] = drupal_mail('email_confirm', 'user_change_mail', $edit['mail'], user_preferred_language($user), $params, $from)) {
$params['context']['body'] = email_confirm_mail_text('email_confirm_confirmation_original_email_body');
drupal_mail('email_confirm', 'user_change_mail_original', $user->mail, user_preferred_language($user), $params, $from);
drupal_set_message(t('A confirmation email has been sent to your new email address. You must follow the link provided in that email within 24 hours in order to confirm the change to your account email address.'));
}
}
function email_confirm_user_email_rehash($pass, $mail) {
return md5($pass . $mail . drupal_get_private_key());
}
function email_confirm_mail_text($key, $language = NULL, $variables = array()) {
$langcode = isset($language) ? $language->language : NULL;
if ($default_text = variable_get($key, FALSE)) {
return strtr($default_text, $variables);
}
else {
switch ($key) {
case 'email_confirm_confirmation_email_subject':
case 'user_change_mail_subject':
case 'user_change_mail_original_subject':
return t('Email address change request for !username at !site', $variables, $langcode);
break;
case 'email_confirm_confirmation_email_body':
case 'user_change_mail_body':
return t('Hello !username,
A request to change your email address has been made at !site.
You need to verify the change by clicking on the link below or by
copying and pasting it in your browser:
!email_url
This is a one-time URL - it can be used only once. It expires after
24 hours. If you do not click the link to confirm, your email address
at !site will not be updated.
', $variables, $langcode);
break;
case 'email_confirm_confirmation_original_email_body':
case 'user_change_mail_original_body':
return t('Hello !username,
A request to change your email address has been made at !site.
In order to confirm the update of your email address you will
need to follow the instructions sent to your new email address
within 24 hours.
', $variables, $langcode);
break;
}
}
}
if (module_exists('mail_edit')) {
module_load_include('inc', 'email_confirm', 'email_confirm.mail_edit');
}