Cleanup pgp decrypt code and show green when decrypted

This commit is contained in:
the-djmaze 2022-02-17 10:18:47 +01:00
parent b2a492bdab
commit f4bed88e39
8 changed files with 280 additions and 302 deletions

View file

@ -75,10 +75,11 @@ export class MessageModel extends AbstractModel {
hasExternals: false,
pgpSigned: null,
pgpEncrypted: null,
isPgpEncrypted: false,
pgpVerified: null,
pgpEncrypted: null,
pgpDecrypted: false,
readReceipt: '',
hasUnseenSubMessage: false,
@ -153,10 +154,11 @@ export class MessageModel extends AbstractModel {
this.attachments(new AttachmentCollectionModel);
this.pgpSigned(null);
this.pgpEncrypted(null);
this.isPgpEncrypted(false);
this.pgpVerified(null);
this.pgpEncrypted(null);
this.pgpDecrypted(false);
this.priority(MessagePriority.Normal);
this.readReceipt('');
@ -472,6 +474,7 @@ export class MessageModel extends AbstractModel {
initView() {
// init BlockquoteSwitcher
this.body.querySelectorAll('blockquote:not(.rl-bq-switcher)').forEach(node => {
node.removeAttribute('style')
if (node.textContent.trim() && !node.parentNode.closest('blockquote')) {
let h = node.clientHeight || getRealHeight(node);
if (0 === h || 100 < h) {

View file

@ -372,7 +372,7 @@ export const MessageUserStore = new class {
} else {
body = Element.fromHTML('<div id="' + id + '" hidden="" class="b-text-part '
+ (message.pgpSigned() ? ' openpgp-signed' : '')
+ (message.isPgpEncrypted() ? ' openpgp-encrypted' : '')
+ (message.pgpEncrypted() ? ' openpgp-encrypted' : '')
+ '">'
+ '</div>');
message.body = body;

View file

@ -176,7 +176,7 @@ export const
}
} else {
body.classList.add('mailvelope');
return;
return true;
}
}
}

View file

@ -174,264 +174,6 @@ html.rl-no-preview-pane {
}
}
#messageItem {
color: #000;
height: 100%;
overflow: auto;
scroll-behavior: smooth;
.buttonFull {
display: inline-block;
position: fixed;
right: 25px;
bottom: 25px;
height: 30px;
width: 30px;
text-align: center;
vertical-align: middle;
line-height: 30px;
background-color: transparent;
background-color: #fff;
border: 1px solid #333;
color: #333;
z-index: 2;
cursor: pointer;
border-radius: 5px;
opacity: 0.5;
&:hover {
opacity: 0.8;
border-color: #666;
background-color: #888;
color: #fff;
}
}
.loading {
text-align: center;
font-size: 24px;
color: grey;
padding: 50px 0;
}
.showImages, .readReceipt, .pgpSigned, .pgpEncrypted {
cursor: pointer;
padding: 10px 15px;
border-bottom: 1px solid #ddd;
background-color: #eee;
}
.pgpInfo {
padding: 5px 15px;
border-bottom: 1px solid #ddd;
background-color: #fcf8e3;
&.success {
background-color: #e9f4ff;
}
}
.readReceipt {
background-color: #ffffd9;
}
.attachmentsPlace {
padding: 10px 10px 6px 10px;
background: #eee;
border-bottom: 1px solid #ddd;
position: relative;
.attachmentList {
margin: 0;
}
&:not(.selection-mode) {
.checkboxAttachment {
display: none;
}
}
&.unselectedAttachmentsError {
.attachmentItem {
box-shadow: 0 1px 4px red;
box-shadow: 0 1px 5px rgba(255, 0, 0, 0.4);
box-shadow: 0 0 0 1px rgba(255, 0, 0, 0.2), 0 1px 5px rgba(255, 0, 0, 0.3);
}
}
.controls-handle {
position: absolute;
bottom: 5px;
right: 8px;
color: #999;
cursor: pointer;
}
}
.attachmentsControls {
padding: 7px 5px 7px 14px;
background: #e8e8e8;
border-bottom: 1px solid #ddd;
}
.rlBlockquoteSwitcher {
border: 1px solid #999;
display: block;
width: 3em;
line-height: 1em;
text-align: center;
cursor: pointer;
margin: 2em 0 10px;
opacity: 0.5;
&:hover {
opacity: 1;
}
}
.b-text-part {
height: 100%;
div[data-x-div-type=html] {
height: 100%;
div[data-x-div-type=body] {
height: 100%;
}
}
a {
color: blue;
text-decoration: underline;
&:visited {
color: #609;
}
&:active {
color: red;
}
}
blockquote {
border-left: 2px solid #000;
padding: 0 10px;
margin: 0;
}
.rl-bq-switcher.hidden-bq {
display: none;
}
&.html {
div[data-x-div-type=body] {
/*padding: 15px;*/
margin: 15px;
}
img {
max-width: 90vw;
}
img[data-x-src]:not([src]) {
border: 1px solid #999;
position: relative;
}
img[data-x-src]:not([src])::after {
content: "🖼";
font-family: snappymail;
position: absolute;
top: 0;
left: 0;
color: #000;
background-color: #fff;
}
img[data-x-src]:not([src]):hover::after {
content: attr(data-x-src);
font-family: var(--fontSans);
font-size: 11px;
height: auto;
transform: translate(-25%,0);
width: auto;
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
z-index: 1000;
}
pre, code {
margin: 0;
border: none;
word-break: normal;
word-wrap: break-word;
}
code {
border-radius: 0;
display: inline;
padding: 2px 5px;
}
pre {
border-radius: 5px;
display: block;
padding: 5px 10px;
}
pre > code {
padding: 0;
}
}
&.plain {
padding: 15px;
white-space: pre-wrap;
font-family: var(--fontMono);
pre {
margin: 0;
padding: 0;
border: none;
display: block;
word-break: normal;
}
blockquote {
border-left: 2px solid blue;
color: blue;
}
blockquote blockquote {
border-left: 2px solid green;
color: green;
}
blockquote blockquote blockquote {
border-left: 2px solid red;
color: red;
}
}
/*
&.openpgp-signed,
&.openpgp-encrypted {
border: 1px dashed #FA0;
&.success {
border-color: green;
background-color: rgba(0, 255, 0, 0.03);
}
&.error {
border-color: red;
background-color: rgba(255, 0, 0, 0.03);
}
}
*/
}
}
.openpgp-control {
margin: 0.5em;
padding: 0.5em;
@ -482,6 +224,249 @@ html.rl-no-preview-pane {
}
}
#messageItem {
color: #000;
height: 100%;
overflow: auto;
scroll-behavior: smooth;
.buttonFull {
display: inline-block;
position: fixed;
right: 25px;
bottom: 25px;
height: 30px;
width: 30px;
text-align: center;
vertical-align: middle;
line-height: 30px;
background-color: transparent;
background-color: #fff;
border: 1px solid #333;
color: #333;
z-index: 2;
cursor: pointer;
border-radius: 5px;
opacity: 0.5;
&:hover {
opacity: 0.8;
border-color: #666;
background-color: #888;
color: #fff;
}
}
.loading {
text-align: center;
font-size: 24px;
color: grey;
padding: 50px 0;
}
.showImages, .readReceipt, .pgpSigned, .pgpEncrypted {
cursor: pointer;
padding: 10px 15px;
border-bottom: 1px solid #ddd;
background-color: #eee;
}
.pgpInfo {
padding: 5px 15px;
border-bottom: 1px solid #ddd;
background-color: #fcf8e3;
&.success {
background-color: #e9f4ff;
}
}
.readReceipt {
background-color: #ffffd9;
}
.attachmentsPlace {
padding: 10px 10px 6px 10px;
background: #eee;
border-bottom: 1px solid #ddd;
position: relative;
.attachmentList {
margin: 0;
}
&:not(.selection-mode) {
.checkboxAttachment {
display: none;
}
}
&.unselectedAttachmentsError {
.attachmentItem {
box-shadow: 0 1px 4px red;
box-shadow: 0 1px 5px rgba(255, 0, 0, 0.4);
box-shadow: 0 0 0 1px rgba(255, 0, 0, 0.2), 0 1px 5px rgba(255, 0, 0, 0.3);
}
}
.controls-handle {
position: absolute;
bottom: 5px;
right: 8px;
color: #999;
cursor: pointer;
}
}
.attachmentsControls {
padding: 7px 5px 7px 14px;
background: #e8e8e8;
border-bottom: 1px solid #ddd;
}
.rlBlockquoteSwitcher {
border: 1px solid #999;
display: block;
width: 3em;
line-height: 1em;
text-align: center;
cursor: pointer;
margin: 2em 0 10px;
opacity: 0.5;
&:hover {
opacity: 1;
}
}
.b-text-part {
height: 100%;
padding: 10px;
div[data-x-div-type=html] {
height: 100%;
div[data-x-div-type=body] {
height: 100%;
}
}
a {
color: blue;
text-decoration: underline;
&:visited {
color: #609;
}
&:active {
color: red;
}
}
blockquote {
border-left: 2px solid #000;
opacity: 0.8;
padding: 0 10px;
margin: 0;
}
.rl-bq-switcher.hidden-bq {
display: none;
}
&.html {
div[data-x-div-type=body] {
/*padding: 15px;*/
margin: 15px;
}
img {
max-width: 90vw;
}
img[data-x-src]:not([src]) {
border: 1px solid #999;
position: relative;
}
img[data-x-src]:not([src])::after {
content: "🖼";
font-family: snappymail;
position: absolute;
top: 0;
left: 0;
color: #000;
background-color: #fff;
}
img[data-x-src]:not([src]):hover::after {
content: attr(data-x-src);
font-family: var(--fontSans);
font-size: 11px;
height: auto;
transform: translate(-25%,0);
width: auto;
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
z-index: 1000;
}
pre, code {
margin: 0;
border: none;
word-break: normal;
word-wrap: break-word;
}
code {
border-radius: 0;
display: inline;
padding: 2px 5px;
}
pre {
border-radius: 5px;
display: block;
padding: 5px 10px;
}
pre > code {
padding: 0;
}
}
&.plain {
white-space: pre-wrap;
font-family: var(--fontMono);
pre {
margin: 0;
padding: 0;
border: none;
display: block;
word-break: normal;
}
}
/*
&.openpgp-signed,
&.openpgp-encrypted {
border: 1px dashed #FA0;
&.success {
border-color: green;
background-color: rgba(0, 255, 0, 0.03);
}
&.error {
border-color: red;
background-color: rgba(255, 0, 0, 0.03);
}
}
*/
}
}
html.rl-no-preview-pane .messageView {
.toolbar {

View file

@ -583,15 +583,18 @@ export class MailMessageView extends AbstractViewRight {
pgpDecrypt() {
const oMessage = currentMessage();
PgpUserStore.decrypt(oMessage).then(result => {
if (result && result.data) {
MimeToMessage(result.data, oMessage);
oMessage.html() ? oMessage.viewHtml() : oMessage.viewPlain();
if (result.signatures && result.signatures.length) {
oMessage.pgpSigned(true);
oMessage.pgpVerified({
signatures: result.signatures,
success: !!result.signatures.length
});
if (result) {
oMessage.pgpDecrypted(true);
if (result.data) {
MimeToMessage(result.data, oMessage);
oMessage.html() ? oMessage.viewHtml() : oMessage.viewPlain();
if (result.signatures && result.signatures.length) {
oMessage.pgpSigned(true);
oMessage.pgpVerified({
signatures: result.signatures,
success: !!result.signatures.length
});
}
}
}
});

View file

@ -78,8 +78,7 @@ class Message implements \JsonSerializable
$aThreads = array(),
$aPgpSigned = null,
$aPgpEncrypted = null,
$bPgpEncrypted = false;
$aPgpEncrypted = null;
function __construct()
{
@ -106,11 +105,6 @@ class Message implements \JsonSerializable
return $this->aPgpEncrypted;
}
public function isPgpEncrypted() : bool
{
return $this->bPgpEncrypted || $this->aPgpEncrypted;
}
public function Folder() : string
{
return $this->sFolder;
@ -491,10 +485,6 @@ class Message implements \JsonSerializable
$oMessage->sInReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
}
// Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"
$oMessage->bPgpEncrypted = ('multipart/encrypted' === \strtolower($oMessage->sContentType)
&& 'application/pgp-encrypted' === \strtolower($oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, \MailSo\Mime\Enumerations\Parameter::PROTOCOL)));
if ($oBodyStructure)
{
$gEncryptedParts = $oBodyStructure->SearchByContentType('multipart/encrypted');
@ -573,25 +563,25 @@ class Message implements \JsonSerializable
];
}
if (\str_contains($sText, '-----BEGIN PGP MESSAGE-----'))
{
$keyIds = [];
if (\SnappyMail\PGP\GPG::isSupported()) {
$GPG = new \SnappyMail\PGP\GPG('');
$keyIds = $GPG->getEncryptedMessageKeys($sText);
}
$oMessage->aPgpEncrypted = [
'PartId' => $oPart->PartID(),
'KeyIds' => $keyIds
];
}
if ('text/html' === $oPart->ContentType())
{
$aHtmlParts[] = $sText;
}
else
{
if (\str_contains($sText, '-----BEGIN PGP MESSAGE-----'))
{
$keyIds = [];
if (\SnappyMail\PGP\GPG::isSupported()) {
$GPG = new \SnappyMail\PGP\GPG('');
$keyIds = $GPG->getEncryptedMessageKeys($sText);
}
$oMessage->aPgpEncrypted = [
'PartId' => $oPart->PartID(),
'KeyIds' => $keyIds
];
}
if ($oPart->IsFlowedFormat())
{
$sText = Utils::DecodeFlowedFormat($sText);
@ -605,9 +595,7 @@ class Message implements \JsonSerializable
$oMessage->sHtml = \implode('<br>', $aHtmlParts);
$oMessage->sPlain = \trim(\implode("\n", $aPlainParts));
$oMessage->bPgpEncrypted = !$oMessage->bPgpEncrypted && false !== \stripos($oMessage->sPlain, '-----BEGIN PGP MESSAGE-----');
unset($aHtmlParts, $aPlainParts, $aMatch);
unset($aHtmlParts, $aPlainParts);
}
$gAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();

View file

@ -211,7 +211,6 @@ trait Response
$mResult['Plain'] = $mResponse->Plain();
// $this->GetCapa(Capa::OPEN_PGP) || $this->GetCapa(Capa::GNUPG)
$mResult['isPgpEncrypted'] = $mResponse->isPgpEncrypted();
$mResult['PgpSigned'] = $mResponse->PgpSigned();
$mResult['PgpEncrypted'] = $mResponse->PgpEncrypted();

View file

@ -264,7 +264,7 @@
</div>
</div>
<div class="openpgp-control encrypted" data-bind="visible: message().pgpEncrypted() || message().isPgpEncrypted()">
<div class="openpgp-control encrypted" data-bind="visible: message().pgpEncrypted(), css: {'success': message().pgpDecrypted()}">
<span data-icon="🔒" data-i18n="OPENPGP/ENCRYPTED_MESSAGE"></span>
<button class="btn" data-bind="visible: pgpSupported, click: pgpDecrypt" data-i18n="OPENPGP/BUTTON_DECRYPT"></button>
</div>