Skip to content

Commit 54d9363

Browse files
authored
Merge pull request #61 from magento-mpi/MC-30896
MC-30896: Move PayPalRecaptcha module to Magento Security Extensions
2 parents db0456c + 765b548 commit 54d9363

File tree

28 files changed

+556
-27
lines changed

28 files changed

+556
-27
lines changed

ReCaptchaAdminUi/etc/di.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
99
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
10-
<virtualType name="Magento\ReCaptchaApi\Model\OptionSource\Type"
10+
<virtualType name="Magento\ReCaptchaAdminUi\Model\OptionSource\Type"
1111
type="Magento\ReCaptchaAdminUi\Model\OptionSource">
1212
<arguments>
1313
<argument name="options" xsi:type="array">

ReCaptchaCheckout/view/frontend/layout/checkout_index_index.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
<item name="displayArea" xsi:type="string">additional-login-form-fields</item>
2929
<item name="configSource" xsi:type="string">checkoutConfig</item>
3030
<item name="reCaptchaId" xsi:type="string">recaptcha-checkout-inline-login</item>
31-
<item name="zone" xsi:type="string">login</item>
3231
</item>
3332
</item>
3433
</item>
@@ -47,7 +46,6 @@
4746
<item name="displayArea" xsi:type="string">additional-login-form-fields</item>
4847
<item name="configSource" xsi:type="string">checkoutConfig</item>
4948
<item name="reCaptchaId" xsi:type="string">recaptcha-checkout-inline-login-billing</item>
50-
<item name="zone" xsi:type="string">login</item>
5149
</item>
5250
</item>
5351
</item>

ReCaptchaContact/etc/adminhtml/system.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<field id="contact" translate="label" type="select" sortOrder="140" showInDefault="1"
1414
showInWebsite="1" showInStore="0" canRestore="1">
1515
<label>Enable for Contact Us</label>
16-
<source_model>Magento\ReCaptchaApi\Model\OptionSource\Type</source_model>
16+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
1717
</field>
1818
</group>
1919
</section>

ReCaptchaCustomer/etc/adminhtml/system.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
<field id="customer_login" translate="label" type="select" sortOrder="110" showInDefault="1"
1414
showInWebsite="1" showInStore="0" canRestore="1">
1515
<label>Enable for Customer Login</label>
16-
<source_model>Magento\ReCaptchaApi\Model\OptionSource\Type</source_model>
16+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
1717
</field>
1818
<field id="customer_forgot_password" translate="label" type="select" sortOrder="120" showInDefault="1"
1919
showInWebsite="1" showInStore="0" canRestore="1">
2020
<label>Enable for Forgot Password</label>
21-
<source_model>Magento\ReCaptchaApi\Model\OptionSource\Type</source_model>
21+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
2222
</field>
2323
<field id="customer_create" translate="label" type="select" sortOrder="130" showInDefault="1"
2424
showInWebsite="1" showInStore="0" canRestore="1">
2525
<label>Enable for Create New Customer Account</label>
26-
<source_model>Magento\ReCaptchaApi\Model\OptionSource\Type</source_model>
26+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
2727
</field>
2828
</group>
2929
</section>

ReCaptchaFrontendUi/view/frontend/web/js/reCaptcha.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ define(
8989
$parentForm,
9090
$wrapper,
9191
$reCaptcha,
92-
widgetId,
93-
listeners;
92+
widgetId;
9493

9594
if (this.captchaInitialized) {
9695
return;
@@ -129,9 +128,26 @@ define(
129128

130129
// eslint-disable-next-line no-undef
131130
widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);
131+
this.initParentForm($parentForm, widgetId);
132+
133+
registry.ids.push(this.getReCaptchaId());
134+
registry.captchaList.push(widgetId);
135+
registry.tokenFields.push(this.tokenField);
132136

133-
if (this.getIsInvisibleRecaptcha() && $parentForm.length > 0) {
134-
$parentForm.submit(function (event) {
137+
},
138+
139+
/**
140+
* Initialize parent form.
141+
*
142+
* @param {Object} parentForm
143+
* @param {String} widgetId
144+
*/
145+
initParentForm: function (parentForm, widgetId) {
146+
var me = this,
147+
listeners;
148+
149+
if (this.getIsInvisibleRecaptcha() && parentForm.length > 0) {
150+
parentForm.submit(function (event) {
135151
if (!me.tokenField.value) {
136152
// eslint-disable-next-line no-undef
137153
grecaptcha.execute(widgetId);
@@ -141,21 +157,16 @@ define(
141157
});
142158

143159
// Move our (last) handler topmost. We need this to avoid submit bindings with ko.
144-
listeners = $._data($parentForm[0], 'events').submit;
160+
listeners = $._data(parentForm[0], 'events').submit;
145161
listeners.unshift(listeners.pop());
146162

147163
// Create a virtual token field
148164
this.tokenField = $('<input type="text" name="token" style="display: none" />')[0];
149-
this.$parentForm = $parentForm;
150-
$parentForm.append(this.tokenField);
165+
this.$parentForm = parentForm;
166+
parentForm.append(this.tokenField);
151167
} else {
152168
this.tokenField = null;
153169
}
154-
155-
registry.ids.push(this.getReCaptchaId());
156-
registry.captchaList.push(widgetId);
157-
registry.tokenFields.push(this.tokenField);
158-
159170
},
160171

161172
validateReCaptcha: function (state) {

ReCaptchaNewsletter/etc/adminhtml/system.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
showInWebsite="1" showInStore="0" canRestore="1">
1515
<label>Enable Invisible reCAPTCHA in Newsletter Subscription</label>
1616
<comment>If enabled, a badge will be displayed in every page.</comment>
17-
<source_model>Magento\ReCaptchaApi\Model\OptionSource\Type</source_model>
17+
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
1818
</field>
1919
</group>
2020
</section>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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\ReCaptchaPaypal\Block\LayoutProcessor\Checkout;
9+
10+
use Magento\Checkout\Block\Checkout\LayoutProcessorInterface;
11+
use Magento\Framework\Exception\InputException;
12+
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
13+
use Magento\ReCaptchaUi\Model\UiConfigResolverInterface;
14+
15+
/**
16+
* Provides reCaptcha component configuration.
17+
*/
18+
class Onepage implements LayoutProcessorInterface
19+
{
20+
/**
21+
* @var UiConfigResolverInterface
22+
*/
23+
private $captchaUiConfigResolver;
24+
25+
/**
26+
* @var IsCaptchaEnabledInterface
27+
*/
28+
private $isCaptchaEnabled;
29+
30+
/**
31+
* @param UiConfigResolverInterface $captchaUiConfigResolver
32+
* @param IsCaptchaEnabledInterface $isCaptchaEnabled
33+
*/
34+
public function __construct(
35+
UiConfigResolverInterface $captchaUiConfigResolver,
36+
IsCaptchaEnabledInterface $isCaptchaEnabled
37+
) {
38+
$this->captchaUiConfigResolver = $captchaUiConfigResolver;
39+
$this->isCaptchaEnabled = $isCaptchaEnabled;
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*
45+
* @param array $jsLayout
46+
* @return array
47+
* @throws InputException
48+
*/
49+
public function process($jsLayout)
50+
{
51+
$key = 'paypal_payflowpro';
52+
if ($this->isCaptchaEnabled->isCaptchaEnabledFor($key)) {
53+
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
54+
['payment']['children']['payments-list']['children']['paypal-captcha']['children']
55+
['recaptcha']['settings'] = $this->captchaUiConfigResolver->get($key);
56+
} else {
57+
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
58+
['payment']['children']['payments-list']['children']['paypal-captcha']['children']['recaptcha'])) {
59+
unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
60+
['payment']['children']['payments-list']['children']['paypal-captcha']['children']['recaptcha']);
61+
}
62+
}
63+
64+
return $jsLayout;
65+
}
66+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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\ReCaptchaPaypal\Model;
9+
10+
use Magento\Checkout\Model\ConfigProviderInterface;
11+
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
12+
13+
/**
14+
* Adds reCaptcha configuration to checkout.
15+
*/
16+
class CheckoutConfigProvider implements ConfigProviderInterface
17+
{
18+
/**
19+
* @var IsCaptchaEnabledInterface
20+
*/
21+
private $isCaptchaEnabled;
22+
23+
/**
24+
* @param IsCaptchaEnabledInterface $isCaptchaEnabled
25+
*/
26+
public function __construct(
27+
IsCaptchaEnabledInterface $isCaptchaEnabled
28+
) {
29+
$this->isCaptchaEnabled = $isCaptchaEnabled;
30+
}
31+
32+
/**
33+
* @inheritdoc
34+
*/
35+
public function getConfig()
36+
{
37+
return [
38+
'recaptcha_paypal' => $this->isCaptchaEnabled->isCaptchaEnabledFor('paypal_payflowpro')
39+
];
40+
}
41+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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\ReCaptchaPaypal\Observer;
9+
10+
use Magento\Framework\App\Action\Action;
11+
use Magento\Framework\App\ActionFlag;
12+
use Magento\Framework\Event\Observer;
13+
use Magento\Framework\Event\ObserverInterface;
14+
use Magento\Framework\Exception\InputException;
15+
use Magento\Framework\Exception\LocalizedException;
16+
use Magento\Framework\Serialize\SerializerInterface;
17+
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
18+
use Magento\ReCaptchaUi\Model\CaptchaResponseResolverInterface;
19+
use Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface;
20+
use Magento\ReCaptchaValidationApi\Api\ValidatorInterface;
21+
use Psr\Log\LoggerInterface;
22+
23+
/**
24+
* AjaxLoginObserver
25+
*/
26+
class PayPalObserver implements ObserverInterface
27+
{
28+
/**
29+
* @var CaptchaResponseResolverInterface
30+
*/
31+
private $captchaResponseResolver;
32+
33+
/**
34+
* @var ValidationConfigResolverInterface
35+
*/
36+
private $validationConfigResolver;
37+
38+
/**
39+
* @var ValidatorInterface
40+
*/
41+
private $captchaValidator;
42+
43+
/**
44+
* @var ActionFlag
45+
*/
46+
private $actionFlag;
47+
48+
/**
49+
* @var SerializerInterface
50+
*/
51+
private $serializer;
52+
53+
/**
54+
* @var IsCaptchaEnabledInterface
55+
*/
56+
private $isCaptchaEnabled;
57+
58+
/**
59+
* @var LoggerInterface
60+
*/
61+
private $logger;
62+
63+
/**
64+
* @param CaptchaResponseResolverInterface $captchaResponseResolver
65+
* @param ValidationConfigResolverInterface $validationConfigResolver
66+
* @param ValidatorInterface $captchaValidator
67+
* @param ActionFlag $actionFlag
68+
* @param SerializerInterface $serializer
69+
* @param IsCaptchaEnabledInterface $isCaptchaEnabled
70+
* @param LoggerInterface $logger
71+
*/
72+
public function __construct(
73+
CaptchaResponseResolverInterface $captchaResponseResolver,
74+
ValidationConfigResolverInterface $validationConfigResolver,
75+
ValidatorInterface $captchaValidator,
76+
ActionFlag $actionFlag,
77+
SerializerInterface $serializer,
78+
IsCaptchaEnabledInterface $isCaptchaEnabled,
79+
LoggerInterface $logger
80+
) {
81+
$this->captchaResponseResolver = $captchaResponseResolver;
82+
$this->validationConfigResolver = $validationConfigResolver;
83+
$this->captchaValidator = $captchaValidator;
84+
$this->actionFlag = $actionFlag;
85+
$this->serializer = $serializer;
86+
$this->isCaptchaEnabled = $isCaptchaEnabled;
87+
$this->logger = $logger;
88+
}
89+
90+
/**
91+
* Validates reCaptcha response.
92+
*
93+
* @param Observer $observer
94+
* @return void
95+
* @throws LocalizedException
96+
*/
97+
public function execute(Observer $observer): void
98+
{
99+
$key = 'paypal_payflowpro';
100+
if ($this->isCaptchaEnabled->isCaptchaEnabledFor($key)) {
101+
/** @var Action $controller */
102+
$controller = $observer->getControllerAction();
103+
$request = $controller->getRequest();
104+
$response = $controller->getResponse();
105+
106+
$validationConfig = $this->validationConfigResolver->get($key);
107+
108+
try {
109+
$reCaptchaResponse = $this->captchaResponseResolver->resolve($request);
110+
} catch (InputException $e) {
111+
$this->logger->error($e);
112+
113+
$jsonPayload = $this->serializer->serialize([
114+
'success' => false,
115+
'error' => true,
116+
'error_messages' => $validationConfig->getValidationFailureMessage(),
117+
]);
118+
$response->representJson($jsonPayload);
119+
return;
120+
}
121+
122+
$validationResult = $this->captchaValidator->isValid($reCaptchaResponse, $validationConfig);
123+
if (false === $validationResult->isValid()) {
124+
$this->actionFlag->set('', Action::FLAG_NO_DISPATCH, true);
125+
126+
$jsonPayload = $this->serializer->serialize([
127+
'success' => false,
128+
'error' => true,
129+
'error_messages' => $validationConfig->getValidationFailureMessage(),
130+
]);
131+
132+
$response->representJson($jsonPayload);
133+
}
134+
}
135+
}
136+
}

ReCaptchaPaypal/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Please refer to: https://github.com/magento/security-package

0 commit comments

Comments
 (0)