2

I have a live site with customer details imported manually. At the time of import no customer passwords were provided so I set the email address as the password.

Now I need to be able to prompt users to change their password if it is still set to their email address.

I have an observer running on customer login but I can't seem to extract the existing password hash to compare. I have tried a couple of solutions:

1) Creating a new hash from the email address and comparing:

\Magento\Framework\Encryption\EncryptorInterface $encryptor
$this->encryptor->getHash("[email protected]");

However the hash this generates is nothing like the hash that is stored in the customer_entity table (same password though) - although the hash changes each time even when I set the same password.

2) "Fake" authenticating the user to see if password is still email:

try{
    $cust = $this->customerAccountManagement->authenticate($customer->getEmail(), $customer->getEmail());
    //die("1"); // authenticated correctly - change password!
}catch(\Exception $e){
    //die("2"); // failed authentication - password different from email address - that's good.
}

Method 2 ..kind of.. works but for some reason when testing it logs the customer out.

I guess my real question is: How can I check if the logged in customers password is still set as their email?

Thanks

1 Answer 1

3

Finally cracked this with the help of this post: https://magento.stackexchange.com/a/152371/4093 In particular this line:

$bool = $this->encryptor->validateHash($password, $hash);

Final observer class looks like this:

<?php

namespace Sulman\PasswordCheck\Observer;

use Magento\Framework\Event\ObserverInterface;

class CustomerLogin implements ObserverInterface
{
    protected $encryptor;
    protected $customerAccountManagement;
    protected $_messageManager;
    protected $objectManager;
    protected $responseFactory;
    protected $url;

    public function __construct(\Magento\Framework\Encryption\EncryptorInterface $encryptor,
                                \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement,
                                \Magento\Framework\Message\ManagerInterface $messageManager,
                                \Magento\Framework\ObjectManagerInterface $objectManager,
                                \Magento\Framework\App\ResponseFactory $responseFactory,
                                \Magento\Framework\UrlInterface $url)
    {
        $this->encryptor = $encryptor;
        $this->customerAccountManagement = $customerAccountManagement;
        $this->_messageManager = $messageManager;
        $this->objectManager = $objectManager;
        $this->responseFactory = $responseFactory;
        $this->url = $url;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $customer = $observer->getEvent()->getCustomer();
        $currentHash = $this->getCurrentPasswordHash($customer->getEntityId());
        try{
            $bool = $this->encryptor->validateHash(strtolower($customer->getEmail()), $currentHash);
            if($bool){
                // password is same as email - urge change
                $this->_messageManager->addWarning(__("Your password is still your original default password. Please change this below to keep your account secure."));
                // redirect to change password page
                $customRedirectionUrl = $this->url->getUrl('customer/account/edit/'); //Get url of page
                $this->responseFactory->create()->setRedirect($customRedirectionUrl)->sendResponse(); //Redirect to cms page
                die(); //This will stop execution and redirect to specific page
            }
        }catch(\Exception $e){
            echo 'Error::'.$e->getMessage();
        }
    }

    private function getCurrentPasswordHash($customerId){
        $resource = $this->objectManager->get('Magento\Framework\App\ResourceConnection');
        $connection = $resource->getConnection();
        $sql = "Select password_hash from customer_entity WHERE entity_id = ".$customerId;
        $hash = $connection->fetchOne($sql);
        return $hash;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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