How can I allow users to opt out of receiving e-mails with one-time login links? So I have been working on an update to my site to allow users to log in via one-time login links when they receive a Private Message.  Unfortunately, this kind of feature recently has been in the news as a security issue, so I want to make sure that I give users a way to opt out.

The one-time login links are provided by the Login One Time module.  The e-mail notifications are provided by the Privatemsg module's PM E-mail Notify submodule, but ideally the solution would also work for e-mails sent by Rules, system e-mails, etc.

How I add the login link

In the PM E-mail Notify UI, in the body of the "You have received a new message" e-mail, I insert the following token:

[privatemsg_message:recipient:login-one-time]

and the whole link is:

[privatemsg_message:recipient:login-one-time]?edit[name]=[privatemsg_message:recipient:mail]

This provides the user with a one-time login link that looks like this:


  http://localhost:8888/en/login_one_time/1173/1377182743/RZCfB7uwKRB_bFVCeKPNwtOnDn2jFfGMO2FdaE_cpxI?destination=?edit[name]=useremail@example.com


(Note: the ?edit[name]=useremail@example.com part is a query string for the Prepopulate module which pre-fills the e-mail address on the login form in the event that the one-time login link has already been used.)

What I want to do


Add a boolean field to the user profile, "Do not send me one-time login links in my e-mail."
Somehow check the value of that field when sending e-mail notifications.


Is there a robust way to do this?  Here is what I have thought of so far:


Instead of using Privatemsg to send the e-mail notifications, attempt to create the notifications in Rules.  But if I do this, then I cannot use any of the nice Privatemsg configuration settings (such as allowing users to choose when they would like to receive e-mails, e.g. every time they receive a message, only once per sender, etc.)
I could somehow create a token that gives the one-time link if the user has not opted out or the regular link if the user has opted out. (I'm not really sure how to do this.)
I could hack the PM E-mail Notify submodule to do what I want.


Ideally, I want to do the following: if a user has opted out, I want to replace the one-time login link in any e-mail sent by the site with a link to the login form.

Note: My site is multilingual, and I am translating the e-mails sent with the site using the Variable and i18n modules.  So, any solution needs to be robust enough to handle multilingual e-mails.
What I would do is define your own token.

Start off with copying login_one_time_token_info() and login_one_time_tokens() into a custom module, change the hook names and rename the token to something like login-one-time-optional or whatever you prefer :)

Then, change the implementation of the hook_tokens() implementation so that you check the field on the $account and use either the existing function or url('user/login', array('absolute' =&gt; TRUE)). Keep in mind that existing users users might not have any data saved in that field, so add a default value, you might want to put something like this in a helper function:

if ($items = field_get_items('user', $account, 'your_settings_field')) {
  return (bool) $items[0]['value'];
}
else {
  // Default to use the one time login link.
  return TRUE;
}