diff --git a/appinfo/info.xml b/appinfo/info.xml index a7d19c1cc5..66d9e49a44 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -46,6 +46,7 @@ Learn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud OCA\Mail\BackgroundJob\CleanupJob OCA\Mail\BackgroundJob\OutboxWorkerJob OCA\Mail\BackgroundJob\IMipMessageJob + OCA\Mail\BackgroundJob\DraftsJob diff --git a/appinfo/routes.php b/appinfo/routes.php index 1b1bdfef94..43b206baa1 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -400,11 +400,18 @@ 'url' => '/api/list/unsubscribe/{id}', 'verb' => 'POST', ], + [ + 'name' => 'drafts#move', + 'url' => '/api/drafts/move/{id}', + 'verb' => 'POST', + ], + ], 'resources' => [ 'accounts' => ['url' => '/api/accounts'], 'aliases' => ['url' => '/api/accounts/{accountId}/aliases'], 'autoComplete' => ['url' => '/api/autoComplete'], + 'drafts' => ['url' => '/api/drafts'], 'localAttachments' => ['url' => '/api/attachments'], 'mailboxes' => ['url' => '/api/mailboxes'], 'messages' => ['url' => '/api/messages'], diff --git a/lib/Controller/DraftsController.php b/lib/Controller/DraftsController.php index c36b8cd6a3..16cde87803 100644 --- a/lib/Controller/DraftsController.php +++ b/lib/Controller/DraftsController.php @@ -27,11 +27,14 @@ namespace OCA\Mail\Controller; use OCA\Mail\Db\LocalMessage; +use OCA\Mail\Exception\ClientException; use OCA\Mail\Http\JsonResponse; use OCA\Mail\Http\TrapError; use OCA\Mail\Service\AccountService; use OCA\Mail\Service\DraftsService; +use OCA\Mail\Service\SmimeService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IRequest; @@ -41,18 +44,22 @@ class DraftsController extends Controller { private string $userId; private AccountService $accountService; private ITimeFactory $timeFactory; + private SmimeService $smimeService; + public function __construct(string $appName, $UserId, IRequest $request, DraftsService $service, AccountService $accountService, - ITimeFactory $timeFactory) { + ITimeFactory $timeFactory, + SmimeService $smimeService) { parent::__construct($appName, $request); $this->userId = $UserId; $this->service = $service; $this->accountService = $accountService; $this->timeFactory = $timeFactory; + $this->smimeService = $smimeService; } /** @@ -63,15 +70,21 @@ public function __construct(string $appName, * @param string $body * @param string $editorBody * @param bool $isHtml + * @param bool $smimeSign + * @param bool $smimeEncrypt * @param array $to i. e. [['label' => 'Linus', 'email' => 'tent@stardewvalley.com'], ['label' => 'Pierre', 'email' => 'generalstore@stardewvalley.com']] * @param array $cc * @param array $bcc * @param array $attachments * @param int|null $aliasId * @param string|null $inReplyToMessageId + * @param int|null $smimeCertificateId * @param int|null $sendAt * @param int|null $draftId + * * @return JsonResponse + * @throws DoesNotExistException + * @throws ClientException */ #[TrapError] public function create( @@ -80,12 +93,15 @@ public function create( string $body, string $editorBody, bool $isHtml, + ?bool $smimeSign, + ?bool $smimeEncrypt, array $to = [], array $cc = [], array $bcc = [], array $attachments = [], ?int $aliasId = null, ?string $inReplyToMessageId = null, + ?int $smimeCertificateId = null, ?int $sendAt = null, ?int $draftId = null) : JsonResponse { $account = $this->accountService->find($this->userId, $accountId); @@ -103,9 +119,17 @@ public function create( $message->setInReplyToMessageId($inReplyToMessageId); $message->setUpdatedAt($this->timeFactory->getTime()); $message->setSendAt($sendAt); + $message->setSmimeSign($smimeSign); + $message->setSmimeEncrypt($smimeEncrypt); if ($sendAt !== null) { $message->setType(LocalMessage::TYPE_OUTGOING); } + + if (!empty($smimeCertificateId)) { + $smimeCertificate = $this->smimeService->findCertificate($smimeCertificateId, $this->userId); + $message->setSmimeCertificateId($smimeCertificate->getId()); + } + $this->service->saveMessage($account, $message, $to, $cc, $bcc, $attachments); return JsonResponse::success($message, Http::STATUS_CREATED); @@ -137,6 +161,8 @@ public function update(int $id, string $body, string $editorBody, bool $isHtml, + ?bool $smimeSign, + ?bool $smimeEncrypt, bool $failed = false, array $to = [], array $cc = [], @@ -144,6 +170,7 @@ public function update(int $id, array $attachments = [], ?int $aliasId = null, ?string $inReplyToMessageId = null, + ?int $smimeCertificateId = null, ?int $sendAt = null): JsonResponse { $message = $this->service->getMessage($id, $this->userId); $account = $this->accountService->find($this->userId, $accountId); @@ -161,6 +188,13 @@ public function update(int $id, $message->setInReplyToMessageId($inReplyToMessageId); $message->setSendAt($sendAt); $message->setUpdatedAt($this->timeFactory->getTime()); + $message->setSmimeSign($smimeSign); + $message->setSmimeEncrypt($smimeEncrypt); + + if (!empty($smimeCertificateId)) { + $smimeCertificate = $this->smimeService->findCertificate($smimeCertificateId, $this->userId); + $message->setSmimeCertificateId($smimeCertificate->getId()); + } $message = $this->service->updateMessage($account, $message, $to, $cc, $bcc, $attachments); return JsonResponse::success($message, Http::STATUS_ACCEPTED); diff --git a/src/components/Composer.vue b/src/components/Composer.vue index 5e39466f20..20a276f74e 100644 --- a/src/components/Composer.vue +++ b/src/components/Composer.vue @@ -604,7 +604,7 @@ export default { bodyVal: this.editorBody, attachments: this.attachmentsData, noReply: this.to.some((to) => to.email?.startsWith('noreply@') || to.email?.startsWith('no-reply@')), - saveDraftDebounced: debounce(10 * 1000, this.saveDraft), + saveDraftDebounced: debounce(5 * 1000, this.saveDraft), selectTo: this.to, selectCc: this.cc, selectBcc: this.bcc, diff --git a/src/components/NewMessageModal.vue b/src/components/NewMessageModal.vue index ed0802ac25..8446e22325 100644 --- a/src/components/NewMessageModal.vue +++ b/src/components/NewMessageModal.vue @@ -1,3 +1,4 @@ +