257 lines
7.6 KiB
C++
257 lines
7.6 KiB
C++
/**
|
|
* Copyright (C) 2021-2024 Saturneric <eric@bktus.com>
|
|
*
|
|
* This file is part of GpgFrontend.
|
|
*
|
|
* GpgFrontend is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GpgFrontend is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* The initial version of the source code is inherited from
|
|
* the gpg4usb project, which is under GPL-3.0-or-later.
|
|
*
|
|
* All the source code of GpgFrontend was modified and released by
|
|
* Saturneric <eric@bktus.com> starting on May 12, 2021.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
*/
|
|
|
|
#include "EMailMetaDataDialog.h"
|
|
|
|
#include <GFSDKGpg.h>
|
|
|
|
#include <QCryptographicHash>
|
|
#include <QDialog>
|
|
#include <QMessageBox>
|
|
#include <QRegularExpression>
|
|
|
|
#include "EMailHelper.h"
|
|
#include "ui_EMailMetaDataDialog.h"
|
|
|
|
static const QRegularExpression kNameEmailStringValidateRegex(
|
|
R"(^\s*(.*\s*)?<\s*([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)\s*>\s*$|(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$))");
|
|
|
|
class ParameterizedHeaderField : public vmime::parameterizedHeaderField {
|
|
public:
|
|
ParameterizedHeaderField() = default;
|
|
};
|
|
|
|
class HeaderField : public vmime::headerField {
|
|
public:
|
|
HeaderField() = default;
|
|
};
|
|
|
|
class ContentTypeField : public vmime::contentTypeField {
|
|
public:
|
|
ContentTypeField() = default;
|
|
};
|
|
|
|
EMailMetaDataDialog::EMailMetaDataDialog(int mode, QWidget* parent)
|
|
: QDialog(parent),
|
|
ui_(QSharedPointer<Ui_EMailMetaDataDialog>::create()),
|
|
mode_(mode) {
|
|
ui_->setupUi(this);
|
|
|
|
ui_->ccEdit->setHidden(true);
|
|
ui_->ccLabel->setHidden(true);
|
|
ui_->bccEdit->setHidden(true);
|
|
ui_->bccLabel->setHidden(true);
|
|
|
|
connect(ui_->okButton, &QPushButton::clicked, this,
|
|
&EMailMetaDataDialog::slot_parse_eml_meta_data);
|
|
|
|
connect(ui_->cancelButton, &QPushButton::clicked, this, &QDialog::close);
|
|
|
|
connect(ui_->ccButton, &QPushButton::clicked, this, [this]() {
|
|
ui_->ccEdit->setHidden(!ui_->ccEdit->isHidden());
|
|
ui_->ccLabel->setHidden(!ui_->ccLabel->isHidden());
|
|
});
|
|
|
|
connect(ui_->bccButton, &QPushButton::clicked, this, [this]() {
|
|
ui_->bccEdit->setHidden(!ui_->bccEdit->isHidden());
|
|
ui_->bccLabel->setHidden(!ui_->bccLabel->isHidden());
|
|
});
|
|
|
|
connect(this, &EMailMetaDataDialog::SignalEMLMetaData, this, &QDialog::close);
|
|
connect(this, &EMailMetaDataDialog::SignalNoEMLMetaData, this,
|
|
&QDialog::close);
|
|
|
|
setModal(true);
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
setWindowFlags(Qt::Dialog | Qt::Window);
|
|
}
|
|
|
|
Q_VARIANT_Q_OBJECT_FACTORY_DEFINE(CreateEMailMetaDataDialog,
|
|
[](QVariant mode) -> void* {
|
|
return new EMailMetaDataDialog(mode.toInt(),
|
|
nullptr);
|
|
});
|
|
|
|
void EMailMetaDataDialog::slot_parse_eml_meta_data() {
|
|
// sign key is a must
|
|
if (keys_.isEmpty()) {
|
|
emit SignalNoEMLMetaData("No Sign Key");
|
|
return;
|
|
}
|
|
|
|
// only allow one sign key
|
|
const auto sign_key = keys_.front();
|
|
|
|
// validate
|
|
slot_validate_inputs_and_show_errors();
|
|
if (!ui_->errorLabel->text().trimmed().isEmpty()) return;
|
|
|
|
auto from = ui_->fromEdit->text();
|
|
auto raw_to = ui_->toEdit->text();
|
|
auto raw_cc = ui_->ccEdit->text();
|
|
auto raw_bcc = ui_->bccEdit->text();
|
|
auto subject = ui_->subjectEdit->text();
|
|
|
|
auto to = raw_to.split(';', Qt::SkipEmptyParts);
|
|
auto cc = raw_cc.split(';', Qt::SkipEmptyParts);
|
|
auto bcc = raw_bcc.split(';', Qt::SkipEmptyParts);
|
|
|
|
QString name;
|
|
QString email;
|
|
|
|
EMailMetaData meta_data;
|
|
meta_data.from = from;
|
|
meta_data.to = to;
|
|
meta_data.cc = cc;
|
|
meta_data.bcc = bcc;
|
|
meta_data.subject = subject;
|
|
|
|
emit SignalEMLMetaData(meta_data);
|
|
}
|
|
|
|
void EMailMetaDataDialog::slot_export_encrypted_data() {}
|
|
|
|
void EMailMetaDataDialog::SetKeys(QStringList k) {
|
|
keys_ = std::move(k);
|
|
|
|
if (mode_ == 0) {
|
|
slot_set_from_field_by_sign_key();
|
|
} else {
|
|
slot_set_to_field_by_encrypt_keys();
|
|
}
|
|
}
|
|
|
|
void EMailMetaDataDialog::SetChannel(int c) { channel_ = c; }
|
|
|
|
void EMailMetaDataDialog::slot_set_from_field_by_sign_key() {
|
|
// only allow one sign key
|
|
const auto sign_key = keys_.front();
|
|
|
|
GFGpgKeyUID* s;
|
|
auto ret = GFGpgKeyPrimaryUID(channel_, QDUP(sign_key), &s);
|
|
if (ret != 0) {
|
|
FLOG_WARN("cannot get primary uid from sign key %1, ret: %2", sign_key,
|
|
ret);
|
|
return;
|
|
}
|
|
|
|
from_name_ = UDUP(s->name);
|
|
from_email_ = UDUP(s->email);
|
|
auto comment = UDUP(s->comment);
|
|
|
|
GFFreeMemory(s);
|
|
|
|
ui_->fromEdit->setText(QString("%1 <%2>").arg(from_name_).arg(from_email_));
|
|
}
|
|
|
|
void EMailMetaDataDialog::slot_validate_inputs_and_show_errors() {
|
|
QString error_message;
|
|
|
|
if (ui_->fromEdit->text().trimmed().isEmpty()) {
|
|
error_message = tr("The 'From' field cannot be empty.");
|
|
} else if (!is_valid_email(ui_->fromEdit->text().trimmed())) {
|
|
error_message = tr("The 'From' field must contain a valid email address.");
|
|
}
|
|
|
|
if (error_message.isEmpty() && ui_->toEdit->text().trimmed().isEmpty()) {
|
|
error_message = tr("The 'To' field cannot be empty.");
|
|
} else if (error_message.isEmpty() &&
|
|
!are_valid_emails(ui_->toEdit->text())) {
|
|
error_message =
|
|
tr("One or more 'To' addresses are invalid. Please separate multiple "
|
|
"addresses with \";\".");
|
|
}
|
|
|
|
if (error_message.isEmpty() && !ui_->ccEdit->text().trimmed().isEmpty()) {
|
|
if (!are_valid_emails(ui_->ccEdit->text())) {
|
|
error_message =
|
|
tr("One or more 'CC' addresses are invalid. Please separate "
|
|
"multiple addresses with \";\".");
|
|
}
|
|
}
|
|
|
|
if (error_message.isEmpty() && !ui_->bccEdit->text().trimmed().isEmpty()) {
|
|
if (!are_valid_emails(ui_->bccEdit->text())) {
|
|
error_message =
|
|
tr("One or more 'BCC' addresses are invalid. Please separate "
|
|
"multiple addresses with \";\".");
|
|
}
|
|
}
|
|
|
|
if (error_message.isEmpty() && ui_->subjectEdit->text().trimmed().isEmpty()) {
|
|
error_message = tr("The 'Subject' field cannot be empty.");
|
|
}
|
|
|
|
if (!error_message.isEmpty()) {
|
|
ui_->errorLabel->setText(error_message);
|
|
ui_->errorLabel->setStyleSheet("QLabel { color : red; }");
|
|
} else {
|
|
ui_->errorLabel->clear();
|
|
}
|
|
}
|
|
|
|
auto EMailMetaDataDialog::are_valid_emails(const QString& emails) -> bool {
|
|
QStringList email_list = emails.split(';', Qt::SkipEmptyParts);
|
|
for (const QString& email : email_list) {
|
|
if (!is_valid_email(email.trimmed())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
auto EMailMetaDataDialog::is_valid_email(const QString& email) -> bool {
|
|
return kNameEmailStringValidateRegex.match(email).hasMatch();
|
|
}
|
|
|
|
void EMailMetaDataDialog::SetBodyData(QByteArray b) {
|
|
body_data_ = std::move(b);
|
|
}
|
|
|
|
void EMailMetaDataDialog::slot_set_to_field_by_encrypt_keys() {
|
|
QStringList to_list;
|
|
|
|
for (const auto& key : keys_) {
|
|
GFGpgKeyUID* s;
|
|
auto ret = GFGpgKeyPrimaryUID(channel_, QDUP(key), &s);
|
|
if (ret != 0) {
|
|
FLOG_WARN("cannot get primary uid from sign key %1, ret: %2", key, ret);
|
|
continue;
|
|
}
|
|
|
|
from_name_ = UDUP(s->name);
|
|
from_email_ = UDUP(s->email);
|
|
auto comment = UDUP(s->comment);
|
|
|
|
GFFreeMemory(s);
|
|
|
|
to_list.append(QString("%1 <%2>").arg(from_name_).arg(from_email_));
|
|
}
|
|
|
|
ui_->toEdit->setText(to_list.join("; "));
|
|
} |