From 50635d947b5d0b62496d9078fb7d46ae15f4e336 Mon Sep 17 00:00:00 2001 From: Michal Derlatka Date: Fri, 12 Jun 2020 19:21:13 +0200 Subject: [PATCH 1/5] magento/magento2#28561: GraphQL added CORS headers --- .../CorsAllowCredentialsHeaderProvider.php | 38 ++++++++++++ .../Cors/CorsAllowHeadersHeaderProvider.php | 43 ++++++++++++++ .../Cors/CorsAllowMethodsHeaderProvider.php | 44 ++++++++++++++ .../Cors/CorsAllowOriginHeaderProvider.php | 39 ++++++++++++ .../Cors/CorsMaxAgeHeaderProvider.php | 44 ++++++++++++++ .../GraphQl/Model/Cors/Configuration.php | 58 ++++++++++++++++++ .../Model/Cors/ConfigurationInterface.php | 20 +++++++ .../Magento/GraphQl/etc/adminhtml/system.xml | 59 +++++++++++++++++++ app/code/Magento/GraphQl/etc/config.xml | 16 +++++ app/code/Magento/GraphQl/etc/di.xml | 2 + app/code/Magento/GraphQl/etc/graphql/di.xml | 11 ++++ 11 files changed, 374 insertions(+) create mode 100644 app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php create mode 100644 app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php create mode 100644 app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php create mode 100644 app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php create mode 100644 app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php create mode 100644 app/code/Magento/GraphQl/Model/Cors/Configuration.php create mode 100644 app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php create mode 100644 app/code/Magento/GraphQl/etc/adminhtml/system.xml create mode 100644 app/code/Magento/GraphQl/etc/config.xml diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php new file mode 100644 index 0000000000000..3f7c912b574fc --- /dev/null +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php @@ -0,0 +1,38 @@ +corsConfiguration = $corsConfiguration; + } + + public function getName() + { + return $this->headerName; + } + + public function getValue() + { + return true; + } + + public function canApply() : bool + { + return $this->corsConfiguration->isEnabled() && $this->corsConfiguration->isCredentialsAllowed(); + } +} diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php new file mode 100644 index 0000000000000..e44e7c6b1e872 --- /dev/null +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php @@ -0,0 +1,43 @@ +corsConfiguration = $corsConfiguration; + } + + public function getName() + { + return $this->headerName; + } + + public function canApply() : bool + { + return $this->corsConfiguration->isEnabled() && $this->getValue(); + } + + public function getValue() + { + return $this->corsConfiguration->getAllowedHeaders() + ? $this->corsConfiguration->getAllowedHeaders() + : $this->headerValue; + } +} diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php new file mode 100644 index 0000000000000..548ffc1aec3f6 --- /dev/null +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php @@ -0,0 +1,44 @@ +corsConfiguration = $corsConfiguration; + } + + public function getName() + { + return $this->headerName; + } + + public function canApply() : bool + { + return $this->corsConfiguration->isEnabled() && $this->getValue(); + } + + public function getValue() + { + return $this->corsConfiguration->getAllowedMethods() + ? $this->corsConfiguration->getAllowedMethods() + : $this->headerValue; + } +} diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php new file mode 100644 index 0000000000000..8df8c2ec6e39c --- /dev/null +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php @@ -0,0 +1,39 @@ +corsConfiguration = $corsConfiguration; + } + + public function getName() + { + return $this->headerName; + } + + public function canApply() : bool + { + return $this->corsConfiguration->isEnabled() && $this->getValue(); + } + + public function getValue() + { + return $this->corsConfiguration->getAllowedOrigins(); + } +} diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php new file mode 100644 index 0000000000000..b74f405930caf --- /dev/null +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php @@ -0,0 +1,44 @@ +corsConfiguration = $corsConfiguration; + } + + public function getName() + { + return $this->headerName; + } + + public function canApply() + { + return $this->corsConfiguration->isEnabled() && $this->getValue(); + } + + public function getValue() + { + return $this->corsConfiguration->getMaxAge() + ? $this->corsConfiguration->getMaxAge() + : $this->headerValue; + } +} diff --git a/app/code/Magento/GraphQl/Model/Cors/Configuration.php b/app/code/Magento/GraphQl/Model/Cors/Configuration.php new file mode 100644 index 0000000000000..6748ea6c3c9a1 --- /dev/null +++ b/app/code/Magento/GraphQl/Model/Cors/Configuration.php @@ -0,0 +1,58 @@ +scopeConfig = $scopeConfig; + } + + public function isEnabled(): bool + { + return $this->scopeConfig->isSetFlag(self::XML_PATH_CORS_HEADERS_ENABLED); + } + + public function getAllowedOrigins(): ?string + { + return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_ORIGINS); + } + + public function getAllowedHeaders(): ?string + { + return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_HEADERS); + } + + public function getAllowedMethods(): ?string + { + return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_METHODS); + } + + public function getMaxAge(): int + { + return $this->scopeConfig->getValue(self::XML_PATH_CORS_MAX_AGE); + } + + public function isCredentialsAllowed(): bool + { + return $this->scopeConfig->isSetFlag(self::XML_PATH_CORS_ALLOW_CREDENTIALS); + } + +} diff --git a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php new file mode 100644 index 0000000000000..bbb23abe854b6 --- /dev/null +++ b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php @@ -0,0 +1,20 @@ + + + + +
+ + service + Magento_Integration::config_oauth + + + + + Magento\Config\Model\Config\Source\Yesno + + + + + + 1 + + + + + + + 1 + + + + + + + 1 + + + + + + + 1 + + + + + + Magento\Config\Model\Config\Source\Yesno + + 1 + + + +
+
+
diff --git a/app/code/Magento/GraphQl/etc/config.xml b/app/code/Magento/GraphQl/etc/config.xml new file mode 100644 index 0000000000000..76a1fac199582 --- /dev/null +++ b/app/code/Magento/GraphQl/etc/config.xml @@ -0,0 +1,16 @@ + + + + + + 0 + + + + 86400 + 0 + + + + diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index b356f33c4f4bf..79052c717bc96 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -98,4 +98,6 @@ 300 + + diff --git a/app/code/Magento/GraphQl/etc/graphql/di.xml b/app/code/Magento/GraphQl/etc/graphql/di.xml index 77fce336374dd..23d49124d1a02 100644 --- a/app/code/Magento/GraphQl/etc/graphql/di.xml +++ b/app/code/Magento/GraphQl/etc/graphql/di.xml @@ -30,4 +30,15 @@ + + + + Magento\GraphQl\Controller\HttpResponse\Cors\CorsAllowOriginHeaderProvider + Magento\GraphQl\Controller\HttpResponse\Cors\CorsAllowHeadersHeaderProvider + Magento\GraphQl\Controller\HttpResponse\Cors\CorsAllowMethodsHeaderProvider + Magento\GraphQl\Controller\HttpResponse\Cors\CorsAllowCredentialsHeaderProvider + Magento\GraphQl\Controller\HttpResponse\Cors\CorsMaxAgeHeaderProvider + + + From b79c484c3b0f9153a78edb3aa96f1332c6157fd8 Mon Sep 17 00:00:00 2001 From: Michal Derlatka Date: Mon, 22 Jun 2020 14:47:12 +0200 Subject: [PATCH 2/5] magento/magento2#28561: GraphQL added CORS headers --- .../CorsAllowCredentialsHeaderProvider.php | 17 ++- .../Cors/CorsAllowHeadersHeaderProvider.php | 24 ++-- .../Cors/CorsAllowMethodsHeaderProvider.php | 25 ++-- .../Cors/CorsAllowOriginHeaderProvider.php | 18 ++- .../Cors/CorsMaxAgeHeaderProvider.php | 25 ++-- .../GraphQl/Model/Cors/Configuration.php | 12 +- .../Model/Cors/ConfigurationInterface.php | 10 +- .../Magento/GraphQl/etc/adminhtml/system.xml | 6 + app/code/Magento/GraphQl/etc/di.xml | 25 ++++ .../Magento/GraphQl/CorsHeadersTest.php | 122 ++++++++++++++++++ 10 files changed, 243 insertions(+), 41 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php index 3f7c912b574fc..086cf2bbef877 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php @@ -1,13 +1,21 @@ corsConfiguration = $corsConfiguration; + $this->headerName = $headerName; } public function getName() diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php index e44e7c6b1e872..26df47cb1e312 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php @@ -1,16 +1,21 @@ corsConfiguration = $corsConfiguration; + $this->headerName = $headerName; } public function getName() @@ -36,8 +44,6 @@ public function canApply() : bool public function getValue() { - return $this->corsConfiguration->getAllowedHeaders() - ? $this->corsConfiguration->getAllowedHeaders() - : $this->headerValue; + return $this->corsConfiguration->getAllowedHeaders(); } } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php index 548ffc1aec3f6..d2b2994367883 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php @@ -1,17 +1,21 @@ corsConfiguration = $corsConfiguration; + $this->headerName = $headerName; } public function getName() @@ -37,8 +44,6 @@ public function canApply() : bool public function getValue() { - return $this->corsConfiguration->getAllowedMethods() - ? $this->corsConfiguration->getAllowedMethods() - : $this->headerValue; + return $this->corsConfiguration->getAllowedMethods(); } } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php index 8df8c2ec6e39c..0cdc976525a7d 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php @@ -1,14 +1,21 @@ corsConfiguration = $corsConfiguration; + $this->headerName = $headerName; } public function getName() diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php index b74f405930caf..065138dcd7936 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php @@ -1,17 +1,21 @@ corsConfiguration = $corsConfiguration; + $this->headerName = $headerName; } public function getName() @@ -37,8 +44,6 @@ public function canApply() public function getValue() { - return $this->corsConfiguration->getMaxAge() - ? $this->corsConfiguration->getMaxAge() - : $this->headerValue; + return $this->corsConfiguration->getMaxAge(); } } diff --git a/app/code/Magento/GraphQl/Model/Cors/Configuration.php b/app/code/Magento/GraphQl/Model/Cors/Configuration.php index 6748ea6c3c9a1..cddc3f2ae9653 100644 --- a/app/code/Magento/GraphQl/Model/Cors/Configuration.php +++ b/app/code/Magento/GraphQl/Model/Cors/Configuration.php @@ -1,11 +1,17 @@ scopeConfig->getValue(self::XML_PATH_CORS_MAX_AGE); + return (int) $this->scopeConfig->getValue(self::XML_PATH_CORS_MAX_AGE); } public function isCredentialsAllowed(): bool diff --git a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php index bbb23abe854b6..ef298f2d9cfda 100644 --- a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php +++ b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php @@ -1,9 +1,15 @@ + The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin. Fill this field with one or more origins (comma separated) or use '*' to allow access from all origins. 1 @@ -27,6 +28,7 @@ + The Access-Control-Allow-Methods response header specifies the method or methods allowed when accessing the resource in response to a preflight request. Use comma separated methods (e.g. GET,POST) 1 @@ -34,6 +36,7 @@ + The Access-Control-Allow-Headers response header is used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request. Use comma separated headers. 1 @@ -41,6 +44,8 @@ + validate-digits + The Access-Control-Max-Age response header indicates how long the results of a preflight request (that is the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can be cached. 1 @@ -49,6 +54,7 @@ Magento\Config\Model\Config\Source\Yesno + The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to frontend code when the request's credentials mode is include. 1 diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 79052c717bc96..f0a8eca87ec58 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,4 +100,29 @@ + + + Access-Control-Max-Age + + + + + Access-Control-Allow-Credentials + + + + + Access-Control-Allow-Headers + + + + + Access-Control-Allow-Methods + + + + + Access-Control-Allow-Origin + + diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php new file mode 100644 index 0000000000000..8110937468280 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php @@ -0,0 +1,122 @@ +resourceConfig = $objectManager->get(Config::class); + $this->reinitConfig = $objectManager->get(ReinitableConfigInterface::class); + $this->scopeConfig = $objectManager->get(ScopeConfigInterface::class); + } + + protected function tearDown(): void + { + parent::tearDown(); // TODO: Change the autogenerated stub + + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 0); + $this->reinitConfig->reinit(); + } + + public function testNoCorsHeadersWhenCorsIsDisabled() + { + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 0); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, 'Origin'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOW_CREDENTIALS, '1'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_METHODS, 'GET,POST'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_ORIGINS, 'magento.local'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_MAX_AGE, '86400'); + $this->reinitConfig->reinit(); + + $headers = $this->getHeadersFromIntrospectionQuery(); + + self::assertArrayNotHasKey('Access-Control-Max-Age', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Credentials', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Headers', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Methods', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Origin', $headers); + } + + public function testCorsHeadersWhenCorsIsEnabled() + { + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 1); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, 'Origin'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOW_CREDENTIALS, '1'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_METHODS, 'GET,POST'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_ORIGINS, 'magento.local'); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_MAX_AGE, '86400'); + $this->reinitConfig->reinit(); + + $headers = $this->getHeadersFromIntrospectionQuery(); + + self::assertEquals('Origin', $headers['Access-Control-Allow-Headers']); + self::assertEquals('1', $headers['Access-Control-Allow-Credentials']); + self::assertEquals('GET,POST', $headers['Access-Control-Allow-Methods']); + self::assertEquals('magento.local', $headers['Access-Control-Allow-Origin']); + self::assertEquals('86400', $headers['Access-Control-Max-Age']); + } + + public function testEmptyCorsHeadersWhenCorsIsEnabled() + { + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 1); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, ''); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOW_CREDENTIALS, ''); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_METHODS, ''); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_ORIGINS, ''); + $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_MAX_AGE, ''); + $this->reinitConfig->reinit(); + + $headers = $this->getHeadersFromIntrospectionQuery(); + + self::assertArrayNotHasKey('Access-Control-Max-Age', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Credentials', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Headers', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Methods', $headers); + self::assertArrayNotHasKey('Access-Control-Allow-Origin', $headers); + } + + private function getHeadersFromIntrospectionQuery() + { + $query + = <<graphQlQueryWithResponseHeaders($query)['headers']; + } +} From 5ba8fd7888ccc2658616fa8897ca9dff58265198 Mon Sep 17 00:00:00 2001 From: Michal Derlatka Date: Tue, 23 Jun 2020 10:23:21 +0200 Subject: [PATCH 3/5] magento/magento2#28561: GraphQL added CORS headers (static test fix) --- .../CorsAllowCredentialsHeaderProvider.php | 24 ++++++++++++- .../Cors/CorsAllowHeadersHeaderProvider.php | 22 ++++++++++++ .../Cors/CorsAllowMethodsHeaderProvider.php | 15 ++++++++ .../Cors/CorsAllowOriginHeaderProvider.php | 15 ++++++++ .../Cors/CorsMaxAgeHeaderProvider.php | 15 ++++++++ .../GraphQl/Model/Cors/Configuration.php | 36 +++++++++++++++++-- .../Model/Cors/ConfigurationInterface.php | 30 ++++++++++++++++ app/code/Magento/GraphQl/etc/config.xml | 6 ++++ .../Magento/GraphQl/CorsHeadersTest.php | 6 +++- 9 files changed, 165 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php index 086cf2bbef877..39edeb8e6667b 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php @@ -15,6 +15,9 @@ */ class CorsAllowCredentialsHeaderProvider implements HeaderProviderInterface { + /** + * @var string + */ private $headerName; /** @@ -24,6 +27,10 @@ class CorsAllowCredentialsHeaderProvider implements HeaderProviderInterface */ private $corsConfiguration; + /** + * @param ConfigurationInterface $corsConfiguration + * @param string $headerName + */ public function __construct( ConfigurationInterface $corsConfiguration, string $headerName @@ -32,16 +39,31 @@ public function __construct( $this->headerName = $headerName; } + /** + * Get name of header + * + * @return string + */ public function getName() { return $this->headerName; } + /** + * Get value for header + * + * @return string + */ public function getValue() { - return true; + return "1"; } + /** + * Check if header can be applied + * + * @return bool + */ public function canApply() : bool { return $this->corsConfiguration->isEnabled() && $this->corsConfiguration->isCredentialsAllowed(); diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php index 26df47cb1e312..e07cb70644441 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php @@ -15,6 +15,9 @@ */ class CorsAllowHeadersHeaderProvider implements HeaderProviderInterface { + /** + * @var string + */ private $headerName; /** @@ -24,6 +27,10 @@ class CorsAllowHeadersHeaderProvider implements HeaderProviderInterface */ private $corsConfiguration; + /** + * @param ConfigurationInterface $corsConfiguration + * @param string $headerName + */ public function __construct( ConfigurationInterface $corsConfiguration, string $headerName @@ -32,16 +39,31 @@ public function __construct( $this->headerName = $headerName; } + /** + * Get name of header + * + * @return string + */ public function getName() { return $this->headerName; } + /** + * Check if header can be applied + * + * @return bool + */ public function canApply() : bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } + /** + * Get value for header + * + * @return string + */ public function getValue() { return $this->corsConfiguration->getAllowedHeaders(); diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php index d2b2994367883..35edca3e90615 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php @@ -32,16 +32,31 @@ public function __construct( $this->headerName = $headerName; } + /** + * Get name of header + * + * @return string + */ public function getName() { return $this->headerName; } + /** + * Check if header can be applied + * + * @return bool + */ public function canApply() : bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } + /** + * Get value for header + * + * @return string + */ public function getValue() { return $this->corsConfiguration->getAllowedMethods(); diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php index 0cdc976525a7d..b6c3641e8580c 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php @@ -32,16 +32,31 @@ public function __construct( $this->headerName = $headerName; } + /** + * Get name of header + * + * @return string + */ public function getName() { return $this->headerName; } + /** + * Check if header can be applied + * + * @return bool + */ public function canApply() : bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } + /** + * Get value for header + * + * @return string + */ public function getValue() { return $this->corsConfiguration->getAllowedOrigins(); diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php index 065138dcd7936..46a2f44d8ea38 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php @@ -32,16 +32,31 @@ public function __construct( $this->headerName = $headerName; } + /** + * Get name of header + * + * @return string + */ public function getName() { return $this->headerName; } + /** + * Check if header can be applied + * + * @return bool + */ public function canApply() { return $this->corsConfiguration->isEnabled() && $this->getValue(); } + /** + * Get value for header + * + * @return string + */ public function getValue() { return $this->corsConfiguration->getMaxAge(); diff --git a/app/code/Magento/GraphQl/Model/Cors/Configuration.php b/app/code/Magento/GraphQl/Model/Cors/Configuration.php index cddc3f2ae9653..b06d63832b8d2 100644 --- a/app/code/Magento/GraphQl/Model/Cors/Configuration.php +++ b/app/code/Magento/GraphQl/Model/Cors/Configuration.php @@ -24,41 +24,73 @@ class Configuration implements ConfigurationInterface /** * @var ScopeConfigInterface */ - protected $scopeConfig; + private $scopeConfig; + /** + * @param ScopeConfigInterface $scopeConfig + */ public function __construct(ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; } + /** + * Are CORS headers enabled + * + * @return bool + */ public function isEnabled(): bool { return $this->scopeConfig->isSetFlag(self::XML_PATH_CORS_HEADERS_ENABLED); } + /** + * Get allowed origins or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedOrigins(): ?string { return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_ORIGINS); } + /** + * Get allowed headers or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedHeaders(): ?string { return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_HEADERS); } + /** + * Get allowed methods or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedMethods(): ?string { return $this->scopeConfig->getValue(self::XML_PATH_CORS_ALLOWED_METHODS); } + /** + * Get max age header value + * + * @return int + */ public function getMaxAge(): int { return (int) $this->scopeConfig->getValue(self::XML_PATH_CORS_MAX_AGE); } + /** + * Are credentials allowed + * + * @return bool + */ public function isCredentialsAllowed(): bool { return $this->scopeConfig->isSetFlag(self::XML_PATH_CORS_ALLOW_CREDENTIALS); } - } diff --git a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php index ef298f2d9cfda..9e54e979323fa 100644 --- a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php +++ b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php @@ -12,15 +12,45 @@ */ interface ConfigurationInterface { + /** + * Are CORS headers enabled + * + * @return bool + */ public function isEnabled() : bool; + /** + * Get allowed origins or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedOrigins() : ?string; + /** + * Get allowed headers or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedHeaders() : ?string; + /** + * Get allowed methods or null if stored configuration is empty + * + * @return string|null + */ public function getAllowedMethods() : ?string; + /** + * Get max age header value + * + * @return int + */ public function getMaxAge() : int; + /** + * Are credentials allowed + * + * @return bool + */ public function isCredentialsAllowed() : bool; } diff --git a/app/code/Magento/GraphQl/etc/config.xml b/app/code/Magento/GraphQl/etc/config.xml index 76a1fac199582..39caacbec42d2 100644 --- a/app/code/Magento/GraphQl/etc/config.xml +++ b/app/code/Magento/GraphQl/etc/config.xml @@ -1,4 +1,10 @@ + diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php index 8110937468280..3628d3e4bca32 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php @@ -1,4 +1,9 @@ Date: Tue, 23 Jun 2020 11:50:54 +0200 Subject: [PATCH 4/5] magento/magento2#28561: GraphQL added CORS headers (static test fix) --- .../HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php | 4 ++++ .../HttpResponse/Cors/CorsAllowOriginHeaderProvider.php | 4 ++++ .../Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php index 35edca3e90615..654cacfeb4633 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php @@ -24,6 +24,10 @@ class CorsAllowMethodsHeaderProvider implements HeaderProviderInterface */ private $corsConfiguration; + /** + * @param ConfigurationInterface $corsConfiguration + * @param string $headerName + */ public function __construct( ConfigurationInterface $corsConfiguration, string $headerName diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php index b6c3641e8580c..7ecc06376ca04 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php @@ -24,6 +24,10 @@ class CorsAllowOriginHeaderProvider implements HeaderProviderInterface */ private $corsConfiguration; + /** + * @param ConfigurationInterface $corsConfiguration + * @param string $headerName + */ public function __construct( ConfigurationInterface $corsConfiguration, string $headerName diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php index 46a2f44d8ea38..7221cd252fab0 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php @@ -24,6 +24,10 @@ class CorsMaxAgeHeaderProvider implements HeaderProviderInterface */ private $corsConfiguration; + /** + * @param ConfigurationInterface $corsConfiguration + * @param string $headerName + */ public function __construct( ConfigurationInterface $corsConfiguration, string $headerName From 88840a79ad7076a40fd4fe0cf7e5c70d2bd1b2f4 Mon Sep 17 00:00:00 2001 From: Michal Derlatka Date: Thu, 25 Jun 2020 09:50:57 +0200 Subject: [PATCH 5/5] magento/magento2#28561: GraphQL added CORS headers (fixing issues) --- .../Cors/CorsAllowCredentialsHeaderProvider.php | 6 +++--- .../Cors/CorsAllowHeadersHeaderProvider.php | 8 ++++---- .../Cors/CorsAllowMethodsHeaderProvider.php | 11 +++++++---- .../Cors/CorsAllowOriginHeaderProvider.php | 11 +++++++---- .../HttpResponse/Cors/CorsMaxAgeHeaderProvider.php | 13 ++++++++----- .../Magento/GraphQl/Model/Cors/Configuration.php | 12 ++++++------ .../GraphQl/Model/Cors/ConfigurationInterface.php | 10 +++++----- app/code/Magento/GraphQl/etc/di.xml | 10 +++++----- .../testsuite/Magento/GraphQl/CorsHeadersTest.php | 12 ++++++------ 9 files changed, 51 insertions(+), 42 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php index 39edeb8e6667b..ba2e995d4f704 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowCredentialsHeaderProvider.php @@ -44,7 +44,7 @@ public function __construct( * * @return string */ - public function getName() + public function getName(): string { return $this->headerName; } @@ -54,7 +54,7 @@ public function getName() * * @return string */ - public function getValue() + public function getValue(): string { return "1"; } @@ -64,7 +64,7 @@ public function getValue() * * @return bool */ - public function canApply() : bool + public function canApply(): bool { return $this->corsConfiguration->isEnabled() && $this->corsConfiguration->isCredentialsAllowed(); } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php index e07cb70644441..68760de543daa 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowHeadersHeaderProvider.php @@ -44,7 +44,7 @@ public function __construct( * * @return string */ - public function getName() + public function getName(): string { return $this->headerName; } @@ -54,7 +54,7 @@ public function getName() * * @return bool */ - public function canApply() : bool + public function canApply(): bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } @@ -62,9 +62,9 @@ public function canApply() : bool /** * Get value for header * - * @return string + * @return string|null */ - public function getValue() + public function getValue(): ?string { return $this->corsConfiguration->getAllowedHeaders(); } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php index 654cacfeb4633..233839b9deb74 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowMethodsHeaderProvider.php @@ -15,6 +15,9 @@ */ class CorsAllowMethodsHeaderProvider implements HeaderProviderInterface { + /** + * @var string + */ private $headerName; /** @@ -41,7 +44,7 @@ public function __construct( * * @return string */ - public function getName() + public function getName(): string { return $this->headerName; } @@ -51,7 +54,7 @@ public function getName() * * @return bool */ - public function canApply() : bool + public function canApply(): bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } @@ -59,9 +62,9 @@ public function canApply() : bool /** * Get value for header * - * @return string + * @return string|null */ - public function getValue() + public function getValue(): ?string { return $this->corsConfiguration->getAllowedMethods(); } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php index 7ecc06376ca04..21850f18db1f2 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsAllowOriginHeaderProvider.php @@ -15,6 +15,9 @@ */ class CorsAllowOriginHeaderProvider implements HeaderProviderInterface { + /** + * @var string + */ private $headerName; /** @@ -41,7 +44,7 @@ public function __construct( * * @return string */ - public function getName() + public function getName(): string { return $this->headerName; } @@ -51,7 +54,7 @@ public function getName() * * @return bool */ - public function canApply() : bool + public function canApply(): bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } @@ -59,9 +62,9 @@ public function canApply() : bool /** * Get value for header * - * @return string + * @return string|null */ - public function getValue() + public function getValue(): ?string { return $this->corsConfiguration->getAllowedOrigins(); } diff --git a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php index 7221cd252fab0..e30209ae25e68 100644 --- a/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php +++ b/app/code/Magento/GraphQl/Controller/HttpResponse/Cors/CorsMaxAgeHeaderProvider.php @@ -15,6 +15,9 @@ */ class CorsMaxAgeHeaderProvider implements HeaderProviderInterface { + /** + * @var string + */ private $headerName; /** @@ -41,7 +44,7 @@ public function __construct( * * @return string */ - public function getName() + public function getName(): string { return $this->headerName; } @@ -51,7 +54,7 @@ public function getName() * * @return bool */ - public function canApply() + public function canApply(): bool { return $this->corsConfiguration->isEnabled() && $this->getValue(); } @@ -59,10 +62,10 @@ public function canApply() /** * Get value for header * - * @return string + * @return string|null */ - public function getValue() + public function getValue(): ?string { - return $this->corsConfiguration->getMaxAge(); + return (string) $this->corsConfiguration->getMaxAge(); } } diff --git a/app/code/Magento/GraphQl/Model/Cors/Configuration.php b/app/code/Magento/GraphQl/Model/Cors/Configuration.php index b06d63832b8d2..dd5a0b426e22d 100644 --- a/app/code/Magento/GraphQl/Model/Cors/Configuration.php +++ b/app/code/Magento/GraphQl/Model/Cors/Configuration.php @@ -14,12 +14,12 @@ */ class Configuration implements ConfigurationInterface { - const XML_PATH_CORS_HEADERS_ENABLED = 'graphql/cors/enabled'; - const XML_PATH_CORS_ALLOWED_ORIGINS = 'graphql/cors/allowed_origins'; - const XML_PATH_CORS_ALLOWED_HEADERS = 'graphql/cors/allowed_headers'; - const XML_PATH_CORS_ALLOWED_METHODS = 'graphql/cors/allowed_methods'; - const XML_PATH_CORS_MAX_AGE = 'graphql/cors/max_age'; - const XML_PATH_CORS_ALLOW_CREDENTIALS = 'graphql/cors/allow_credentials'; + public const XML_PATH_CORS_HEADERS_ENABLED = 'graphql/cors/enabled'; + public const XML_PATH_CORS_ALLOWED_ORIGINS = 'graphql/cors/allowed_origins'; + public const XML_PATH_CORS_ALLOWED_HEADERS = 'graphql/cors/allowed_headers'; + public const XML_PATH_CORS_ALLOWED_METHODS = 'graphql/cors/allowed_methods'; + public const XML_PATH_CORS_MAX_AGE = 'graphql/cors/max_age'; + public const XML_PATH_CORS_ALLOW_CREDENTIALS = 'graphql/cors/allow_credentials'; /** * @var ScopeConfigInterface diff --git a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php index 9e54e979323fa..b40b64f48e51f 100644 --- a/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php +++ b/app/code/Magento/GraphQl/Model/Cors/ConfigurationInterface.php @@ -17,35 +17,35 @@ interface ConfigurationInterface * * @return bool */ - public function isEnabled() : bool; + public function isEnabled(): bool; /** * Get allowed origins or null if stored configuration is empty * * @return string|null */ - public function getAllowedOrigins() : ?string; + public function getAllowedOrigins(): ?string; /** * Get allowed headers or null if stored configuration is empty * * @return string|null */ - public function getAllowedHeaders() : ?string; + public function getAllowedHeaders(): ?string; /** * Get allowed methods or null if stored configuration is empty * * @return string|null */ - public function getAllowedMethods() : ?string; + public function getAllowedMethods(): ?string; /** * Get max age header value * * @return int */ - public function getMaxAge() : int; + public function getMaxAge(): int; /** * Are credentials allowed diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index f0a8eca87ec58..fca6c425e2507 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,27 +100,27 @@ - + Access-Control-Max-Age - + Access-Control-Allow-Credentials - + Access-Control-Allow-Headers - + Access-Control-Allow-Methods - + Access-Control-Allow-Origin diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php index 3628d3e4bca32..25c808a549e80 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CorsHeadersTest.php @@ -45,13 +45,13 @@ protected function setUp(): void protected function tearDown(): void { - parent::tearDown(); // TODO: Change the autogenerated stub + parent::tearDown(); $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 0); $this->reinitConfig->reinit(); } - public function testNoCorsHeadersWhenCorsIsDisabled() + public function testNoCorsHeadersWhenCorsIsDisabled(): void { $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 0); $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, 'Origin'); @@ -70,7 +70,7 @@ public function testNoCorsHeadersWhenCorsIsDisabled() self::assertArrayNotHasKey('Access-Control-Allow-Origin', $headers); } - public function testCorsHeadersWhenCorsIsEnabled() + public function testCorsHeadersWhenCorsIsEnabled(): void { $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 1); $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, 'Origin'); @@ -89,7 +89,7 @@ public function testCorsHeadersWhenCorsIsEnabled() self::assertEquals('86400', $headers['Access-Control-Max-Age']); } - public function testEmptyCorsHeadersWhenCorsIsEnabled() + public function testEmptyCorsHeadersWhenCorsIsEnabled(): void { $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_HEADERS_ENABLED, 1); $this->resourceConfig->saveConfig(Configuration::XML_PATH_CORS_ALLOWED_HEADERS, ''); @@ -108,7 +108,7 @@ public function testEmptyCorsHeadersWhenCorsIsEnabled() self::assertArrayNotHasKey('Access-Control-Allow-Origin', $headers); } - private function getHeadersFromIntrospectionQuery() + private function getHeadersFromIntrospectionQuery(): array { $query = <<graphQlQueryWithResponseHeaders($query)['headers']; + return $this->graphQlQueryWithResponseHeaders($query)['headers'] ?? []; } }