@atproto-labs/identity-resolver 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/atproto-identity-resolver.d.ts +20 -0
- package/dist/atproto-identity-resolver.d.ts.map +1 -0
- package/dist/atproto-identity-resolver.js +87 -0
- package/dist/atproto-identity-resolver.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/identity-resolver.d.ts +15 -17
- package/dist/identity-resolver.d.ts.map +1 -1
- package/dist/identity-resolver.js +0 -72
- package/dist/identity-resolver.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/atproto-identity-resolver.ts +126 -0
- package/src/constants.ts +1 -0
- package/src/identity-resolver.ts +19 -106
- package/src/index.ts +2 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atproto-labs/identity-resolver
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @atproto-labs/did-resolver@0.2.1
|
|
9
|
+
- @atproto-labs/handle-resolver@0.3.1
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#3982](https://github.com/bluesky-social/atproto/pull/3982) [`4c2d49917`](https://github.com/bluesky-social/atproto/commit/4c2d499178c61eb8a9d7f658e89fe68fa07f81e7) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Identity resolver's `resolve()` method returns value consistent with `com.atproto.identity.resolveIdentity`
|
|
16
|
+
|
|
17
|
+
- [#3982](https://github.com/bluesky-social/atproto/pull/3982) [`4c2d49917`](https://github.com/bluesky-social/atproto/commit/4c2d499178c61eb8a9d7f658e89fe68fa07f81e7) Thanks [@matthieusieben](https://github.com/matthieusieben)! - `IdentityResolver` is now an interface. The `IdentityResolverProto` class is the default implementation for the `IdentityResolver` interface.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#3982](https://github.com/bluesky-social/atproto/pull/3982) [`4c2d49917`](https://github.com/bluesky-social/atproto/commit/4c2d499178c61eb8a9d7f658e89fe68fa07f81e7) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Export `HANDLE_INVALID` constant
|
|
22
|
+
|
|
3
23
|
## 0.2.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AtprotoDid, AtprotoIdentityDidMethods, DidDocument, DidResolver, ResolveDidOptions } from '@atproto-labs/did-resolver';
|
|
2
|
+
import { HandleResolver, ResolveHandleOptions } from '@atproto-labs/handle-resolver';
|
|
3
|
+
import { IdentityInfo, IdentityResolver, ResolveIdentityOptions } from './identity-resolver.js';
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of the official ATPROTO identity resolution strategy.
|
|
6
|
+
* This implementation relies on two primitives:
|
|
7
|
+
* - DID resolution (using the `DidResolver` interface)
|
|
8
|
+
* - Handle resolution (using the `HandleResolver` interface)
|
|
9
|
+
*/
|
|
10
|
+
export declare class AtprotoIdentityResolver implements IdentityResolver {
|
|
11
|
+
protected readonly didResolver: DidResolver<AtprotoIdentityDidMethods>;
|
|
12
|
+
protected readonly handleResolver: HandleResolver;
|
|
13
|
+
constructor(didResolver: DidResolver<AtprotoIdentityDidMethods>, handleResolver: HandleResolver);
|
|
14
|
+
resolve(input: string, options?: ResolveIdentityOptions): Promise<IdentityInfo>;
|
|
15
|
+
resolveFromDid(did: AtprotoDid, options?: ResolveDidOptions): Promise<IdentityInfo>;
|
|
16
|
+
resolveFromHandle(handle: string, options?: ResolveHandleOptions): Promise<IdentityInfo>;
|
|
17
|
+
getDocumentFromDid(did: AtprotoDid, options?: ResolveDidOptions): Promise<DidDocument<AtprotoIdentityDidMethods>>;
|
|
18
|
+
getDocumentFromHandle(input: string, options?: ResolveHandleOptions): Promise<DidDocument<AtprotoIdentityDidMethods>>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=atproto-identity-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atproto-identity-resolver.d.ts","sourceRoot":"","sources":["../src/atproto-identity-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,yBAAyB,EACzB,WAAW,EACX,WAAW,EACX,iBAAiB,EAElB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,cAAc,EACd,oBAAoB,EACrB,MAAM,+BAA+B,CAAA;AAGtC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,wBAAwB,CAAA;AAO/B;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAE5D,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,yBAAyB,CAAC;IACtE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc;gBAD9B,WAAW,EAAE,WAAW,CAAC,yBAAyB,CAAC,EACnD,cAAc,EAAE,cAAc;IAGtC,OAAO,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,YAAY,CAAC;IAMX,cAAc,CACzB,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAqBX,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC;IAYX,kBAAkB,CAC7B,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;IAIrC,qBAAqB,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;CA8BnD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AtprotoIdentityResolver = void 0;
|
|
4
|
+
const did_resolver_1 = require("@atproto-labs/did-resolver");
|
|
5
|
+
const constants_js_1 = require("./constants.js");
|
|
6
|
+
const identity_resolver_error_js_1 = require("./identity-resolver-error.js");
|
|
7
|
+
const util_js_1 = require("./util.js");
|
|
8
|
+
// @TODO Move this to its own package as soon as we have a distinct
|
|
9
|
+
// implementation based on XRPC calls to the
|
|
10
|
+
// "com.atproto.identity.resolveIdentity" method.
|
|
11
|
+
/**
|
|
12
|
+
* Implementation of the official ATPROTO identity resolution strategy.
|
|
13
|
+
* This implementation relies on two primitives:
|
|
14
|
+
* - DID resolution (using the `DidResolver` interface)
|
|
15
|
+
* - Handle resolution (using the `HandleResolver` interface)
|
|
16
|
+
*/
|
|
17
|
+
class AtprotoIdentityResolver {
|
|
18
|
+
constructor(didResolver, handleResolver) {
|
|
19
|
+
Object.defineProperty(this, "didResolver", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: didResolver
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "handleResolver", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: handleResolver
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async resolve(input, options) {
|
|
33
|
+
return (0, did_resolver_1.isAtprotoDid)(input)
|
|
34
|
+
? this.resolveFromDid(input, options)
|
|
35
|
+
: this.resolveFromHandle(input, options);
|
|
36
|
+
}
|
|
37
|
+
async resolveFromDid(did, options) {
|
|
38
|
+
const document = await this.getDocumentFromDid(did, options);
|
|
39
|
+
options?.signal?.throwIfAborted();
|
|
40
|
+
// We will only return the document's handle alias if it resolves to the
|
|
41
|
+
// same DID as the input.
|
|
42
|
+
const handle = (0, util_js_1.extractNormalizedHandle)(document);
|
|
43
|
+
const resolvedDid = handle
|
|
44
|
+
? await this.handleResolver
|
|
45
|
+
.resolve(handle, options)
|
|
46
|
+
.catch(() => undefined) // Ignore errors (temporarily unavailable)
|
|
47
|
+
: undefined;
|
|
48
|
+
return {
|
|
49
|
+
did: document.id,
|
|
50
|
+
didDoc: document,
|
|
51
|
+
handle: handle && resolvedDid === did ? handle : constants_js_1.HANDLE_INVALID,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async resolveFromHandle(handle, options) {
|
|
55
|
+
const document = await this.getDocumentFromHandle(handle, options);
|
|
56
|
+
// @NOTE bi-directional resolution enforced in getDocumentFromHandle()
|
|
57
|
+
return {
|
|
58
|
+
did: document.id,
|
|
59
|
+
didDoc: document,
|
|
60
|
+
handle: (0, util_js_1.extractNormalizedHandle)(document) || constants_js_1.HANDLE_INVALID,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async getDocumentFromDid(did, options) {
|
|
64
|
+
return this.didResolver.resolve(did, options);
|
|
65
|
+
}
|
|
66
|
+
async getDocumentFromHandle(input, options) {
|
|
67
|
+
const handle = (0, util_js_1.asNormalizedHandle)(input);
|
|
68
|
+
if (!handle) {
|
|
69
|
+
throw new identity_resolver_error_js_1.IdentityResolverError(`Invalid handle "${input}" provided.`);
|
|
70
|
+
}
|
|
71
|
+
const did = await this.handleResolver.resolve(handle, options);
|
|
72
|
+
if (!did) {
|
|
73
|
+
throw new identity_resolver_error_js_1.IdentityResolverError(`Handle "${handle}" does not resolve to a DID`);
|
|
74
|
+
}
|
|
75
|
+
options?.signal?.throwIfAborted();
|
|
76
|
+
// Note: Not using "return this.resolveDid(did, options)" to make the extra
|
|
77
|
+
// check for the handle in the DID document:
|
|
78
|
+
const document = await this.didResolver.resolve(did, options);
|
|
79
|
+
// Enforce bi-directional resolution
|
|
80
|
+
if (handle !== (0, util_js_1.extractNormalizedHandle)(document)) {
|
|
81
|
+
throw new identity_resolver_error_js_1.IdentityResolverError(`Did document for "${did}" does not include the handle "${handle}"`);
|
|
82
|
+
}
|
|
83
|
+
return document;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.AtprotoIdentityResolver = AtprotoIdentityResolver;
|
|
87
|
+
//# sourceMappingURL=atproto-identity-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atproto-identity-resolver.js","sourceRoot":"","sources":["../src/atproto-identity-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,gBAAgB,CAAA"}
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { AtprotoDid, AtprotoIdentityDidMethods, DidDocument
|
|
2
|
-
import {
|
|
3
|
-
export type
|
|
4
|
-
|
|
1
|
+
import { AtprotoDid, AtprotoIdentityDidMethods, DidDocument } from '@atproto-labs/did-resolver';
|
|
2
|
+
import { HANDLE_INVALID } from './constants';
|
|
3
|
+
export type IdentityInfo = {
|
|
4
|
+
did: AtprotoDid;
|
|
5
|
+
didDoc: DidDocument<AtprotoIdentityDidMethods>;
|
|
5
6
|
/**
|
|
6
|
-
* Will be
|
|
7
|
-
*
|
|
7
|
+
* Will be 'handle.invalid' if the handle does not resolve to the
|
|
8
|
+
* same DID as the input, or if the handle is not present in the DID
|
|
9
|
+
* document.
|
|
8
10
|
*/
|
|
9
|
-
handle
|
|
11
|
+
handle: typeof HANDLE_INVALID | string;
|
|
10
12
|
};
|
|
11
|
-
export type ResolveIdentityOptions =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
resolve(
|
|
17
|
-
resolveFromDid(did: AtprotoDid, options?: ResolveDidOptions): Promise<ResolvedIdentity>;
|
|
18
|
-
resolveFromHandle(handle: string, options?: ResolveHandleOptions): Promise<ResolvedIdentity>;
|
|
19
|
-
getDocumentFromDid(did: AtprotoDid, options?: ResolveDidOptions): Promise<DidDocument<AtprotoIdentityDidMethods>>;
|
|
20
|
-
getDocumentFromHandle(input: string, options?: ResolveHandleOptions): Promise<DidDocument<AtprotoIdentityDidMethods>>;
|
|
13
|
+
export type ResolveIdentityOptions = {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
noCache?: boolean;
|
|
16
|
+
};
|
|
17
|
+
export interface IdentityResolver {
|
|
18
|
+
resolve(identifier: string, options?: ResolveIdentityOptions): Promise<IdentityInfo>;
|
|
21
19
|
}
|
|
22
20
|
//# sourceMappingURL=identity-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-resolver.d.ts","sourceRoot":"","sources":["../src/identity-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,yBAAyB,EACzB,WAAW,
|
|
1
|
+
{"version":3,"file":"identity-resolver.d.ts","sourceRoot":"","sources":["../src/identity-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,yBAAyB,EACzB,WAAW,EACZ,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAI5C,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,UAAU,CAAA;IAEf,MAAM,EAAE,WAAW,CAAC,yBAAyB,CAAC,CAAA;IAE9C;;;;OAIG;IACH,MAAM,EAAE,OAAO,cAAc,GAAG,MAAM,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CACL,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,YAAY,CAAC,CAAA;CACzB"}
|
|
@@ -1,75 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.IdentityResolver = void 0;
|
|
4
|
-
const did_resolver_1 = require("@atproto-labs/did-resolver");
|
|
5
|
-
const identity_resolver_error_1 = require("./identity-resolver-error");
|
|
6
|
-
const util_1 = require("./util");
|
|
7
|
-
class IdentityResolver {
|
|
8
|
-
constructor(didResolver, handleResolver) {
|
|
9
|
-
Object.defineProperty(this, "didResolver", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: didResolver
|
|
14
|
-
});
|
|
15
|
-
Object.defineProperty(this, "handleResolver", {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
configurable: true,
|
|
18
|
-
writable: true,
|
|
19
|
-
value: handleResolver
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
async resolve(input, options) {
|
|
23
|
-
return (0, did_resolver_1.isAtprotoDid)(input)
|
|
24
|
-
? this.resolveFromDid(input, options)
|
|
25
|
-
: this.resolveFromHandle(input, options);
|
|
26
|
-
}
|
|
27
|
-
async resolveFromDid(did, options) {
|
|
28
|
-
const document = await this.getDocumentFromDid(did, options);
|
|
29
|
-
options?.signal?.throwIfAborted();
|
|
30
|
-
// We will only return the document's handle alias if it resolves to the
|
|
31
|
-
// same DID as the input.
|
|
32
|
-
const handle = (0, util_1.extractNormalizedHandle)(document);
|
|
33
|
-
const resolvedDid = handle
|
|
34
|
-
? await this.handleResolver
|
|
35
|
-
.resolve(handle, options)
|
|
36
|
-
.catch(() => undefined) // Ignore errors (temporarily unavailable)
|
|
37
|
-
: undefined;
|
|
38
|
-
return {
|
|
39
|
-
document,
|
|
40
|
-
handle: resolvedDid === did ? handle : undefined,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
async resolveFromHandle(handle, options) {
|
|
44
|
-
const document = await this.getDocumentFromHandle(handle, options);
|
|
45
|
-
// @NOTE bi-directional resolution enforced in getDocumentFromHandle()
|
|
46
|
-
return {
|
|
47
|
-
document,
|
|
48
|
-
handle: (0, util_1.extractNormalizedHandle)(document),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
async getDocumentFromDid(did, options) {
|
|
52
|
-
return this.didResolver.resolve(did, options);
|
|
53
|
-
}
|
|
54
|
-
async getDocumentFromHandle(input, options) {
|
|
55
|
-
const handle = (0, util_1.asNormalizedHandle)(input);
|
|
56
|
-
if (!handle) {
|
|
57
|
-
throw new identity_resolver_error_1.IdentityResolverError(`Invalid handle "${input}" provided.`);
|
|
58
|
-
}
|
|
59
|
-
const did = await this.handleResolver.resolve(handle, options);
|
|
60
|
-
if (!did) {
|
|
61
|
-
throw new identity_resolver_error_1.IdentityResolverError(`Handle "${handle}" does not resolve to a DID`);
|
|
62
|
-
}
|
|
63
|
-
options?.signal?.throwIfAborted();
|
|
64
|
-
// Note: Not using "return this.resolveDid(did, options)" to make the extra
|
|
65
|
-
// check for the handle in the DID document:
|
|
66
|
-
const document = await this.didResolver.resolve(did, options);
|
|
67
|
-
// Enforce bi-directional resolution
|
|
68
|
-
if (handle !== (0, util_1.extractNormalizedHandle)(document)) {
|
|
69
|
-
throw new identity_resolver_error_1.IdentityResolverError(`Did document for "${did}" does not include the handle "${handle}"`);
|
|
70
|
-
}
|
|
71
|
-
return document;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
exports.IdentityResolver = IdentityResolver;
|
|
75
3
|
//# sourceMappingURL=identity-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-resolver.js","sourceRoot":"","sources":["../src/identity-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity-resolver.js","sourceRoot":"","sources":["../src/identity-resolver.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./atproto-identity-resolver.js"), exports);
|
|
18
|
+
__exportStar(require("./constants.js"), exports);
|
|
17
19
|
__exportStar(require("./identity-resolver-error.js"), exports);
|
|
18
20
|
__exportStar(require("./identity-resolver.js"), exports);
|
|
19
21
|
__exportStar(require("./util.js"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+DAA4C;AAC5C,yDAAsC;AACtC,4CAAyB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA8C;AAC9C,iDAA8B;AAC9B,+DAA4C;AAC5C,yDAAsC;AACtC,4CAAyB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto-labs/identity-resolver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "A library resolving ATPROTO identities",
|
|
6
6
|
"keywords": [
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@atproto-labs/did-resolver": "0.2.
|
|
29
|
-
"@atproto-labs/handle-resolver": "0.3.
|
|
28
|
+
"@atproto-labs/did-resolver": "0.2.1",
|
|
29
|
+
"@atproto-labs/handle-resolver": "0.3.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"typescript": "^5.6.3"
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AtprotoDid,
|
|
3
|
+
AtprotoIdentityDidMethods,
|
|
4
|
+
DidDocument,
|
|
5
|
+
DidResolver,
|
|
6
|
+
ResolveDidOptions,
|
|
7
|
+
isAtprotoDid,
|
|
8
|
+
} from '@atproto-labs/did-resolver'
|
|
9
|
+
import {
|
|
10
|
+
HandleResolver,
|
|
11
|
+
ResolveHandleOptions,
|
|
12
|
+
} from '@atproto-labs/handle-resolver'
|
|
13
|
+
import { HANDLE_INVALID } from './constants.js'
|
|
14
|
+
import { IdentityResolverError } from './identity-resolver-error.js'
|
|
15
|
+
import {
|
|
16
|
+
IdentityInfo,
|
|
17
|
+
IdentityResolver,
|
|
18
|
+
ResolveIdentityOptions,
|
|
19
|
+
} from './identity-resolver.js'
|
|
20
|
+
import { asNormalizedHandle, extractNormalizedHandle } from './util.js'
|
|
21
|
+
|
|
22
|
+
// @TODO Move this to its own package as soon as we have a distinct
|
|
23
|
+
// implementation based on XRPC calls to the
|
|
24
|
+
// "com.atproto.identity.resolveIdentity" method.
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Implementation of the official ATPROTO identity resolution strategy.
|
|
28
|
+
* This implementation relies on two primitives:
|
|
29
|
+
* - DID resolution (using the `DidResolver` interface)
|
|
30
|
+
* - Handle resolution (using the `HandleResolver` interface)
|
|
31
|
+
*/
|
|
32
|
+
export class AtprotoIdentityResolver implements IdentityResolver {
|
|
33
|
+
constructor(
|
|
34
|
+
protected readonly didResolver: DidResolver<AtprotoIdentityDidMethods>,
|
|
35
|
+
protected readonly handleResolver: HandleResolver,
|
|
36
|
+
) {}
|
|
37
|
+
|
|
38
|
+
public async resolve(
|
|
39
|
+
input: string,
|
|
40
|
+
options?: ResolveIdentityOptions,
|
|
41
|
+
): Promise<IdentityInfo> {
|
|
42
|
+
return isAtprotoDid(input)
|
|
43
|
+
? this.resolveFromDid(input, options)
|
|
44
|
+
: this.resolveFromHandle(input, options)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public async resolveFromDid(
|
|
48
|
+
did: AtprotoDid,
|
|
49
|
+
options?: ResolveDidOptions,
|
|
50
|
+
): Promise<IdentityInfo> {
|
|
51
|
+
const document = await this.getDocumentFromDid(did, options)
|
|
52
|
+
|
|
53
|
+
options?.signal?.throwIfAborted()
|
|
54
|
+
|
|
55
|
+
// We will only return the document's handle alias if it resolves to the
|
|
56
|
+
// same DID as the input.
|
|
57
|
+
const handle = extractNormalizedHandle(document)
|
|
58
|
+
const resolvedDid = handle
|
|
59
|
+
? await this.handleResolver
|
|
60
|
+
.resolve(handle, options)
|
|
61
|
+
.catch(() => undefined) // Ignore errors (temporarily unavailable)
|
|
62
|
+
: undefined
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
did: document.id,
|
|
66
|
+
didDoc: document,
|
|
67
|
+
handle: handle && resolvedDid === did ? handle : HANDLE_INVALID,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async resolveFromHandle(
|
|
72
|
+
handle: string,
|
|
73
|
+
options?: ResolveHandleOptions,
|
|
74
|
+
): Promise<IdentityInfo> {
|
|
75
|
+
const document = await this.getDocumentFromHandle(handle, options)
|
|
76
|
+
|
|
77
|
+
// @NOTE bi-directional resolution enforced in getDocumentFromHandle()
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
did: document.id,
|
|
81
|
+
didDoc: document,
|
|
82
|
+
handle: extractNormalizedHandle(document) || HANDLE_INVALID,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public async getDocumentFromDid(
|
|
87
|
+
did: AtprotoDid,
|
|
88
|
+
options?: ResolveDidOptions,
|
|
89
|
+
): Promise<DidDocument<AtprotoIdentityDidMethods>> {
|
|
90
|
+
return this.didResolver.resolve(did, options)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async getDocumentFromHandle(
|
|
94
|
+
input: string,
|
|
95
|
+
options?: ResolveHandleOptions,
|
|
96
|
+
): Promise<DidDocument<AtprotoIdentityDidMethods>> {
|
|
97
|
+
const handle = asNormalizedHandle(input)
|
|
98
|
+
if (!handle) {
|
|
99
|
+
throw new IdentityResolverError(`Invalid handle "${input}" provided.`)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const did = await this.handleResolver.resolve(handle, options)
|
|
103
|
+
|
|
104
|
+
if (!did) {
|
|
105
|
+
throw new IdentityResolverError(
|
|
106
|
+
`Handle "${handle}" does not resolve to a DID`,
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
options?.signal?.throwIfAborted()
|
|
111
|
+
|
|
112
|
+
// Note: Not using "return this.resolveDid(did, options)" to make the extra
|
|
113
|
+
// check for the handle in the DID document:
|
|
114
|
+
|
|
115
|
+
const document = await this.didResolver.resolve(did, options)
|
|
116
|
+
|
|
117
|
+
// Enforce bi-directional resolution
|
|
118
|
+
if (handle !== extractNormalizedHandle(document)) {
|
|
119
|
+
throw new IdentityResolverError(
|
|
120
|
+
`Did document for "${did}" does not include the handle "${handle}"`,
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return document
|
|
125
|
+
}
|
|
126
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const HANDLE_INVALID = 'handle.invalid'
|
package/src/identity-resolver.ts
CHANGED
|
@@ -2,119 +2,32 @@ import {
|
|
|
2
2
|
AtprotoDid,
|
|
3
3
|
AtprotoIdentityDidMethods,
|
|
4
4
|
DidDocument,
|
|
5
|
-
DidResolver,
|
|
6
|
-
ResolveDidOptions,
|
|
7
|
-
isAtprotoDid,
|
|
8
5
|
} from '@atproto-labs/did-resolver'
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
import { HANDLE_INVALID } from './constants'
|
|
7
|
+
|
|
8
|
+
// Consistent with `com.atproto.identity.defs#identityInfo` returned by
|
|
9
|
+
// `com.atproto.identity.resolveIdentity` endpoint.
|
|
10
|
+
export type IdentityInfo = {
|
|
11
|
+
did: AtprotoDid
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
document: DidDocument<AtprotoIdentityDidMethods>
|
|
13
|
+
didDoc: DidDocument<AtprotoIdentityDidMethods>
|
|
18
14
|
|
|
19
15
|
/**
|
|
20
|
-
* Will be
|
|
21
|
-
*
|
|
16
|
+
* Will be 'handle.invalid' if the handle does not resolve to the
|
|
17
|
+
* same DID as the input, or if the handle is not present in the DID
|
|
18
|
+
* document.
|
|
22
19
|
*/
|
|
23
|
-
handle
|
|
20
|
+
handle: typeof HANDLE_INVALID | string
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
export type ResolveIdentityOptions =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
readonly didResolver: DidResolver<AtprotoIdentityDidMethods>,
|
|
31
|
-
readonly handleResolver: HandleResolver,
|
|
32
|
-
) {}
|
|
23
|
+
export type ResolveIdentityOptions = {
|
|
24
|
+
signal?: AbortSignal
|
|
25
|
+
noCache?: boolean
|
|
26
|
+
}
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
export interface IdentityResolver {
|
|
29
|
+
resolve(
|
|
30
|
+
identifier: string,
|
|
36
31
|
options?: ResolveIdentityOptions,
|
|
37
|
-
): Promise<
|
|
38
|
-
return isAtprotoDid(input)
|
|
39
|
-
? this.resolveFromDid(input, options)
|
|
40
|
-
: this.resolveFromHandle(input, options)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public async resolveFromDid(
|
|
44
|
-
did: AtprotoDid,
|
|
45
|
-
options?: ResolveDidOptions,
|
|
46
|
-
): Promise<ResolvedIdentity> {
|
|
47
|
-
const document = await this.getDocumentFromDid(did, options)
|
|
48
|
-
|
|
49
|
-
options?.signal?.throwIfAborted()
|
|
50
|
-
|
|
51
|
-
// We will only return the document's handle alias if it resolves to the
|
|
52
|
-
// same DID as the input.
|
|
53
|
-
const handle = extractNormalizedHandle(document)
|
|
54
|
-
const resolvedDid = handle
|
|
55
|
-
? await this.handleResolver
|
|
56
|
-
.resolve(handle, options)
|
|
57
|
-
.catch(() => undefined) // Ignore errors (temporarily unavailable)
|
|
58
|
-
: undefined
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
document,
|
|
62
|
-
handle: resolvedDid === did ? handle : undefined,
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public async resolveFromHandle(
|
|
67
|
-
handle: string,
|
|
68
|
-
options?: ResolveHandleOptions,
|
|
69
|
-
): Promise<ResolvedIdentity> {
|
|
70
|
-
const document = await this.getDocumentFromHandle(handle, options)
|
|
71
|
-
|
|
72
|
-
// @NOTE bi-directional resolution enforced in getDocumentFromHandle()
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
document,
|
|
76
|
-
handle: extractNormalizedHandle(document),
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public async getDocumentFromDid(
|
|
81
|
-
did: AtprotoDid,
|
|
82
|
-
options?: ResolveDidOptions,
|
|
83
|
-
): Promise<DidDocument<AtprotoIdentityDidMethods>> {
|
|
84
|
-
return this.didResolver.resolve(did, options)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
public async getDocumentFromHandle(
|
|
88
|
-
input: string,
|
|
89
|
-
options?: ResolveHandleOptions,
|
|
90
|
-
): Promise<DidDocument<AtprotoIdentityDidMethods>> {
|
|
91
|
-
const handle = asNormalizedHandle(input)
|
|
92
|
-
if (!handle) {
|
|
93
|
-
throw new IdentityResolverError(`Invalid handle "${input}" provided.`)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const did = await this.handleResolver.resolve(handle, options)
|
|
97
|
-
|
|
98
|
-
if (!did) {
|
|
99
|
-
throw new IdentityResolverError(
|
|
100
|
-
`Handle "${handle}" does not resolve to a DID`,
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
options?.signal?.throwIfAborted()
|
|
105
|
-
|
|
106
|
-
// Note: Not using "return this.resolveDid(did, options)" to make the extra
|
|
107
|
-
// check for the handle in the DID document:
|
|
108
|
-
|
|
109
|
-
const document = await this.didResolver.resolve(did, options)
|
|
110
|
-
|
|
111
|
-
// Enforce bi-directional resolution
|
|
112
|
-
if (handle !== extractNormalizedHandle(document)) {
|
|
113
|
-
throw new IdentityResolverError(
|
|
114
|
-
`Did document for "${did}" does not include the handle "${handle}"`,
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return document
|
|
119
|
-
}
|
|
32
|
+
): Promise<IdentityInfo>
|
|
120
33
|
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/identity-resolver-error.ts","./src/identity-resolver.ts","./src/index.ts","./src/util.ts"],"version":"5.8.2"}
|
|
1
|
+
{"root":["./src/atproto-identity-resolver.ts","./src/constants.ts","./src/identity-resolver-error.ts","./src/identity-resolver.ts","./src/index.ts","./src/util.ts"],"version":"5.8.2"}
|