Tuesday, November 10, 2015

PrestaShop: Improved Customer Password Recovery

No comments:
Ever since I started using PrestaShop, I hated the password recovery method: send email with link, clicking on link sends you a new password via email.

For me, this method has various problems:
  • Two emails to the client are needed. Not all emails arrive instantly, so this can slow down a customer that wants to do business with you.
  • A password is being sent as plain text to the user.
  • The password auto-generated by PrestaShop is hard for the user to remember.
  • The customer's secure key is sent out as plain text (it's the "token" parameter in the URL of the first email).
Therefore, I decided to change the "forgotten password" feature. My goal was to send ONE email to the user, which directs them to a page to change their password.

The link which allows the password must be unique to the user, can only be used once, and additionally will only work if used within some arbitrary amount of time... let's say one hour.

FORGOT YOUR PASSWORD?


Looking at the code, I decided that a complete override of the PasswordController was needed. I did this as an override. I created the file /override/controllers/front/PasswordController.php, with public function postProcess, and deleted the /cache/class_index.php to make sure my overridden controller gets called.

I also extensively changed my theme's password.tpl to handle the new method. In addition, the text of the template, the error message, and the email needed to be changed to reflect the new implementation.

In order to limit the tokens to 1 hour, I needed to add a new MySQL table.

CREATE TABLE `customer_extra_info` (
  `id_customer` int(10) unsigned NOT NULL,
  `datetime_password_request` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `token_password_request` varchar(32) NOT NULL DEFAULT '-1',
  PRIMARY KEY (`id_customer`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I plan to use this table for more customer specific info, which explains it's "non-specific" name.


Why I switched from Mandrill to Mailgun for PrestaShop

No comments:
I was working on an override of PrestaShop's "forgotten password" feature (article to arrive here shortly) when I ran into a problem... the "forgotten password" email that I was sending to my Gmail account via Mandrill from my RackSpace Cloud server was taking up to 10 minutes to arrive in my Gmail account! 10 minutes may be fine for sending newsletters, but if a customer is in the middle of the checkout process and has to wait 10 minutes for us to respond to his request for help on a forgotten email, we've lost the client.

I started by checking my Mandrill account. I have the free account (up to 12,000 emails a month for free), since I only use it for transactional emails. DKIM and SPF were working, domain was verified, reputation excellent... I saw nothing there that indicated that there was a problem. Their knowledge base had no info on the problem, and since I have a free account, they don't offer support (and I can't blame them ;->).

When reading about the problem, I saw that other Mandrill users were having the same problem. I also saw that Mailgun (owned by RackSpace) offered 50,000 free emails per month for RackSpace cloud users, and thought I would give it a whirl.

After setting up the DNS records and getting the domain verified, I realized that I had PrestaShop configured to send emails via the PHP mail function, and then had Mandrill set up via Postfix. I would assume that is slower than using SMTP directly (which means that my problem may have been a configuration problem), but since I had come this far (and since Mailgun has more free emails per month), I decided to set up Mailgun as my PrestaShop SMTP server.

My tests with Mailgun were mostly arriving in my Gmail account within a couple of seconds, with one taking almost 30 seconds, but it looked acceptable. Gmail's DKIM and SPF authentication tests all passed.

For the moment, I'll stay with Mailgun. I will keep an eye on delivery times, and switch back to Mandrill if I have problems.