|
18 | 18 | use Magento\Customer\Model\Metadata\Validator;
|
19 | 19 | use Magento\Eav\Model\Validator\Attribute\Backend;
|
20 | 20 | use Magento\Framework\Api\ExtensibleDataObjectConverter;
|
| 21 | +use Magento\Framework\Api\SearchCriteriaBuilder; |
21 | 22 | use Magento\Framework\App\Area;
|
22 | 23 | use Magento\Framework\App\Config\ScopeConfigInterface;
|
23 | 24 | use Magento\Framework\App\ObjectManager;
|
|
39 | 40 | use Magento\Framework\Intl\DateTimeFactory;
|
40 | 41 | use Magento\Framework\Mail\Template\TransportBuilder;
|
41 | 42 | use Magento\Framework\Math\Random;
|
| 43 | +use Magento\Framework\Phrase; |
42 | 44 | use Magento\Framework\Reflection\DataObjectProcessor;
|
43 | 45 | use Magento\Framework\Registry;
|
44 | 46 | use Magento\Framework\Stdlib\DateTime;
|
@@ -310,6 +312,11 @@ class AccountManagement implements AccountManagementInterface
|
310 | 312 | */
|
311 | 313 | private $dateTimeFactory;
|
312 | 314 |
|
| 315 | + /** |
| 316 | + * @var SearchCriteriaBuilder |
| 317 | + */ |
| 318 | + private $searchCriteriaBuilder; |
| 319 | + |
313 | 320 | /**
|
314 | 321 | * @param CustomerFactory $customerFactory
|
315 | 322 | * @param ManagerInterface $eventManager
|
@@ -338,6 +345,7 @@ class AccountManagement implements AccountManagementInterface
|
338 | 345 | * @param SessionManagerInterface|null $sessionManager
|
339 | 346 | * @param SaveHandlerInterface|null $saveHandler
|
340 | 347 | * @param CollectionFactory|null $visitorCollectionFactory
|
| 348 | + * @param SearchCriteriaBuilder|null $searchCriteriaBuilder |
341 | 349 | * @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
342 | 350 | */
|
343 | 351 | public function __construct(
|
@@ -367,7 +375,8 @@ public function __construct(
|
367 | 375 | DateTimeFactory $dateTimeFactory = null,
|
368 | 376 | SessionManagerInterface $sessionManager = null,
|
369 | 377 | SaveHandlerInterface $saveHandler = null,
|
370 |
| - CollectionFactory $visitorCollectionFactory = null |
| 378 | + CollectionFactory $visitorCollectionFactory = null, |
| 379 | + SearchCriteriaBuilder $searchCriteriaBuilder = null |
371 | 380 | ) {
|
372 | 381 | $this->customerFactory = $customerFactory;
|
373 | 382 | $this->eventManager = $eventManager;
|
@@ -399,6 +408,8 @@ public function __construct(
|
399 | 408 | ?: ObjectManager::getInstance()->get(SaveHandlerInterface::class);
|
400 | 409 | $this->visitorCollectionFactory = $visitorCollectionFactory
|
401 | 410 | ?: ObjectManager::getInstance()->get(CollectionFactory::class);
|
| 411 | + $this->searchCriteriaBuilder = $searchCriteriaBuilder |
| 412 | + ?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class); |
402 | 413 | }
|
403 | 414 |
|
404 | 415 | /**
|
@@ -572,12 +583,55 @@ public function initiatePasswordReset($email, $template, $websiteId = null)
|
572 | 583 | return false;
|
573 | 584 | }
|
574 | 585 |
|
| 586 | + /** |
| 587 | + * Match a customer by their RP token. |
| 588 | + * |
| 589 | + * @param string $rpToken |
| 590 | + * @throws ExpiredException |
| 591 | + * @throws NoSuchEntityException |
| 592 | + * |
| 593 | + * @return CustomerInterface |
| 594 | + */ |
| 595 | + private function matchCustomerByRpToken($rpToken) |
| 596 | + { |
| 597 | + |
| 598 | + $this->searchCriteriaBuilder->addFilter( |
| 599 | + 'rp_token', |
| 600 | + $rpToken |
| 601 | + ); |
| 602 | + $this->searchCriteriaBuilder->setPageSize(1); |
| 603 | + $found = $this->customerRepository->getList( |
| 604 | + $this->searchCriteriaBuilder->create() |
| 605 | + ); |
| 606 | + |
| 607 | + if ($found->getTotalCount() > 1) { |
| 608 | + //Failed to generated unique RP token |
| 609 | + throw new ExpiredException( |
| 610 | + new Phrase('Reset password token expired.') |
| 611 | + ); |
| 612 | + } |
| 613 | + if ($found->getTotalCount() === 0) { |
| 614 | + //Customer with such token not found. |
| 615 | + throw NoSuchEntityException::singleField( |
| 616 | + 'rp_token', |
| 617 | + $rpToken |
| 618 | + ); |
| 619 | + } |
| 620 | + |
| 621 | + //Unique customer found. |
| 622 | + return $found->getItems()[0]; |
| 623 | + } |
| 624 | + |
575 | 625 | /**
|
576 | 626 | * {@inheritdoc}
|
577 | 627 | */
|
578 | 628 | public function resetPassword($email, $resetToken, $newPassword)
|
579 | 629 | {
|
580 |
| - $customer = $this->customerRepository->get($email); |
| 630 | + if (!$email) { |
| 631 | + $customer = $this->matchCustomerByRpToken($resetToken); |
| 632 | + } else { |
| 633 | + $customer = $this->customerRepository->get($email); |
| 634 | + } |
581 | 635 | //Validate Token and new password strength
|
582 | 636 | $this->validateResetPasswordToken($customer->getId(), $resetToken);
|
583 | 637 | $this->checkPasswordStrength($newPassword);
|
@@ -977,12 +1031,9 @@ public function isCustomerInStore($customerWebsiteId, $storeId)
|
977 | 1031 | private function validateResetPasswordToken($customerId, $resetPasswordLinkToken)
|
978 | 1032 | {
|
979 | 1033 | if (empty($customerId) || $customerId < 0) {
|
980 |
| - throw new InputException( |
981 |
| - __( |
982 |
| - 'Invalid value of "%value" provided for the %fieldName field.', |
983 |
| - ['value' => $customerId, 'fieldName' => 'customerId'] |
984 |
| - ) |
985 |
| - ); |
| 1034 | + //Looking for the customer. |
| 1035 | + $customerId = $this->matchCustomerByRpToken($resetPasswordLinkToken) |
| 1036 | + ->getId(); |
986 | 1037 | }
|
987 | 1038 | if (!is_string($resetPasswordLinkToken) || empty($resetPasswordLinkToken)) {
|
988 | 1039 | $params = ['fieldName' => 'resetPasswordLinkToken'];
|
|
0 commit comments