Skip to content

Customer Account Registration Email Confirmation Flow #35233

Open
@pawel-siejba

Description

@pawel-siejba

As a customer I want to confirm my account registration so that I can login to my account when confirmation is required.

Not having this essentially breaks GraphQL customer registration flow when the "Require Emails Confirmation" option is turned on. https://docs.magento.com/user-guide/customers/account-options-new.html
Seems pretty urgent since nobody wants anybody to be able to create an account email with somebody else's email.

AC

  • GraphQL mutation is added for confirming user account registration from the email link.
  • generateCustomerToken mutation is adjusted so that it throws an appropriate error when the user tries to login, but has not confirmed his account/

Proposed Schema

type Mutation {
    customerConfirmRegistration(id: Int!, key: String!): ConfirmOutput @doc(description: "Confirm customer account registration and get access token") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Confirm")
    customerConfirmResend(email: String!): Boolean @doc(description: "Resend customer confirmation email") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\ConfirmResend")
}

type ConfirmOutput {
    token: String
}

To enable additional information when the customer tries to login but his account is not confirmed yet, something like this should be done:

--- magento/module-integration/Model/CustomerTokenService.php
+++ magento/module-integration/Model/CustomerTokenService.php
@@ -7,6 +7,7 @@
 namespace Magento\Integration\Model;

 use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Framework\Exception\EmailNotConfirmedException;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Integration\Model\CredentialsValidator;
 use Magento\Integration\Model\Oauth\Token as Token;
@@ -90,6 +91,9 @@
         $this->getRequestThrottler()->throttle($username, RequestThrottler::USER_TYPE_CUSTOMER);
         try {
             $customerDataObject = $this->accountManagement->authenticate($username, $password);
+        } catch (EmailNotConfirmedException $e) {
+            $this->getRequestThrottler()->logAuthenticationFailure($username, RequestThrottler::USER_TYPE_CUSTOMER);
+            throw $e;
         } catch (\Exception $e) {
             $this->getRequestThrottler()->logAuthenticationFailure($username, RequestThrottler::USER_TYPE_CUSTOMER);
             throw new AuthenticationException(

--- /dev/null
+++ magento/module-customer-graph-ql/Exception/GraphQlAuthenticationEmailNotConfirmedException.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © Vaimo Group. All rights reserved.
+ * See LICENSE_VAIMO.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\CustomerGraphQl\Exception;
+
+use GraphQL\Error\ClientAware;
+use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
+use Magento\Framework\Phrase;
+
+class GraphQlAuthenticationEmailNotConfirmedException extends GraphQlAuthenticationException implements ClientAware
+{
+    public const EXCEPTION_CATEGORY = 'graphql-authentication-email-not-confirmed';
+
+    public function __construct(Phrase $phrase, \Exception $cause = null, int $code = 0)
+    {
+        parent::__construct($phrase, $cause, $code);
+    }
+
+    public function isClientSafe(): bool
+    {
+        return true;
+    }
+
+    public function getCategory(): string
+    {
+        return self::EXCEPTION_CATEGORY;
+    }
+}

--- magento/module-customer-graph-ql/Model/Resolver/GenerateCustomerToken.php
+++ magento/module-customer-graph-ql/Model/Resolver/GenerateCustomerToken.php
@@ -8,7 +8,9 @@
 namespace Magento\CustomerGraphQl\Model\Resolver;

 use Magento\Framework\Exception\AuthenticationException;
+use Magento\Framework\Exception\EmailNotConfirmedException;
 use Magento\Framework\GraphQl\Config\Element\Field;
+use Magento\CustomerGraphQl\Exception\GraphQlAuthenticationEmailNotConfirmedException;
 use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
 use Magento\Framework\GraphQl\Exception\GraphQlInputException;
 use Magento\Framework\GraphQl\Query\ResolverInterface;
@@ -55,7 +57,10 @@
         try {
             $token = $this->customerTokenService->createCustomerAccessToken($args['email'], $args['password']);
             return ['token' => $token];
-        } catch (AuthenticationException $e) {
+        } catch (EmailNotConfirmedException $e) {
+            throw new GraphQlAuthenticationEmailNotConfirmedException(__($e->getMessage()), $e);
+        }
+        catch (AuthenticationException $e) {
             throw new GraphQlAuthenticationException(__($e->getMessage()), $e);
         }
     }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: APIsComponent: CustomerIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedPriority: P2A defect with this priority could have functionality issues which are not to expectations.Progress: ready for devProject: GraphQLReported on 2.4.xIndicates original Magento version for the Issue report.Reproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions