diff --git a/web/src/app.css b/web/src/app.css index ddae5b6..1472994 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -74,14 +74,21 @@ body { /* Custom card styling */ .card { - border: none; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: transform 0.2s ease, box-shadow 0.2s ease; } -.card:hover { +.card:not(.fade-in .card) { + border: none; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.fade-in .card:not(.card .card) { + border: none; +} + +.card:hover:not(.fade-in .card) { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); } diff --git a/web/src/lib/components/AuthenticationCard.svelte b/web/src/lib/components/AuthenticationCard.svelte index 13ae525..b44c102 100644 --- a/web/src/lib/components/AuthenticationCard.svelte +++ b/web/src/lib/components/AuthenticationCard.svelte @@ -72,10 +72,9 @@ -
-
+
-
+
{#if authentication.spf} @@ -108,7 +107,7 @@
-
+
{#if authentication.dkim && authentication.dkim.length > 0} @@ -147,7 +146,7 @@
-
+
{#if authentication.dmarc} @@ -200,7 +199,7 @@
-
+
{#if authentication.bimi && authentication.bimi.result != "none"} @@ -240,7 +239,7 @@ {#if authentication.arc} -
+
@@ -258,6 +257,5 @@
{/if} -
diff --git a/web/src/lib/components/BlacklistCard.svelte b/web/src/lib/components/BlacklistCard.svelte index 94ff2b8..1e5fd2a 100644 --- a/web/src/lib/components/BlacklistCard.svelte +++ b/web/src/lib/components/BlacklistCard.svelte @@ -35,32 +35,24 @@
{#each Object.entries(blacklists) as [ip, checks]}
-
+
{ip} -
-
- - + +
+ + {#each checks as check} - - + + - - - {#each checks as check} - - - - - {/each} - -
RBLStatus + + {check.error ? 'Error' : (check.listed ? 'Listed' : 'Clean')} + + {check.rbl}
{check.rbl} - - {check.error ? 'Error' : (check.listed ? 'Listed' : 'Clean')} - -
-
+ {/each} + +
{/each}
diff --git a/web/src/lib/components/DnsRecordsCard.svelte b/web/src/lib/components/DnsRecordsCard.svelte index 0a4c0f8..884d2c4 100644 --- a/web/src/lib/components/DnsRecordsCard.svelte +++ b/web/src/lib/components/DnsRecordsCard.svelte @@ -48,8 +48,10 @@ {/if} -
- Return-Path Domain: {dnsResults.rp_domain || dnsResults.from_domain} +
+

+ Return-Path Domain: {dnsResults.rp_domain || dnsResults.from_domain} +

{#if dnsResults.rp_domain && dnsResults.rp_domain !== dnsResults.from_domain} Different from From domain @@ -64,6 +66,7 @@ {#if dnsResults.rp_mx_records && dnsResults.rp_mx_records.length > 0} {#if dnsResults.spf_records && dnsResults.spf_records.length > 0} -
-
- SPF Sender Policy Framework -
-

SPF validates the Return-Path (envelope sender) domain.

- {#each dnsResults.spf_records as spf, index} -
-
+ {@const spfIsValid = dnsResults.spf_records.reduce((acc, r) => acc && r.valid, true)} +
+
+
+ + Sender Policy Framework +
+ SPF +
+
+

SPF specifies which mail servers are authorized to send emails on behalf of your domain. Receiving servers check the sender's IP address against your SPF record to prevent email spoofing.

+
+
+ {#each dnsResults.spf_records as spf, index} +
{#if spf.domain}
Domain: {spf.domain} @@ -109,16 +125,18 @@
{/if}
-
- {/each} + {/each} +
{/if} -
+
-
- From Domain: {dnsResults.from_domain} +
+

+ From Domain: {dnsResults.from_domain} +

{#if dnsResults.rp_domain && dnsResults.rp_domain !== dnsResults.from_domain} Different from Return-Path domain {/if} @@ -127,6 +145,7 @@ {#if dnsResults.from_mx_records && dnsResults.from_mx_records.length > 0} {#if dnsResults.dkim_records && dnsResults.dkim_records.length > 0} -
-
- DKIM DomainKeys Identified Mail -
- {#each dnsResults.dkim_records as dkim} -
-
+ {@const dkimIsValid = dnsResults.dkim_records.reduce((acc, r) => acc && r.valid, true)} +
+
+
+ + DomainKeys Identified Mail +
+ DKIM +
+
+

DKIM cryptographically signs your emails, proving they haven't been tampered with in transit. Receiving servers verify this signature against your DNS records.

+
+
+ {#each dnsResults.dkim_records as dkim} +
Selector: {dkim.selector} Domain: {dkim.domain} @@ -166,59 +199,79 @@
{/if}
-
- {/each} + {/each} +
{/if} {#if dnsResults.dmarc_record} -
-
- DMARC Domain-based Message Authentication -
-
-
-
- Status: - {#if dnsResults.dmarc_record.valid} - Valid - {:else} - Invalid - {/if} -
- {#if dnsResults.dmarc_record.policy} -
- Policy: - - {dnsResults.dmarc_record.policy} - -
- {/if} - {#if dnsResults.dmarc_record.record} -
- Record:
- {dnsResults.dmarc_record.record} -
- {/if} - {#if dnsResults.dmarc_record.error} -
- Error: {dnsResults.dmarc_record.error} -
+
+
+
+ + Domain-based Message Authentication +
+ DMARC +
+
+

DMARC builds on SPF and DKIM by telling receiving servers what to do with emails that fail authentication checks. It also enables reporting so you can monitor your email security.

+
+ Status: + {#if dnsResults.dmarc_record.valid} + Valid + {:else} + Invalid {/if}
+ {#if dnsResults.dmarc_record.policy} +
+ Policy: + + {dnsResults.dmarc_record.policy} + +
+ {/if} + {#if dnsResults.dmarc_record.record} +
+ Record:
+ {dnsResults.dmarc_record.record} +
+ {/if} + {#if dnsResults.dmarc_record.error} +
+ Error: {dnsResults.dmarc_record.error} +
+ {/if}
{/if} {#if dnsResults.bimi_record} -
-
- BIMI Brand Indicators for Message Identification -
+
+
+
+ + Brand Indicators for Message Identification +
+ BIMI +
+

BIMI allows your brand logo to be displayed next to your emails in supported mail clients. Requires strong DMARC enforcement (quarantine or reject policy) and optionally a Verified Mark Certificate (VMC).

Selector: {dnsResults.bimi_record.selector} Domain: {dnsResults.bimi_record.domain} diff --git a/web/src/lib/components/HeaderAnalysisCard.svelte b/web/src/lib/components/HeaderAnalysisCard.svelte index 382da56..9a7857c 100644 --- a/web/src/lib/components/HeaderAnalysisCard.svelte +++ b/web/src/lib/components/HeaderAnalysisCard.svelte @@ -34,7 +34,7 @@
{#if headerAnalysis.issues && headerAnalysis.issues.length > 0}
-
Issues
+
Issues
{#each headerAnalysis.issues as issue}
@@ -56,50 +56,59 @@ {/if} {#if headerAnalysis.domain_alignment} -
-
Domain Alignment
-
-
-
-
- Aligned -
- +
+
+
+ + Domain Alignment +
+
+
+

+ Domain alignment ensures that the visible "From" domain matches the domain used for authentication (Return-Path). Proper alignment is crucial for DMARC compliance and helps prevent email spoofing by verifying that the sender domain is consistent across all authentication layers. +

+
+
+ Aligned +
+ + {headerAnalysis.domain_alignment.aligned ? 'Yes' : 'No'} -
-
-
- From Domain -
{headerAnalysis.domain_alignment.from_domain || '-'}
-
-
- Return-Path Domain -
{headerAnalysis.domain_alignment.return_path_domain || '-'}
+
- {#if headerAnalysis.domain_alignment.issues && headerAnalysis.domain_alignment.issues.length > 0} -
- {#each headerAnalysis.domain_alignment.issues as issue} -
- - {issue} -
- {/each} -
- {/if} +
+ From Domain +
{headerAnalysis.domain_alignment.from_domain || '-'}
+
+
+ Return-Path Domain +
{headerAnalysis.domain_alignment.return_path_domain || '-'}
+
+ {#if headerAnalysis.domain_alignment.issues && headerAnalysis.domain_alignment.issues.length > 0} +
+ {#each headerAnalysis.domain_alignment.issues as issue} +
+ + {issue} +
+ {/each} +
+ {/if}
{/if} {#if headerAnalysis.headers && Object.keys(headerAnalysis.headers).length > 0}
-
Headers
+
Headers
- + + @@ -115,10 +124,12 @@ +
HeaderWhen? Present Valid Value
{name} + {#if check.importance} - + {check.importance} - + {/if} @@ -132,7 +143,7 @@ {/if} - {check.value || '-'} + {check.value || '-'} {#if check.issues && check.issues.length > 0} {#each check.issues as issue}
diff --git a/web/src/lib/components/MxRecordsDisplay.svelte b/web/src/lib/components/MxRecordsDisplay.svelte index 55fd7df..c739c5d 100644 --- a/web/src/lib/components/MxRecordsDisplay.svelte +++ b/web/src/lib/components/MxRecordsDisplay.svelte @@ -1,49 +1,54 @@ -
-
- MX {title} -
- {#if description} -

{description}

- {/if} -
- - - - - - - - - - {#each mxRecords as mx} - - - - - - {/each} - -
PriorityHostStatus
{mx.priority}{mx.host} - {#if mx.valid} - Valid - {:else} - Invalid - {#if mx.error} -
{mx.error} - {/if} - {/if} -
+
+
+
+ + {title} +
+ MX +
+
+ {#if description} +

{description}

+ {/if} +
+
+ {#each mxRecords as mx} +
+
+ {#if mx.valid} + Valid + {:else} + Invalid + {/if} +
Host: {mx.host}
+
Priority: {mx.priority}
+
+ {#if mx.error} + {mx.error} + {/if} +
+ {/each}
diff --git a/web/src/lib/components/SpamAssassinCard.svelte b/web/src/lib/components/SpamAssassinCard.svelte index 374a4f7..7a588f0 100644 --- a/web/src/lib/components/SpamAssassinCard.svelte +++ b/web/src/lib/components/SpamAssassinCard.svelte @@ -12,7 +12,7 @@ let { spamassassin, spamGrade, spamScore }: Props = $props(); -
+