2

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

  1. Add a boolean field to the user profile, "Do not send me one-time login links in my e-mail."
  2. 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.

  • How exactly do you currently add those one time links? If you can explain that in more detail, it should be easier to expand that to cover this. – Berdir Aug 22 '13 at 21:58
  • @Berdir Question updated. I am using the following token in the e-mail body: [privatemsg_message:recipient:login-one-time] – Patrick Kenny Aug 23 '13 at 2:03
2
+100

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' => 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;
}
1

I think you should add the boolean field that you want to the user profile and then use hook_mail_alter or a similiar hook of the email module to check the value of that settings. (Make sure the value is added to the $user global so you could read it)

  • I could use hook_mail_alter to check the setting, but I still need to send the e-mail without the token if the user has opted out. – Patrick Kenny Aug 27 '13 at 0:39
  • You can also alter the mail content and replace the link with the token to a static link to the login form. – rreiss Aug 27 '13 at 5:28
  • 1
    Or, even better, you can add either link (or no link at all) from within hook_mail. – Capi Etheriel Aug 30 '13 at 10:32
0

Try out this.

Create a menu path some thing like my-login/%user and let all my-login/%user/* paths handled by this menu handler (may be with custom module, panel with php code content)

prefix the url with my-login/%user so that it looks like my-login/[UID]/login_one_time/*

on the menu handler, load the %user and check the boolean, if allowed, direct the request to login_one_time/* the actual path, or show the login block.

*You can use the shorturl module tokens if that link looks lengthy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.