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

View file

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

View file

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

View file

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

View file

@ -18,69 +18,74 @@ namespace MailSo\Mime\Enumerations;
*/ */
abstract class Header abstract class Header
{ {
const DATE = 'Date'; const
const RECEIVED = 'Received'; DATE = 'Date',
RECEIVED = 'Received',
const SUBJECT = 'Subject'; SUBJECT = 'Subject',
const TO_ = 'To'; TO_ = 'To',
const FROM_ = 'From'; FROM_ = 'From',
const CC = 'Cc'; CC = 'Cc',
const BCC = 'Bcc'; BCC = 'Bcc',
const REPLY_TO = 'Reply-To'; REPLY_TO = 'Reply-To',
const SENDER = 'Sender'; SENDER = 'Sender',
const RETURN_PATH = 'Return-Path'; RETURN_PATH = 'Return-Path',
const DELIVERED_TO = 'Delivered-To'; DELIVERED_TO = 'Delivered-To',
const MESSAGE_ID = 'Message-ID'; MESSAGE_ID = 'Message-ID',
const IN_REPLY_TO = 'In-Reply-To'; IN_REPLY_TO = 'In-Reply-To',
const REFERENCES = 'References'; REFERENCES = 'References',
const X_DRAFT_INFO = 'X-Draft-Info'; X_DRAFT_INFO = 'X-Draft-Info',
const X_ORIGINATING_IP = 'X-Originating-IP'; X_ORIGINATING_IP = 'X-Originating-IP',
const CONTENT_TYPE = 'Content-Type'; CONTENT_TYPE = 'Content-Type',
const CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding'; CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding',
const CONTENT_DISPOSITION = 'Content-Disposition'; CONTENT_DISPOSITION = 'Content-Disposition',
const CONTENT_DESCRIPTION = 'Content-Description'; CONTENT_DESCRIPTION = 'Content-Description',
const CONTENT_ID = 'Content-ID'; CONTENT_ID = 'Content-ID',
const CONTENT_LOCATION = 'Content-Location'; CONTENT_LOCATION = 'Content-Location',
const SENSITIVITY = 'Sensitivity'; SENSITIVITY = 'Sensitivity',
const RECEIVED_SPF = 'Received-SPF'; RECEIVED_SPF = 'Received-SPF',
const AUTHENTICATION_RESULTS = 'Authentication-Results'; AUTHENTICATION_RESULTS = 'Authentication-Results',
const X_DKIM_AUTHENTICATION_RESULTS = 'X-DKIM-Authentication-Results'; X_DKIM_AUTHENTICATION_RESULTS = 'X-DKIM-Authentication-Results',
const DKIM_SIGNATURE = 'DKIM-Signature'; DKIM_SIGNATURE = 'DKIM-Signature',
const DOMAINKEY_SIGNATURE = 'DomainKey-Signature'; DOMAINKEY_SIGNATURE = 'DomainKey-Signature',
// SpamAssassin // SpamAssassin
const X_SPAM_FLAG = 'X-Spam-Flag'; // YES/NO X_SPAM_FLAG = 'X-Spam-Flag', // YES/NO
const X_SPAM_LEVEL = 'X-Spam-Level'; // ******* X_SPAM_LEVEL = 'X-Spam-Level', // *******
const X_SPAM_STATUS = 'X-Spam-Status'; // Yes|No X_SPAM_STATUS = 'X-Spam-Status', // Yes|No
// Rspamd // Rspamd
const X_SPAMD_RESULT = 'X-Spamd-Result'; // default: False [7.13 / 9.00]; X_SPAMD_RESULT = 'X-Spamd-Result', // default: False [7.13 / 9.00],
const X_SPAMD_BAR = 'X-Spamd-Bar'; // +++++++ X_SPAMD_BAR = 'X-Spamd-Bar', // +++++++
// Bogofilter // Bogofilter
const X_BOGOSITY = 'X-Bogosity'; X_BOGOSITY = 'X-Bogosity',
// Unknown // Unknown
const X_SPAM_CATEGORY = 'X-Spam-Category'; // SPAM|LEGIT X_SPAM_CATEGORY = 'X-Spam-Category', // SPAM|LEGIT
const X_SPAM_SCORE = 'X-Spam-Score'; // 0 X_SPAM_SCORE = 'X-Spam-Score', // 0
const X_HAM_REPORT = 'X-Ham-Report'; X_HAM_REPORT = 'X-Ham-Report',
const X_MICROSOFT_ANTISPAM = 'x-microsoft-antispam:'; 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'; RETURN_RECEIPT_TO = 'Return-Receipt-To',
const DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To'; DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To',
const X_CONFIRM_READING_TO = 'X-Confirm-Reading-To'; X_CONFIRM_READING_TO = 'X-Confirm-Reading-To',
const MIME_VERSION = 'MIME-Version'; MIME_VERSION = 'MIME-Version',
const X_MAILER = 'X-Mailer'; X_MAILER = 'X-Mailer',
const X_MSMAIL_PRIORITY = 'X-MSMail-Priority'; X_MSMAIL_PRIORITY = 'X-MSMail-Priority',
const IMPORTANCE = 'Importance'; IMPORTANCE = 'Importance',
const X_PRIORITY = 'X-Priority'; 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_SIGNED_MESSAGE_DESC": "OpenPGP-signierte Nachricht (klicken, um zu überprüfen)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)", "PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)",
"LINK_DOWNLOAD_AS_ZIP": "Als ZIP-Datei herunterladen", "LINK_DOWNLOAD_AS_ZIP": "Als ZIP-Datei herunterladen",
"SPAM_SCORE": "Spam-Score" "SPAM_SCORE": "Spam-Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
}, },
"READ_RECEIPT": { "READ_RECEIPT": {
"SUBJECT": "Empfangsbestätigung (angezeigt) - %SUBJECT%", "SUBJECT": "Empfangsbestätigung (angezeigt) - %SUBJECT%",

View file

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

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "Mensaje firmado mediante OpenPGP (click para verificar)", "PGP_SIGNED_MESSAGE_DESC": "Mensaje firmado mediante OpenPGP (click para verificar)",
"PGP_ENCRYPTED_MESSAGE_DESC": "Mensaje cifrado mediante OpenPGP (click para desencriptar)", "PGP_ENCRYPTED_MESSAGE_DESC": "Mensaje cifrado mediante OpenPGP (click para desencriptar)",
"LINK_DOWNLOAD_AS_ZIP": "Descargar todo (archivo ZIP)", "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": { "READ_RECEIPT": {
"SUBJECT": "Acuse de recibo (se visualiza) - %SUBJECT%", "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_SIGNED_MESSAGE_DESC": "Message signé par OpenPGP (cliquer pour vérifier)",
"PGP_ENCRYPTED_MESSAGE_DESC": "Message chiffré par OpenPGP (cliquer pour déchiffrer)", "PGP_ENCRYPTED_MESSAGE_DESC": "Message chiffré par OpenPGP (cliquer pour déchiffrer)",
"LINK_DOWNLOAD_AS_ZIP": "Télécharger le zip", "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": { "READ_RECEIPT": {
"SUBJECT": "Accusé de réception (affiché) - %SUBJECT%", "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_SIGNED_MESSAGE_DESC": "OpenPGP aláírt üzenet (kattints az ellenőrzéshez)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP kódolt üzenet (kattints a visszafejtéshez)", "PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP kódolt üzenet (kattints a visszafejtéshez)",
"LINK_DOWNLOAD_AS_ZIP": "Letöltés zip fájlként", "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": { "READ_RECEIPT": {
"SUBJECT": "Visszaigazolás (megjelenítve) - %SUBJECT%", "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_SIGNED_MESSAGE_DESC": "OpenPGP ondertekend bericht (klik om te verifiëren)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP versleuteld bericht (klik om te ontsleutelen)", "PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP versleuteld bericht (klik om te ontsleutelen)",
"LINK_DOWNLOAD_AS_ZIP": "Download als zip", "LINK_DOWNLOAD_AS_ZIP": "Download als zip",
"SPAM_SCORE": "Spamscore" "SPAM_SCORE": "Spamscore",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
}, },
"READ_RECEIPT": { "READ_RECEIPT": {
"SUBJECT": "Ontvangstbevestiging (weergegeven) - %SUBJECT%", "SUBJECT": "Ontvangstbevestiging (weergegeven) - %SUBJECT%",

View file

@ -145,7 +145,8 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signerat meddelande (klicka för att verifiera)", "PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signerat meddelande (klicka för att verifiera)",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-krypterat meddelande (klicka för att dekryptera)", "PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-krypterat meddelande (klicka för att dekryptera)",
"LINK_DOWNLOAD_AS_ZIP": "Ladda ner som ZIP-fil", "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": { "READ_RECEIPT": {
"SUBJECT": "Mottagar kvitto (visad) - %SUBJECT%", "SUBJECT": "Mottagar kvitto (visad) - %SUBJECT%",

View file

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

View file

@ -193,12 +193,10 @@
<span data-bind="text: viewCc"></span> <span data-bind="text: viewCc"></span>
</div> </div>
</div> </div>
<!-- <div class="informationShort" data-bind="visible: viewSpamStatus()">
<div class="informationShort">
<span data-i18n="MESSAGE/SPAM_SCORE"></span>:&nbsp; <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> <meter min="0" max="100" optimum="0" low="33" high="66" data-bind="value: viewSpamScore, title: viewSpamStatus"></meter>
</div> </div>
-->
</div> </div>
<div class="informationFull" data-bind="visible: showFullInfo()"> <div class="informationFull" data-bind="visible: showFullInfo()">
<table> <table>
@ -245,8 +243,9 @@
</tr> </tr>
</table> </table>
</div> </div>
<div class="hasVirus" data-bind="visible: hasVirus()" data-i18n="MESSAGE/HAS_VIRUS_WARNING"></div>
</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 tabindex="0" data-bind="hasfocus: messageDomFocused">
<div> <div>