fix: set content type parameters for attachments

Horde_Mime_Part.setType takes the mimetype (e.g. text/calendar) and discards additional parameters (like method=REQUEST).

Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
This commit is contained in:
Daniel Kesselberg 2024-08-27 12:03:16 +02:00
Родитель cf4d190207
Коммит e3524c810a
2 изменённых файлов: 41 добавлений и 1 удалений

Просмотреть файл

@ -85,7 +85,22 @@ class TransmissionService {
$part->setDisposition('attachment');
$part->setName($localAttachment->getFileName());
$part->setContents($file->getContent());
$part->setType($localAttachment->getMimeType());
/*
* Horde_Mime_Part.setType takes the mimetype (e.g. text/calendar)
* and discards additional parameters (like method=REQUEST).
*
* $part->setType('text/calendar; method=REQUEST')
* $part->getType() => text/calendar
*/
$contentTypeHeader = \Horde_Mime_Headers_ContentParam_ContentType::create();
$contentTypeHeader->decode($localAttachment->getMimeType());
$part->setType($contentTypeHeader->value);
foreach($contentTypeHeader->params as $label => $data) {
$part->setContentTypeParameter($label, $data);
}
return $part;
} catch (AttachmentNotFoundException $e) {
$this->logger->warning('Ignoring local attachment because it does not exist', ['exception' => $e]);

Просмотреть файл

@ -25,6 +25,7 @@ use OCA\Mail\Service\GroupsIntegration;
use OCA\Mail\Service\SmimeService;
use OCA\Mail\Service\TransmissionService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\Files\SimpleFS\InMemoryFile;
use OCP\Files\SimpleFS\ISimpleFile;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
@ -358,4 +359,28 @@ class TransmissionServiceTest extends TestCase {
$this->transmissionService->getEncryptMimePart($localMessage, $to, $cc, $bcc, $account, $send);
$this->assertEquals(LocalMessage::STATUS_SMIME_ENCRYT_FAIL, $localMessage->getStatus());
}
public function testHandleAttachmentKeepAdditionalContentTypeParameters(): void {
$mailAccount = new MailAccount();
$mailAccount->setUserId('bob');
$account = new Account($mailAccount);
$attachment = new LocalAttachment();
$attachment->setFileName('event.ics');
$attachment->setMimeType('text/calendar; method=REQUEST');
$file = new InMemoryFile(
'event.ics',
"BEGIN:VCALENDAR\nEND:VCALENDAR"
);
$this->attachmentService->expects(self::once())
->method('getAttachment')
->willReturn([$attachment, $file]);
$part = $this->transmissionService->handleAttachment($account, ['id' => 1, 'type' => 'local']);
$this->assertEquals('event.ics', $part->getContentTypeParameter('name'));
$this->assertEquals('REQUEST', $part->getContentTypeParameter('method'));
}
}