Skip to content

Commit

Permalink
Merge branch 'b-7.3.x-fix-duplicate-email-error-OXDEV-8351' into b-8.…
Browse files Browse the repository at this point in the history
…0.x-fix-duplicate-email-error-OXDEV-8351

# Conflicts:
#	CHANGELOG-7.3.md
#	composer.json
  • Loading branch information
moritzdemmer committed Nov 13, 2024
2 parents 8ebd064 + 34ec1b1 commit ade8de1
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 78 deletions.
3 changes: 3 additions & 0 deletions .github/oxid-esales/shop_ce.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# {{ $name := "oxideshop-ce" }}name: {{ $name }}

install: &install
git:
ref: &ref 'b-7.3.x-fix-duplicate-email-error-OXDEV-8351'
shop_ref: *ref
add_services: 'selenium-chrome-126'
method: script
script: 'source/.github/oxid-esales/install.sh'
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"incenteev/composer-parameter-handler": "^v2.1.4",
"mikey179/vfsstream": "~1.6.8",
"oxid-esales/codeception-modules": "dev-b-8.0.x",
"oxid-esales/codeception-page-objects": "dev-b-8.0.x",
"oxid-esales/codeception-page-objects": "dev-b-8.0.x-fix-duplicate-email-error-OXDEV-8351",
"oxid-esales/developer-tools": "dev-b-8.0.x",
"oxid-esales/oxideshop-ide-helper": "dev-b-8.0.x",
"phpspec/prophecy-phpunit": "^v2.0.1",
Expand Down
65 changes: 33 additions & 32 deletions source/Application/Component/UserComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -654,59 +654,60 @@ protected function changeUserWithoutRedirect()
if (!$user) {
return;
}

$currentEmail = $user->getFieldData('oxusername');
$password = $user->getFieldData('oxpassword');
$shippingAddress = $this->getShippingAddress();
$billingAddress = $this->getBillingAddress();
$newEmail = $billingAddress['oxuser__oxusername'] ?? '';

$username = $user->getFieldData('oxusername');
$password = $user->getFieldData('oxpassword');
try {
$newName = $billingAddress['oxuser__oxusername'] ?? '';
$isUsernameUpdated = $this->isUserNameUpdated($currentEmail ?? '', $newEmail);
if ($isUsernameUpdated && $this->isGuestUser($user)) {
$this->deleteExistingGuestUser($newEmail);
}
if (
$this->isGuestUser($user)
&& $this->isUserNameUpdated($user->oxuser__oxusername->value ?? '', $newName)
!$this->isGuestUser($user)
&& $isUsernameUpdated
&& $user->checkIfEmailExists($newEmail, true)
) {
$this->deleteExistingGuestUser($newName);
Registry::getUtilsView()->addErrorToDisplay('ERROR_MESSAGE_USER_USEREXISTS');
return false;
}
$user->changeUserData($username, $password, $password, $billingAddress, $shippingAddress);
$user->changeUserData($currentEmail, $password, $password, $billingAddress, $shippingAddress);

$isSubscriptionRequested = Registry::getRequest()->getRequestEscapedParameter('blnewssubscribed');
$userSubscriptionStatus = $isSubscriptionRequested
?? $user->getNewsSubscription()->getOptInStatus();
// check if email address changed, if so, force check newsletter subscription settings.
$billingUsername = $billingAddress['oxuser__oxusername'] ?? null;
$forceSubscriptionCheck = ($billingUsername !== null && $billingUsername !== $username);
$userSubscriptionStatus = $isSubscriptionRequested ?? $user->getNewsSubscription()->getOptInStatus();
$isSubscriptionEmailRequested = Registry::getConfig()->getConfigParam('blOrderOptInEmail');

$this->_blNewsSubscriptionStatus = $user->setNewsSubscription(
$userSubscriptionStatus,
$isSubscriptionEmailRequested,
$forceSubscriptionCheck
$isUsernameUpdated
);

$this->resetPermissions();

$orderRemark = Registry::getRequest()->getRequestParameter('order_remark', true);
if ($orderRemark) {
$session->setVariable('ordrem', $orderRemark);
} else {
$session->deleteVariable('ordrem');
}

if ($basket = $session->getBasket()) {
$basket->setBasketUser(null);
$basket->onUpdate();
}

return true;
} catch (UserException | ConnectionException | InputException $exception) {
Registry::getUtilsView()->addErrorToDisplay($exception, false, true);

return;
} catch (\Throwable) {
Registry::getUtilsView()->addErrorToDisplay('ERROR_MESSAGE_USER_UPDATE_FAILED', false, true);
return false;
}

$this->resetPermissions();

// order remark
$orderRemark = Registry::getRequest()->getRequestParameter('order_remark', true);

if ($orderRemark) {
$session->setVariable('ordrem', $orderRemark);
} else {
$session->deleteVariable('ordrem');
}

if ($basket = $session->getBasket()) {
$basket->setBasketUser(null);
$basket->onUpdate();
}

return true;
}

/**
Expand Down
25 changes: 11 additions & 14 deletions source/Application/Controller/Admin/UserMain.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace OxidEsales\EshopCommunity\Application\Controller\Admin;

use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Registry;
use stdClass;
use Exception;
Expand All @@ -26,7 +27,7 @@ public function render()
parent::render();

// malladmin stuff
$oAuthUser = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
$oAuthUser = oxNew(User::class);
$oAuthUser->loadAdminUser();
$blisMallAdmin = $oAuthUser->oxuser__oxrights->value == "malladmin";

Expand All @@ -52,7 +53,7 @@ public function render()
$soxId = $this->_aViewData["oxid"] = $this->getEditObjectId();
if (isset($soxId) && $soxId != "-1") {
// load object
$oUser = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
$oUser = oxNew(User::class);
$oUser->load($soxId);
$this->_aViewData["edit"] = $oUser;

Expand Down Expand Up @@ -102,50 +103,46 @@ public function save()
{
parent::save();

//allow admin information edit only for MALL admins
$soxId = $this->getEditObjectId();
if ($this->allowAdminEdit($soxId)) {
$aParams = Registry::getRequest()->getRequestEscapedParameter("editval");

// checkbox handling
if (!isset($aParams['oxuser__oxactive'])) {
$aParams['oxuser__oxactive'] = 0;
}

$oUser = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
$oUser = oxNew(User::class);
if ($soxId != "-1") {
$oUser->load($soxId);
} else {
$aParams['oxuser__oxid'] = null;
}

//setting new password
if (($sNewPass = Registry::getRequest()->getRequestEscapedParameter("newPassword"))) {
$oUser->setPassword($sNewPass);
}

//FS#2167 V checks for already used email

if (isset($aParams['oxuser__oxusername']) && $oUser->checkIfEmailExists($aParams['oxuser__oxusername'])) {
if (
isset($aParams['oxuser__oxusername']) &&
($aParams['oxuser__oxusername'] !== $oUser->getRawFieldData('oxusername')) &&
$oUser->checkIfEmailExists($aParams['oxuser__oxusername'], true)
) {
$this->_sSaveError = 'EXCEPTION_USER_USEREXISTS';

return;
}

$oUser->assign($aParams);

//seting shop id for ONLY for new created user
if ($soxId == "-1") {
$this->onUserCreation($oUser);
}

// A. changing field type to save birth date correctly
$oUser->oxuser__oxbirthdate->fldtype = 'char';

try {
$oUser->save();

// set oxid if inserted
$this->setEditObjectId($oUser->getId());
} catch (Exception $oExcp) {
$this->_sSaveError = $oExcp->getMessage();
Expand All @@ -168,9 +165,9 @@ protected function calculateAdditionalRights($userRights)
/**
* Additional actions on user creation.
*
* @param \OxidEsales\Eshop\Application\Model\User $user
* @param User $user
*
* @return \OxidEsales\Eshop\Application\Model\User
* @return User
*/
protected function onUserCreation($user)
{
Expand Down
4 changes: 2 additions & 2 deletions source/Application/Model/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ protected function update()
*
* @return bool
*/
public function checkIfEmailExists($sEmail)
public function checkIfEmailExists($sEmail, $changeMail = false)
{
$myConfig = \OxidEsales\Eshop\Core\Registry::getConfig();
// We force reading from master to prevent issues with slow replications or open transactions (see ESDEV-3804).
Expand Down Expand Up @@ -1750,7 +1750,7 @@ public function checkIfEmailExists($sEmail)
// exists admin with same login - must not allow
$blExists = true;
break;
} elseif ($oRs->fields[0] == $iShopId && $oRs->fields[2]) {
} elseif ($oRs->fields[0] == $iShopId && $oRs->fields[2] || $changeMail) {
// exists same login (with password) in same shop
$blExists = true;
break;
Expand Down
2 changes: 1 addition & 1 deletion source/Application/translations/de/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
'ERROR_MESSAGE_USER_NOVALUES' => 'E-Mail und Passwort müssen ausgefüllt sein!',
'ERROR_MESSAGE_USER_USERCREATIONFAILED' => 'Fehler beim Anlegen des Benutzers!',
'ERROR_MESSAGE_USER_UPDATE_FAILED' => 'Fehler beim Aktualisieren der Benutzerdaten!',
'ERROR_MESSAGE_USER_USEREXISTS' => '%s konnte nicht registriert werden. Haben Sie bereits ein Kundenkonto bei uns?',
'ERROR_MESSAGE_USER_USEREXISTS' => 'Bei dieser E-Mail-Adresse ist ein Fehler aufgetreten. Bitte wenden Sie sich an unseren Support.',
'ERROR_MESSAGE_VERSION_EXPIRED1' => 'Ihre Version ist leider abgelaufen. Bitte kontaktieren Sie',
'ERROR_MESSAGE_VOUCHER_INCORRECTPRICE' => 'Einkaufswert ist zu niedrig für diesen Gutschein!',
'ERROR_MESSAGE_VOUCHER_ISRESERVED' => 'Gutschein ist reserviert!',
Expand Down
2 changes: 1 addition & 1 deletion source/Application/translations/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
'ERROR_MESSAGE_USER_NOVALUES' => 'E-mail address and password have to be entered!',
'ERROR_MESSAGE_USER_USERCREATIONFAILED' => 'Error creating the user!',
'ERROR_MESSAGE_USER_UPDATE_FAILED' => 'Error while updating the user data!',
'ERROR_MESSAGE_USER_USEREXISTS' => 'Not possible to register %s. Maybe you have already registered?',
'ERROR_MESSAGE_USER_USEREXISTS' => 'An error has occurred with this e-mail address. Please contact our support.',
'ERROR_MESSAGE_VERSION_EXPIRED1' => 'Your version is expired. Please contact',
'ERROR_MESSAGE_VOUCHER_INCORRECTPRICE' => 'The total price is too low for this coupon!',
'ERROR_MESSAGE_VOUCHER_ISRESERVED' => 'This coupon is reserved!',
Expand Down
35 changes: 20 additions & 15 deletions source/Core/InputValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
use OxidEsales\Eshop\Application\Model\Address;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Exception\ArticleInputException;
use OxidEsales\Eshop\Core\Exception\InputException;
use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Exception\UserException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Str;
use OxidEsales\EshopCommunity\Core\Di\ContainerFacade;
Expand Down Expand Up @@ -107,34 +109,37 @@ public function validateBasketAmount($amount)
*/
public function checkLogin($user, $login, $invAddress)
{
$login = (isset($invAddress['oxuser__oxusername'])) ? $invAddress['oxuser__oxusername'] : $login;
$login = (isset($invAddress['oxuser__oxusername']))
? $invAddress['oxuser__oxusername']
: $login;

if (
isset($user->oxuser__oxpassword->value) &&
$user->oxuser__oxpassword->value &&
$login != $user->oxuser__oxusername->value
) {
$newPassword = (isset($invAddress['oxuser__oxpassword']) && $invAddress['oxuser__oxpassword'])
? $invAddress['oxuser__oxpassword']
: Registry::getRequest()->getRequestEscapedParameter('user_password');

// check only for users with password during registration
// if user wants to change user name - we must check if passwords are ok before changing
if (isset($user->oxuser__oxpassword->value) && $user->oxuser__oxpassword->value && $login != $user->oxuser__oxusername->value) {
// on this case password must be taken directly from request
$newPassword = (isset($invAddress['oxuser__oxpassword']) && $invAddress['oxuser__oxpassword']) ? $invAddress['oxuser__oxpassword'] : Registry::getRequest()->getRequestEscapedParameter('user_password');
if (!$newPassword) {
// 1. user forgot to enter password
$exception = oxNew(\OxidEsales\Eshop\Core\Exception\InputException::class);
$exception->setMessage(\OxidEsales\Eshop\Core\Registry::getLang()->translateString('ERROR_MESSAGE_INPUT_NOTALLFIELDS'));
$message = Registry::getLang()->translateString('ERROR_MESSAGE_INPUT_NOTALLFIELDS');
$exception = oxNew(InputException::class, $message);

return $this->addValidationError("oxuser__oxpassword", $exception);
} else {
// 2. entered wrong password
if (!$user->isSamePassword($newPassword)) {
$exception = oxNew(\OxidEsales\Eshop\Core\Exception\UserException::class);
$exception->setMessage(\OxidEsales\Eshop\Core\Registry::getLang()->translateString('ERROR_MESSAGE_PASSWORD_DO_NOT_MATCH'));
$message = Registry::getLang()->translateString('ERROR_MESSAGE_PASSWORD_DO_NOT_MATCH');
$exception = oxNew(UserException::class, $message);

return $this->addValidationError("oxuser__oxpassword", $exception);
}
}
}

if ($user->checkIfEmailExists($login)) {
//if exists then we do not allow to do that
$exception = oxNew(\OxidEsales\Eshop\Core\Exception\UserException::class);
$exception->setMessage(sprintf(\OxidEsales\Eshop\Core\Registry::getLang()->translateString('ERROR_MESSAGE_USER_USEREXISTS'), $login));
$message = Registry::getLang()->translateString('ERROR_MESSAGE_USER_USEREXISTS');
$exception = oxNew(UserException::class, $message);

return $this->addValidationError("oxuser__oxusername", $exception);
}
Expand Down
3 changes: 2 additions & 1 deletion source/Internal/Setup/Database/Sql/initial_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ INSERT INTO `oxconfig` (`OXID`, `OXSHOPID`, `OXMODULE`, `OXVARNAME`, `OXVARTYPE`
('mla50c74dd79703312ffb8cfd82c3741', 1, '', 'aLanguageURLs', 'arr', 'a:2:{i:0;s:0:\"\";i:1;N;}'),
('mlabefd7ebdb5946e8f3f7e7a953b323', 1, '', 'aLanguageSSLURLs', 'arr', 'a:2:{i:0;s:0:\"\";i:1;N;}'),
('mlae44cdad808d9b994c58540db39e7a', 1, '', 'aLanguages', 'aarr', 'a:2:{s:2:\"de\";s:7:\"Deutsch\";s:2:\"en\";s:7:\"English\";}'),
('omc4555952125c3c2.98253113', 1, '', 'blDisableNavBars', 'bool', '1');
('omc4555952125c3c2.98253113', 1, '', 'blDisableNavBars', 'bool', '1'),
('feb42aecdf7bacc7c76c9d36102da622', 1, '', 'blSkipDebitOldBankInfo', 'bool', '1');

INSERT INTO `oxcontents` (`OXID`, `OXLOADID`, `OXSHOPID`, `OXSNIPPET`, `OXTYPE`, `OXACTIVE`, `OXACTIVE_1`, `OXPOSITION`, `OXTITLE`, `OXCONTENT`, `OXTITLE_1`, `OXCONTENT_1`, `OXACTIVE_2`, `OXTITLE_2`, `OXCONTENT_2`, `OXACTIVE_3`, `OXTITLE_3`, `OXCONTENT_3`, `OXCATID`, `OXFOLDER`, `OXTERMVERSION`) VALUES
('8709e45f31a86909e9f999222e80b1d0', 'oxstdfooter', 1, 1, 0, 1, 1, '', 'Standard Footer', '<div>OXID Online Shop - Alles rund um das Thema Wassersport, Sportbekleidung und Mode </div>', 'standard footer', '<div>OXID Online Shop - All about watersports, sportswear and fashion </div>', 1, '', '', 1, '', '', '30e44ab83fdee7564.23264141', '', ''),
Expand Down
34 changes: 34 additions & 0 deletions tests/Codeception/Acceptance/Admin/UserCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use OxidEsales\Codeception\Admin\DataObject\AdminUser;
use OxidEsales\Codeception\Admin\DataObject\AdminUserAddresses;
use OxidEsales\Codeception\Admin\DataObject\AdminUserExtendedInfo;
use OxidEsales\Codeception\Module\Translation\Translator;
use OxidEsales\EshopCommunity\Tests\Codeception\Support\AcceptanceTester;

#[Group('admin')]
Expand Down Expand Up @@ -197,6 +198,39 @@ public function updatePassword(AcceptanceTester $I): void
->login($userData['userLoginName'], $newPass);
}

public function testChangeUserEmail(AcceptanceTester $I): void
{
$I->wantToTest('changing user email addresses with validation in admin');

$userData = Fixtures::get('existingUser');
$guestUserData = Fixtures::get('existingGuestUser');
$adminUserData = Fixtures::get('adminUser');
$newEmail = '[email protected]';

$I->amGoingTo('login as admin and find the test user');
$adminUsersPage = $I->loginAdmin()
->openUsers()
->findByUserName($userData['userLoginName']);

$I->amGoingTo('try to change email to an existing guest user email');
$adminUsersPage->updateUsername($guestUserData['userLoginName']);
$I->expect('to see an error message about existing user');
$I->see(Translator::translate('EXCEPTION_USER_USEREXISTS'));

$I->amGoingTo('try to change email to an existing admin email');
$adminUsersPage->updateUsername($adminUserData['userLoginName']);
$I->expect('to see an error message about existing user');
$I->see(Translator::translate('EXCEPTION_USER_USEREXISTS'));

$I->amGoingTo('change user email to a new valid email address');
$adminUsersPage->updateUsername($newEmail);
$I->expect('not to see any error message');
$I->dontSee(Translator::translate('EXCEPTION_USER_USEREXISTS'));

$I->amGoingTo('change the email back to the original one');
$adminUsersPage->updateUsername($userData['userLoginName']);
}

private function createAdminTestUser(
AcceptanceTester $I,
AdminUser $user,
Expand Down
Loading

0 comments on commit ade8de1

Please sign in to comment.