Add a score to DNS
This commit is contained in:
parent
fdb43533cd
commit
abfd1f0155
6 changed files with 143 additions and 5 deletions
|
|
@ -296,12 +296,19 @@ components:
|
|||
ScoreSummary:
|
||||
type: object
|
||||
required:
|
||||
- dns_score
|
||||
- authentication_score
|
||||
- spam_score
|
||||
- blacklist_score
|
||||
- content_score
|
||||
- header_score
|
||||
properties:
|
||||
dns_score:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: DNS records score (in percentage)
|
||||
example: 42
|
||||
authentication_score:
|
||||
type: integer
|
||||
minimum: 0
|
||||
|
|
|
|||
|
|
@ -441,3 +441,103 @@ func (d *DNSAnalyzer) validateBIMI(record string) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
// CalculateDNSScore calculates the DNS score from records results
|
||||
// Returns a score from 0-100 where higher is better
|
||||
func (d *DNSAnalyzer) CalculateDNSScore(results *api.DNSResults) int {
|
||||
if results == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
score := 0
|
||||
|
||||
// TODO: 20 points for correct PTR and A/AAAA
|
||||
|
||||
// MX Records: 20 points
|
||||
// Having valid MX records is critical for email deliverability
|
||||
if results.MxRecords != nil && len(*results.MxRecords) > 0 {
|
||||
hasValidMX := false
|
||||
for _, mx := range *results.MxRecords {
|
||||
if mx.Valid {
|
||||
hasValidMX = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasValidMX {
|
||||
score += 20
|
||||
}
|
||||
}
|
||||
|
||||
// SPF Record: 20 points
|
||||
// SPF is essential for email authentication
|
||||
if results.SpfRecord != nil {
|
||||
if results.SpfRecord.Valid {
|
||||
score += 20
|
||||
} else if results.SpfRecord.Record != nil {
|
||||
// Partial credit if SPF record exists but has issues
|
||||
score += 5
|
||||
}
|
||||
}
|
||||
|
||||
// DKIM Records: 20 points
|
||||
// DKIM provides strong email authentication
|
||||
if results.DkimRecords != nil && len(*results.DkimRecords) > 0 {
|
||||
hasValidDKIM := false
|
||||
for _, dkim := range *results.DkimRecords {
|
||||
if dkim.Valid {
|
||||
hasValidDKIM = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasValidDKIM {
|
||||
score += 20
|
||||
} else {
|
||||
// Partial credit if DKIM record exists but has issues
|
||||
score += 5
|
||||
}
|
||||
}
|
||||
|
||||
// DMARC Record: 20 points
|
||||
// DMARC ties SPF and DKIM together and provides policy
|
||||
if results.DmarcRecord != nil {
|
||||
if results.DmarcRecord.Valid {
|
||||
score += 15
|
||||
// Bonus points for stricter policies
|
||||
if results.DmarcRecord.Policy != nil {
|
||||
switch *results.DmarcRecord.Policy {
|
||||
case "reject":
|
||||
// Strictest policy - full points already awarded
|
||||
score += 5
|
||||
case "quarantine":
|
||||
// Good policy - no deduction
|
||||
case "none":
|
||||
// Weakest policy - deduct 5 points
|
||||
score -= 5
|
||||
}
|
||||
}
|
||||
} else if results.DmarcRecord.Record != nil {
|
||||
// Partial credit if DMARC record exists but has issues
|
||||
score += 5
|
||||
}
|
||||
}
|
||||
|
||||
// BIMI Record: 5 bonus points
|
||||
// BIMI is optional but indicates advanced email branding
|
||||
if results.BimiRecord != nil && results.BimiRecord.Valid {
|
||||
if score >= 100 {
|
||||
return 100
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure score doesn't exceed maximum
|
||||
if score > 100 {
|
||||
score = 100
|
||||
}
|
||||
|
||||
// Ensure score is non-negative
|
||||
if score < 0 {
|
||||
score = 0
|
||||
}
|
||||
|
||||
return score
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ func (r *ReportGenerator) GenerateReport(testID uuid.UUID, results *AnalysisResu
|
|||
}
|
||||
|
||||
// Calculate scores directly from analyzers (no more checks array)
|
||||
dnsScore := 0
|
||||
if results.DNS != nil {
|
||||
dnsScore = r.dnsAnalyzer.CalculateDNSScore(results.DNS)
|
||||
}
|
||||
|
||||
authScore := 0
|
||||
if results.Authentication != nil {
|
||||
authScore = r.authAnalyzer.CalculateAuthenticationScore(results.Authentication)
|
||||
|
|
@ -121,6 +126,7 @@ func (r *ReportGenerator) GenerateReport(testID uuid.UUID, results *AnalysisResu
|
|||
}
|
||||
|
||||
report.Summary = &api.ScoreSummary{
|
||||
DnsScore: dnsScore,
|
||||
AuthenticationScore: authScore,
|
||||
BlacklistScore: blacklistScore,
|
||||
ContentScore: contentScore,
|
||||
|
|
|
|||
|
|
@ -3,16 +3,24 @@
|
|||
|
||||
interface Props {
|
||||
dnsResults?: DNSResults;
|
||||
dnsScore?: number;
|
||||
}
|
||||
|
||||
let { dnsResults }: Props = $props();
|
||||
let { dnsResults, dnsScore }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h4 class="mb-0">
|
||||
<i class="bi bi-diagram-3 me-2"></i>
|
||||
DNS Records
|
||||
<h4 class="mb-0 d-flex justify-content-between align-items-center">
|
||||
<span>
|
||||
<i class="bi bi-diagram-3 me-2"></i>
|
||||
DNS Records
|
||||
</span>
|
||||
{#if dnsScore !== undefined}
|
||||
<span class="badge bg-secondary">
|
||||
{dnsScore}%
|
||||
</span>
|
||||
{/if}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
|
|
|||
|
|
@ -36,6 +36,20 @@
|
|||
|
||||
{#if summary}
|
||||
<div class="row g-3 text-start">
|
||||
<div class="col-md-6 col-lg">
|
||||
<div class="p-2 bg-light rounded text-center">
|
||||
<strong
|
||||
class="fs-2"
|
||||
class:text-success={summary.dns_score >= 100}
|
||||
class:text-warning={summary.dns_score < 100 &&
|
||||
summary.dns_score >= 50}
|
||||
class:text-danger={summary.dns_score < 50}
|
||||
>
|
||||
{summary.dns_score}%
|
||||
</strong>
|
||||
<small class="text-muted d-block">DNS</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg">
|
||||
<div class="p-2 bg-light rounded text-center">
|
||||
<strong
|
||||
|
|
|
|||
|
|
@ -148,7 +148,10 @@
|
|||
{#if report.dns_results}
|
||||
<div class="row mb-4" id="dns">
|
||||
<div class="col-12">
|
||||
<DnsRecordsCard dnsResults={report.dns_results} />
|
||||
<DnsRecordsCard
|
||||
dnsResults={report.dns_results}
|
||||
dnsScore={report.summary?.dns_score}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue