-
Notifications
You must be signed in to change notification settings - Fork 0
fix(cli): surface TLSA for on-chain domains, clearer verify output #669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
6ecb840
bdaf08a
7899820
635040c
58666a9
faa0146
8540cfc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -350,7 +350,7 @@ func websitesActionAdapter(op catalog.Operation) cli.ActionFunc { | |
| // human (non-JSON) output — in --json mode the error document stays machine | ||
| // clean, and it no-ops for every non-verify operation. | ||
| func renderVerifyGuidance(output Output, op catalog.Operation, err error) { | ||
| if op.Name() == "websites_domains_verify" && !output.IsJSON() { | ||
| if op.Name() == catalogops.OpWebsitesDomainsVerify && !output.IsJSON() { | ||
| renderDNSSelfServiceGuidance(output, err) | ||
| } | ||
| } | ||
|
|
@@ -380,7 +380,13 @@ func renderWebsitesResult(_ context.Context, c *cli.Command, op catalog.Operatio | |
| // Slices/maps are excluded — a nil slice legitimately means an empty | ||
| // result set (e.g. `websites domains list` with no domains) and is handled | ||
| // by the renderer's empty-state branches. | ||
| // A verify returning (nil, nil) is meaningful: DNS is not resolvable yet, | ||
| // so render the not-verified outcome rather than bailing out. | ||
| if result != nil && isNilPointerResult(result) { | ||
| if op.Name() == catalogops.OpWebsitesDomainsVerify { | ||
| renderDomainVerifyResult(output, nil) | ||
| return nil | ||
| } | ||
| return fmt.Errorf("%s returned no result", op.Name()) | ||
| } | ||
|
|
||
|
|
@@ -421,6 +427,7 @@ func renderWebsitesResult(_ context.Context, c *cli.Command, op catalog.Operatio | |
| {"Message", r.Message}, | ||
| }, | ||
| }) | ||
| renderValidationChecks(output, r.Checks) | ||
| return nil | ||
|
|
||
| case *ipfs.WebsiteConfigResponse: | ||
|
|
@@ -450,6 +457,20 @@ func renderWebsitesResult(_ context.Context, c *cli.Command, op catalog.Operatio | |
| output.Printfln("Website deleted successfully") | ||
| return nil | ||
|
|
||
| case *catalogops.DomainDNSRequirements: | ||
| // websites domains dns-requirements: the domain response plus the | ||
| // owning website, from which the renderer derives the authoritative | ||
| // records the backend no longer returns for on-chain bindings. | ||
| // --json keeps the historical domain-response shape. | ||
| if r.Domain == nil { | ||
| return fmt.Errorf("no result returned for %s", op.Name()) | ||
| } | ||
| if output.IsJSON() { | ||
| return output.PrintJSON(r.Domain) | ||
| } | ||
| renderDomainDelegation(output, r.Domain, r.Domain.DnsHostingEnabled, r.Website) | ||
| return nil | ||
|
|
||
| case []ipfs.DomainResponse: | ||
| // websites domains list: a website's domain bindings. | ||
| if output.IsJSON() { | ||
|
|
@@ -491,8 +512,8 @@ func renderWebsitesResult(_ context.Context, c *cli.Command, op catalog.Operatio | |
| if output.IsJSON() { | ||
| return output.PrintJSON(r) | ||
| } | ||
| if op.Name() == "websites_domains_dns_requirements" { | ||
| renderDomainDelegation(output, r, r.DnsHostingEnabled) | ||
| if op.Name() == catalogops.OpWebsitesDomainsVerify { | ||
| renderDomainVerifyResult(output, r) | ||
| return nil | ||
| } | ||
| renderDomainResponse(output, r) | ||
|
|
@@ -609,20 +630,21 @@ func renderDomainDANEResponse(output Output, r *ipfs.DomainDANERepublishResponse | |
| if r.OwnerName != nil { | ||
| ownerName = *r.OwnerName | ||
| } | ||
| tlsaRecord := "" | ||
| if r.TlsaRecord != nil { | ||
| tlsaRecord = *r.TlsaRecord | ||
| } | ||
| output.PrintFields(FieldGroup{ | ||
| Fields: []Field{ | ||
| {"ID", fmt.Sprintf("%d", r.Id)}, | ||
| {"Domain", r.Domain}, | ||
| {"Namespace", string(r.Namespace)}, | ||
| {"Status", status}, | ||
| {"Owner Name", ownerName}, | ||
| {"TLSA Record", tlsaRecord}, | ||
| }, | ||
| }) | ||
| fields := []Field{ | ||
| {"ID", fmt.Sprintf("%d", r.Id)}, | ||
| {"Domain", r.Domain}, | ||
| {"Namespace", string(r.Namespace)}, | ||
| {"Status", status}, | ||
| {"Owner Name", ownerName}, | ||
| // published_to_managed_zone is a required field and always echoed; a | ||
| // false value means the republished TLSA is NOT live in the managed | ||
| // zone yet, so the user must not treat the command as a success. | ||
| {"TLSA Published", fmt.Sprintf("%t", r.PublishedToManagedZone)}, | ||
| } | ||
| if r.TlsaRdata != nil && *r.TlsaRdata != "" { | ||
| fields = append(fields, Field{"TLSA Record", *r.TlsaRdata}) | ||
| } | ||
| output.PrintFields(FieldGroup{Fields: fields}) | ||
|
Comment on lines
+639
to
+647
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The renderDomainDANEResponse function silently reports success when published_to_managed_zone is false, contradicting the code's own comment (lines 628-631) that a false value means the TLSA is NOT live. Return an error from the renderer/caller path or propagate failure through the exit code so a failed zone publication exits non-zero. // published_to_managed_zone=false means the TLSA did NOT land in the
// managed zone; surface it as a failure so the command does not exit 0.
fields := []Field{
{"ID", fmt.Sprintf("%d", r.Id)},
{"Domain", r.Domain},
{"Namespace", string(r.Namespace)},
{"Status", status},
{"Owner Name", ownerName},
{"TLSA Published", fmt.Sprintf("%t", r.PublishedToManagedZone)},
}
if r.TlsaRdata != nil && *r.TlsaRdata != "" {
fields = append(fields, Field{"TLSA Record", *r.TlsaRdata})
}
output.PrintFields(FieldGroup{Fields: fields})
if !r.PublishedToManagedZone {
return fmt.Errorf("TLSA was not published to the managed zone")
}
return nil
}Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| } | ||
|
|
||
| // renderWebsiteItemHuman renders the fields of a single website (used by get, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The typed-nil verify branch calls renderDomainVerifyResult(output, nil) without an output.IsJSON() guard, writing human-readable '⏳ not verified yet' text even in --json mode. Under --json, jsonFormatter.Printfln emits the text as a single non-JSON line, so
pinner websites domains verify <d> --jsonon an unresolvable (nil,nil) result produces broken output instead of a machine JSON document, while all sibling branches honor IsJSON. Guard withif output.IsJSON() { return output.PrintJSON(map[string]any{"verified": false, "message": "not verified yet"}) }before calling renderDomainVerifyResult.Prompt for LLM
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.