Skip to content

Commit 9b092ca

Browse files
committed
Merge branch 'b-7.4.x' into b-7.4.x-simplify-OXDEV-9078
2 parents 71ef6be + 1cd6cfa commit 9b092ca

14 files changed

Lines changed: 299 additions & 219 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Two-Factor Authentication (2FA) with email OTP verification
1111

12+
### Fixed
13+
- Captcha validation moved from User model to UserComponent to prevent API login failures
14+
1215
## [2.1.0] - 2026-01-14
1316

1417
### Added
@@ -58,6 +61,7 @@ This is the stable release of v1.0.0. No changes have been made since v1.0.0-rc.
5861
- Button for generating strong password
5962
- Button for show/hide password in password fields
6063

64+
[2.1.0]: https://github.com/OXID-eSales/security-module/compare/v2.0.0...v2.1.0
6165
[2.0.0]: https://github.com/OXID-eSales/security-module/compare/v2.0.0-rc.3...v2.0.0
6266
[2.0.0-rc.3]: https://github.com/OXID-eSales/security-module/compare/v2.0.0-rc.2...v2.0.0-rc.3
6367
[2.0.0-rc.2]: https://github.com/OXID-eSales/security-module/compare/v2.0.0-rc.1...v2.0.0-rc.2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ A collection of security features for OXID eShop
1414
This module assumes you have OXID eShop Compilation version 7.4.0 installed.
1515

1616
### Branches
17-
* b-7.4.x branch is compatible with OXID eShop compilation 7.4.x
17+
* 2.1.0.x versions (or b-7.4.x branch) are compatible with OXID eShop compilation 7.4.x
1818
* 2.0.0.x versions (or b-7.3.x branch) are compatible with OXID eShop compilation 7.3.x.
1919
* 1.0.0.x versions (or b-7.2.x branch) are compatible with OXID eShop compilation 7.2.x.
2020

assets/out/src/css/providers.css

Lines changed: 0 additions & 9 deletions
This file was deleted.

metadata.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
'de' => 'Werkzeuge zum Schutz Ihres Shops und zur Sicherung von Kundenkonten.'
2828
],
2929
'thumbnail' => 'logo.png',
30-
'version' => '2.0.0',
30+
'version' => '2.1.0',
3131
'author' => 'OXID eSales AG',
3232
'url' => 'https://github.com/OXID-eSales/security-module',
3333
'email' => 'info@oxid-esales.com',
3434
'extend' => [
35+
\OxidEsales\Eshop\Application\Component\UserComponent::class => \OxidEsales\SecurityModule\Captcha\Shop\UserComponent::class,
3536
\OxidEsales\Eshop\Application\Controller\NewsletterController::class => \OxidEsales\SecurityModule\Captcha\Shop\NewsletterController::class,
3637
\OxidEsales\Eshop\Application\Controller\ForgotPasswordController::class => \OxidEsales\SecurityModule\Shared\Controller\ForgotPasswordController::class,
3738
\OxidEsales\Eshop\Application\Model\User::class => \OxidEsales\SecurityModule\Shared\Model\User::class,

src/Captcha/Form/ContactFormDecorator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use OxidEsales\EshopCommunity\Internal\Framework\Form\FormInterface;
1515
use OxidEsales\EshopCommunity\Internal\Framework\FormConfiguration\FormConfigurationInterface;
1616

17-
class ContactFormDecorator
17+
class ContactFormDecorator implements ContactFormBridgeInterface
1818
{
1919
public function __construct(
2020
private ContactFormBridgeInterface $contactFormBridge,

src/Captcha/Shop/UserComponent.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Captcha\Shop;
11+
12+
use OxidEsales\Eshop\Core\Exception\StandardException;
13+
use OxidEsales\Eshop\Core\Registry;
14+
use OxidEsales\SecurityModule\Captcha\Service\CaptchaServiceInterface;
15+
use OxidEsales\SecurityModule\Captcha\Service\ModuleSettingsServiceInterface;
16+
17+
/**
18+
* @mixin \OxidEsales\Eshop\Application\Component\UserComponent
19+
* @eshopExtension
20+
*/
21+
class UserComponent extends UserComponent_parent
22+
{
23+
public function login()
24+
{
25+
if (!$this->isCaptchaEnabled()) {
26+
return parent::login();
27+
}
28+
29+
try {
30+
$this->getService(CaptchaServiceInterface::class)
31+
->validate(Registry::getRequest());
32+
} catch (StandardException $e) {
33+
Registry::getUtilsView()->addErrorToDisplay($e->getMessage());
34+
$this->setLoginStatus(USER_LOGIN_FAIL);
35+
return 'user';
36+
}
37+
38+
return parent::login();
39+
}
40+
41+
public function createUser()
42+
{
43+
if (!$this->isCaptchaEnabled()) {
44+
return parent::createUser();
45+
}
46+
47+
try {
48+
$this->getService(CaptchaServiceInterface::class)
49+
->validate(Registry::getRequest());
50+
} catch (StandardException $e) {
51+
Registry::getUtilsView()->addErrorToDisplay($e->getMessage());
52+
return false;
53+
}
54+
55+
return parent::createUser();
56+
}
57+
58+
private function isCaptchaEnabled(): bool
59+
{
60+
$settings = $this->getService(ModuleSettingsServiceInterface::class);
61+
return $settings->isCaptchaEnabled() || $settings->isHoneyPotCaptchaEnabled();
62+
}
63+
}

src/Shared/Model/User.php

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,7 @@
99

1010
namespace OxidEsales\SecurityModule\Shared\Model;
1111

12-
use OxidEsales\Eshop\Core\Exception\InputException;
13-
use OxidEsales\Eshop\Core\Exception\UserException;
14-
use OxidEsales\Eshop\Core\Registry;
1512
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\TwoFAUserServiceInterface;
16-
use OxidEsales\SecurityModule\Captcha\Captcha\Image\Exception\CaptchaValidateException as ImageCaptchaException;
17-
use OxidEsales\SecurityModule\Captcha\Captcha\HoneyPot\Exception\CaptchaValidateException as HoneyPotCaptchaException;
18-
use OxidEsales\SecurityModule\Captcha\Service\CaptchaServiceInterface;
19-
use OxidEsales\SecurityModule\Captcha\Service\ModuleSettingsServiceInterface as CaptchaSettingsServiceInterface;
20-
use OxidEsales\SecurityModule\Shared\Core\InputValidator;
2113

2214
/**
2315
* User model extended
@@ -27,62 +19,6 @@
2719
*/
2820
class User extends User_parent
2921
{
30-
public function checkValues(
31-
$sLogin,
32-
#[\SensitiveParameter] $sPassword,
33-
#[\SensitiveParameter] $sPassword2,
34-
$aInvAddress,
35-
$aDelAddress
36-
): void {
37-
if ($this->isCaptchaEnabled() && $this->shouldValidateCaptcha()) {
38-
/** @var InputValidator $oInputValidator */
39-
$oInputValidator = Registry::getInputValidator();
40-
$captchaService = $this->getService(CaptchaServiceInterface::class);
41-
42-
try {
43-
$captchaService->validate(
44-
Registry::getRequest()
45-
);
46-
} catch (ImageCaptchaException $e) {
47-
$oInputValidator->addValidationError(
48-
"captcha",
49-
oxNew(
50-
InputException::class,
51-
Registry::getLang()->translateString($e->getMessage())
52-
)
53-
);
54-
} catch (HoneyPotCaptchaException $e) {
55-
throw $e;
56-
}
57-
}
58-
59-
parent::checkValues($sLogin, $sPassword, $sPassword2, $aInvAddress, $aDelAddress);
60-
}
61-
62-
/**
63-
* @SuppressWarnings(PHPMD.BooleanArgumentFlag)
64-
*/
65-
public function login($userName, #[\SensitiveParameter] $password, $setSessionCookie = false): bool
66-
{
67-
if ($this->isAdmin()) {
68-
return parent::login($userName, $password, $setSessionCookie);
69-
}
70-
71-
if ($password !== null && $this->isCaptchaEnabled()) {
72-
$captchaService = $this->getService(CaptchaServiceInterface::class);
73-
74-
try {
75-
$captchaService->validate(
76-
Registry::getRequest()
77-
);
78-
} catch (ImageCaptchaException | HoneyPotCaptchaException $e) {
79-
throw oxNew(UserException::class, $e->getMessage());
80-
}
81-
}
82-
83-
return parent::login($userName, $password, $setSessionCookie);
84-
}
85-
8622
/** @phpstan-ignore missingType.return (inherited from parent without return type) */
8723
protected function onLogin($userName, #[\SensitiveParameter] $password)
8824
{
@@ -96,15 +32,4 @@ protected function onLogin($userName, #[\SensitiveParameter] $password)
9632
}
9733
}
9834
}
99-
100-
private function isCaptchaEnabled(): bool
101-
{
102-
$settingsService = $this->getService(CaptchaSettingsServiceInterface::class);
103-
return $settingsService->isCaptchaEnabled() || $settingsService->isHoneyPotCaptchaEnabled();
104-
}
105-
106-
protected function shouldValidateCaptcha(): bool
107-
{
108-
return !$this->getUser();
109-
}
11035
}

tests/Codeception/Support/Data/fixtures.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SET @@session.sql_mode = '';
22

33
REPLACE INTO `oxuser` (`OXID`, `OXACTIVE`, `OXRIGHTS`, `OXSHOPID`, `OXUSERNAME`, `OXPASSWORD`, `OXPASSSALT`, `OXCUSTNR`, `OXUSTID`, `OXCOMPANY`, `OXFNAME`, `OXLNAME`, `OXSTREET`, `OXSTREETNR`, `OXADDINFO`, `OXCITY`, `OXCOUNTRYID`, `OXZIP`, `OXFON`, `OXFAX`, `OXSAL`, `OXBONI`, `OXCREATE`, `OXREGISTER`, `OXPRIVFON`, `OXMOBFON`, `OXBIRTHDATE`)
4-
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', '$2y$10$b186f117054b700a89de9uXDzfahkizUucitfPov3C2cwF5eit2M2', 'b186f117054b700a89de929ce90c6aef', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
4+
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', 'c9dadd994241c9e5fa6469547009328a', '7573657275736572', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
55

66
REPLACE INTO `oxarticles` (`OXID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXTITLE`, `OXSHORTDESC`, `OXPRICE`, `OXPRICEA`, `OXPRICEB`, `OXPRICEC`, `OXTPRICE`, `OXUNITNAME`, `OXUNITQUANTITY`, `OXVAT`, `OXWEIGHT`, `OXSTOCK`, `OXSTOCKFLAG`, `OXSTOCKTEXT`, `OXNOSTOCKTEXT`, `OXDELIVERY`, `OXINSERT`, `OXTIMESTAMP`, `OXLENGTH`, `OXWIDTH`, `OXHEIGHT`, `OXSEARCHKEYS`, `OXISSEARCH`, `OXVARNAME`, `OXVARSTOCK`, `OXVARCOUNT`, `OXVARSELECT`, `OXVARMINPRICE`, `OXVARMAXPRICE`, `OXVARNAME_1`, `OXVARSELECT_1`, `OXTITLE_1`, `OXSHORTDESC_1`, `OXSEARCHKEYS_1`, `OXBUNDLEID`, `OXSTOCKTEXT_1`, `OXNOSTOCKTEXT_1`, `OXSORT`, `OXVENDORID`, `OXMANUFACTURERID`, `OXMINDELTIME`, `OXMAXDELTIME`, `OXDELTIMEUNIT`)
77
VALUES ('1000', 1, '', 1, '1000', '[DE 4] Test product 0 šÄßüл', 'Test product 0 short desc [DE]', 50, 35, 45, 55, 0, 'kg', 2, NULL, 2, 15, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:07:48', 1, 2, 2, 'search1000', 1, '', 0, 0, '', 50, 0, '', '', 'Test product 0 [EN] šÄßüл', 'Test product 0 short desc [EN] šÄßüл', 'šÄßüл1000', '', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'DAY');

tests/Codeception/Support/Data/fixtures_ee.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SET @@session.sql_mode = '';
22

33
REPLACE INTO `oxuser` (`OXID`, `OXACTIVE`, `OXRIGHTS`, `OXSHOPID`, `OXUSERNAME`, `OXPASSWORD`, `OXPASSSALT`, `OXCUSTNR`, `OXUSTID`, `OXCOMPANY`, `OXFNAME`, `OXLNAME`, `OXSTREET`, `OXSTREETNR`, `OXADDINFO`, `OXCITY`, `OXCOUNTRYID`, `OXZIP`, `OXFON`, `OXFAX`, `OXSAL`, `OXBONI`, `OXCREATE`, `OXREGISTER`, `OXPRIVFON`, `OXMOBFON`, `OXBIRTHDATE`)
4-
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', '$2y$10$b186f117054b700a89de9uXDzfahkizUucitfPov3C2cwF5eit2M2', 'b186f117054b700a89de929ce90c6aef', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
4+
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', 'c9dadd994241c9e5fa6469547009328a', '7573657275736572', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
55

66
REPLACE INTO `oxarticles` (`OXID`, `OXMAPID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXTITLE`, `OXSHORTDESC`, `OXPRICE`, `OXPRICEA`, `OXPRICEB`, `OXPRICEC`, `OXTPRICE`, `OXUNITNAME`, `OXUNITQUANTITY`, `OXVAT`, `OXWEIGHT`, `OXSTOCK`, `OXSTOCKFLAG`, `OXSTOCKTEXT`, `OXNOSTOCKTEXT`, `OXDELIVERY`, `OXINSERT`, `OXTIMESTAMP`, `OXLENGTH`, `OXWIDTH`, `OXHEIGHT`, `OXSEARCHKEYS`, `OXISSEARCH`, `OXVARNAME`, `OXVARSTOCK`, `OXVARCOUNT`, `OXVARSELECT`, `OXVARMINPRICE`, `OXVARMAXPRICE`, `OXVARNAME_1`, `OXVARSELECT_1`, `OXTITLE_1`, `OXSHORTDESC_1`, `OXSEARCHKEYS_1`, `OXBUNDLEID`, `OXSTOCKTEXT_1`, `OXNOSTOCKTEXT_1`, `OXSORT`, `OXVENDORID`, `OXMANUFACTURERID`, `OXMINDELTIME`, `OXMAXDELTIME`, `OXDELTIMEUNIT`)
77
VALUES ('1000', 1, 1, '', 1, '1000', '[DE 4] Test product 0 šÄßüл', 'Test product 0 short desc [DE]', 50, 35, 45, 55, 0, 'kg', 2, NULL, 2, 15, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:07:48', 1, 2, 2, 'search1000', 1, '', 0, 0, '', 50, 0, '', '', 'Test product 0 [EN] šÄßüл', 'Test product 0 short desc [EN] šÄßüл', 'šÄßüл1000', '', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'DAY');

0 commit comments

Comments
 (0)