diff --git a/vendor/magento/module-customer-graph-ql/Model/GetGuestOrdersByEmail.php b/vendor/magento/module-customer-graph-ql/Model/GetGuestOrdersByEmail.php
new file mode 100644
index 0000000000000..b06ff42b7d2de
--- /dev/null
+++ b/vendor/magento/module-customer-graph-ql/Model/GetGuestOrdersByEmail.php
@@ -0,0 +1,54 @@
+searchCriteriaBuilder->addFilter(
+ 'customer_email',
+ $email,
+ 'eq'
+ )->addFilter(
+ 'customer_is_guest',
+ 1,
+ 'eq'
+ );
+ return $this->orderRepository->getList($this->searchCriteriaBuilder->create());
+ }
+}
diff --git a/vendor/magento/module-customer-graph-ql/Plugin/Model/MergeGuestOrder.php b/vendor/magento/module-customer-graph-ql/Plugin/Model/MergeGuestOrder.php
new file mode 100644
index 0000000000000..b86c133a5da54
--- /dev/null
+++ b/vendor/magento/module-customer-graph-ql/Plugin/Model/MergeGuestOrder.php
@@ -0,0 +1,51 @@
+getGuestOrdersByEmail->execute($customer->getEmail());
+ foreach ($searchResult->getItems() as $order) {
+ $this->customerAssignment->execute($order, $customer);
+ }
+ return $customer;
+ }
+}
diff --git a/vendor/magento/module-customer-graph-ql/etc/graphql/di.xml b/vendor/magento/module-customer-graph-ql/etc/graphql/di.xml
index 305e9cd12d676..22bfedf0d00cc 100644
--- a/vendor/magento/module-customer-graph-ql/etc/graphql/di.xml
+++ b/vendor/magento/module-customer-graph-ql/etc/graphql/di.xml
@@ -209,4 +209,8 @@
+
+
+
diff --git a/vendor/magento/module-graph-ql/Controller/GraphQl.php b/vendor/magento/module-graph-ql/Controller/GraphQl.php
index f3536b9683d4e..853d42cf3f453 100644
--- a/vendor/magento/module-graph-ql/Controller/GraphQl.php
+++ b/vendor/magento/module-graph-ql/Controller/GraphQl.php
@@ -9,6 +9,8 @@
namespace Magento\GraphQl\Controller;
+use Exception;
+use GraphQL\Error\FormattedError;
use GraphQL\Error\SyntaxError;
use GraphQL\Language\Source;
use Magento\Framework\App\Area;
@@ -21,7 +23,10 @@
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\GraphQl\Exception\ExceptionFormatter;
+use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
+use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
+use Magento\Framework\GraphQl\Exception\InvalidRequestInterface;
use Magento\Framework\GraphQl\Query\Fields as QueryFields;
use Magento\Framework\GraphQl\Query\QueryParser;
use Magento\Framework\GraphQl\Query\QueryProcessor;
@@ -224,10 +229,8 @@ public function dispatch(RequestInterface $request): ResponseInterface
$this->contextFactory->create(),
$data['variables'] ?? []
);
- } catch (\Exception $error) {
- $result['errors'] = isset($result['errors']) ? $result['errors'] : [];
- $result['errors'][] = $this->graphQlError->create($error);
- $statusCode = ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS;
+ } catch (Exception $error) {
+ [$result, $statusCode] = $this->handleGraphQlException($error);
}
$jsonResult->setHttpResponseCode($statusCode);
@@ -243,6 +246,26 @@ public function dispatch(RequestInterface $request): ResponseInterface
return $this->httpResponse;
}
+ /**
+ * Handle GraphQL Exceptions
+ *
+ * @param Exception $e
+ * @return array
+ */
+ private function handleGraphQlException(Exception $e): array
+ {
+ [$error, $statusCode] = match (true) {
+ $e instanceof InvalidRequestInterface => [FormattedError::createFromException($e), $e->getStatusCode()],
+ $e instanceof SyntaxError => [FormattedError::createFromException($e), 400],
+ $e instanceof GraphQlAuthenticationException => [$this->graphQlError->create($e), 401],
+ $e instanceof GraphQlAuthorizationException => [$this->graphQlError->create($e), 403],
+ $e instanceof GraphQlInputException => [FormattedError::createFromException($e), 200],
+ default => [$this->graphQlError->create($e), ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS],
+ };
+
+ return [['errors' => [$error]], $statusCode];
+ }
+
/**
* Get data from request body or query string
*
@@ -267,10 +290,14 @@ private function getDataFromRequest(RequestInterface $request): array
}
} elseif ($request->isGet()) {
$data = $request->getParams();
- $data['variables'] = isset($data['variables']) ?
- $this->jsonSerializer->unserialize($data['variables']) : null;
- $data['variables'] = is_array($data['variables']) ?
- $data['variables'] : null;
+ try {
+ $data['variables'] = !empty($data['variables']) && is_string($data['variables'])
+ ? $this->jsonSerializer->unserialize($data['variables'])
+ : null;
+ } catch (\InvalidArgumentException) {
+ $source = new Source($data['variables']);
+ throw new SyntaxError($source, 0, 'Unable to parse the variables.');
+ }
} else {
return [];
}
diff --git a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php
index 555048aac6771..a8e6a8478f4ce 100644
--- a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php
+++ b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php
@@ -1,14 +1,15 @@
isPost()
&& strpos($headerValue, $requiredHeaderValue) === false
) {
- throw new GraphQlInputException(
- new \Magento\Framework\Phrase('Request content type must be application/json')
+ throw new UnsupportedMediaTypeException(
+ new Phrase('Request content type must be application/json')
);
}
}
diff --git a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php
index 56351c7711cec..ff4cb247175f9 100644
--- a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php
+++ b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php
@@ -1,7 +1,7 @@
orderRepository->get($orderId);
+ if ($order->getCustomerIsGuest() && $order->getCustomerEmail()) {
+ try {
+ $websiteID = $this->storeManager->getStore()->getWebsiteId();
+ $customer = $this->customerRepository->get($order->getCustomerEmail(), $websiteID);
+ if ($customer->getId()) {
+ $this->customerAssignment->execute($order, $customer);
+ }
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ } catch (NoSuchEntityException $e) {
+ // Do not remove this handle as it used to check that customer
+ // with this email not registered in the system
+ }
+ }
+ }
+ return $orderId;
+ }
+}
diff --git a/vendor/magento/module-quote-graph-ql/etc/graphql/di.xml b/vendor/magento/module-quote-graph-ql/etc/graphql/di.xml
index 83942f1daebb2..6ded0467ecd0e 100644
--- a/vendor/magento/module-quote-graph-ql/etc/graphql/di.xml
+++ b/vendor/magento/module-quote-graph-ql/etc/graphql/di.xml
@@ -73,4 +73,8 @@
+
+
+
diff --git a/vendor/magento/theme-frontend-blank/i18n/en_US.csv b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
index 48f33bd2af411..f4c7b3e3f3fa2 100644
--- a/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+++ b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
@@ -442,3 +442,4 @@ Test,Test
test,test
Two,Two
"Invalid data type","Invalid data type"
+"Unknown type ""%1"".","Unknown type ""%1""."
diff --git a/vendor/magento/theme-frontend-luma/i18n/en_US.csv b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
index 09de2264af4f6..22d3d38d08f3b 100644
--- a/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+++ b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
@@ -492,3 +492,4 @@ Test,Test
test,test
Two,Two
"Invalid data type","Invalid data type"
+"Unknown type ""%1"".","Unknown type ""%1""."
diff --git a/vendor/magento/framework/GraphQl/Exception/InvalidRequestInterface.php b/vendor/magento/framework/GraphQl/Exception/InvalidRequestInterface.php
new file mode 100644
index 0000000000000..4a6d16f32ee71
--- /dev/null
+++ b/vendor/magento/framework/GraphQl/Exception/InvalidRequestInterface.php
@@ -0,0 +1,23 @@
+isSafe;
+ }
+}
diff --git a/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php b/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php
new file mode 100644
index 0000000000000..6be650a3eb01b
--- /dev/null
+++ b/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php
@@ -0,0 +1,46 @@
+isSafe;
+ }
+}
diff --git a/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php b/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php
index 250b80defa6dd..2a81b5d32ced2 100644
--- a/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php
+++ b/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php
@@ -1,13 +1,14 @@
$this->typeRegistry->get('Query'),
'mutation' => $this->typeRegistry->get('Mutation'),
'typeLoader' => function ($name) {
- return $this->typeRegistry->get($name);
+ try {
+ return $this->typeRegistry->get($name);
+ } catch (GraphQlInputException) {
+ return null;
+ }
},
'types' => function () {
$typesImplementors = [];
diff --git a/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php b/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php
index 414e1eebe6531..1b8cb47e4048d 100644
--- a/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php
+++ b/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php
@@ -1,12 +1,13 @@
types[$typeName])) {
- $configElement = $this->config->getConfigElement($typeName);
+ try {
+ $configElement = $this->config->getConfigElement($typeName);
+ } catch (LogicException) {
+ throw new GraphQlInputException(
+ new Phrase('Unknown type "%1".', [$typeName])
+ );
+ }
$configElementClass = get_class($configElement);
if (!isset($this->configToTypeMap[$configElementClass])) {