Skip to content

Commit 5ddbc7c

Browse files
authored
Merge branch 'develop' into develop
2 parents 8c81877 + 4cbf69f commit 5ddbc7c

File tree

90 files changed

+3400
-14
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+3400
-14
lines changed

ReCaptchaAdminUi/etc/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@
3030
</argument>
3131
</arguments>
3232
</virtualType>
33+
<type name="Magento\ReCaptchaUi\Model\CaptchaTypeResolver">
34+
<arguments>
35+
<argument name="resolvers" xsi:type="array">
36+
<item name="admin" xsi:type="object">Magento\ReCaptchaAdminUi\Model\CaptchaTypeResolver</item>
37+
</argument>
38+
</arguments>
39+
</type>
3340
</config>

ReCaptchaCheckout/Block/LayoutProcessor/Checkout/Onepage.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ public function __construct(
4040
}
4141

4242
/**
43-
* {@inheritdoc}
44-
*
45-
* @param array $jsLayout
46-
* @return array
47-
* @throws InputException
43+
* @inheritDoc
4844
*/
4945
public function process($jsLayout): array
5046
{
@@ -77,6 +73,20 @@ public function process($jsLayout): array
7773
}
7874
}
7975

76+
$key = 'place_order';
77+
if ($this->isCaptchaEnabled->isCaptchaEnabledFor($key)) {
78+
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
79+
['payment']['children']['beforeMethods']['children']['place-order-recaptcha-container']['children']
80+
['place-order-recaptcha']['settings'] = $this->captchaUiConfigResolver->get($key);
81+
} else {
82+
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
83+
['payment']['children']['beforeMethods']['children']['place-order-recaptcha'])) {
84+
unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
85+
['payment']['children']['beforeMethods']['children']['place-order-recaptcha-container']
86+
['children']['place-order-recaptcha']);
87+
}
88+
}
89+
8090
return $jsLayout;
8191
}
8292
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReCaptchaCheckout\Model;
9+
10+
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
11+
use Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface;
12+
use Magento\ReCaptchaValidationApi\Api\Data\ValidationConfigInterface;
13+
use Magento\ReCaptchaWebapiApi\Api\Data\EndpointInterface;
14+
use Magento\ReCaptchaWebapiApi\Api\WebapiValidationConfigProviderInterface;
15+
16+
/**
17+
* Provide checkout related endpoint configuration.
18+
*/
19+
class WebapiConfigProvider implements WebapiValidationConfigProviderInterface
20+
{
21+
private const CAPTCHA_ID = 'place_order';
22+
23+
/**
24+
* @var IsCaptchaEnabledInterface
25+
*/
26+
private $isEnabled;
27+
28+
/**
29+
* @var ValidationConfigResolverInterface
30+
*/
31+
private $configResolver;
32+
33+
/**
34+
* @param IsCaptchaEnabledInterface $isEnabled
35+
* @param ValidationConfigResolverInterface $configResolver
36+
*/
37+
public function __construct(IsCaptchaEnabledInterface $isEnabled, ValidationConfigResolverInterface $configResolver)
38+
{
39+
$this->isEnabled = $isEnabled;
40+
$this->configResolver = $configResolver;
41+
}
42+
43+
/**
44+
* @inheritDoc
45+
*/
46+
public function getConfigFor(EndpointInterface $endpoint): ?ValidationConfigInterface
47+
{
48+
//phpcs:disable Magento2.PHP.LiteralNamespaces
49+
if ($endpoint->getServiceMethod() === 'savePaymentInformationAndPlaceOrder'
50+
|| $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\SetPaymentAndPlaceOrder'
51+
|| $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\PlaceOrder'
52+
) {
53+
if ($this->isEnabled->isCaptchaEnabledFor(self::CAPTCHA_ID)) {
54+
return $this->configResolver->get(self::CAPTCHA_ID);
55+
}
56+
}
57+
//phpcs:enable Magento2.PHP.LiteralNamespaces
58+
59+
return null;
60+
}
61+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReCaptchaCheckout\Test\Api;
9+
10+
use Magento\Framework\Webapi\Rest\Request;
11+
use Magento\Quote\Model\Quote;
12+
use Magento\Quote\Model\QuoteFactory;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use Magento\TestFramework\TestCase\WebapiAbstract;
15+
16+
/**
17+
* Test that checkout APIs are covered with ReCaptcha
18+
*/
19+
class GuestPaymentInformationManagementTest extends WebapiAbstract
20+
{
21+
private const API_ROUTE = '/V1/guest-carts/%s/payment-information';
22+
23+
/**
24+
* @var QuoteFactory
25+
*/
26+
private $quoteFactory;
27+
28+
/**
29+
* @inheritDoc
30+
*/
31+
protected function setUp(): void
32+
{
33+
parent::setUp();
34+
35+
$this->_markTestAsRestOnly();
36+
$objectManager = Bootstrap::getObjectManager();
37+
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
38+
}
39+
40+
/**
41+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_check_payment.php
42+
* @magentoConfigFixture default_store customer/captcha/enable 0
43+
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/public_key test_public_key
44+
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/private_key test_private_key
45+
* @magentoConfigFixture base_website recaptcha_frontend/type_for/place_order invisible
46+
*/
47+
public function testRequired(): void
48+
{
49+
$this->expectException(\Throwable::class);
50+
$this->expectExceptionCode(400);
51+
$this->expectExceptionMessage('{"message":"ReCaptcha validation failed, please try again"}');
52+
53+
/** @var Quote $quote */
54+
$quote = $this->quoteFactory->create();
55+
$quote->load('test_order_1', 'reserved_order_id');
56+
$cartId = $quote->getId();
57+
$payment = $quote->getPayment();
58+
$address = $quote->getBillingAddress();
59+
$addressData = [];
60+
$addressProperties = [
61+
'city', 'company', 'countryId', 'firstname', 'lastname', 'postcode',
62+
'region', 'regionCode', 'regionId', 'saveInAddressBook', 'street', 'telephone', 'email'
63+
];
64+
foreach ($addressProperties as $property) {
65+
$method = 'get' . $property;
66+
$addressData[$property] = $address->$method();
67+
}
68+
69+
$serviceInfo = [
70+
'rest' => [
71+
'resourcePath' => sprintf(self::API_ROUTE, $cartId),
72+
'httpMethod' => Request::HTTP_METHOD_POST,
73+
'token' => null
74+
],
75+
];
76+
$requestData = [
77+
'cart_id' => $cartId,
78+
'billingAddress' => $addressData,
79+
'email' => $quote->getCustomerEmail(),
80+
'paymentMethod' => [
81+
'additional_data' => $payment->getAdditionalData(),
82+
'method' => $payment->getMethod(),
83+
'po_number' => $payment->getPoNumber()
84+
]
85+
];
86+
87+
$this->_webApiCall($serviceInfo, $requestData);
88+
}
89+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReCaptchaCheckout\Test\Api;
9+
10+
use Magento\Framework\Webapi\Rest\Request;
11+
use Magento\Integration\Api\CustomerTokenServiceInterface;
12+
use Magento\Quote\Model\Quote;
13+
use Magento\Quote\Model\QuoteFactory;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use Magento\TestFramework\TestCase\WebapiAbstract;
16+
17+
/**
18+
* Test that checkout APIs are covered with ReCaptcha
19+
*/
20+
class PaymentInformationManagementTest extends WebapiAbstract
21+
{
22+
private const API_ROUTE = '/V1/carts/mine/payment-information';
23+
24+
/**
25+
* @var QuoteFactory
26+
*/
27+
private $quoteFactory;
28+
29+
/**
30+
* @var CustomerTokenServiceInterface
31+
*/
32+
private $tokenService;
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
protected function setUp(): void
38+
{
39+
parent::setUp();
40+
41+
$this->_markTestAsRestOnly();
42+
$objectManager = Bootstrap::getObjectManager();
43+
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
44+
$this->tokenService = $objectManager->get(CustomerTokenServiceInterface::class);
45+
}
46+
47+
/**
48+
* @magentoApiDataFixture Magento/Checkout/_files/customer_quote_ready_for_order.php
49+
* @magentoConfigFixture default_store customer/captcha/enable 0
50+
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/public_key test_public_key
51+
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/private_key test_private_key
52+
* @magentoConfigFixture base_website recaptcha_frontend/type_for/place_order invisible
53+
*/
54+
public function testRequired(): void
55+
{
56+
$this->expectException(\Throwable::class);
57+
$this->expectExceptionCode(400);
58+
$this->expectExceptionMessage('{"message":"ReCaptcha validation failed, please try again"}');
59+
60+
/** @var Quote $quote */
61+
$quote = $this->quoteFactory->create();
62+
$quote->load('55555555', 'reserved_order_id');
63+
$cartId = $quote->getId();
64+
$payment = $quote->getPayment();
65+
$address = $quote->getBillingAddress();
66+
$addressData = [];
67+
$addressProperties = [
68+
'city', 'company', 'countryId', 'firstname', 'lastname', 'postcode',
69+
'region', 'regionCode', 'regionId', 'saveInAddressBook', 'street', 'telephone', 'email'
70+
];
71+
foreach ($addressProperties as $property) {
72+
$method = 'get' . $property;
73+
$addressData[$property] = $address->$method();
74+
}
75+
$token = $this->tokenService->createCustomerAccessToken('[email protected]', 'password');
76+
77+
$serviceInfo = [
78+
'rest' => [
79+
'resourcePath' => self::API_ROUTE,
80+
'httpMethod' => Request::HTTP_METHOD_POST,
81+
'token' => $token
82+
],
83+
];
84+
$requestData = [
85+
'cart_id' => $cartId,
86+
'billingAddress' => $addressData,
87+
'email' => $quote->getCustomerEmail(),
88+
'paymentMethod' => [
89+
'additional_data' => $payment->getAdditionalData(),
90+
'method' => $payment->getMethod(),
91+
'po_number' => $payment->getPoNumber()
92+
]
93+
];
94+
95+
$this->_webApiCall($serviceInfo, $requestData);
96+
}
97+
}

ReCaptchaCheckout/composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
"php": "~7.3.0||~7.4.0",
66
"magento/framework": "*",
77
"magento/module-checkout": "*",
8-
"magento/module-re-captcha-ui": "*"
8+
"magento/module-re-captcha-ui": "*",
9+
"magento/module-re-captcha-validation-api": "*",
10+
"magento/module-re-captcha-admin-ui": "*",
11+
"magento/module-re-captcha-frontend-ui": "*",
12+
"magento/module-re-captcha-webapi-api": "*",
13+
"magento/module-re-captcha-webapi-ui": "*"
914
},
1015
"type": "magento2-module",
1116
"license": "OSL-3.0",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
10+
<system>
11+
<section id="recaptcha_frontend">
12+
<group id="type_for">
13+
<field id="place_order" translate="label" type="select" sortOrder="175" showInDefault="1"
14+
showInWebsite="1" showInStore="0" canRestore="1">
15+
<label>Enable for Checkout/Placing Order</label>
16+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
17+
</field>
18+
</group>
19+
</section>
20+
</system>
21+
</config>

ReCaptchaCheckout/etc/config.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
10+
<default>
11+
<recaptcha_frontend>
12+
<type_for>
13+
<place_order/>
14+
</type_for>
15+
</recaptcha_frontend>
16+
</default>
17+
</config>

ReCaptchaCheckout/etc/di.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
10+
<type name="Magento\ReCaptchaWebapiApi\Model\CompositeWebapiValidationConfigProvider">
11+
<arguments>
12+
<argument name="providers" xsi:type="array">
13+
<item name="checkout" xsi:type="object">Magento\ReCaptchaCheckout\Model\WebapiConfigProvider</item>
14+
</argument>
15+
</arguments>
16+
</type>
17+
</config>

ReCaptchaCheckout/view/frontend/layout/checkout_index_index.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@
4747
</item>
4848
</item>
4949
</item>
50+
<item name="beforeMethods" xsi:type="array">
51+
<item name="children" xsi:type="array">
52+
<item name="place-order-recaptcha-container" xsi:type="array">
53+
<item name="component" xsi:type="string">uiComponent</item>
54+
<item name="template" xsi:type="string">Magento_ReCaptchaCheckout/payment-recaptcha-container</item>
55+
<item name="displayArea" xsi:type="string">beforeMethods</item>
56+
<item name="children" xsi:type="array">
57+
<item name="place-order-recaptcha" xsi:type="array">
58+
<item name="component" xsi:type="string">Magento_ReCaptchaWebapiUi/js/webapiReCaptcha</item>
59+
<item name="displayArea" xsi:type="string">place-order-recaptcha</item>
60+
<item name="configSource" xsi:type="string">checkoutConfig</item>
61+
<item name="reCaptchaId" xsi:type="string">recaptcha-checkout-place-order</item>
62+
</item>
63+
</item>
64+
</item>
65+
</item>
66+
</item>
5067
</item>
5168
</item>
5269
</item>

0 commit comments

Comments
 (0)