///|
pub fn parse_bimi(text : String) -> BimiRecord {
let raw = clean(text)
let version = tag_value(raw, "v")
let logo_url = tag_value(raw, "l")
let authority_url = tag_value(raw, "a")
let valid_version = lower(version) == "bimi1"
let logo_svg = contains_svg_path(logo_url)
let findings = bimi_findings(
raw, valid_version, version, logo_url, authority_url, logo_svg,
)
{ raw, valid_version, version, logo_url, authority_url, logo_svg, findings }
}
///|
fn bimi_findings(
raw : String,
valid_version : Bool,
version : String,
logo_url : String,
authority_url : String,
logo_svg : Bool,
) -> Array[PolicyFinding] {
let findings = Array::new(capacity=8)
if raw.is_empty() {
findings.push(
warn(
"bimi.record-missing",
"BIMI record is missing",
"BIMI is optional, but useful for brand display readiness.",
"",
"Publish a BIMI record only after DMARC enforcement is ready.",
penalty=2,
),
)
return findings
}
if valid_version {
findings.push(pass("bimi.version", "BIMI version is present", version))
} else {
findings.push(
fail(
"bimi.version-invalid", "BIMI version is invalid", "The v tag must be BIMI1.",
version, "Use v=BIMI1.",
),
)
}
if logo_url.is_empty() {
findings.push(
fail(
"bimi.logo-missing", "BIMI logo URL is missing", "BIMI requires an l tag that points to a logo file.",
"", "Add l=https://example.com/bimi.svg.",
),
)
} else if !starts_with_https_url(logo_url) {
findings.push(
fail(
"bimi.logo-not-https", "BIMI logo URL is not HTTPS", "Mailbox providers expect a secure logo URL.",
logo_url, "Serve the BIMI SVG from an HTTPS URL.",
),
)
} else if !logo_svg {
findings.push(
warn(
"bimi.logo-not-svg", "BIMI logo URL does not look like SVG", "BIMI normally uses a square SVG Tiny profile logo.",
logo_url, "Use an HTTPS URL ending in .svg and validate the SVG profile.",
),
)
} else {
findings.push(pass("bimi.logo", "BIMI logo URL is present", logo_url))
}
if authority_url.is_empty() {
findings.push(
warn(
"bimi.authority-missing",
"BIMI authority URL is missing",
"Some mailbox providers require a verified mark certificate.",
"",
"Add a= with a certificate URL when provider requirements demand it.",
penalty=3,
),
)
} else if !starts_with_https_url(authority_url) {
findings.push(
fail(
"bimi.authority-not-https", "BIMI authority URL is not HTTPS", "Certificate material should be delivered over HTTPS.",
authority_url, "Use an HTTPS authority URL.",
),
)
} else {
findings.push(
pass("bimi.authority", "BIMI authority URL is present", authority_url),
)
}
findings
}
///|
pub fn BimiRecord::is_configured(self : BimiRecord) -> Bool {
!self.raw.is_empty() && self.valid_version && !self.logo_url.is_empty()
}
///|
pub fn BimiRecord::has_authority(self : BimiRecord) -> Bool {
!self.authority_url.is_empty()
}
///|
pub fn BimiRecord::has_https_logo(self : BimiRecord) -> Bool {
starts_with_https_url(self.logo_url)
}