Add DNS-over-HTTPS TXT and well-known atproto handle-resolution components - #57
Merged
Merged
Conversation
Ports DNSWireFormat, DNSTXTFetcher, and DoHTXTFetcher (RFC 1035 / RFC 8484), and adds two new public resolvers alongside DidWebResolver and DidPlcResolver: WellKnownHandleResolver (HTTPS well-known method, over the injected HTTPFetcher seam) and DnsHandleResolver (DNS TXT method, defaulting to DoHTXTFetcher). Both refuse redirects and validate their result through Atproto.DID.init(string:), matching the existing resolvers' security shape. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- WellKnownHandleResolver now rejects reserved TLDs before building the well-known URL, matching DidWebResolver's screen (reuses its reservedTLDs set as the shared source of truth). - Add tests exercising the two untested parser bounds in decodeTXTRecords - a short answer header and an RDLENGTH exceeding the buffer - both verified to fail (crash) when their guard is neutralized. - Reword the maxBodySize comment: the bound rejects a body before parsing, not before it's buffered. - Reword the changeset to not oversell DID validation. - Make joinedCharacterStrings private - nothing outside the type uses it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DoHTXTFetcher, DNSWireFormat, DNSTXTFetcher, and DNSTXTFetcherError move into extension Atproto, matching DnsHandleResolver and WellKnownHandleResolver. Names and casing unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 1b4b358 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Three additive helpers on Atproto.XRPC.BskyAppCallable: relationshipLookup(actor:others:) dedupes/chunks app.bsky.graph.getRelationships at the lexicon's 30-subject limit and reports not-found subjects rather than dropping them (not an account-existence check - the AppView returns a relationship entry for any well-formed DID); bskyProfileIfExists(actor:) maps getProfile's undeclared not-found shape (400 InvalidRequest, "Profile not found") to nil; and Atproto.BskyCDN.imageURL(_:did:blob:host:) builds CDN image URLs from a blob reference with explicit RFC 3986 path-segment encoding so a crafted DID/CID can't escape its segment. Also fixes GetRelationships.Parameters.init to accept exactly 30 others (the lexicon's own maxLength, previously rejected) and makes GetRelationships.Errors public, since it's already thrown by public API. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add relationshipLookup, bskyProfileIfExists, and BskyCDN read helpers
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds two single-purpose atproto handle-resolution components beside the existing
DidPlcResolver/DidWebResolver, plus the supporting DNS machinery — allAtproto-namespaced and additive (no changes to existing files):Atproto.DoHTXTFetcher— RFC 8484 DNS-over-HTTPS TXT lookups over the injectedHTTPFetcher; DoH servers are parametrizable config (serverURLs, Cloudflare→Google default, per-provider fallback). Backed by a minimal RFC 1035 wire codec (Atproto.DNSWireFormat) behind anAtproto.DNSTXTFetcherseam.Atproto.DnsHandleResolver— resolves a handle to a DID via its_atprotoTXT record.Atproto.WellKnownHandleResolver— resolves a handle viahttps://<handle>/.well-known/atproto-did, mirroringDidWebResolver's hardening: redirect-refusing fetcher, reserved-TLD screen, response-size bound, DID method-form checked on parse.Portable (no platform DNS APIs) so it builds and tests on Linux/Android; the Darwin
dnssdpath is intentionally out of scope.Test notes: ported wire-format fixtures plus new coverage for the parser's out-of-bounds guards (mutation-verified — each new test fails when its guard is neutralized) and the well-known resolver's redirect/size/reserved-TLD behavior.
swift testgreen (91 tests),swift formatlint clean. Purely additive → minor changeset.🤖 Generated with Claude Code