feat(bimi): reconcile the BIMI record to Cloudflare and keep it in step with the logo

The reconciler never wrote the BIMI record: only the console's verification
knew about it, so a stored logo was never published to the zone.

- SyncDnsRecordsInput carries the BIMI logo and certificate URLs; the record is
  created, updated (a= added or dropped) and, when the logo is removed,
  deleted. Only a record carrying this reconciler's comment is retired: one
  made by hand is left alone
- bimi.Publish decides the record in one place for the timer sweep, the
  console's button and the panel's verification. A held certificate is
  advertised only while it is valid for the logo being served: replacing the
  logo ends the certificate, and a record that kept naming it makes every
  receiver reject BIMI, including those that need no certificate
- saving or removing the logo or the certificate triggers the reconciliation in
  the background; the panel shows the record as the server writes it, says when
  a certificate is held back and why, and has a publish-now button
- a read error is not 'no logo': the sync leaves the record alone instead of
  deleting it over a database hiccup

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-10-16 18:17:07 -03:00
1 parent 0ff9028927
commit 6e49ca00e2
17 files changed
+641 -59

No files matched your search

@@ -207,14 +207,10 @@ func BuildDnsRecordSpecs(spec DnsRecordSpec) []DnsRecord {
// BIMI, published only when there is a logo to point at.
if spec.BimiLogoURL != "" {
value := fmt.Sprintf("v=BIMI1; l=%s;", spec.BimiLogoURL)
if spec.BimiVmcURL != "" {
value = fmt.Sprintf("v=BIMI1; l=%s; a=%s;", spec.BimiLogoURL, spec.BimiVmcURL)
}
records = append(records, DnsRecord{
Type: "TXT",
Name: fmt.Sprintf("default._bimi.%s", domainName),
Value: value,
Value: BimiRecordValue(spec.BimiLogoURL, spec.BimiVmcURL),
TTL: 1,
Comment: "LambdaMail BIMI Record",
})
@@ -316,3 +312,15 @@ func hostInsideDomain(host, domain string) bool {
// inside "example.test".
return host == domain || strings.HasSuffix(host, "."+domain)
}
// BimiRecordValue is the text of a domain's BIMI TXT record. The reconciler
// writes it and the console shows it, so both come from here.
func BimiRecordValue(logoURL, certificateURL string) string {
if logoURL == "" {
return ""
}
if certificateURL != "" {
return fmt.Sprintf("v=BIMI1; l=%s; a=%s;", logoURL, certificateURL)
}
return fmt.Sprintf("v=BIMI1; l=%s;", logoURL)
}