Resolve issue #139

This commit is contained in:
djmaze 2021-09-02 12:09:16 +02:00
parent a15e7f6d1e
commit cca8ce065c
14 changed files with 135 additions and 89 deletions

View file

@ -48,6 +48,7 @@ export class MessageModel extends AbstractModel {
spamScore: 0,
spamResult: '',
isSpam: false,
hasVirus: null, // or boolean when scanned
dateTimeStampInUTC: 0,
priority: MessagePriority.Normal,
@ -120,6 +121,7 @@ export class MessageModel extends AbstractModel {
this.spamScore(0);
this.spamResult('');
this.isSpam(false);
this.hasVirus(null);
this.dateTimeStampInUTC(0);
this.priority(MessagePriority.Normal);
@ -419,6 +421,7 @@ export class MessageModel extends AbstractModel {
this.spamScore(message.spamScore());
this.spamResult(message.spamResult());
this.isSpam(message.isSpam());
this.hasVirus(message.hasVirus());
this.dateTimeStampInUTC(message.dateTimeStampInUTC());
this.priority(message.priority());

View file

@ -159,6 +159,12 @@
&.emptySubject .emptySubjectText {
display: inline;
}
.hasVirus {
background: #f00;
color: #fff;
padding: 3px;
}
}
.messageItem {

View file

@ -158,6 +158,9 @@ class MailClient
\MailSo\Mime\Enumerations\Header::X_SPAM_STATUS,
\MailSo\Mime\Enumerations\Header::X_SPAMD_RESULT,
\MailSo\Mime\Enumerations\Header::X_BOGOSITY
// Virus
,\MailSo\Mime\Enumerations\Header::X_VIRUS_SCANNED,
,\MailSo\Mime\Enumerations\Header::X_VIRUS_STATUS
), true);
//
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;

View file

@ -27,6 +27,7 @@ class Message implements \JsonSerializable
$iSpamScore = 0,
$sSpamResult = '',
$bIsSpam = false,
$bHasVirus = null,
$iInternalTimeStampInUTC = 0,
$iHeaderTimeStampInUTC = 0,
$sHeaderDate = '',
@ -168,6 +169,16 @@ class Message implements \JsonSerializable
return $this->bIsSpam;
}
/**
* null = not scanned
* true = scanned and infected
* false = scanned and no infection found
*/
public function HasVirus() : ?bool
{
return $this->bHasVirus;
}
public function InternalTimeStampInUTC() : int
{
return $this->iInternalTimeStampInUTC;
@ -456,6 +467,7 @@ class Message implements \JsonSerializable
$this->iSpamScore = \max(0, \min(100, \floatval($spamicity[1])));
}
} else if ($spam = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_SPAM_STATUS)) {
$this->sSpamResult = $spam;
if (\preg_match('/(?:hits|score)=([\\d\\.-]+)/', $spam, $value)
&& \preg_match('/required=([\\d\\.-]+)/', $spam, $required)) {
if ($threshold = \floatval($required[1])) {
@ -467,6 +479,17 @@ class Message implements \JsonSerializable
$this->bIsSpam = false !== \stripos($spam, 'YES');
}
if ($virus = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_VIRUS_STATUS)) {
if (false !== \stripos($spam, 'infected')) {
$this->bHasVirus = true;
} else if (false !== \stripos($spam, 'clean')) {
$this->bHasVirus = false;
}
}
if ($virus = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_VIRUS_SCANNED)) {
$this->sVirusScanned = $virus;
}
$sDraftInfo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO);
if (0 < \strlen($sDraftInfo)) {
$sType = '';
@ -632,44 +655,43 @@ class Message implements \JsonSerializable
public function jsonSerialize()
{
$oAttachments = $this->Attachments();
$aFlags = $this->FlagsLowerCase();
return array(
'@Object' => 'Object/Message',
'Folder' => $this->Folder(),
'Uid' => (string) $this->Uid(),
'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->Subject())),
'MessageId' => $this->MessageId(),
'Size' => $this->Size(),
'SpamScore' => $this->SpamScore(),
'SpamResult' => $this->SpamResult(),
'IsSpam' => $this->IsSpam(),
'DateTimeStampInUTC' => $this->InternalTimeStampInUTC(),
'Folder' => $this->sFolder,
'Uid' => (string) $this->iUid,
'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->sSubject)),
'MessageId' => $this->sMessageId,
'Size' => $this->iSize,
'SpamScore' => $this->iSpamScore,
'SpamResult' => $this->sSpamResult,
'IsSpam' => $this->bIsSpam,
'HasVirus' => $this->bHasVirus,
'DateTimeStampInUTC' => $this->iInternalTimeStampInUTC,
// \MailSo\Mime\EmailCollection
'From' => $this->From(),
'ReplyTo' => $this->ReplyTo(),
'To' => $this->To(),
'Cc' => $this->Cc(),
'Bcc' => $this->Bcc(),
'Sender' => $this->Sender(),
'DeliveredTo' => $this->DeliveredTo(),
'From' => $this->oFrom,
'ReplyTo' => $this->oReplyTo,
'To' => $this->oTo,
'Cc' => $this->oCc,
'Bcc' => $this->oBcc,
'Sender' => $this->oSender,
'DeliveredTo' => $this->oDeliveredTo,
'Priority' => $this->Priority(),
'Threads' => $this->Threads(),
'Sensitivity' => $this->Sensitivity(),
'UnsubsribeLinks' => $this->UnsubsribeLinks(),
'Priority' => $this->iPriority,
'Threads' => $this->aThreads,
'Sensitivity' => $this->iSensitivity,
'UnsubsribeLinks' => $this->aUnsubsribeLinks,
'ReadReceipt' => '',
'HasAttachments' => $oAttachments ? 0 < $oAttachments->Count() : false,
'AttachmentsSpecData' => $oAttachments ? $oAttachments->SpecData() : array(),
'HasAttachments' => $this->oAttachments && 0 < $this->oAttachments->Count(),
'AttachmentsSpecData' => $this->oAttachments ? $this->oAttachments->SpecData() : array(),
// Flags
'IsUnseen' => \in_array('\\unseen', $aFlags) || !\in_array('\\seen', $aFlags),
'IsSeen' => \in_array('\\seen', $aFlags),
'IsFlagged' => \in_array('\\flagged', $aFlags),
'IsAnswered' => \in_array('\\answered', $aFlags),
'IsDeleted' => \in_array('\\deleted', $aFlags)
'IsUnseen' => \in_array('\\unseen', $this->aFlagsLowerCase) || !\in_array('\\seen', $this->aFlagsLowerCase),
'IsSeen' => \in_array('\\seen', $this->aFlagsLowerCase),
'IsFlagged' => \in_array('\\flagged', $this->aFlagsLowerCase),
'IsAnswered' => \in_array('\\answered', $this->aFlagsLowerCase),
'IsDeleted' => \in_array('\\deleted', $this->aFlagsLowerCase)
);
}
}

View file

@ -18,69 +18,74 @@ namespace MailSo\Mime\Enumerations;
*/
abstract class Header
{
const DATE = 'Date';
const RECEIVED = 'Received';
const
DATE = 'Date',
RECEIVED = 'Received',
const SUBJECT = 'Subject';
SUBJECT = 'Subject',
const TO_ = 'To';
const FROM_ = 'From';
const CC = 'Cc';
const BCC = 'Bcc';
const REPLY_TO = 'Reply-To';
const SENDER = 'Sender';
const RETURN_PATH = 'Return-Path';
const DELIVERED_TO = 'Delivered-To';
TO_ = 'To',
FROM_ = 'From',
CC = 'Cc',
BCC = 'Bcc',
REPLY_TO = 'Reply-To',
SENDER = 'Sender',
RETURN_PATH = 'Return-Path',
DELIVERED_TO = 'Delivered-To',
const MESSAGE_ID = 'Message-ID';
const IN_REPLY_TO = 'In-Reply-To';
const REFERENCES = 'References';
const X_DRAFT_INFO = 'X-Draft-Info';
const X_ORIGINATING_IP = 'X-Originating-IP';
MESSAGE_ID = 'Message-ID',
IN_REPLY_TO = 'In-Reply-To',
REFERENCES = 'References',
X_DRAFT_INFO = 'X-Draft-Info',
X_ORIGINATING_IP = 'X-Originating-IP',
const CONTENT_TYPE = 'Content-Type';
const CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding';
const CONTENT_DISPOSITION = 'Content-Disposition';
const CONTENT_DESCRIPTION = 'Content-Description';
const CONTENT_ID = 'Content-ID';
const CONTENT_LOCATION = 'Content-Location';
CONTENT_TYPE = 'Content-Type',
CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding',
CONTENT_DISPOSITION = 'Content-Disposition',
CONTENT_DESCRIPTION = 'Content-Description',
CONTENT_ID = 'Content-ID',
CONTENT_LOCATION = 'Content-Location',
const SENSITIVITY = 'Sensitivity';
SENSITIVITY = 'Sensitivity',
const RECEIVED_SPF = 'Received-SPF';
const AUTHENTICATION_RESULTS = 'Authentication-Results';
const X_DKIM_AUTHENTICATION_RESULTS = 'X-DKIM-Authentication-Results';
RECEIVED_SPF = 'Received-SPF',
AUTHENTICATION_RESULTS = 'Authentication-Results',
X_DKIM_AUTHENTICATION_RESULTS = 'X-DKIM-Authentication-Results',
const DKIM_SIGNATURE = 'DKIM-Signature';
const DOMAINKEY_SIGNATURE = 'DomainKey-Signature';
DKIM_SIGNATURE = 'DKIM-Signature',
DOMAINKEY_SIGNATURE = 'DomainKey-Signature',
// SpamAssassin
const X_SPAM_FLAG = 'X-Spam-Flag'; // YES/NO
const X_SPAM_LEVEL = 'X-Spam-Level'; // *******
const X_SPAM_STATUS = 'X-Spam-Status'; // Yes|No
X_SPAM_FLAG = 'X-Spam-Flag', // YES/NO
X_SPAM_LEVEL = 'X-Spam-Level', // *******
X_SPAM_STATUS = 'X-Spam-Status', // Yes|No
// Rspamd
const X_SPAMD_RESULT = 'X-Spamd-Result'; // default: False [7.13 / 9.00];
const X_SPAMD_BAR = 'X-Spamd-Bar'; // +++++++
X_SPAMD_RESULT = 'X-Spamd-Result', // default: False [7.13 / 9.00],
X_SPAMD_BAR = 'X-Spamd-Bar', // +++++++
// Bogofilter
const X_BOGOSITY = 'X-Bogosity';
X_BOGOSITY = 'X-Bogosity',
// Unknown
const X_SPAM_CATEGORY = 'X-Spam-Category'; // SPAM|LEGIT
const X_SPAM_SCORE = 'X-Spam-Score'; // 0
const X_HAM_REPORT = 'X-Ham-Report';
const X_MICROSOFT_ANTISPAM = 'x-microsoft-antispam:';
X_SPAM_CATEGORY = 'X-Spam-Category', // SPAM|LEGIT
X_SPAM_SCORE = 'X-Spam-Score', // 0
X_HAM_REPORT = 'X-Ham-Report',
X_MICROSOFT_ANTISPAM = 'x-microsoft-antispam',
const X_VIRUS = 'X-Virus';
// X-Quarantine-ID
X_VIRUS = 'X-Virus',
// ClamAV
X_VIRUS_SCANNED = 'X-Virus-Scanned',
X_VIRUS_STATUS = 'X-Virus-Status', // clean/infected/not-scanned
const RETURN_RECEIPT_TO = 'Return-Receipt-To';
const DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To';
const X_CONFIRM_READING_TO = 'X-Confirm-Reading-To';
RETURN_RECEIPT_TO = 'Return-Receipt-To',
DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To',
X_CONFIRM_READING_TO = 'X-Confirm-Reading-To',
const MIME_VERSION = 'MIME-Version';
const X_MAILER = 'X-Mailer';
MIME_VERSION = 'MIME-Version',
X_MAILER = 'X-Mailer',
const X_MSMAIL_PRIORITY = 'X-MSMail-Priority';
const IMPORTANCE = 'Importance';
const X_PRIORITY = 'X-Priority';
X_MSMAIL_PRIORITY = 'X-MSMail-Priority',
IMPORTANCE = 'Importance',
X_PRIORITY = 'X-Priority',
const LIST_UNSUBSCRIBE = 'List-Unsubscribe';
LIST_UNSUBSCRIBE = 'List-Unsubscribe';
}

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signierte Nachricht (klicken, um zu überprüfen)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)",
"LINK_DOWNLOAD_AS_ZIP": "Als ZIP-Datei herunterladen",
"SPAM_SCORE": "Spam-Score"
"SPAM_SCORE": "Spam-Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Empfangsbestätigung (angezeigt) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message (click to verify)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message (click to decrypt)",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score"
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Return Receipt (displayed) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "Mensaje firmado mediante OpenPGP (click para verificar)",
"PGP_ENCRYPTED_MESSAGE_DESC": "Mensaje cifrado mediante OpenPGP (click para desencriptar)",
"LINK_DOWNLOAD_AS_ZIP": "Descargar todo (archivo ZIP)",
"SPAM_SCORE": "Puntuación de spam"
"SPAM_SCORE": "Puntuación de spam",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Acuse de recibo (se visualiza) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "Message signé par OpenPGP (cliquer pour vérifier)",
"PGP_ENCRYPTED_MESSAGE_DESC": "Message chiffré par OpenPGP (cliquer pour déchiffrer)",
"LINK_DOWNLOAD_AS_ZIP": "Télécharger le zip",
"SPAM_SCORE": "Score de spam"
"SPAM_SCORE": "Score de spam",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Accusé de réception (affiché) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP aláírt üzenet (kattints az ellenőrzéshez)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP kódolt üzenet (kattints a visszafejtéshez)",
"LINK_DOWNLOAD_AS_ZIP": "Letöltés zip fájlként",
"SPAM_SCORE": "Spam Score"
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Visszaigazolás (megjelenítve) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP ondertekend bericht (klik om te verifiëren)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP versleuteld bericht (klik om te ontsleutelen)",
"LINK_DOWNLOAD_AS_ZIP": "Download als zip",
"SPAM_SCORE": "Spamscore"
"SPAM_SCORE": "Spamscore",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Ontvangstbevestiging (weergegeven) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signerat meddelande (klicka för att verifiera)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-krypterat meddelande (klicka för att dekryptera)",
"LINK_DOWNLOAD_AS_ZIP": "Ladda ner som ZIP-fil",
"SPAM_SCORE": "Spam Score"
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "Mottagar kvitto (visad) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "由 OpenPGP 签名 (点击验证)",
"PGP_ENCRYPTED_MESSAGE_DESC": "由 OpenPGP 加密 (点击解密)",
"LINK_DOWNLOAD_AS_ZIP": "下载为zip压缩包",
"SPAM_SCORE": "垃圾邮件分数"
"SPAM_SCORE": "垃圾邮件分数",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
},
"READ_RECEIPT": {
"SUBJECT": "送达回执 - %SUBJECT%",

View file

@ -193,12 +193,10 @@
<span data-bind="text: viewCc"></span>
</div>
</div>
<!--
<div class="informationShort">
<div class="informationShort" data-bind="visible: viewSpamStatus()">
<span data-i18n="MESSAGE/SPAM_SCORE"></span>:&nbsp;
<meter min="0" max="100" optimum="0" low="33" high="66" data-bind="value: viewSpamScore, title: viewSpamStatus"></meter>
</div>
-->
</div>
<div class="informationFull" data-bind="visible: showFullInfo()">
<table>
@ -245,8 +243,9 @@
</tr>
</table>
</div>
<div class="hasVirus" data-bind="visible: hasVirus()" data-i18n="MESSAGE/HAS_VIRUS_WARNING"></div>
</div>
<div class="messageItem fixIndex" data-bind="css: viewLineAsCss(), attr: {'style': 'top:' + viewBodyTopValue() + 'px' }">
<div class="messageItem" data-bind="css: viewLineAsCss(), attr: {'style': 'top:' + viewBodyTopValue() + 'px' }">
<div tabindex="0" data-bind="hasfocus: messageDomFocused">
<div>