@atproto/did 0.1.5 → 0.2.0
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 +14 -0
- package/LICENSE.txt +1 -1
- package/dist/atproto.d.ts +2 -0
- package/dist/atproto.d.ts.map +1 -1
- package/dist/atproto.js +43 -8
- package/dist/atproto.js.map +1 -1
- package/dist/did-document.d.ts +16 -16
- package/dist/did-document.d.ts.map +1 -1
- package/dist/did-document.js +19 -12
- package/dist/did-document.js.map +1 -1
- package/dist/lib/uri.d.ts +7 -0
- package/dist/lib/uri.d.ts.map +1 -0
- package/dist/lib/uri.js +68 -0
- package/dist/lib/uri.js.map +1 -0
- package/dist/methods/web.d.ts +1 -0
- package/dist/methods/web.d.ts.map +1 -1
- package/dist/methods/web.js +31 -14
- package/dist/methods/web.js.map +1 -1
- package/package.json +1 -1
- package/src/atproto.ts +55 -9
- package/src/did-document.ts +21 -11
- package/src/lib/uri.ts +67 -0
- package/src/methods/web.ts +39 -18
- package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atproto/did
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#4108](https://github.com/bluesky-social/atproto/pull/4108) [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Enforce proper formatting of relative uris fragments
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#4108](https://github.com/bluesky-social/atproto/pull/4108) [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Export `AtprotoAudience` type and validation function
|
|
12
|
+
|
|
13
|
+
- [#4108](https://github.com/bluesky-social/atproto/pull/4108) [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Small performance improvement
|
|
14
|
+
|
|
15
|
+
- [#4108](https://github.com/bluesky-social/atproto/pull/4108) [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Small performance improvement
|
|
16
|
+
|
|
3
17
|
## 0.1.5
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Dual MIT/Apache-2.0 License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2022-
|
|
3
|
+
Copyright (c) 2022-2025 Bluesky Social PBC, and Contributors
|
|
4
4
|
|
|
5
5
|
Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
|
|
6
6
|
|
package/dist/atproto.d.ts
CHANGED
|
@@ -11,4 +11,6 @@ export declare function assertAtprotoDidWeb(input: unknown): asserts input is Di
|
|
|
11
11
|
* @see {@link https://atproto.com/specs/did#blessed-did-methods}
|
|
12
12
|
*/
|
|
13
13
|
export declare function isAtprotoDidWeb(input: unknown): input is Did<'web'>;
|
|
14
|
+
export type AtprotoAudience = `${AtprotoDid}#${string}`;
|
|
15
|
+
export declare const isAtprotoAudience: (value: unknown) => value is AtprotoAudience;
|
|
14
16
|
//# sourceMappingURL=atproto.d.ts.map
|
package/dist/atproto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atproto.d.ts","sourceRoot":"","sources":["../src/atproto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"atproto.d.ts","sourceRoot":"","sources":["../src/atproto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAa9B,MAAM,MAAM,yBAAyB,GAAG,KAAK,GAAG,KAAK,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAA;AAEvD,eAAO,MAAM,gBAAgB,8EAE6C,CAAA;AAE1E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAahE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAGvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAa5E;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAgB7B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAcnE;AA+BD,MAAM,MAAM,eAAe,GAAG,GAAG,UAAU,IAAI,MAAM,EAAE,CAAA;AACvD,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,eAQ3D,CAAA"}
|
package/dist/atproto.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.atprotoDidSchema = void 0;
|
|
3
|
+
exports.isAtprotoAudience = exports.atprotoDidSchema = void 0;
|
|
4
4
|
exports.isAtprotoDid = isAtprotoDid;
|
|
5
5
|
exports.asAtprotoDid = asAtprotoDid;
|
|
6
6
|
exports.assertAtprotoDid = assertAtprotoDid;
|
|
@@ -8,6 +8,7 @@ exports.assertAtprotoDidWeb = assertAtprotoDidWeb;
|
|
|
8
8
|
exports.isAtprotoDidWeb = isAtprotoDidWeb;
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
10
|
const did_error_js_1 = require("./did-error.js");
|
|
11
|
+
const uri_js_1 = require("./lib/uri.js");
|
|
11
12
|
const methods_js_1 = require("./methods.js");
|
|
12
13
|
exports.atprotoDidSchema = zod_1.z
|
|
13
14
|
.string()
|
|
@@ -48,11 +49,10 @@ function assertAtprotoDid(input) {
|
|
|
48
49
|
}
|
|
49
50
|
function assertAtprotoDidWeb(input) {
|
|
50
51
|
(0, methods_js_1.assertDidWeb)(input);
|
|
51
|
-
if (input
|
|
52
|
+
if (isDidWebWithPath(input)) {
|
|
52
53
|
throw new did_error_js_1.InvalidDidError(input, `Atproto does not allow path components in Web DIDs`);
|
|
53
54
|
}
|
|
54
|
-
if (input
|
|
55
|
-
!input.startsWith('did:web:localhost%3A')) {
|
|
55
|
+
if (isDidWebWithHttpsPort(input)) {
|
|
56
56
|
throw new did_error_js_1.InvalidDidError(input, `Atproto does not allow port numbers in Web DIDs, except for localhost`);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -60,12 +60,47 @@ function assertAtprotoDidWeb(input) {
|
|
|
60
60
|
* @see {@link https://atproto.com/specs/did#blessed-did-methods}
|
|
61
61
|
*/
|
|
62
62
|
function isAtprotoDidWeb(input) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if (!(0, methods_js_1.isDidWeb)(input)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (isDidWebWithPath(input)) {
|
|
67
|
+
return false;
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
if (isDidWebWithHttpsPort(input)) {
|
|
68
70
|
return false;
|
|
69
71
|
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
function isDidWebWithPath(did) {
|
|
75
|
+
return did.includes(':', methods_js_1.DID_WEB_PREFIX.length);
|
|
76
|
+
}
|
|
77
|
+
function isLocalhostDid(did) {
|
|
78
|
+
return (did === 'did:web:localhost' ||
|
|
79
|
+
did.startsWith('did:web:localhost:') ||
|
|
80
|
+
did.startsWith('did:web:localhost%3A'));
|
|
70
81
|
}
|
|
82
|
+
function isDidWebWithHttpsPort(did) {
|
|
83
|
+
if (isLocalhostDid(did))
|
|
84
|
+
return false;
|
|
85
|
+
const pathIdx = did.indexOf(':', methods_js_1.DID_WEB_PREFIX.length);
|
|
86
|
+
const hasPort = pathIdx === -1
|
|
87
|
+
? // No path component, check if there's a port separator anywhere after
|
|
88
|
+
// the "did:web:" prefix
|
|
89
|
+
did.includes('%3A', methods_js_1.DID_WEB_PREFIX.length)
|
|
90
|
+
: // There is a path component; if there is an encoded colon *before* it,
|
|
91
|
+
// then there is a port number
|
|
92
|
+
did.lastIndexOf('%3A', pathIdx) !== -1;
|
|
93
|
+
return hasPort;
|
|
94
|
+
}
|
|
95
|
+
const isAtprotoAudience = (value) => {
|
|
96
|
+
if (typeof value !== 'string')
|
|
97
|
+
return false;
|
|
98
|
+
const hashIndex = value.indexOf('#');
|
|
99
|
+
if (hashIndex === -1)
|
|
100
|
+
return false;
|
|
101
|
+
if (value.indexOf('#', hashIndex + 1) !== -1)
|
|
102
|
+
return false;
|
|
103
|
+
return ((0, uri_js_1.isFragment)(value, hashIndex + 1) && isAtprotoDid(value.slice(0, hashIndex)));
|
|
104
|
+
};
|
|
105
|
+
exports.isAtprotoAudience = isAtprotoAudience;
|
|
71
106
|
//# sourceMappingURL=atproto.js.map
|
package/dist/atproto.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atproto.js","sourceRoot":"","sources":["../src/atproto.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"atproto.js","sourceRoot":"","sources":["../src/atproto.ts"],"names":[],"mappings":"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"}
|
package/dist/did-document.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { Did } from './did.js';
|
|
|
5
5
|
* @see {@link https://www.w3.org/TR/did-core/#services}
|
|
6
6
|
*/
|
|
7
7
|
declare const didServiceSchema: z.ZodObject<{
|
|
8
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
8
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
9
9
|
type: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
10
|
-
serviceEndpoint: z.ZodUnion<[z.
|
|
10
|
+
serviceEndpoint: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>, "atleastone">]>;
|
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
|
12
12
|
type: string | string[];
|
|
13
13
|
id: string;
|
|
@@ -26,11 +26,11 @@ export declare const didDocumentSchema: z.ZodObject<{
|
|
|
26
26
|
'@context': z.ZodUnion<[z.ZodLiteral<"https://www.w3.org/ns/did/v1">, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>]>;
|
|
27
27
|
id: z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>;
|
|
28
28
|
controller: z.ZodOptional<z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>>;
|
|
29
|
-
alsoKnownAs: z.ZodOptional<z.ZodArray<z.
|
|
29
|
+
alsoKnownAs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
30
30
|
service: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
31
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
31
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
32
32
|
type: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
33
|
-
serviceEndpoint: z.ZodUnion<[z.
|
|
33
|
+
serviceEndpoint: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>, "atleastone">]>;
|
|
34
34
|
}, "strip", z.ZodTypeAny, {
|
|
35
35
|
type: string | string[];
|
|
36
36
|
id: string;
|
|
@@ -40,8 +40,8 @@ export declare const didDocumentSchema: z.ZodObject<{
|
|
|
40
40
|
id: string;
|
|
41
41
|
serviceEndpoint: string | Record<string, string> | [string | Record<string, string>, ...(string | Record<string, string>)[]];
|
|
42
42
|
}>, "many">>;
|
|
43
|
-
authentication: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>, z.ZodObject<{
|
|
44
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
43
|
+
authentication: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>, z.ZodObject<{
|
|
44
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
45
45
|
type: z.ZodString;
|
|
46
46
|
controller: z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>;
|
|
47
47
|
publicKeyJwk: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -60,7 +60,7 @@ export declare const didDocumentSchema: z.ZodObject<{
|
|
|
60
60
|
publicKeyMultibase?: string | undefined;
|
|
61
61
|
}>]>, "many">>;
|
|
62
62
|
verificationMethod: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodObject<{
|
|
63
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
63
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
64
64
|
type: z.ZodString;
|
|
65
65
|
controller: z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>;
|
|
66
66
|
publicKeyJwk: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -77,7 +77,7 @@ export declare const didDocumentSchema: z.ZodObject<{
|
|
|
77
77
|
controller: string | string[];
|
|
78
78
|
publicKeyJwk?: Record<string, unknown> | undefined;
|
|
79
79
|
publicKeyMultibase?: string | undefined;
|
|
80
|
-
}>, z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>]>, "many">>;
|
|
80
|
+
}>, z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>]>, "many">>;
|
|
81
81
|
}, "strip", z.ZodTypeAny, {
|
|
82
82
|
id: `did:${string}:${string}`;
|
|
83
83
|
'@context': "https://www.w3.org/ns/did/v1" | [string, ...string[]];
|
|
@@ -134,11 +134,11 @@ export declare const didDocumentValidator: z.ZodEffects<z.ZodObject<{
|
|
|
134
134
|
'@context': z.ZodUnion<[z.ZodLiteral<"https://www.w3.org/ns/did/v1">, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>]>;
|
|
135
135
|
id: z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>;
|
|
136
136
|
controller: z.ZodOptional<z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>>;
|
|
137
|
-
alsoKnownAs: z.ZodOptional<z.ZodArray<z.
|
|
137
|
+
alsoKnownAs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
138
138
|
service: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
139
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
139
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
140
140
|
type: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
141
|
-
serviceEndpoint: z.ZodUnion<[z.
|
|
141
|
+
serviceEndpoint: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>, "atleastone">]>;
|
|
142
142
|
}, "strip", z.ZodTypeAny, {
|
|
143
143
|
type: string | string[];
|
|
144
144
|
id: string;
|
|
@@ -148,8 +148,8 @@ export declare const didDocumentValidator: z.ZodEffects<z.ZodObject<{
|
|
|
148
148
|
id: string;
|
|
149
149
|
serviceEndpoint: string | Record<string, string> | [string | Record<string, string>, ...(string | Record<string, string>)[]];
|
|
150
150
|
}>, "many">>;
|
|
151
|
-
authentication: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>, z.ZodObject<{
|
|
152
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
151
|
+
authentication: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>, z.ZodObject<{
|
|
152
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
153
153
|
type: z.ZodString;
|
|
154
154
|
controller: z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>;
|
|
155
155
|
publicKeyJwk: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -168,7 +168,7 @@ export declare const didDocumentValidator: z.ZodEffects<z.ZodObject<{
|
|
|
168
168
|
publicKeyMultibase?: string | undefined;
|
|
169
169
|
}>]>, "many">>;
|
|
170
170
|
verificationMethod: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodObject<{
|
|
171
|
-
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>;
|
|
171
|
+
id: z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>;
|
|
172
172
|
type: z.ZodString;
|
|
173
173
|
controller: z.ZodUnion<[z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, z.ZodArray<z.ZodEffects<z.ZodString, `did:${string}:${string}`, string>, "many">]>;
|
|
174
174
|
publicKeyJwk: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -185,7 +185,7 @@ export declare const didDocumentValidator: z.ZodEffects<z.ZodObject<{
|
|
|
185
185
|
controller: string | string[];
|
|
186
186
|
publicKeyJwk?: Record<string, unknown> | undefined;
|
|
187
187
|
publicKeyMultibase?: string | undefined;
|
|
188
|
-
}>, z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodString]>]>, "many">>;
|
|
188
|
+
}>, z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>]>]>, "many">>;
|
|
189
189
|
}, "strip", z.ZodTypeAny, {
|
|
190
190
|
id: `did:${string}:${string}`;
|
|
191
191
|
'@context': "https://www.w3.org/ns/did/v1" | [string, ...string[]];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"did-document.d.ts","sourceRoot":"","sources":["../src/did-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,GAAG,EAAa,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"did-document.d.ts","sourceRoot":"","sources":["../src/did-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,GAAG,EAAa,MAAM,UAAU,CAAA;AA+EzC;;;GAGG;AACH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;EAIpB,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAQzD;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB5B,CAAA;AAEF,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,CAC/D,OAAO,iBAAiB,CACzB,GAAG;IAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAAA;AAGvB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB7B,CAAA"}
|
package/dist/did-document.js
CHANGED
|
@@ -3,27 +3,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.didDocumentValidator = exports.didDocumentSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const did_js_1 = require("./did.js");
|
|
6
|
+
const uri_js_1 = require("./lib/uri.js");
|
|
6
7
|
/**
|
|
7
8
|
* RFC3968 compliant URI
|
|
8
9
|
*
|
|
9
10
|
* @see {@link https://www.rfc-editor.org/rfc/rfc3986}
|
|
10
11
|
*/
|
|
11
|
-
const rfc3968UriSchema = zod_1.z.string().
|
|
12
|
-
try {
|
|
13
|
-
new URL(data);
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
}, 'RFC3968 compliant URI');
|
|
12
|
+
const rfc3968UriSchema = zod_1.z.string().url('RFC3968 compliant URI');
|
|
20
13
|
const didControllerSchema = zod_1.z.union([did_js_1.didSchema, zod_1.z.array(did_js_1.didSchema)]);
|
|
21
14
|
/**
|
|
22
|
-
* @note this schema
|
|
15
|
+
* @note this schema is too permissive
|
|
23
16
|
*/
|
|
24
17
|
const didRelativeUriSchema = zod_1.z.union([
|
|
25
|
-
rfc3968UriSchema
|
|
26
|
-
|
|
18
|
+
rfc3968UriSchema.refine((value) => {
|
|
19
|
+
const fragmentIndex = value.indexOf('#');
|
|
20
|
+
if (fragmentIndex === -1)
|
|
21
|
+
return false;
|
|
22
|
+
return (0, uri_js_1.isFragment)(value, fragmentIndex + 1);
|
|
23
|
+
}, {
|
|
24
|
+
message: 'Missing or invalid fragment in RFC3968 URI',
|
|
25
|
+
}),
|
|
26
|
+
zod_1.z
|
|
27
|
+
.string()
|
|
28
|
+
.refine((value) => value.charCodeAt(0) === 35 /* # */, {
|
|
29
|
+
message: 'Fragment must start with #',
|
|
30
|
+
})
|
|
31
|
+
.refine((value) => (0, uri_js_1.isFragment)(value, 1), {
|
|
32
|
+
message: 'Invalid char in URI fragment',
|
|
33
|
+
}),
|
|
27
34
|
]);
|
|
28
35
|
const didVerificationMethodSchema = zod_1.z.object({
|
|
29
36
|
id: didRelativeUriSchema,
|
package/dist/did-document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"did-document.js","sourceRoot":"","sources":["../src/did-document.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AACvB,qCAAyC;AAEzC;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"did-document.js","sourceRoot":"","sources":["../src/did-document.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see {@link https://www.w3.org/TR/did-1.0/#dfn-did-fragments}
|
|
3
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc3986#section-3.5}
|
|
4
|
+
*/
|
|
5
|
+
export declare function isFragment(value: string, startIdx?: number, endIdx?: number): boolean;
|
|
6
|
+
export declare function isHexDigit(code: number): boolean;
|
|
7
|
+
//# sourceMappingURL=uri.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../../src/lib/uri.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,QAAQ,SAAI,EACZ,MAAM,SAAe,GACpB,OAAO,CAkDT;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMhD"}
|
package/dist/lib/uri.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFragment = isFragment;
|
|
4
|
+
exports.isHexDigit = isHexDigit;
|
|
5
|
+
/**
|
|
6
|
+
* @see {@link https://www.w3.org/TR/did-1.0/#dfn-did-fragments}
|
|
7
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc3986#section-3.5}
|
|
8
|
+
*/
|
|
9
|
+
function isFragment(value, startIdx = 0, endIdx = value.length) {
|
|
10
|
+
let charCode;
|
|
11
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
12
|
+
charCode = value.charCodeAt(i);
|
|
13
|
+
// fragment = *( pchar / "/" / "?" )
|
|
14
|
+
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
15
|
+
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
16
|
+
// pct-encoded = "%" HEXDIG HEXDIG
|
|
17
|
+
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
18
|
+
if ((charCode >= 65 /* A */ && charCode <= 90) /* Z */ ||
|
|
19
|
+
(charCode >= 97 /* a */ && charCode <= 122) /* z */ ||
|
|
20
|
+
(charCode >= 48 /* 0 */ && charCode <= 57) /* 9 */ ||
|
|
21
|
+
charCode === 45 /* "-" */ ||
|
|
22
|
+
charCode === 46 /* "." */ ||
|
|
23
|
+
charCode === 95 /* "_" */ ||
|
|
24
|
+
charCode === 126 /* "~" */) {
|
|
25
|
+
// unreserved
|
|
26
|
+
}
|
|
27
|
+
else if (charCode === 33 /* "!" */ ||
|
|
28
|
+
charCode === 36 /* "$" */ ||
|
|
29
|
+
charCode === 38 /* "&" */ ||
|
|
30
|
+
charCode === 39 /* "'" */ ||
|
|
31
|
+
charCode === 40 /* "(" */ ||
|
|
32
|
+
charCode === 41 /* ")" */ ||
|
|
33
|
+
charCode === 42 /* "*" */ ||
|
|
34
|
+
charCode === 43 /* "+" */ ||
|
|
35
|
+
charCode === 44 /* "," */ ||
|
|
36
|
+
charCode === 59 /* ";" */ ||
|
|
37
|
+
charCode === 61 /* "=" */) {
|
|
38
|
+
// sub-delims
|
|
39
|
+
}
|
|
40
|
+
else if (charCode === 58 /* ":" */ || charCode === 64 /* "@" */) {
|
|
41
|
+
// pchar extra
|
|
42
|
+
}
|
|
43
|
+
else if (charCode === 47 /* "/" */ || charCode === 63 /* "?" */) {
|
|
44
|
+
// fragment extra
|
|
45
|
+
}
|
|
46
|
+
else if (charCode === 37 /* "%" */) {
|
|
47
|
+
// pct-enc
|
|
48
|
+
if (i + 2 >= endIdx)
|
|
49
|
+
return false;
|
|
50
|
+
if (!isHexDigit(value.charCodeAt(i + 1)))
|
|
51
|
+
return false;
|
|
52
|
+
if (!isHexDigit(value.charCodeAt(i + 2)))
|
|
53
|
+
return false;
|
|
54
|
+
i += 2;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
function isHexDigit(code) {
|
|
63
|
+
return ((code >= 48 && code <= 57) || // 0-9
|
|
64
|
+
(code >= 65 && code <= 70) || // A-F
|
|
65
|
+
(code >= 97 && code <= 102) // a-f
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=uri.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/lib/uri.ts"],"names":[],"mappings":";;AAIA,gCAsDC;AAED,gCAMC;AAlED;;;GAGG;AACH,SAAgB,UAAU,CACxB,KAAa,EACb,QAAQ,GAAG,CAAC,EACZ,MAAM,GAAG,KAAK,CAAC,MAAM;IAErB,IAAI,QAAgB,CAAA;IACpB,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAE9B,uCAAuC;QACvC,kEAAkE;QAClE,sDAAsD;QACtD,kCAAkC;QAClC,gFAAgF;QAChF,IACE,CAAC,QAAQ,IAAI,EAAE,CAAC,OAAO,IAAI,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO;YAClD,CAAC,QAAQ,IAAI,EAAE,CAAC,OAAO,IAAI,QAAQ,IAAI,GAAG,CAAC,CAAC,OAAO;YACnD,CAAC,QAAQ,IAAI,EAAE,CAAC,OAAO,IAAI,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO;YAClD,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,GAAG,CAAC,SAAS,EAC1B,CAAC;YACD,aAAa;QACf,CAAC;aAAM,IACL,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS;YACzB,QAAQ,KAAK,EAAE,CAAC,SAAS,EACzB,CAAC;YACD,aAAa;QACf,CAAC;aAAM,IAAI,QAAQ,KAAK,EAAE,CAAC,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC;YAClE,cAAc;QAChB,CAAC;aAAM,IAAI,QAAQ,KAAK,EAAE,CAAC,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC;YAClE,iBAAiB;QACnB,CAAC;aAAM,IAAI,QAAQ,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC;YACrC,UAAU;YACV,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM;gBAAE,OAAO,KAAK,CAAA;YACjC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAA;YACtD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAA;YACtD,CAAC,IAAI,CAAC,CAAA;QACR,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,CACL,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM;QACpC,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM;QACpC,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,MAAM;KACnC,CAAA;AACH,CAAC"}
|
package/dist/methods/web.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAiB,MAAM,WAAW,CAAA;AAE9C,eAAO,MAAM,cAAc,aAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAiB,MAAM,WAAW,CAAA;AAE9C,eAAO,MAAM,cAAc,aAAkC,CAAA;AAa7D;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAa5D;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAGnD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAmBxE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC;cAG3B,OAAO,GAAG,QAAQ;EAKjC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAKhD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAetD"}
|
package/dist/methods/web.js
CHANGED
|
@@ -6,9 +6,20 @@ exports.asDidWeb = asDidWeb;
|
|
|
6
6
|
exports.assertDidWeb = assertDidWeb;
|
|
7
7
|
exports.didWebToUrl = didWebToUrl;
|
|
8
8
|
exports.urlToDidWeb = urlToDidWeb;
|
|
9
|
+
exports.buildDidWebUrl = buildDidWebUrl;
|
|
9
10
|
const did_error_js_1 = require("../did-error.js");
|
|
10
11
|
const did_js_1 = require("../did.js");
|
|
11
12
|
exports.DID_WEB_PREFIX = `did:web:`;
|
|
13
|
+
const canParse = URL.canParse?.bind(URL) ??
|
|
14
|
+
((url, base) => {
|
|
15
|
+
try {
|
|
16
|
+
new URL(url, base);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
12
23
|
/**
|
|
13
24
|
* This function checks if the input is a valid Web DID, as per DID spec.
|
|
14
25
|
*/
|
|
@@ -21,12 +32,12 @@ function isDidWeb(input) {
|
|
|
21
32
|
if (input.charAt(exports.DID_WEB_PREFIX.length) === ':')
|
|
22
33
|
return false;
|
|
23
34
|
try {
|
|
24
|
-
|
|
25
|
-
return true;
|
|
35
|
+
(0, did_js_1.assertDidMsid)(input, exports.DID_WEB_PREFIX.length);
|
|
26
36
|
}
|
|
27
37
|
catch {
|
|
28
38
|
return false;
|
|
29
39
|
}
|
|
40
|
+
return canParse(buildDidWebUrl(input));
|
|
30
41
|
}
|
|
31
42
|
function asDidWeb(input) {
|
|
32
43
|
assertDidWeb(input);
|
|
@@ -42,21 +53,15 @@ function assertDidWeb(input) {
|
|
|
42
53
|
if (input.charAt(exports.DID_WEB_PREFIX.length) === ':') {
|
|
43
54
|
throw new did_error_js_1.InvalidDidError(input, 'did:web MSID must not start with a colon');
|
|
44
55
|
}
|
|
45
|
-
|
|
56
|
+
// Make sure every char is valid (per DID spec)
|
|
57
|
+
(0, did_js_1.assertDidMsid)(input, exports.DID_WEB_PREFIX.length);
|
|
58
|
+
if (!canParse(buildDidWebUrl(input))) {
|
|
59
|
+
throw new did_error_js_1.InvalidDidError(input, 'Invalid Web DID');
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
62
|
function didWebToUrl(did) {
|
|
48
|
-
// Make sure every char is valid (per DID spec)
|
|
49
|
-
(0, did_js_1.assertDidMsid)(did, exports.DID_WEB_PREFIX.length);
|
|
50
|
-
const hostIdx = exports.DID_WEB_PREFIX.length;
|
|
51
|
-
const pathIdx = did.indexOf(':', hostIdx);
|
|
52
|
-
const host = pathIdx === -1 ? did.slice(hostIdx) : did.slice(hostIdx, pathIdx);
|
|
53
|
-
const path = pathIdx === -1 ? '' : did.slice(pathIdx);
|
|
54
63
|
try {
|
|
55
|
-
|
|
56
|
-
if (url.hostname === 'localhost') {
|
|
57
|
-
url.protocol = 'http:';
|
|
58
|
-
}
|
|
59
|
-
return url;
|
|
64
|
+
return new URL(buildDidWebUrl(did));
|
|
60
65
|
}
|
|
61
66
|
catch (cause) {
|
|
62
67
|
throw new did_error_js_1.InvalidDidError(did, 'Invalid Web DID', cause);
|
|
@@ -67,4 +72,16 @@ function urlToDidWeb(url) {
|
|
|
67
72
|
const path = url.pathname === '/' ? '' : url.pathname.replaceAll('/', ':');
|
|
68
73
|
return `did:web:${url.hostname}${port}${path}`;
|
|
69
74
|
}
|
|
75
|
+
function buildDidWebUrl(did) {
|
|
76
|
+
const hostIdx = exports.DID_WEB_PREFIX.length;
|
|
77
|
+
const pathIdx = did.indexOf(':', hostIdx);
|
|
78
|
+
const hostEnc = pathIdx === -1 ? did.slice(hostIdx) : did.slice(hostIdx, pathIdx);
|
|
79
|
+
const host = hostEnc.replaceAll('%3A', ':');
|
|
80
|
+
const path = pathIdx === -1 ? '' : did.slice(pathIdx).replaceAll(':', '/');
|
|
81
|
+
const proto = host.startsWith('localhost') &&
|
|
82
|
+
(host.length === 9 || host.charCodeAt(9) === 58) /* ':' */
|
|
83
|
+
? 'http'
|
|
84
|
+
: 'https';
|
|
85
|
+
return `${proto}://${host}${path}`;
|
|
86
|
+
}
|
|
70
87
|
//# sourceMappingURL=web.js.map
|
package/dist/methods/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/atproto.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { InvalidDidError } from './did-error.js'
|
|
3
3
|
import { Did } from './did.js'
|
|
4
|
+
import { isFragment } from './lib/uri.js'
|
|
4
5
|
import {
|
|
5
6
|
DID_PLC_PREFIX,
|
|
6
7
|
DID_WEB_PREFIX,
|
|
7
8
|
assertDidPlc,
|
|
8
9
|
assertDidWeb,
|
|
9
10
|
isDidPlc,
|
|
11
|
+
isDidWeb,
|
|
10
12
|
} from './methods.js'
|
|
11
13
|
|
|
12
14
|
// This file contains atproto-specific DID validation utilities.
|
|
@@ -58,17 +60,14 @@ export function assertAtprotoDidWeb(
|
|
|
58
60
|
): asserts input is Did<'web'> {
|
|
59
61
|
assertDidWeb(input)
|
|
60
62
|
|
|
61
|
-
if (input
|
|
63
|
+
if (isDidWebWithPath(input)) {
|
|
62
64
|
throw new InvalidDidError(
|
|
63
65
|
input,
|
|
64
66
|
`Atproto does not allow path components in Web DIDs`,
|
|
65
67
|
)
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
if (
|
|
69
|
-
input.includes('%3A', DID_WEB_PREFIX.length) &&
|
|
70
|
-
!input.startsWith('did:web:localhost%3A')
|
|
71
|
-
) {
|
|
70
|
+
if (isDidWebWithHttpsPort(input)) {
|
|
72
71
|
throw new InvalidDidError(
|
|
73
72
|
input,
|
|
74
73
|
`Atproto does not allow port numbers in Web DIDs, except for localhost`,
|
|
@@ -80,10 +79,57 @@ export function assertAtprotoDidWeb(
|
|
|
80
79
|
* @see {@link https://atproto.com/specs/did#blessed-did-methods}
|
|
81
80
|
*/
|
|
82
81
|
export function isAtprotoDidWeb(input: unknown): input is Did<'web'> {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
if (!isDidWeb(input)) {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (isDidWebWithPath(input)) {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (isDidWebWithHttpsPort(input)) {
|
|
87
91
|
return false
|
|
88
92
|
}
|
|
93
|
+
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function isDidWebWithPath(did: Did<'web'>): boolean {
|
|
98
|
+
return did.includes(':', DID_WEB_PREFIX.length)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function isLocalhostDid(did: Did<'web'>): boolean {
|
|
102
|
+
return (
|
|
103
|
+
did === 'did:web:localhost' ||
|
|
104
|
+
did.startsWith('did:web:localhost:') ||
|
|
105
|
+
did.startsWith('did:web:localhost%3A')
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function isDidWebWithHttpsPort(did: Did<'web'>): boolean {
|
|
110
|
+
if (isLocalhostDid(did)) return false
|
|
111
|
+
|
|
112
|
+
const pathIdx = did.indexOf(':', DID_WEB_PREFIX.length)
|
|
113
|
+
|
|
114
|
+
const hasPort =
|
|
115
|
+
pathIdx === -1
|
|
116
|
+
? // No path component, check if there's a port separator anywhere after
|
|
117
|
+
// the "did:web:" prefix
|
|
118
|
+
did.includes('%3A', DID_WEB_PREFIX.length)
|
|
119
|
+
: // There is a path component; if there is an encoded colon *before* it,
|
|
120
|
+
// then there is a port number
|
|
121
|
+
did.lastIndexOf('%3A', pathIdx) !== -1
|
|
122
|
+
|
|
123
|
+
return hasPort
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type AtprotoAudience = `${AtprotoDid}#${string}`
|
|
127
|
+
export const isAtprotoAudience = (value: unknown): value is AtprotoAudience => {
|
|
128
|
+
if (typeof value !== 'string') return false
|
|
129
|
+
const hashIndex = value.indexOf('#')
|
|
130
|
+
if (hashIndex === -1) return false
|
|
131
|
+
if (value.indexOf('#', hashIndex + 1) !== -1) return false
|
|
132
|
+
return (
|
|
133
|
+
isFragment(value, hashIndex + 1) && isAtprotoDid(value.slice(0, hashIndex))
|
|
134
|
+
)
|
|
89
135
|
}
|
package/src/did-document.ts
CHANGED
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { Did, didSchema } from './did.js'
|
|
3
|
+
import { isFragment } from './lib/uri.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* RFC3968 compliant URI
|
|
6
7
|
*
|
|
7
8
|
* @see {@link https://www.rfc-editor.org/rfc/rfc3986}
|
|
8
9
|
*/
|
|
9
|
-
const rfc3968UriSchema = z.string().
|
|
10
|
-
try {
|
|
11
|
-
new URL(data)
|
|
12
|
-
return true
|
|
13
|
-
} catch {
|
|
14
|
-
return false
|
|
15
|
-
}
|
|
16
|
-
}, 'RFC3968 compliant URI')
|
|
10
|
+
const rfc3968UriSchema = z.string().url('RFC3968 compliant URI')
|
|
17
11
|
|
|
18
12
|
const didControllerSchema = z.union([didSchema, z.array(didSchema)])
|
|
19
13
|
|
|
20
14
|
/**
|
|
21
|
-
* @note this schema
|
|
15
|
+
* @note this schema is too permissive
|
|
22
16
|
*/
|
|
23
17
|
const didRelativeUriSchema = z.union([
|
|
24
|
-
rfc3968UriSchema
|
|
25
|
-
|
|
18
|
+
rfc3968UriSchema.refine(
|
|
19
|
+
(value) => {
|
|
20
|
+
const fragmentIndex = value.indexOf('#')
|
|
21
|
+
if (fragmentIndex === -1) return false
|
|
22
|
+
return isFragment(value, fragmentIndex + 1)
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
message: 'Missing or invalid fragment in RFC3968 URI',
|
|
26
|
+
},
|
|
27
|
+
),
|
|
28
|
+
z
|
|
29
|
+
.string()
|
|
30
|
+
.refine((value) => value.charCodeAt(0) === 35 /* # */, {
|
|
31
|
+
message: 'Fragment must start with #',
|
|
32
|
+
})
|
|
33
|
+
.refine((value) => isFragment(value, 1), {
|
|
34
|
+
message: 'Invalid char in URI fragment',
|
|
35
|
+
}),
|
|
26
36
|
])
|
|
27
37
|
|
|
28
38
|
const didVerificationMethodSchema = z.object({
|
package/src/lib/uri.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see {@link https://www.w3.org/TR/did-1.0/#dfn-did-fragments}
|
|
3
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc3986#section-3.5}
|
|
4
|
+
*/
|
|
5
|
+
export function isFragment(
|
|
6
|
+
value: string,
|
|
7
|
+
startIdx = 0,
|
|
8
|
+
endIdx = value.length,
|
|
9
|
+
): boolean {
|
|
10
|
+
let charCode: number
|
|
11
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
12
|
+
charCode = value.charCodeAt(i)
|
|
13
|
+
|
|
14
|
+
// fragment = *( pchar / "/" / "?" )
|
|
15
|
+
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
16
|
+
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
17
|
+
// pct-encoded = "%" HEXDIG HEXDIG
|
|
18
|
+
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
19
|
+
if (
|
|
20
|
+
(charCode >= 65 /* A */ && charCode <= 90) /* Z */ ||
|
|
21
|
+
(charCode >= 97 /* a */ && charCode <= 122) /* z */ ||
|
|
22
|
+
(charCode >= 48 /* 0 */ && charCode <= 57) /* 9 */ ||
|
|
23
|
+
charCode === 45 /* "-" */ ||
|
|
24
|
+
charCode === 46 /* "." */ ||
|
|
25
|
+
charCode === 95 /* "_" */ ||
|
|
26
|
+
charCode === 126 /* "~" */
|
|
27
|
+
) {
|
|
28
|
+
// unreserved
|
|
29
|
+
} else if (
|
|
30
|
+
charCode === 33 /* "!" */ ||
|
|
31
|
+
charCode === 36 /* "$" */ ||
|
|
32
|
+
charCode === 38 /* "&" */ ||
|
|
33
|
+
charCode === 39 /* "'" */ ||
|
|
34
|
+
charCode === 40 /* "(" */ ||
|
|
35
|
+
charCode === 41 /* ")" */ ||
|
|
36
|
+
charCode === 42 /* "*" */ ||
|
|
37
|
+
charCode === 43 /* "+" */ ||
|
|
38
|
+
charCode === 44 /* "," */ ||
|
|
39
|
+
charCode === 59 /* ";" */ ||
|
|
40
|
+
charCode === 61 /* "=" */
|
|
41
|
+
) {
|
|
42
|
+
// sub-delims
|
|
43
|
+
} else if (charCode === 58 /* ":" */ || charCode === 64 /* "@" */) {
|
|
44
|
+
// pchar extra
|
|
45
|
+
} else if (charCode === 47 /* "/" */ || charCode === 63 /* "?" */) {
|
|
46
|
+
// fragment extra
|
|
47
|
+
} else if (charCode === 37 /* "%" */) {
|
|
48
|
+
// pct-enc
|
|
49
|
+
if (i + 2 >= endIdx) return false
|
|
50
|
+
if (!isHexDigit(value.charCodeAt(i + 1))) return false
|
|
51
|
+
if (!isHexDigit(value.charCodeAt(i + 2))) return false
|
|
52
|
+
i += 2
|
|
53
|
+
} else {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function isHexDigit(code: number): boolean {
|
|
62
|
+
return (
|
|
63
|
+
(code >= 48 && code <= 57) || // 0-9
|
|
64
|
+
(code >= 65 && code <= 70) || // A-F
|
|
65
|
+
(code >= 97 && code <= 102) // a-f
|
|
66
|
+
)
|
|
67
|
+
}
|
package/src/methods/web.ts
CHANGED
|
@@ -3,6 +3,17 @@ import { Did, assertDidMsid } from '../did.js'
|
|
|
3
3
|
|
|
4
4
|
export const DID_WEB_PREFIX = `did:web:` satisfies Did<'web'>
|
|
5
5
|
|
|
6
|
+
const canParse =
|
|
7
|
+
URL.canParse?.bind(URL) ??
|
|
8
|
+
((url, base) => {
|
|
9
|
+
try {
|
|
10
|
+
new URL(url, base)
|
|
11
|
+
return true
|
|
12
|
+
} catch {
|
|
13
|
+
return false
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
6
17
|
/**
|
|
7
18
|
* This function checks if the input is a valid Web DID, as per DID spec.
|
|
8
19
|
*/
|
|
@@ -13,11 +24,12 @@ export function isDidWeb(input: unknown): input is Did<'web'> {
|
|
|
13
24
|
if (input.charAt(DID_WEB_PREFIX.length) === ':') return false
|
|
14
25
|
|
|
15
26
|
try {
|
|
16
|
-
|
|
17
|
-
return true
|
|
27
|
+
assertDidMsid(input, DID_WEB_PREFIX.length)
|
|
18
28
|
} catch {
|
|
19
29
|
return false
|
|
20
30
|
}
|
|
31
|
+
|
|
32
|
+
return canParse(buildDidWebUrl(input as Did<'web'>))
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
export function asDidWeb(input: unknown): Did<'web'> {
|
|
@@ -38,27 +50,19 @@ export function assertDidWeb(input: unknown): asserts input is Did<'web'> {
|
|
|
38
50
|
throw new InvalidDidError(input, 'did:web MSID must not start with a colon')
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
void didWebToUrl(input as Did<'web'>)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function didWebToUrl(did: Did<'web'>) {
|
|
45
53
|
// Make sure every char is valid (per DID spec)
|
|
46
|
-
assertDidMsid(
|
|
47
|
-
|
|
48
|
-
const hostIdx = DID_WEB_PREFIX.length
|
|
49
|
-
const pathIdx = did.indexOf(':', hostIdx)
|
|
54
|
+
assertDidMsid(input, DID_WEB_PREFIX.length)
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
if (!canParse(buildDidWebUrl(input as Did<'web'>))) {
|
|
57
|
+
throw new InvalidDidError(input, 'Invalid Web DID')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
53
60
|
|
|
61
|
+
export function didWebToUrl(did: Did<'web'>) {
|
|
54
62
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
) as URL & { protocol: 'http:' | 'https:' }
|
|
58
|
-
if (url.hostname === 'localhost') {
|
|
59
|
-
url.protocol = 'http:'
|
|
63
|
+
return new URL(buildDidWebUrl(did)) as URL & {
|
|
64
|
+
protocol: 'http:' | 'https:'
|
|
60
65
|
}
|
|
61
|
-
return url
|
|
62
66
|
} catch (cause) {
|
|
63
67
|
throw new InvalidDidError(did, 'Invalid Web DID', cause)
|
|
64
68
|
}
|
|
@@ -70,3 +74,20 @@ export function urlToDidWeb(url: URL): Did<'web'> {
|
|
|
70
74
|
|
|
71
75
|
return `did:web:${url.hostname}${port}${path}`
|
|
72
76
|
}
|
|
77
|
+
|
|
78
|
+
export function buildDidWebUrl(did: Did<'web'>): string {
|
|
79
|
+
const hostIdx = DID_WEB_PREFIX.length
|
|
80
|
+
const pathIdx = did.indexOf(':', hostIdx)
|
|
81
|
+
|
|
82
|
+
const hostEnc =
|
|
83
|
+
pathIdx === -1 ? did.slice(hostIdx) : did.slice(hostIdx, pathIdx)
|
|
84
|
+
const host = hostEnc.replaceAll('%3A', ':')
|
|
85
|
+
const path = pathIdx === -1 ? '' : did.slice(pathIdx).replaceAll(':', '/')
|
|
86
|
+
const proto =
|
|
87
|
+
host.startsWith('localhost') &&
|
|
88
|
+
(host.length === 9 || host.charCodeAt(9) === 58) /* ':' */
|
|
89
|
+
? 'http'
|
|
90
|
+
: 'https'
|
|
91
|
+
|
|
92
|
+
return `${proto}://${host}${path}`
|
|
93
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/atproto.ts","./src/did-document.ts","./src/did-error.ts","./src/did.ts","./src/index.ts","./src/methods.ts","./src/methods/plc.ts","./src/methods/web.ts"],"version":"5.
|
|
1
|
+
{"root":["./src/atproto.ts","./src/did-document.ts","./src/did-error.ts","./src/did.ts","./src/index.ts","./src/methods.ts","./src/lib/uri.ts","./src/methods/plc.ts","./src/methods/web.ts"],"version":"5.8.2"}
|