diff options
author | Richard Steinmetz <richard@steinmetz.cloud> | 2022-08-02 16:35:15 +0300 |
---|---|---|
committer | Richard Steinmetz <richard@steinmetz.cloud> | 2022-08-09 12:56:30 +0300 |
commit | 23399752fb7db380cf9462e965d1d0ce14d956e8 (patch) | |
tree | 0d0c7976cd1528dc5fa28373ac23a1304fd7f0d1 | |
parent | e2857d0b64e09d7c16333046eda2f555eed52c4f (diff) |
Add envelope action links to download whole message
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
-rw-r--r-- | appinfo/routes.php | 5 | ||||
-rwxr-xr-x | lib/Controller/MessagesController.php | 33 | ||||
-rw-r--r-- | src/components/Envelope.vue | 23 | ||||
-rw-r--r-- | src/components/MenuEnvelope.vue | 18 | ||||
-rw-r--r-- | tests/Unit/Controller/MessagesControllerTest.php | 44 |
5 files changed, 123 insertions, 0 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index ab1e15ea6..6da97e398 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -205,6 +205,11 @@ return [ 'verb' => 'GET' ], [ + 'name' => 'messages#export', + 'url' => '/api/messages/{id}/export', + 'verb' => 'GET' + ], + [ 'name' => 'messages#getHtmlBody', 'url' => '/api/messages/{id}/html', 'verb' => 'GET' diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php index 36945b46c..68ecfe2c7 100755 --- a/lib/Controller/MessagesController.php +++ b/lib/Controller/MessagesController.php @@ -438,6 +438,39 @@ class MessagesController extends Controller { } /** + * Export a whole message as an .eml file. + * + * @NoAdminRequired + * @NoCSRFRequired + * @TrapError + * + * @param int $id + * @return Response + * @throws ClientException + * @throws ServiceException + */ + 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); + } + + $source = $this->mailManager->getSource( + $account, + $mailbox->getName(), + $message->getUid() + ); + return new AttachmentDownloadResponse( + $source, + $message->getSubject() . '.eml', + 'message/rfc822', + ); + } + + /** * @NoAdminRequired * @NoCSRFRequired * @TrapError diff --git a/src/components/Envelope.vue b/src/components/Envelope.vue index 5bce4bdda..4d687eb71 100644 --- a/src/components/Envelope.vue +++ b/src/components/Envelope.vue @@ -197,6 +197,14 @@ </template> {{ t('mail', 'Create event') }} </ActionButton> + <ActionLink + :close-after-click="true" + :href="exportMessageLink"> + <template #icon> + <DownloadIcon :size="20" /> + </template> + {{ t('mail', 'Download message') }} + </ActionLink> </template> </template> <template #extra> @@ -265,6 +273,9 @@ import TagModal from './TagModal' import EventModal from './EventModal' import EnvelopePrimaryActions from './EnvelopePrimaryActions' import { hiddenTags } from './tags.js' +import { generateUrl } from '@nextcloud/router' +import ActionLink from '@nextcloud/vue/dist/Components/ActionLink' +import DownloadIcon from 'vue-material-design-icons/Download' export default { name: 'Envelope', @@ -293,6 +304,8 @@ export default { Email, IconAttachment, Reply, + ActionLink, + DownloadIcon, }, directives: { draggableEnvelope: DraggableEnvelopeDirective, @@ -439,6 +452,16 @@ export default { // or undefined. return this.data.subject || this.t('mail', 'No subject') }, + /** + * Link to download the whole message (.eml). + * + * @return {string} + */ + exportMessageLink() { + return generateUrl('/apps/mail/api/messages/{id}/export', { + id: this.data.databaseId, + }) + }, }, methods: { setSelected(value) { diff --git a/src/components/MenuEnvelope.vue b/src/components/MenuEnvelope.vue index 7d26f3101..abb8bb544 100644 --- a/src/components/MenuEnvelope.vue +++ b/src/components/MenuEnvelope.vue @@ -187,6 +187,14 @@ </template> {{ t('mail', 'View source') }} </ActionButton> + <ActionLink + :close-after-click="true" + :href="exportMessageLink"> + <template #icon> + <DownloadIcon :size="20" /> + </template> + {{ t('mail', 'Download message') }} + </ActionLink> <ActionLink v-if="debug" :download="threadingFileName" :href="threadingFile" @@ -379,6 +387,16 @@ export default { .getEnvelopeTags(this.envelope.databaseId) .some((tag) => tag.imapLabel === '$label1') }, + /** + * Link to download the whole message (.eml). + * + * @return {string} + */ + exportMessageLink() { + return generateUrl('/apps/mail/api/messages/{id}/export', { + id: this.envelope.databaseId, + }) + }, }, methods: { onForward() { diff --git a/tests/Unit/Controller/MessagesControllerTest.php b/tests/Unit/Controller/MessagesControllerTest.php index ff6ed12b2..08d332e00 100644 --- a/tests/Unit/Controller/MessagesControllerTest.php +++ b/tests/Unit/Controller/MessagesControllerTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); /** * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> + * @author Richard Steinmetz <richard@steinmetz.cloud> * * Mail * @@ -1069,4 +1070,47 @@ class MessagesControllerTest extends TestCase { $this->controller->getThread($id); } + + public function testExport() { + $accountId = 17; + $mailboxId = 13; + $folderId = 'testfolder'; + $messageId = 4321; + $this->account + ->method('getId') + ->willReturn($accountId); + $mailbox = new \OCA\Mail\Db\Mailbox(); + $message = new \OCA\Mail\Db\Message(); + $message->setMailboxId($mailboxId); + $message->setUid(123); + $message->setSubject('core/master has new results'); + $mailbox->setAccountId($accountId); + $mailbox->setName($folderId); + $this->mailManager->expects($this->exactly(1)) + ->method('getMessage') + ->with($this->userId, $messageId) + ->willReturn($message); + $this->mailManager->expects($this->exactly(1)) + ->method('getMailbox') + ->with($this->userId, $mailboxId) + ->willReturn($mailbox); + $this->accountService->expects($this->exactly(1)) + ->method('find') + ->with($this->equalTo($this->userId), $this->equalTo($accountId)) + ->will($this->returnValue($this->account)); + $source = file_get_contents(__DIR__ . '/../../data/mail-message-123.txt'); + $this->mailManager->expects($this->exactly(1)) + ->method('getSource') + ->with($this->account, $folderId, 123) + ->willReturn($source); + + $expectedResponse = new AttachmentDownloadResponse( + $source, + 'core/master has new results.eml', + 'message/rfc822' + ); + $actualResponse = $this->controller->export($messageId); + + $this->assertEquals($expectedResponse, $actualResponse); + } } |