···250250 return nil, fmt.Errorf("at-identifier neither a Handle nor a DID")
251251}
252252253253-func (d *CacheDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) {
254254- // XXX: cache this kind of doc separately
255255- return d.Inner.ResolveDID(ctx, did)
256256-}
257257-258253func (d *CacheDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error {
259254 handle, err := a.AsHandle()
260255 if nil == err { // if not an error, is a handle
+21-14
atproto/identity/did.go
···1414 "github.com/bluesky-social/indigo/atproto/syntax"
1515)
16161717-// This is a low-level method for resolving a DID to a raw JSON document.
1818-//
1919-// This method does not parse the DID document into an atproto-specific format, and does not bi-directionally verify handles. Most atproto-specific code should use the "Lookup*" methods, which do implement that functionality.
2020-func (d *BaseDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) {
2121- raw, err := d.resolveDIDBytes(ctx, did)
1717+// Variant of ResolveDID which parses in to a DIDDocument struct.
1818+func (d *BaseDirectory) ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
1919+ b, err := d.resolveDIDBytes(ctx, did)
2220 if err != nil {
2321 return nil, err
2422 }
25232626- var doc map[string]any
2727- if err := json.Unmarshal(raw, &doc); err != nil {
2424+ var doc DIDDocument
2525+ if err := json.Unmarshal(b, &doc); err != nil {
2826 return nil, fmt.Errorf("%w: JSON DID document parse: %w", ErrDIDResolutionFailed, err)
2927 }
3030- return doc, nil
2828+ if doc.DID != did {
2929+ return nil, fmt.Errorf("document ID did not match DID")
3030+ }
3131+ return &doc, nil
3132}
32333333-// Variant of ResolveDID which parses in to a DIDDocument struct.
3434-func (d *BaseDirectory) ResolveDIDDoc(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
3535- raw, err := d.resolveDIDBytes(ctx, did)
3434+// Low-level method for resolving a DID to a raw JSON document.
3535+//
3636+// This method does not parse the DID document into an atproto-specific format, and does not bi-directionally verify handles. Most atproto-specific code should use the "Lookup*" methods, which do implement that functionality.
3737+func (d *BaseDirectory) ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) {
3838+ b, err := d.resolveDIDBytes(ctx, did)
3639 if err != nil {
3740 return nil, err
3841 }
39424343+ // parse as doc, to validate at least some syntax
4044 var doc DIDDocument
4141- if err := json.Unmarshal(raw, &doc); err != nil {
4545+ if err := json.Unmarshal(b, &doc); err != nil {
4246 return nil, fmt.Errorf("%w: JSON DID document parse: %w", ErrDIDResolutionFailed, err)
4347 }
4444- return &doc, nil
4848+ if doc.DID != did {
4949+ return nil, fmt.Errorf("document ID did not match DID")
5050+ }
5151+5252+ return json.RawMessage(b), nil
4553}
46544747-// Package-internal helper which resolves a DID document to the response bytes.
4855func (d *BaseDirectory) resolveDIDBytes(ctx context.Context, did syntax.DID) ([]byte, error) {
4956 var b []byte
5057 var err error
+3-8
atproto/identity/directory.go
···1010 "github.com/bluesky-social/indigo/atproto/syntax"
1111)
12121313-// Common for doing atproto identity lookups by DID or handle.
1414-//
1515-// The "Lookup" methods do bi-directional handle verification automatically, and format results in a compact atproto-specific struct ("Identity"). Clients and services should use these methods by default, instead of resolving handles or DIDs separately.
1313+// Ergonomic interface for atproto identity lookup, by DID or handle.
1614//
1717-// Handles which fail to resolve, or don't match DID alsoKnownAs, are an error. DIDs which resolve but the handle does not resolve back to the DID return an Identity where the Handle is the special `handle.invalid` value.
1515+// The "Lookup" methods resolve identities (handle and DID), and return results in a compact, opinionated struct (`Identity`). They do bi-directional handle/DID verification by default. Clients and services should use these methods by default, instead of resolving handles or DIDs separately.
1816//
1919-// The "Resolve" methods do direct resolution of just the identifier indicated.
1717+// Looking up a handle which fails to resolve, or don't match DID alsoKnownAs, returns an error. When looking up a DID, if the handle does not resolve back to the DID, the lookup succeeds and returns an `Identity` where the Handle is the special `handle.invalid` value.
2018//
2119// Some example implementations of this interface could be:
2220// - basic direct resolution on every call
···2725 LookupHandle(ctx context.Context, handle syntax.Handle) (*Identity, error)
2826 LookupDID(ctx context.Context, did syntax.DID) (*Identity, error)
2927 Lookup(ctx context.Context, atid syntax.AtIdentifier) (*Identity, error)
3030-3131- ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error)
3232- ResolveHandle(ctx context.Context, handle syntax.Handle) (syntax.DID, error)
33283429 // Flushes any cache of the indicated identifier. If directory is not using caching, can ignore this.
3530 Purge(ctx context.Context, i syntax.AtIdentifier) error