From a6448a1533bb1523abc75a36daf9bbca9fa3b577 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 23 Oct 2025 12:36:28 +0700 Subject: [PATCH] Split DnsRecordsCard in several components --- .../lib/components/BimiRecordDisplay.svelte | 77 ++++++++ .../lib/components/DkimRecordsDisplay.svelte | 64 +++++++ .../lib/components/DmarcRecordDisplay.svelte | 127 ++++++++++---- web/src/lib/components/DnsRecordsCard.svelte | 166 +----------------- .../lib/components/MxRecordsDisplay.svelte | 2 +- .../lib/components/SpfRecordsDisplay.svelte | 69 ++++++++ 6 files changed, 310 insertions(+), 195 deletions(-) create mode 100644 web/src/lib/components/BimiRecordDisplay.svelte create mode 100644 web/src/lib/components/DkimRecordsDisplay.svelte create mode 100644 web/src/lib/components/SpfRecordsDisplay.svelte diff --git a/web/src/lib/components/BimiRecordDisplay.svelte b/web/src/lib/components/BimiRecordDisplay.svelte new file mode 100644 index 0000000..0d7a1b9 --- /dev/null +++ b/web/src/lib/components/BimiRecordDisplay.svelte @@ -0,0 +1,77 @@ + + +{#if bimiRecord} +
+
+
+ + 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: {bimiRecord.selector} + Domain: {bimiRecord.domain} +
+
+ Status: + {#if bimiRecord.valid} + Valid + {:else} + Invalid + {/if} +
+ {#if bimiRecord.logo_url} +
+ Logo URL: + {bimiRecord.logo_url} +
+ {/if} + {#if bimiRecord.vmc_url} +
+ VMC URL: + {bimiRecord.vmc_url} +
+ {/if} + {#if bimiRecord.record} +
+ Record:
+ {bimiRecord.record} +
+ {/if} + {#if bimiRecord.error} +
+ Error: + {bimiRecord.error} +
+ {/if} +
+
+{/if} diff --git a/web/src/lib/components/DkimRecordsDisplay.svelte b/web/src/lib/components/DkimRecordsDisplay.svelte new file mode 100644 index 0000000..45c67b3 --- /dev/null +++ b/web/src/lib/components/DkimRecordsDisplay.svelte @@ -0,0 +1,64 @@ + + +{#if dkimRecords && dkimRecords.length > 0} +
+
+
+ + 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 dkimRecords as dkim} +
+
+ Selector: {dkim.selector} + Domain: {dkim.domain} +
+
+ Status: + {#if dkim.valid} + Valid + {:else} + Invalid + {/if} +
+ {#if dkim.record} +
+ Record:
+ {dkim.record} +
+ {/if} + {#if dkim.error} +
+ Error: {dkim.error} +
+ {/if} +
+ {/each} +
+
+{/if} diff --git a/web/src/lib/components/DmarcRecordDisplay.svelte b/web/src/lib/components/DmarcRecordDisplay.svelte index 30cddeb..4d4cad3 100644 --- a/web/src/lib/components/DmarcRecordDisplay.svelte +++ b/web/src/lib/components/DmarcRecordDisplay.svelte @@ -10,7 +10,7 @@ // Helper function to determine policy strength const policyStrength = (policy: string | undefined): number => { const strength: Record = { none: 0, quarantine: 1, reject: 2 }; - return strength[policy || 'none'] || 0; + return strength[policy || "none"] || 0; }; @@ -22,7 +22,8 @@ class="bi" class:bi-check-circle-fill={dmarcRecord.valid && dmarcRecord.policy != "none"} class:text-success={dmarcRecord.valid && dmarcRecord.policy != "none"} - class:bi-arrow-up-circle-fill={dmarcRecord.valid && dmarcRecord.policy == "none"} + class:bi-arrow-up-circle-fill={dmarcRecord.valid && + dmarcRecord.policy == "none"} class:text-warning={dmarcRecord.valid && dmarcRecord.policy == "none"} class:bi-x-circle-fill={!dmarcRecord.valid} class:text-danger={!dmarcRecord.valid} @@ -32,7 +33,13 @@ 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.

+

+ 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. +

+ +
@@ -48,32 +55,44 @@ {#if dmarcRecord.policy}
Policy: - + {dmarcRecord.policy} - {#if dmarcRecord.policy === 'reject'} + {#if dmarcRecord.policy === "reject"}
- Maximum protection — emails failing DMARC checks are rejected. This provides the strongest defense against spoofing and phishing. + Maximum protection — emails failing DMARC checks are rejected. + This provides the strongest defense against spoofing and phishing.
- {:else if dmarcRecord.policy === 'quarantine'} + {:else if dmarcRecord.policy === "quarantine"}
- Good protection — emails failing DMARC checks are quarantined (sent to spam). This is a safe middle ground.
+ Good protection — emails failing DMARC checks are + quarantined (sent to spam). This is a safe middle ground.
- Once you've validated your configuration and ensured all legitimate mail passes, consider upgrading to p=reject for maximum protection. + Once you've validated your configuration and ensured all legitimate mail + passes, consider upgrading to p=reject for maximum protection.
- {:else if dmarcRecord.policy === 'none'} + {:else if dmarcRecord.policy === "none"}
- Monitoring only — emails failing DMARC are delivered normally. This is only recommended during initial setup.
+ Monitoring only — emails failing DMARC are delivered + normally. This is only recommended during initial setup.
- After monitoring reports, upgrade to p=quarantine or p=reject to actively protect your domain. + After monitoring reports, upgrade to p=quarantine or + p=reject to actively protect your domain.
{:else}
- Unknown policy — the policy value is not recognized. Valid options are: none, quarantine, or reject. + Unknown policy — the policy value is not recognized. Valid + options are: none, quarantine, or reject.
{/if}
@@ -85,18 +104,27 @@ {@const subStrength = policyStrength(dmarcRecord.subdomain_policy)}
Subdomain Policy: - + {dmarcRecord.subdomain_policy} {#if subStrength >= mainStrength}
- Good configuration — subdomain policy is equal to or stricter than main policy. + Good configuration — subdomain policy is equal to or stricter + than main policy.
{:else}
- Weaker subdomain protection — consider setting sp={dmarcRecord.policy} to match your main policy for consistent protection. + Weaker subdomain protection — consider setting + sp={dmarcRecord.policy} to match your main policy for consistent + protection.
{/if}
@@ -106,7 +134,9 @@ Inherits main policy
- Good default — subdomains inherit the main policy ({dmarcRecord.policy}) which provides consistent protection. + Good default — subdomains inherit the main policy ({dmarcRecord.policy}) which provides consistent protection.
{/if} @@ -115,23 +145,34 @@ {#if dmarcRecord.percentage !== undefined}
Enforcement Percentage: - + {dmarcRecord.percentage}% {#if dmarcRecord.percentage === 100}
- Full enforcement — all messages are subject to DMARC policy. This provides maximum protection. + Full enforcement — all messages are subject to DMARC policy. + This provides maximum protection.
{:else if dmarcRecord.percentage >= 50}
- Partial enforcement — only {dmarcRecord.percentage}% of messages are subject to DMARC policy. Consider increasing to pct=100 once you've validated your configuration. + Partial enforcement — only {dmarcRecord.percentage}% of + messages are subject to DMARC policy. Consider increasing to + pct=100 once you've validated your configuration.
{:else}
- Low enforcement — only {dmarcRecord.percentage}% of messages are protected. Gradually increase to pct=100 for full protection. + Low enforcement — only {dmarcRecord.percentage}% of + messages are protected. Gradually increase to pct=100 for full + protection.
{/if}
@@ -141,7 +182,8 @@ 100% (default)
- Full enforcement — all messages are subject to DMARC policy by default. + Full enforcement — all messages are subject to DMARC policy + by default.
{/if} @@ -150,20 +192,28 @@ {#if dmarcRecord.spf_alignment}
SPF Alignment: - + {dmarcRecord.spf_alignment} - {#if dmarcRecord.spf_alignment === 'relaxed'} + {#if dmarcRecord.spf_alignment === "relaxed"}
- Recommended for most senders — ensures legitimate subdomain mail passes.
+ Recommended for most senders — ensures legitimate + subdomain mail passes.
- For maximum brand protection, consider strict alignment (aspf=s) once your sending domains are standardized. + For maximum brand protection, consider strict alignment (aspf=s) once your sending domains are standardized.
{:else}
- Maximum brand protection — only exact domain matches are accepted. Ensure all legitimate mail comes from the exact From domain. + Maximum brand protection — only exact domain matches are + accepted. Ensure all legitimate mail comes from the exact From domain.
{/if}
@@ -173,20 +223,28 @@ {#if dmarcRecord.dkim_alignment}
DKIM Alignment: - + {dmarcRecord.dkim_alignment} - {#if dmarcRecord.dkim_alignment === 'relaxed'} + {#if dmarcRecord.dkim_alignment === "relaxed"}
- Recommended for most senders — ensures legitimate subdomain mail passes.
+ Recommended for most senders — ensures legitimate + subdomain mail passes.
- For maximum brand protection, consider strict alignment (adkim=s) once your sending domains are standardized. + For maximum brand protection, consider strict alignment (adkim=s) once your sending domains are standardized.
{:else}
- Maximum brand protection — only exact domain matches are accepted. Ensure all DKIM signatures use the exact From domain. + Maximum brand protection — only exact domain matches are + accepted. Ensure all DKIM signatures use the exact From domain.
{/if}
@@ -195,7 +253,7 @@ {#if dmarcRecord.record}
- Record:
+ Record:
{dmarcRecord.record}
{/if} @@ -203,7 +261,8 @@ {#if dmarcRecord.error}
- Error: {dmarcRecord.error} + Error: + {dmarcRecord.error}
{/if} diff --git a/web/src/lib/components/DnsRecordsCard.svelte b/web/src/lib/components/DnsRecordsCard.svelte index 4984f61..a1ee24d 100644 --- a/web/src/lib/components/DnsRecordsCard.svelte +++ b/web/src/lib/components/DnsRecordsCard.svelte @@ -3,7 +3,10 @@ import { getScoreColorClass } from "$lib/score"; import GradeDisplay from "./GradeDisplay.svelte"; import MxRecordsDisplay from "./MxRecordsDisplay.svelte"; + import SpfRecordsDisplay from "./SpfRecordsDisplay.svelte"; + import DkimRecordsDisplay from "./DkimRecordsDisplay.svelte"; import DmarcRecordDisplay from "./DmarcRecordDisplay.svelte"; + import BimiRecordDisplay from "./BimiRecordDisplay.svelte"; interface Props { dnsResults?: DNSResults; @@ -75,61 +78,7 @@ {/if} - {#if dnsResults.spf_records && dnsResults.spf_records.length > 0} - {@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} - {#if index > 0} - Included - {/if} -
- {/if} -
- Status: - {#if spf.valid} - Valid - {:else} - Invalid - {/if} -
- {#if spf.record} -
- Record:
- {spf.record} -
- {/if} - {#if spf.error} -
- - {spf.valid ? 'Warning:' : 'Error:'} {spf.error} -
- {/if} -
- {/each} -
-
- {/if} +
@@ -154,116 +103,13 @@ {/if} - {#if dnsResults.dkim_records && dnsResults.dkim_records.length > 0} - {@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} -
-
- Status: - {#if dkim.valid} - Valid - {:else} - Invalid - {/if} -
- {#if dkim.record} -
- Record:
- {dkim.record} -
- {/if} - {#if dkim.error} -
- Error: {dkim.error} -
- {/if} -
- {/each} -
-
- {/if} + - {#if dnsResults.bimi_record} -
-
-
- - 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} -
-
- Status: - {#if dnsResults.bimi_record.valid} - Valid - {:else} - Invalid - {/if} -
- {#if dnsResults.bimi_record.logo_url} - - {/if} - {#if dnsResults.bimi_record.vmc_url} - - {/if} - {#if dnsResults.bimi_record.record} -
- Record:
- {dnsResults.bimi_record.record} -
- {/if} - {#if dnsResults.bimi_record.error} -
- Error: {dnsResults.bimi_record.error} -
- {/if} -
-
-
- {/if} + {/if} diff --git a/web/src/lib/components/MxRecordsDisplay.svelte b/web/src/lib/components/MxRecordsDisplay.svelte index c739c5d..f0a8088 100644 --- a/web/src/lib/components/MxRecordsDisplay.svelte +++ b/web/src/lib/components/MxRecordsDisplay.svelte @@ -28,7 +28,7 @@ MX -
+
{#if description}

{description}

{/if} diff --git a/web/src/lib/components/SpfRecordsDisplay.svelte b/web/src/lib/components/SpfRecordsDisplay.svelte new file mode 100644 index 0000000..172e9f7 --- /dev/null +++ b/web/src/lib/components/SpfRecordsDisplay.svelte @@ -0,0 +1,69 @@ + + +{#if spfRecords && spfRecords.length > 0} +
+
+
+ + 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 spfRecords as spf, index} +
+ {#if spf.domain} +
+ Domain: {spf.domain} + {#if index > 0} + Included + {/if} +
+ {/if} +
+ Status: + {#if spf.valid} + Valid + {:else} + Invalid + {/if} +
+ {#if spf.record} +
+ Record:
+ {spf.record} +
+ {/if} + {#if spf.error} +
+ + {spf.valid ? 'Warning:' : 'Error:'} {spf.error} +
+ {/if} +
+ {/each} +
+
+{/if}