File indexing completed on 2024-06-23 05:18:30

0001 /*
0002   SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
0003   SPDX-FileCopyrightText: 2009 Andras Mantia <andras@kdab.net>
0004 
0005   SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "messagehelper.h"
0009 
0010 #include "MessageCore/MailingList"
0011 #include "MessageCore/StringUtil"
0012 
0013 #include <KIdentityManagementCore/Identity>
0014 #include <KIdentityManagementCore/IdentityManager>
0015 #include <KMime/DateFormatter>
0016 #include <KMime/MDN>
0017 #include <KMime/Message>
0018 
0019 using namespace MessageCore;
0020 
0021 namespace MessageHelper
0022 {
0023 void initHeader(const KMime::Message::Ptr &message, const KIdentityManagementCore::IdentityManager *identMan, uint id)
0024 {
0025     applyIdentity(message, identMan, id);
0026     message->removeHeader<KMime::Headers::To>();
0027     message->removeHeader<KMime::Headers::Subject>();
0028     message->date()->setDateTime(QDateTime::currentDateTime());
0029 
0030     // This will allow to change Content-Type:
0031     message->contentType()->setMimeType("text/plain");
0032 }
0033 
0034 void initFromMessage(const KMime::Message::Ptr &msg,
0035                      const KMime::Message::Ptr &origMsg,
0036                      KIdentityManagementCore::IdentityManager *identMan,
0037                      uint id,
0038                      bool idHeaders)
0039 {
0040     if (idHeaders) {
0041         MessageHelper::initHeader(msg, identMan, id);
0042     } else {
0043         auto header = new KMime::Headers::Generic("X-KMail-Identity");
0044         header->fromUnicodeString(QString::number(id), "utf-8");
0045         msg->setHeader(header);
0046     }
0047 
0048     if (auto hdr = origMsg->headerByType("X-KMail-Transport")) {
0049         const QString transport = hdr->asUnicodeString();
0050         auto header = new KMime::Headers::Generic("X-KMail-Transport");
0051         header->fromUnicodeString(transport, "utf-8");
0052         msg->setHeader(header);
0053     }
0054 }
0055 
0056 void applyIdentity(const KMime::Message::Ptr &message, const KIdentityManagementCore::IdentityManager *identMan, uint id)
0057 {
0058     const KIdentityManagementCore::Identity &ident = identMan->identityForUoidOrDefault(id);
0059 
0060     if (ident.fullEmailAddr().isEmpty()) {
0061         message->removeHeader<KMime::Headers::From>();
0062     } else {
0063         message->from()->addAddress(ident.primaryEmailAddress().toUtf8(), ident.fullName());
0064     }
0065 
0066     if (ident.replyToAddr().isEmpty()) {
0067         message->removeHeader<KMime::Headers::ReplyTo>();
0068     } else {
0069         message->replyTo()->addAddress(ident.replyToAddr().toUtf8());
0070     }
0071 
0072     if (ident.bcc().isEmpty()) {
0073         message->removeHeader<KMime::Headers::Bcc>();
0074     } else {
0075         const auto mailboxes = KMime::Types::Mailbox::listFromUnicodeString(ident.bcc());
0076         for (const KMime::Types::Mailbox &mailbox : mailboxes) {
0077             message->bcc()->addAddress(mailbox);
0078         }
0079     }
0080 
0081     if (ident.cc().isEmpty()) {
0082         message->removeHeader<KMime::Headers::Cc>();
0083     } else {
0084         const auto mailboxes = KMime::Types::Mailbox::listFromUnicodeString(ident.cc());
0085         for (const KMime::Types::Mailbox &mailbox : mailboxes) {
0086             message->cc()->addAddress(mailbox);
0087         }
0088     }
0089 
0090     if (ident.organization().isEmpty()) {
0091         message->removeHeader<KMime::Headers::Organization>();
0092     } else {
0093         auto const organization = new KMime::Headers::Organization;
0094         organization->fromUnicodeString(ident.organization(), "utf-8");
0095         message->setHeader(organization);
0096     }
0097 
0098     if (ident.isDefault()) {
0099         message->removeHeader("X-KMail-Identity");
0100     } else {
0101         auto header = new KMime::Headers::Generic("X-KMail-Identity");
0102         header->fromUnicodeString(QString::number(ident.uoid()), "utf-8");
0103         message->setHeader(header);
0104     }
0105 
0106     if (ident.transport().isEmpty()) {
0107         message->removeHeader("X-KMail-Transport");
0108     } else {
0109         auto header = new KMime::Headers::Generic("X-KMail-Transport");
0110         header->fromUnicodeString(ident.transport(), "utf-8");
0111         message->setHeader(header);
0112     }
0113 
0114     if (ident.fcc().isEmpty()) {
0115         message->removeHeader("X-KMail-Fcc");
0116     } else {
0117         auto header = new KMime::Headers::Generic("X-KMail-Fcc");
0118         header->fromUnicodeString(ident.fcc(), "utf-8");
0119         message->setHeader(header);
0120     }
0121 
0122     if (ident.disabledFcc()) {
0123         auto header = new KMime::Headers::Generic("X-KMail-FccDisabled");
0124         header->fromUnicodeString(QStringLiteral("true"), "utf-8");
0125         message->setHeader(header);
0126     } else {
0127         message->removeHeader("X-KMail-FccDisabled");
0128     }
0129 }
0130 
0131 KMime::Types::AddrSpecList extractAddrSpecs(const KMime::Message::Ptr &msg, const QByteArray &header)
0132 {
0133     KMime::Types::AddrSpecList result;
0134     if (auto hrd = msg->headerByType(header.constData())) {
0135         // Don't use "asUnicodeString().toUtf8()" it removes \" from \"foo, bla\" <foo@kde.org> => send failed
0136         // Bug 439218
0137         KMime::Types::AddressList al = MessageCore::StringUtil::splitAddressField(hrd->as7BitString(false));
0138         KMime::Types::AddressList::const_iterator alend(al.constEnd());
0139         for (KMime::Types::AddressList::const_iterator ait = al.constBegin(); ait != alend; ++ait) {
0140             KMime::Types::MailboxList::const_iterator mitEnd((*ait).mailboxList.constEnd());
0141             for (KMime::Types::MailboxList::const_iterator mit = (*ait).mailboxList.constBegin(); mit != mitEnd; ++mit) {
0142                 result.push_back((*mit).addrSpec());
0143             }
0144         }
0145     }
0146     return result;
0147 }
0148 
0149 void setAutomaticFields(const KMime::Message::Ptr &msg, bool aIsMulti)
0150 {
0151     auto header = msg->header<KMime::Headers::MIMEVersion>(true);
0152     header->from7BitString("1.0");
0153 
0154     if (aIsMulti || msg->contents().size() > 1) {
0155         // Set the type to 'Multipart' and the subtype to 'Mixed'
0156         msg->contentType(false)->setMimeType("multipart/mixed");
0157         // Create a random printable string and set it as the boundary parameter
0158         msg->contentType(false)->setBoundary(KMime::multiPartBoundary());
0159     }
0160 }
0161 }