2014-07-16 23:29:37 +04:00
|
|
|
<?php
|
2016-07-07 18:26:47 +03:00
|
|
|
|
2018-07-24 13:20:23 +03:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2014-07-16 23:29:37 +04:00
|
|
|
/**
|
2024-06-21 16:58:11 +03:00
|
|
|
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
|
|
|
* SPDX-FileCopyrightText: 2014-2016 ownCloud, Inc.
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
2014-07-16 23:29:37 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
namespace OCA\Mail\Controller;
|
|
|
|
|
2019-09-26 18:07:47 +03:00
|
|
|
use Exception;
|
2020-11-06 16:48:12 +03:00
|
|
|
use OC\Security\CSP\ContentSecurityPolicyNonceManager;
|
2023-04-19 15:59:20 +03:00
|
|
|
use OCA\Mail\Attachment;
|
2023-05-17 01:06:02 +03:00
|
|
|
use OCA\Mail\Contracts\IDkimService;
|
2018-02-02 18:00:30 +03:00
|
|
|
use OCA\Mail\Contracts\IMailManager;
|
2019-10-07 15:07:51 +03:00
|
|
|
use OCA\Mail\Contracts\IMailSearch;
|
2021-01-08 13:29:33 +03:00
|
|
|
use OCA\Mail\Contracts\IMailTransmission;
|
2020-11-19 12:47:50 +03:00
|
|
|
use OCA\Mail\Contracts\ITrustedSenderService;
|
2023-03-15 13:56:14 +03:00
|
|
|
use OCA\Mail\Contracts\IUserPreferences;
|
2020-11-19 12:47:50 +03:00
|
|
|
use OCA\Mail\Db\Message;
|
2020-02-03 16:51:51 +03:00
|
|
|
use OCA\Mail\Exception\ClientException;
|
2019-09-26 18:07:47 +03:00
|
|
|
use OCA\Mail\Exception\ServiceException;
|
2014-07-28 03:53:09 +04:00
|
|
|
use OCA\Mail\Http\AttachmentDownloadResponse;
|
|
|
|
use OCA\Mail\Http\HtmlResponse;
|
2023-04-19 15:59:20 +03:00
|
|
|
use OCA\Mail\Http\TrapError;
|
2022-12-06 18:21:32 +03:00
|
|
|
use OCA\Mail\IMAP\IMAPClientFactory;
|
2023-01-26 16:15:12 +03:00
|
|
|
use OCA\Mail\Model\SmimeData;
|
2015-06-10 00:49:59 +03:00
|
|
|
use OCA\Mail\Service\AccountService;
|
2023-09-13 20:09:13 +03:00
|
|
|
use OCA\Mail\Service\AiIntegrations\AiIntegrationsService;
|
2019-10-10 14:36:35 +03:00
|
|
|
use OCA\Mail\Service\ItineraryService;
|
2023-01-26 16:15:12 +03:00
|
|
|
use OCA\Mail\Service\SmimeService;
|
2023-08-07 22:31:46 +03:00
|
|
|
use OCA\Mail\Service\SnoozeService;
|
2014-07-16 23:29:37 +04:00
|
|
|
use OCP\AppFramework\Controller;
|
2019-10-16 13:13:36 +03:00
|
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
2019-09-26 18:07:47 +03:00
|
|
|
use OCP\AppFramework\Http;
|
2024-07-30 13:09:10 +03:00
|
|
|
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
2015-05-20 13:09:57 +03:00
|
|
|
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
2014-07-16 23:29:37 +04:00
|
|
|
use OCP\AppFramework\Http\JSONResponse;
|
2018-07-24 13:20:23 +03:00
|
|
|
use OCP\AppFramework\Http\Response;
|
2014-08-29 03:06:42 +04:00
|
|
|
use OCP\AppFramework\Http\TemplateResponse;
|
2021-02-17 15:44:52 +03:00
|
|
|
use OCP\AppFramework\Http\ZipResponse;
|
2016-07-22 18:24:24 +03:00
|
|
|
use OCP\Files\Folder;
|
2023-02-27 17:04:43 +03:00
|
|
|
use OCP\Files\GenericFileException;
|
2016-07-22 18:24:24 +03:00
|
|
|
use OCP\Files\IMimeTypeDetector;
|
2023-02-27 17:04:43 +03:00
|
|
|
use OCP\Files\NotPermittedException;
|
2015-04-15 22:43:25 +03:00
|
|
|
use OCP\IL10N;
|
2016-02-05 15:35:08 +03:00
|
|
|
use OCP\IRequest;
|
2016-08-25 15:20:42 +03:00
|
|
|
use OCP\IURLGenerator;
|
2023-02-27 17:04:43 +03:00
|
|
|
use OCP\Lock\LockedException;
|
2020-10-03 17:03:53 +03:00
|
|
|
use Psr\Log\LoggerInterface;
|
2020-02-20 18:12:11 +03:00
|
|
|
use function array_map;
|
2014-07-16 23:29:37 +04:00
|
|
|
|
2024-07-30 13:09:10 +03:00
|
|
|
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
2015-05-07 20:19:49 +03:00
|
|
|
class MessagesController extends Controller {
|
2022-10-01 23:01:07 +03:00
|
|
|
private AccountService $accountService;
|
|
|
|
private IMailManager $mailManager;
|
|
|
|
private IMailSearch $mailSearch;
|
|
|
|
private ItineraryService $itineraryService;
|
|
|
|
private ?string $currentUserId;
|
|
|
|
private LoggerInterface $logger;
|
2022-11-02 21:14:59 +03:00
|
|
|
private ?Folder $userFolder;
|
2022-10-01 23:01:07 +03:00
|
|
|
private IMimeTypeDetector $mimeTypeDetector;
|
|
|
|
private IL10N $l10n;
|
|
|
|
private IURLGenerator $urlGenerator;
|
|
|
|
private ContentSecurityPolicyNonceManager $nonceManager;
|
|
|
|
private ITrustedSenderService $trustedSenderService;
|
|
|
|
private IMailTransmission $mailTransmission;
|
2023-01-26 16:15:12 +03:00
|
|
|
private SmimeService $smimeService;
|
2022-12-06 18:21:32 +03:00
|
|
|
private IMAPClientFactory $clientFactory;
|
2023-05-17 01:06:02 +03:00
|
|
|
private IDkimService $dkimService;
|
2023-03-15 13:56:14 +03:00
|
|
|
private IUserPreferences $preferences;
|
2023-08-07 22:31:46 +03:00
|
|
|
private SnoozeService $snoozeService;
|
2023-09-13 20:09:13 +03:00
|
|
|
private AiIntegrationsService $aiIntegrationService;
|
2014-07-16 23:29:37 +04:00
|
|
|
|
2019-09-26 18:07:47 +03:00
|
|
|
public function __construct(string $appName,
|
2023-06-28 15:44:08 +03:00
|
|
|
IRequest $request,
|
|
|
|
AccountService $accountService,
|
|
|
|
IMailManager $mailManager,
|
|
|
|
IMailSearch $mailSearch,
|
|
|
|
ItineraryService $itineraryService,
|
|
|
|
?string $UserId,
|
|
|
|
$userFolder,
|
|
|
|
LoggerInterface $logger,
|
|
|
|
IL10N $l10n,
|
|
|
|
IMimeTypeDetector $mimeTypeDetector,
|
|
|
|
IURLGenerator $urlGenerator,
|
|
|
|
ContentSecurityPolicyNonceManager $nonceManager,
|
|
|
|
ITrustedSenderService $trustedSenderService,
|
|
|
|
IMailTransmission $mailTransmission,
|
|
|
|
SmimeService $smimeService,
|
|
|
|
IMAPClientFactory $clientFactory,
|
2023-08-07 22:31:46 +03:00
|
|
|
IDkimService $dkimService,
|
2023-03-15 13:56:14 +03:00
|
|
|
IUserPreferences $preferences,
|
2023-09-13 20:09:13 +03:00
|
|
|
SnoozeService $snoozeService,
|
|
|
|
AiIntegrationsService $aiIntegrationService) {
|
2014-07-16 23:29:37 +04:00
|
|
|
parent::__construct($appName, $request);
|
2015-06-10 00:49:59 +03:00
|
|
|
$this->accountService = $accountService;
|
2019-10-07 15:07:51 +03:00
|
|
|
$this->mailManager = $mailManager;
|
|
|
|
$this->mailSearch = $mailSearch;
|
2019-10-10 14:36:35 +03:00
|
|
|
$this->itineraryService = $itineraryService;
|
2016-02-05 15:35:08 +03:00
|
|
|
$this->currentUserId = $UserId;
|
2014-07-28 02:42:13 +04:00
|
|
|
$this->userFolder = $userFolder;
|
2015-03-26 21:00:16 +03:00
|
|
|
$this->logger = $logger;
|
2015-04-15 22:43:25 +03:00
|
|
|
$this->l10n = $l10n;
|
2016-07-22 18:24:24 +03:00
|
|
|
$this->mimeTypeDetector = $mimeTypeDetector;
|
2016-08-25 15:20:42 +03:00
|
|
|
$this->urlGenerator = $urlGenerator;
|
2020-11-06 16:48:12 +03:00
|
|
|
$this->nonceManager = $nonceManager;
|
2020-11-19 12:47:50 +03:00
|
|
|
$this->trustedSenderService = $trustedSenderService;
|
2021-01-08 13:29:33 +03:00
|
|
|
$this->mailTransmission = $mailTransmission;
|
2023-01-26 16:15:12 +03:00
|
|
|
$this->smimeService = $smimeService;
|
2022-12-06 18:21:32 +03:00
|
|
|
$this->clientFactory = $clientFactory;
|
2023-05-17 01:06:02 +03:00
|
|
|
$this->dkimService = $dkimService;
|
2023-03-15 13:56:14 +03:00
|
|
|
$this->preferences = $preferences;
|
2023-08-07 22:31:46 +03:00
|
|
|
$this->snoozeService = $snoozeService;
|
2023-09-13 20:09:13 +03:00
|
|
|
$this->aiIntegrationService = $aiIntegrationService;
|
2014-07-16 23:29:37 +04:00
|
|
|
}
|
|
|
|
|
2017-03-02 22:21:27 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $mailboxId
|
2017-03-02 22:21:27 +03:00
|
|
|
* @param int $cursor
|
|
|
|
* @param string $filter
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int|null $limit
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2017-03-02 22:21:27 +03:00
|
|
|
* @return JSONResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
2020-02-03 16:51:51 +03:00
|
|
|
* @throws ClientException
|
2019-10-07 15:07:51 +03:00
|
|
|
* @throws ServiceException
|
2017-03-02 22:21:27 +03:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function index(int $mailboxId,
|
2024-02-28 16:17:50 +03:00
|
|
|
?int $cursor = null,
|
|
|
|
?string $filter = null,
|
|
|
|
?int $limit = null): JSONResponse {
|
2019-10-16 13:13:36 +03:00
|
|
|
try {
|
2020-08-11 22:10:49 +03:00
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $mailboxId);
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
2019-10-16 13:13:36 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2017-03-02 23:28:49 +03:00
|
|
|
}
|
2017-03-02 22:21:27 +03:00
|
|
|
|
2023-03-15 13:56:14 +03:00
|
|
|
$this->logger->debug("loading messages of mailbox <$mailboxId>");
|
2017-03-02 22:21:27 +03:00
|
|
|
|
2023-03-15 13:56:14 +03:00
|
|
|
$order = $this->preferences->getPreference($this->currentUserId, 'sort-order', 'newest') === 'newest' ? 'DESC': 'ASC';
|
2019-10-07 15:07:51 +03:00
|
|
|
return new JSONResponse(
|
|
|
|
$this->mailSearch->findMessages(
|
|
|
|
$account,
|
2020-08-11 22:10:49 +03:00
|
|
|
$mailbox,
|
2023-03-15 13:56:14 +03:00
|
|
|
$order,
|
2019-10-07 15:07:51 +03:00
|
|
|
$filter === '' ? null : $filter,
|
2020-02-13 17:18:10 +03:00
|
|
|
$cursor,
|
|
|
|
$limit
|
2019-10-07 15:07:51 +03:00
|
|
|
)
|
|
|
|
);
|
2017-03-02 22:21:27 +03:00
|
|
|
}
|
|
|
|
|
2015-11-26 16:27:26 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
2018-07-24 13:20:23 +03:00
|
|
|
* @param int $id
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2020-03-23 16:58:41 +03:00
|
|
|
* @throws ClientException
|
2019-09-26 18:07:47 +03:00
|
|
|
* @throws ServiceException
|
2015-11-26 16:27:26 +03:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function show(int $id): JSONResponse {
|
2019-10-16 13:13:36 +03:00
|
|
|
try {
|
2020-08-11 22:10:49 +03:00
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
2019-10-16 13:13:36 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2019-09-26 18:07:47 +03:00
|
|
|
}
|
|
|
|
|
2020-08-11 22:10:49 +03:00
|
|
|
$this->logger->debug("loading message <$id>");
|
2020-02-20 18:12:11 +03:00
|
|
|
|
|
|
|
return new JSONResponse(
|
|
|
|
$this->mailSearch->findMessage(
|
|
|
|
$account,
|
2020-08-11 22:10:49 +03:00
|
|
|
$mailbox,
|
|
|
|
$message
|
2020-02-20 18:12:11 +03:00
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2020-02-20 18:12:11 +03:00
|
|
|
*
|
|
|
|
* @return JSONResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
2020-02-20 18:12:11 +03:00
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function getBody(int $id): JSONResponse {
|
2020-02-20 18:12:11 +03:00
|
|
|
try {
|
2020-08-11 22:10:49 +03:00
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
2020-02-20 18:12:11 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-02-20 18:12:11 +03:00
|
|
|
}
|
|
|
|
|
2022-12-06 18:21:32 +03:00
|
|
|
$client = $this->clientFactory->getClient($account);
|
|
|
|
try {
|
2023-02-14 19:28:45 +03:00
|
|
|
$imapMessage = $this->mailManager->getImapMessage(
|
2022-12-06 18:21:32 +03:00
|
|
|
$client,
|
|
|
|
$account,
|
|
|
|
$mailbox,
|
|
|
|
$message->getUid(), true
|
2023-02-14 19:28:45 +03:00
|
|
|
);
|
|
|
|
$json = $imapMessage->getFullMessage($id);
|
2022-12-06 18:21:32 +03:00
|
|
|
} finally {
|
|
|
|
$client->logout();
|
|
|
|
}
|
|
|
|
|
2021-12-17 19:11:27 +03:00
|
|
|
$itineraries = $this->itineraryService->getCached($account, $mailbox, $message->getUid());
|
|
|
|
if ($itineraries) {
|
|
|
|
$json['itineraries'] = $itineraries;
|
|
|
|
}
|
2020-08-11 22:10:49 +03:00
|
|
|
$json['attachments'] = array_map(function ($a) use ($id) {
|
|
|
|
return $this->enrichDownloadUrl(
|
|
|
|
$id,
|
|
|
|
$a
|
|
|
|
);
|
2019-09-27 12:49:24 +03:00
|
|
|
}, $json['attachments']);
|
2020-09-02 15:08:15 +03:00
|
|
|
$json['accountId'] = $account->getId();
|
|
|
|
$json['mailboxId'] = $mailbox->getId();
|
2020-08-11 22:10:49 +03:00
|
|
|
$json['databaseId'] = $message->getId();
|
2020-11-19 12:47:50 +03:00
|
|
|
$json['isSenderTrusted'] = $this->isSenderTrusted($message);
|
2019-09-26 18:07:47 +03:00
|
|
|
|
2023-01-26 16:15:12 +03:00
|
|
|
$smimeData = new SmimeData();
|
2023-02-14 19:28:45 +03:00
|
|
|
$smimeData->setIsEncrypted($message->isEncrypted() || $imapMessage->isEncrypted());
|
|
|
|
if ($imapMessage->isSigned()) {
|
|
|
|
$smimeData->setIsSigned(true);
|
|
|
|
$smimeData->setSignatureIsValid($imapMessage->isSignatureValid());
|
|
|
|
}
|
2023-01-26 16:15:12 +03:00
|
|
|
$json['smime'] = $smimeData;
|
2022-12-06 18:21:32 +03:00
|
|
|
|
2023-05-17 01:06:02 +03:00
|
|
|
$dkimResult = $this->dkimService->getCached($account, $mailbox, $message->getUid());
|
|
|
|
if (is_bool($dkimResult)) {
|
|
|
|
$json['dkimValid'] = $dkimResult;
|
|
|
|
}
|
|
|
|
|
2020-12-01 16:22:13 +03:00
|
|
|
$response = new JSONResponse($json);
|
|
|
|
|
|
|
|
// Enable caching
|
2022-09-21 14:58:14 +03:00
|
|
|
$response->cacheFor(60 * 60, false, true);
|
2020-12-01 16:22:13 +03:00
|
|
|
|
|
|
|
return $response;
|
2014-07-16 23:29:37 +04:00
|
|
|
}
|
|
|
|
|
2021-12-17 19:11:27 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2021-12-17 19:11:27 +03:00
|
|
|
public function getItineraries(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
2022-09-21 14:58:14 +03:00
|
|
|
$response = new JsonResponse($this->itineraryService->extract($account, $mailbox, $message->getUid()));
|
|
|
|
$response->cacheFor(24 * 60 * 60, false, true);
|
|
|
|
return $response;
|
2021-12-17 19:11:27 +03:00
|
|
|
}
|
|
|
|
|
2023-05-17 01:06:02 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @param int $id
|
|
|
|
* @return JSONResponse
|
|
|
|
*/
|
|
|
|
public function getDkim(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
2023-06-01 23:23:31 +03:00
|
|
|
$response = new JSONResponse(['valid' => $this->dkimService->validate($account, $mailbox, $message->getUid())]);
|
2023-05-17 01:06:02 +03:00
|
|
|
$response->cacheFor(24 * 60 * 60, false, true);
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2020-11-19 12:47:50 +03:00
|
|
|
private function isSenderTrusted(Message $message): bool {
|
|
|
|
$from = $message->getFrom();
|
|
|
|
$first = $from->first();
|
|
|
|
if ($first === null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$email = $first->getEmail();
|
|
|
|
if ($email === null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return $this->trustedSenderService->isTrusted(
|
|
|
|
$this->currentUserId,
|
|
|
|
$email
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-14 17:30:50 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @NoCSRFRequired
|
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2020-07-14 17:30:50 +03:00
|
|
|
*
|
|
|
|
* @return JSONResponse
|
|
|
|
* @throws ClientException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function getThread(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
2020-07-14 17:30:50 +03:00
|
|
|
|
2022-01-25 21:39:28 +03:00
|
|
|
if (empty($message->getThreadRootId())) {
|
|
|
|
return new JSONResponse([], Http::STATUS_NOT_FOUND);
|
|
|
|
}
|
|
|
|
|
2021-06-01 21:53:19 +03:00
|
|
|
return new JSONResponse($this->mailManager->getThread($account, $message->getThreadRootId()));
|
2020-07-14 17:30:50 +03:00
|
|
|
}
|
|
|
|
|
2016-09-20 14:42:06 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
2020-10-08 16:09:16 +03:00
|
|
|
* @param int $destFolderId
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2016-09-20 14:42:06 +03:00
|
|
|
* @return JSONResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
2016-09-20 14:42:06 +03:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function move(int $id, int $destFolderId): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$srcMailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$dstMailbox = $this->mailManager->getMailbox($this->currentUserId, $destFolderId);
|
|
|
|
$srcAccount = $this->accountService->find($this->currentUserId, $srcMailbox->getAccountId());
|
|
|
|
$dstAccount = $this->accountService->find($this->currentUserId, $dstMailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->mailManager->moveMessage(
|
|
|
|
$srcAccount,
|
|
|
|
$srcMailbox->getName(),
|
|
|
|
$message->getUid(),
|
|
|
|
$dstAccount,
|
|
|
|
$dstMailbox->getName()
|
|
|
|
);
|
2016-09-20 14:42:06 +03:00
|
|
|
return new JSONResponse();
|
|
|
|
}
|
|
|
|
|
2023-08-07 22:31:46 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
* @param int $unixTimestamp
|
2023-08-11 16:55:54 +03:00
|
|
|
* @param int $destMailboxId
|
2023-08-07 22:31:46 +03:00
|
|
|
*
|
|
|
|
* @return JSONResponse
|
2023-08-11 16:55:54 +03:00
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
2023-08-07 22:31:46 +03:00
|
|
|
*/
|
|
|
|
#[TrapError]
|
2023-08-11 16:55:54 +03:00
|
|
|
public function snooze(int $id, int $unixTimestamp, int $destMailboxId): JSONResponse {
|
2023-08-07 22:31:46 +03:00
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
2023-08-11 16:55:54 +03:00
|
|
|
$srcMailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$dstMailbox = $this->mailManager->getMailbox($this->currentUserId, $destMailboxId);
|
|
|
|
$srcAccount = $this->accountService->find($this->currentUserId, $srcMailbox->getAccountId());
|
|
|
|
$dstAccount = $this->accountService->find($this->currentUserId, $dstMailbox->getAccountId());
|
2023-08-07 22:31:46 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
2023-08-11 16:55:54 +03:00
|
|
|
$this->snoozeService->snoozeMessage($message, $unixTimestamp, $srcAccount, $srcMailbox, $dstAccount, $dstMailbox);
|
2023-08-07 22:31:46 +03:00
|
|
|
|
|
|
|
return new JSONResponse();
|
|
|
|
}
|
|
|
|
|
2021-01-08 13:29:33 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
2023-08-18 16:35:34 +03:00
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
|
|
|
#[TrapError]
|
|
|
|
public function unSnooze(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->snoozeService->unSnoozeMessage($message, $this->currentUserId);
|
|
|
|
|
|
|
|
return new JSONResponse();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
2021-01-08 13:29:33 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2021-01-08 13:29:33 +03:00
|
|
|
public function mdn(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($message->getFlagMdnsent()) {
|
|
|
|
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->mailTransmission->sendMdn($account, $mailbox, $message);
|
|
|
|
$this->mailManager->flagMessage($account, $mailbox->getName(), $message->getUid(), 'mdnsent', true);
|
|
|
|
} catch (ServiceException $ex) {
|
|
|
|
$this->logger->error('Sending mdn failed: ' . $ex->getMessage());
|
|
|
|
throw $ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new JSONResponse();
|
|
|
|
}
|
|
|
|
|
2019-11-19 18:25:47 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @NoCSRFRequired
|
|
|
|
*
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function getSource(int $id): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
2019-11-19 18:25:47 +03:00
|
|
|
|
2022-12-06 18:21:32 +03:00
|
|
|
$client = $this->clientFactory->getClient($account);
|
|
|
|
try {
|
|
|
|
$response = new JSONResponse([
|
|
|
|
'source' => $this->mailManager->getSource(
|
|
|
|
$client,
|
|
|
|
$account,
|
|
|
|
$mailbox->getName(),
|
|
|
|
$message->getUid()
|
|
|
|
)
|
|
|
|
]);
|
|
|
|
} finally {
|
|
|
|
$client->logout();
|
|
|
|
}
|
2019-11-19 18:25:47 +03:00
|
|
|
|
|
|
|
// Enable caching
|
2022-09-21 14:58:14 +03:00
|
|
|
$response->cacheFor(60 * 60, false, true);
|
2019-11-19 18:25:47 +03:00
|
|
|
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2022-08-02 16:35:15 +03:00
|
|
|
/**
|
|
|
|
* Export a whole message as an .eml file.
|
|
|
|
*
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @NoCSRFRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
* @return Response
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2022-08-02 16:35:15 +03:00
|
|
|
public function export(int $id): Response {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
2022-12-06 18:21:32 +03:00
|
|
|
$client = $this->clientFactory->getClient($account);
|
|
|
|
try {
|
|
|
|
$source = $this->mailManager->getSource(
|
|
|
|
$client,
|
|
|
|
$account,
|
|
|
|
$mailbox->getName(),
|
|
|
|
$message->getUid()
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
$client->logout();
|
|
|
|
}
|
|
|
|
|
2022-08-02 16:35:15 +03:00
|
|
|
return new AttachmentDownloadResponse(
|
|
|
|
$source,
|
|
|
|
$message->getSubject() . '.eml',
|
|
|
|
'message/rfc822',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-07-25 02:46:43 +04:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
2017-05-29 16:30:26 +03:00
|
|
|
* @NoCSRFRequired
|
2014-07-25 02:46:43 +04:00
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2020-10-28 15:44:28 +03:00
|
|
|
* @param bool $plain do not inject scripts if true (default=false)
|
2019-09-26 18:07:47 +03:00
|
|
|
*
|
2016-07-22 18:24:24 +03:00
|
|
|
* @return HtmlResponse|TemplateResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
2014-07-25 02:46:43 +04:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-12-19 05:15:57 +03:00
|
|
|
public function getHtmlBody(int $id, bool $plain = false): Response {
|
2014-08-29 03:06:42 +04:00
|
|
|
try {
|
2019-10-16 13:13:36 +03:00
|
|
|
try {
|
2020-08-11 22:10:49 +03:00
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
2019-10-16 13:13:36 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
2019-09-26 18:07:47 +03:00
|
|
|
return new TemplateResponse(
|
|
|
|
$this->appName,
|
|
|
|
'error',
|
|
|
|
['message' => 'Not allowed'],
|
|
|
|
'none'
|
|
|
|
);
|
|
|
|
}
|
2014-07-25 02:46:43 +04:00
|
|
|
|
2022-12-06 18:21:32 +03:00
|
|
|
$client = $this->clientFactory->getClient($account);
|
|
|
|
try {
|
|
|
|
$html = $this->mailManager->getImapMessage(
|
|
|
|
$client,
|
|
|
|
$account,
|
|
|
|
$mailbox,
|
|
|
|
$message->getUid(),
|
|
|
|
true
|
|
|
|
)->getHtmlBody(
|
|
|
|
$id
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
$client->logout();
|
|
|
|
}
|
|
|
|
|
2020-11-06 16:48:12 +03:00
|
|
|
$htmlResponse = $plain ?
|
|
|
|
HtmlResponse::plain($html) :
|
|
|
|
HtmlResponse::withResizer(
|
|
|
|
$html,
|
|
|
|
$this->nonceManager->getNonce(),
|
|
|
|
$this->urlGenerator->getAbsoluteURL(
|
2024-06-18 19:08:37 +03:00
|
|
|
$this->urlGenerator->linkTo('mail', 'js/mail-htmlresponse.mjs')
|
|
|
|
),
|
2020-11-06 16:48:12 +03:00
|
|
|
);
|
2015-05-20 13:18:48 +03:00
|
|
|
|
2015-05-20 13:09:57 +03:00
|
|
|
// Harden the default security policy
|
2016-07-22 18:24:24 +03:00
|
|
|
$policy = new ContentSecurityPolicy();
|
|
|
|
$policy->allowEvalScript(false);
|
|
|
|
$policy->disallowScriptDomain('\'self\'');
|
|
|
|
$policy->disallowConnectDomain('\'self\'');
|
|
|
|
$policy->disallowFontDomain('\'self\'');
|
|
|
|
$policy->disallowMediaDomain('\'self\'');
|
|
|
|
$htmlResponse->setContentSecurityPolicy($policy);
|
2015-05-20 13:09:57 +03:00
|
|
|
|
2015-06-18 14:19:14 +03:00
|
|
|
// Enable caching
|
2022-09-21 14:58:14 +03:00
|
|
|
$htmlResponse->cacheFor(60 * 60, false, true);
|
2015-06-18 14:19:14 +03:00
|
|
|
|
2015-05-20 13:09:57 +03:00
|
|
|
return $htmlResponse;
|
2019-09-26 18:07:47 +03:00
|
|
|
} catch (Exception $ex) {
|
|
|
|
return new TemplateResponse(
|
|
|
|
$this->appName,
|
|
|
|
'error',
|
|
|
|
['message' => $ex->getMessage()],
|
|
|
|
'none'
|
|
|
|
);
|
2014-08-29 03:06:42 +04:00
|
|
|
}
|
2014-07-25 02:46:43 +04:00
|
|
|
}
|
|
|
|
|
2014-07-23 14:16:03 +04:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @NoCSRFRequired
|
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2020-10-08 16:09:16 +03:00
|
|
|
* @param string $attachmentId
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @return Response
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
2014-07-23 14:16:03 +04:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function downloadAttachment(int $id,
|
2023-06-28 15:44:08 +03:00
|
|
|
string $attachmentId): Response {
|
2020-08-11 22:10:49 +03:00
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
2023-02-14 19:28:45 +03:00
|
|
|
|
|
|
|
$attachment = $this->mailManager->getMailAttachment(
|
|
|
|
$account,
|
|
|
|
$mailbox,
|
|
|
|
$message,
|
|
|
|
$attachmentId,
|
|
|
|
);
|
2014-07-23 14:16:03 +04:00
|
|
|
|
2020-01-24 16:36:29 +03:00
|
|
|
// Body party and embedded messages do not have a name
|
|
|
|
if ($attachment->getName() === null) {
|
|
|
|
return new AttachmentDownloadResponse(
|
2023-02-28 14:10:27 +03:00
|
|
|
$attachment->getContent(),
|
2020-01-24 16:36:29 +03:00
|
|
|
$this->l10n->t('Embedded message %s', [
|
|
|
|
$attachmentId,
|
|
|
|
]) . '.eml',
|
|
|
|
$attachment->getType()
|
|
|
|
);
|
|
|
|
}
|
2014-07-23 14:16:03 +04:00
|
|
|
return new AttachmentDownloadResponse(
|
2023-02-28 14:10:27 +03:00
|
|
|
$attachment->getContent(),
|
2020-01-24 16:36:29 +03:00
|
|
|
$attachment->getName(),
|
|
|
|
$attachment->getType()
|
|
|
|
);
|
2014-07-23 14:16:03 +04:00
|
|
|
}
|
|
|
|
|
2021-02-17 15:44:52 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
* @NoCSRFRequired
|
|
|
|
*
|
|
|
|
* @param int $id the message id
|
|
|
|
*
|
|
|
|
* @return ZipResponse|JSONResponse
|
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
* @throws DoesNotExistException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2021-02-17 15:44:52 +03:00
|
|
|
public function downloadAttachments(int $id): Response {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
$attachments = $this->mailManager->getMailAttachments($account, $mailbox, $message);
|
|
|
|
$zip = new ZipResponse($this->request, 'attachments');
|
|
|
|
|
|
|
|
foreach ($attachments as $attachment) {
|
2023-02-28 14:10:27 +03:00
|
|
|
$fileName = $attachment->getName();
|
2021-02-17 15:44:52 +03:00
|
|
|
$fh = fopen('php://temp', 'r+');
|
2023-02-28 14:10:27 +03:00
|
|
|
fputs($fh, $attachment->getContent());
|
|
|
|
$size = $attachment->getSize();
|
2021-02-17 15:44:52 +03:00
|
|
|
rewind($fh);
|
|
|
|
$zip->addResource($fh, $fileName, $size);
|
|
|
|
}
|
|
|
|
return $zip;
|
|
|
|
}
|
|
|
|
|
2014-07-23 17:01:09 +04:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2020-10-08 16:09:16 +03:00
|
|
|
* @param string $attachmentId
|
2014-07-23 17:01:09 +04:00
|
|
|
* @param string $targetPath
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2014-07-23 17:01:09 +04:00
|
|
|
* @return JSONResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
2023-02-27 17:04:43 +03:00
|
|
|
* @throws GenericFileException
|
|
|
|
* @throws NotPermittedException
|
|
|
|
* @throws LockedException
|
2014-07-23 17:01:09 +04:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function saveAttachment(int $id,
|
2023-06-28 15:44:08 +03:00
|
|
|
string $attachmentId,
|
|
|
|
string $targetPath) {
|
2020-08-11 22:10:49 +03:00
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
2014-07-23 17:01:09 +04:00
|
|
|
|
2023-02-27 17:04:43 +03:00
|
|
|
/** @var Attachment[] $attachments */
|
|
|
|
$attachments = [];
|
2019-12-12 17:27:03 +03:00
|
|
|
if ($attachmentId === '0') {
|
2023-02-27 17:04:43 +03:00
|
|
|
$attachments = $this->mailManager->getMailAttachments(
|
|
|
|
$account,
|
|
|
|
$mailbox,
|
|
|
|
$message,
|
|
|
|
);
|
2018-07-24 13:20:23 +03:00
|
|
|
} else {
|
2023-02-27 17:04:43 +03:00
|
|
|
$attachments[] = $this->mailManager->getMailAttachment(
|
2023-02-14 19:28:45 +03:00
|
|
|
$account,
|
|
|
|
$mailbox,
|
|
|
|
$message,
|
2023-02-27 17:04:43 +03:00
|
|
|
$attachmentId,
|
2023-02-14 19:28:45 +03:00
|
|
|
);
|
2023-02-27 17:04:43 +03:00
|
|
|
}
|
2014-07-23 20:21:34 +04:00
|
|
|
|
2023-02-27 17:04:43 +03:00
|
|
|
foreach ($attachments as $attachment) {
|
2020-01-28 13:08:01 +03:00
|
|
|
$fileName = $attachment->getName() ?? $this->l10n->t('Embedded message %s', [
|
2023-02-27 17:04:43 +03:00
|
|
|
$attachment->getId(),
|
2020-04-14 17:06:46 +03:00
|
|
|
]) . '.eml';
|
2014-09-17 22:17:42 +04:00
|
|
|
$fileParts = pathinfo($fileName);
|
|
|
|
$fileName = $fileParts['filename'];
|
|
|
|
$fileExtension = $fileParts['extension'];
|
|
|
|
$fullPath = "$targetPath/$fileName.$fileExtension";
|
|
|
|
$counter = 2;
|
2018-02-02 18:00:30 +03:00
|
|
|
while ($this->userFolder->nodeExists($fullPath)) {
|
2014-09-17 22:17:42 +04:00
|
|
|
$fullPath = "$targetPath/$fileName ($counter).$fileExtension";
|
2014-07-23 20:21:34 +04:00
|
|
|
$counter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$newFile = $this->userFolder->newFile($fullPath);
|
2023-02-28 14:10:27 +03:00
|
|
|
$newFile->putContent($attachment->getContent());
|
2014-07-23 17:01:09 +04:00
|
|
|
}
|
|
|
|
return new JSONResponse();
|
|
|
|
}
|
2014-08-06 01:29:00 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
2020-10-08 16:09:16 +03:00
|
|
|
* @param int $id
|
2015-07-29 15:28:40 +03:00
|
|
|
* @param array $flags
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2014-08-06 01:29:00 +04:00
|
|
|
* @return JSONResponse
|
2020-03-23 16:58:41 +03:00
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
2014-08-06 01:29:00 +04:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function setFlags(int $id, array $flags): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2020-08-11 22:10:49 +03:00
|
|
|
}
|
2014-08-06 01:29:00 +04:00
|
|
|
|
2018-02-02 18:00:30 +03:00
|
|
|
foreach ($flags as $flag => $value) {
|
2015-07-29 15:28:40 +03:00
|
|
|
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
2020-08-11 22:10:49 +03:00
|
|
|
$this->mailManager->flagMessage($account, $mailbox->getName(), $message->getUid(), $flag, $value);
|
2015-07-29 15:28:40 +03:00
|
|
|
}
|
2014-08-06 01:29:00 +04:00
|
|
|
return new JSONResponse();
|
|
|
|
}
|
|
|
|
|
2021-03-04 19:31:21 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
* @param string $imapLabel
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2021-03-04 19:31:21 +03:00
|
|
|
public function setTag(int $id, string $imapLabel): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$tag = $this->mailManager->getTagByImapLabel($imapLabel, $this->currentUserId);
|
2021-06-01 17:45:23 +03:00
|
|
|
} catch (ClientException $e) {
|
2021-03-04 19:31:21 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->mailManager->tagMessage($account, $mailbox->getName(), $message, $tag, true);
|
2021-03-30 12:06:02 +03:00
|
|
|
return new JSONResponse($tag);
|
2021-03-04 19:31:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
* @param string $imapLabel
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
|
|
|
*
|
|
|
|
* @throws ClientException
|
|
|
|
* @throws ServiceException
|
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2021-03-04 19:31:21 +03:00
|
|
|
public function removeTag(int $id, string $imapLabel): JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$tag = $this->mailManager->getTagByImapLabel($imapLabel, $this->currentUserId);
|
2021-06-01 17:45:23 +03:00
|
|
|
} catch (ClientException $e) {
|
2021-03-04 19:31:21 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->mailManager->tagMessage($account, $mailbox->getName(), $message, $tag, false);
|
2021-03-25 18:56:27 +03:00
|
|
|
return new JSONResponse($tag);
|
2021-03-04 19:31:21 +03:00
|
|
|
}
|
|
|
|
|
2014-07-16 23:29:37 +04:00
|
|
|
/**
|
2014-10-08 18:51:19 +04:00
|
|
|
* @NoAdminRequired
|
2014-07-16 23:29:37 +04:00
|
|
|
*
|
2018-07-24 13:20:23 +03:00
|
|
|
* @param int $id
|
2019-09-26 18:07:47 +03:00
|
|
|
*
|
2020-03-23 16:58:41 +03:00
|
|
|
* @throws ClientException
|
2019-09-26 18:07:47 +03:00
|
|
|
* @throws ServiceException
|
2014-07-16 23:29:37 +04:00
|
|
|
*/
|
2023-01-25 17:40:41 +03:00
|
|
|
#[TrapError]
|
2020-08-11 22:10:49 +03:00
|
|
|
public function destroy(int $id): JSONResponse {
|
2019-10-16 13:13:36 +03:00
|
|
|
try {
|
2020-08-11 22:10:49 +03:00
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $id);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
2019-10-16 13:13:36 +03:00
|
|
|
} catch (DoesNotExistException $e) {
|
2020-10-08 15:05:03 +03:00
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
2014-07-16 23:29:37 +04:00
|
|
|
}
|
2019-10-16 13:13:36 +03:00
|
|
|
|
2020-08-11 22:10:49 +03:00
|
|
|
$this->logger->debug("deleting message <$id>");
|
2014-07-16 23:29:37 +04:00
|
|
|
|
2020-08-11 22:10:49 +03:00
|
|
|
$this->mailManager->deleteMessage(
|
|
|
|
$account,
|
|
|
|
$mailbox->getName(),
|
|
|
|
$message->getUid()
|
|
|
|
);
|
|
|
|
return new JSONResponse();
|
2014-07-16 23:29:37 +04:00
|
|
|
}
|
|
|
|
|
2023-09-13 20:09:13 +03:00
|
|
|
/**
|
|
|
|
* @NoAdminRequired
|
|
|
|
*
|
|
|
|
* @param int $messageId
|
|
|
|
*
|
|
|
|
* @return JSONResponse
|
|
|
|
*/
|
|
|
|
#[TrapError]
|
|
|
|
public function smartReply(int $messageId):JSONResponse {
|
|
|
|
try {
|
|
|
|
$message = $this->mailManager->getMessage($this->currentUserId, $messageId);
|
|
|
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
|
|
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
|
|
|
} catch (DoesNotExistException $e) {
|
|
|
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
|
|
|
}
|
|
|
|
try {
|
2024-02-29 17:28:27 +03:00
|
|
|
$replies = array_values($this->aiIntegrationService->getSmartReply($account, $mailbox, $message, $this->currentUserId));
|
2023-09-13 20:09:13 +03:00
|
|
|
} catch (ServiceException $e) {
|
|
|
|
$this->logger->error('Smart reply failed: ' . $e->getMessage(), [
|
|
|
|
'exception' => $e,
|
|
|
|
]);
|
|
|
|
return new JSONResponse([], Http::STATUS_NO_CONTENT);
|
|
|
|
}
|
|
|
|
return new JSONResponse($replies);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-07-23 14:16:03 +04:00
|
|
|
/**
|
2020-08-11 22:10:49 +03:00
|
|
|
* @param int $id
|
2018-07-24 13:20:23 +03:00
|
|
|
* @param array $attachment
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2018-07-24 13:20:23 +03:00
|
|
|
* @return array
|
2014-07-23 14:16:03 +04:00
|
|
|
*/
|
2020-08-11 22:10:49 +03:00
|
|
|
private function enrichDownloadUrl(int $id,
|
2023-06-28 15:44:08 +03:00
|
|
|
array $attachment) {
|
2018-02-02 18:00:30 +03:00
|
|
|
$downloadUrl = $this->urlGenerator->linkToRoute('mail.messages.downloadAttachment',
|
|
|
|
[
|
2020-08-11 22:10:49 +03:00
|
|
|
'id' => $id,
|
2018-07-24 13:20:23 +03:00
|
|
|
'attachmentId' => $attachment['id'],
|
|
|
|
]);
|
2016-08-25 15:22:59 +03:00
|
|
|
$downloadUrl = $this->urlGenerator->getAbsoluteURL($downloadUrl);
|
2014-07-23 14:16:03 +04:00
|
|
|
$attachment['downloadUrl'] = $downloadUrl;
|
2016-07-22 18:24:24 +03:00
|
|
|
$attachment['mimeUrl'] = $this->mimeTypeDetector->mimeTypeIcon($attachment['mime']);
|
2015-09-09 21:22:27 +03:00
|
|
|
|
2018-01-15 22:50:23 +03:00
|
|
|
$attachment['isImage'] = $this->attachmentIsImage($attachment);
|
|
|
|
$attachment['isCalendarEvent'] = $this->attachmentIsCalendarEvent($attachment);
|
|
|
|
|
2014-07-23 14:16:03 +04:00
|
|
|
return $attachment;
|
|
|
|
}
|
|
|
|
|
2015-09-09 21:22:27 +03:00
|
|
|
/**
|
|
|
|
* Determines if the content of this attachment is an image
|
2016-05-04 10:36:25 +03:00
|
|
|
*
|
2021-03-04 19:31:21 +03:00
|
|
|
* @param array $attachment
|
|
|
|
*
|
2016-05-04 10:36:25 +03:00
|
|
|
* @return boolean
|
2015-09-09 21:22:27 +03:00
|
|
|
*/
|
2018-07-24 13:20:23 +03:00
|
|
|
private function attachmentIsImage(array $attachment): bool {
|
2016-05-04 10:36:25 +03:00
|
|
|
return in_array(
|
|
|
|
$attachment['mime'], [
|
2020-04-14 17:06:46 +03:00
|
|
|
'image/jpeg',
|
|
|
|
'image/png',
|
|
|
|
'image/gif'
|
|
|
|
]);
|
2016-05-04 10:36:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-01-22 12:47:09 +03:00
|
|
|
* @param array $attachment
|
2019-10-07 15:07:51 +03:00
|
|
|
*
|
2016-05-04 10:36:25 +03:00
|
|
|
* @return boolean
|
|
|
|
*/
|
2018-07-24 13:20:23 +03:00
|
|
|
private function attachmentIsCalendarEvent(array $attachment): bool {
|
2020-01-24 16:36:29 +03:00
|
|
|
return in_array($attachment['mime'], ['text/calendar', 'application/ics'], true);
|
2015-09-09 21:22:27 +03:00
|
|
|
}
|
2014-07-16 23:29:37 +04:00
|
|
|
}
|