diff --git a/lib/Command/CreateAccount.php b/lib/Command/CreateAccount.php index aa515ca448..e2080c84ac 100644 --- a/lib/Command/CreateAccount.php +++ b/lib/Command/CreateAccount.php @@ -97,6 +97,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 1; } + if (empty($this->accountService->findByUserIdAndAddress($userId, $email)) === false) { + $output->writeln("User $userId already has an account for $email"); + return 1; + } + $account = new MailAccount(); $account->setUserId($userId); $account->setName($name); diff --git a/lib/Controller/AccountsController.php b/lib/Controller/AccountsController.php index 81cb19067f..393da826bf 100644 --- a/lib/Controller/AccountsController.php +++ b/lib/Controller/AccountsController.php @@ -338,6 +338,12 @@ public function create(string $accountName, $this->logger->info('Creating account disabled by admin.'); return MailJsonResponse::error('Could not create account'); } + if (empty($this->accountService->findByUserIdAndAddress($this->userId, $emailAddress)) === false) { + $this->logger->info('Trying to create already existing account.'); + return MailJsonResponse::fail([ + 'error' => 'ACCOUNT_EXISTS', + ]); + } if (!$this->hostValidator->isValid($imapHost)) { $this->logger->debug('Prevented access to invalid IMAP host', [ 'host' => $imapHost, diff --git a/src/components/AccountForm.vue b/src/components/AccountForm.vue index 217a214c1f..ec5b9c566d 100644 --- a/src/components/AccountForm.vue +++ b/src/components/AccountForm.vue @@ -692,6 +692,8 @@ export default { } else if (error.data.service === 'SMTP') { this.feedback = t('mail', 'SMTP server is not reachable') } + } else if (error.data?.error === 'ACCOUNT_EXISTS') { + this.feedback = t('mail', 'Account already exists') } else if (error.data?.error === 'AUTHENTICATION_WRONG_PASSWORD') { if (error.data.service === 'IMAP') { this.feedback = t('mail', 'IMAP username or password is wrong') diff --git a/tests/Unit/Controller/AccountsControllerTest.php b/tests/Unit/Controller/AccountsControllerTest.php index d11ebe2603..e2b0bc938b 100644 --- a/tests/Unit/Controller/AccountsControllerTest.php +++ b/tests/Unit/Controller/AccountsControllerTest.php @@ -299,6 +299,30 @@ public function testCreateManualNotAllowed(): void { self::assertEquals($expectedResponse, $response); } + public function testCreateManualNoDuplicate(): void { + $email = 'user@domain.tld'; + $accountName = 'Mail'; + $imapHost = 'localhost'; + $imapPort = 993; + $imapSslMode = 'ssl'; + $imapUser = 'user@domain.tld'; + $imapPassword = 'mypassword'; + $smtpHost = 'localhost'; + $smtpPort = 465; + $smtpSslMode = 'none'; + $smtpUser = 'user@domain.tld'; + $smtpPassword = 'mypassword'; + $this->accountService->expects(self::once()) + ->method('findByUserIdAndAddress') + ->willReturn(['existing account']); + $this->setupService->expects(self::never()) + ->method('createNewAccount'); + + $expectedResponse = \OCA\Mail\Http\JsonResponse::fail(['error' => 'ACCOUNT_EXISTS']); + $response = $this->controller->create($accountName, $email, $imapHost, $imapPort, $imapSslMode, $imapUser, $smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $imapPassword, $smtpPassword); + + self::assertEquals($expectedResponse, $response); + } public function testCreateManualFailure(): void { $email = 'user@domain.tld';