@keytrace/runner 0.0.3

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.
Files changed (142) hide show
  1. package/README.md +139 -0
  2. package/dist/actions/css-select.d.ts +6 -0
  3. package/dist/actions/css-select.d.ts.map +1 -0
  4. package/dist/actions/css-select.js +14 -0
  5. package/dist/actions/css-select.js.map +1 -0
  6. package/dist/actions/dns-txt.d.ts +6 -0
  7. package/dist/actions/dns-txt.d.ts.map +1 -0
  8. package/dist/actions/dns-txt.js +17 -0
  9. package/dist/actions/dns-txt.js.map +1 -0
  10. package/dist/actions/http-get.d.ts +6 -0
  11. package/dist/actions/http-get.d.ts.map +1 -0
  12. package/dist/actions/http-get.js +19 -0
  13. package/dist/actions/http-get.js.map +1 -0
  14. package/dist/actions/index.d.ts +6 -0
  15. package/dist/actions/index.d.ts.map +1 -0
  16. package/dist/actions/index.js +6 -0
  17. package/dist/actions/index.js.map +1 -0
  18. package/dist/actions/json-path.d.ts +12 -0
  19. package/dist/actions/json-path.d.ts.map +1 -0
  20. package/dist/actions/json-path.js +26 -0
  21. package/dist/actions/json-path.js.map +1 -0
  22. package/dist/actions/regex-match.d.ts +6 -0
  23. package/dist/actions/regex-match.d.ts.map +1 -0
  24. package/dist/actions/regex-match.js +14 -0
  25. package/dist/actions/regex-match.js.map +1 -0
  26. package/dist/claim.d.ts +38 -0
  27. package/dist/claim.d.ts.map +1 -0
  28. package/dist/claim.js +253 -0
  29. package/dist/claim.js.map +1 -0
  30. package/dist/constants.d.ts +17 -0
  31. package/dist/constants.d.ts.map +1 -0
  32. package/dist/constants.js +17 -0
  33. package/dist/constants.js.map +1 -0
  34. package/dist/expect.d.ts +12 -0
  35. package/dist/expect.d.ts.map +1 -0
  36. package/dist/expect.js +33 -0
  37. package/dist/expect.js.map +1 -0
  38. package/dist/fetchers/activitypub.d.ts +25 -0
  39. package/dist/fetchers/activitypub.d.ts.map +1 -0
  40. package/dist/fetchers/activitypub.js +32 -0
  41. package/dist/fetchers/activitypub.js.map +1 -0
  42. package/dist/fetchers/dns.d.ts +21 -0
  43. package/dist/fetchers/dns.d.ts.map +1 -0
  44. package/dist/fetchers/dns.js +61 -0
  45. package/dist/fetchers/dns.js.map +1 -0
  46. package/dist/fetchers/http.d.ts +10 -0
  47. package/dist/fetchers/http.d.ts.map +1 -0
  48. package/dist/fetchers/http.js +30 -0
  49. package/dist/fetchers/http.js.map +1 -0
  50. package/dist/fetchers/index.d.ts +16 -0
  51. package/dist/fetchers/index.d.ts.map +1 -0
  52. package/dist/fetchers/index.js +22 -0
  53. package/dist/fetchers/index.js.map +1 -0
  54. package/dist/index.d.ts +21 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +26 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/interpolate.d.ts +12 -0
  59. package/dist/interpolate.d.ts.map +1 -0
  60. package/dist/interpolate.js +23 -0
  61. package/dist/interpolate.js.map +1 -0
  62. package/dist/profile.d.ts +42 -0
  63. package/dist/profile.d.ts.map +1 -0
  64. package/dist/profile.js +176 -0
  65. package/dist/profile.js.map +1 -0
  66. package/dist/recipes/dns-txt.d.ts +9 -0
  67. package/dist/recipes/dns-txt.d.ts.map +1 -0
  68. package/dist/recipes/dns-txt.js +45 -0
  69. package/dist/recipes/dns-txt.js.map +1 -0
  70. package/dist/recipes/github-gist.d.ts +9 -0
  71. package/dist/recipes/github-gist.d.ts.map +1 -0
  72. package/dist/recipes/github-gist.js +52 -0
  73. package/dist/recipes/github-gist.js.map +1 -0
  74. package/dist/recipes/index.d.ts +3 -0
  75. package/dist/recipes/index.d.ts.map +1 -0
  76. package/dist/recipes/index.js +3 -0
  77. package/dist/recipes/index.js.map +1 -0
  78. package/dist/runner.d.ts +7 -0
  79. package/dist/runner.d.ts.map +1 -0
  80. package/dist/runner.js +100 -0
  81. package/dist/runner.js.map +1 -0
  82. package/dist/serviceProviders/activitypub.d.ts +10 -0
  83. package/dist/serviceProviders/activitypub.d.ts.map +1 -0
  84. package/dist/serviceProviders/activitypub.js +73 -0
  85. package/dist/serviceProviders/activitypub.js.map +1 -0
  86. package/dist/serviceProviders/bsky.d.ts +10 -0
  87. package/dist/serviceProviders/bsky.d.ts.map +1 -0
  88. package/dist/serviceProviders/bsky.js +63 -0
  89. package/dist/serviceProviders/bsky.js.map +1 -0
  90. package/dist/serviceProviders/dns.d.ts +10 -0
  91. package/dist/serviceProviders/dns.d.ts.map +1 -0
  92. package/dist/serviceProviders/dns.js +65 -0
  93. package/dist/serviceProviders/dns.js.map +1 -0
  94. package/dist/serviceProviders/github.d.ts +10 -0
  95. package/dist/serviceProviders/github.d.ts.map +1 -0
  96. package/dist/serviceProviders/github.js +100 -0
  97. package/dist/serviceProviders/github.js.map +1 -0
  98. package/dist/serviceProviders/index.d.ts +26 -0
  99. package/dist/serviceProviders/index.d.ts.map +1 -0
  100. package/dist/serviceProviders/index.js +55 -0
  101. package/dist/serviceProviders/index.js.map +1 -0
  102. package/dist/serviceProviders/npm.d.ts +10 -0
  103. package/dist/serviceProviders/npm.d.ts.map +1 -0
  104. package/dist/serviceProviders/npm.js +99 -0
  105. package/dist/serviceProviders/npm.js.map +1 -0
  106. package/dist/serviceProviders/types.d.ts +106 -0
  107. package/dist/serviceProviders/types.d.ts.map +1 -0
  108. package/dist/serviceProviders/types.js +2 -0
  109. package/dist/serviceProviders/types.js.map +1 -0
  110. package/dist/types.d.ts +165 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +12 -0
  113. package/dist/types.js.map +1 -0
  114. package/package.json +37 -0
  115. package/src/actions/css-select.ts +14 -0
  116. package/src/actions/dns-txt.ts +16 -0
  117. package/src/actions/http-get.ts +19 -0
  118. package/src/actions/index.ts +5 -0
  119. package/src/actions/json-path.ts +29 -0
  120. package/src/actions/regex-match.ts +13 -0
  121. package/src/claim.ts +293 -0
  122. package/src/constants.ts +19 -0
  123. package/src/expect.ts +36 -0
  124. package/src/fetchers/activitypub.ts +53 -0
  125. package/src/fetchers/dns.ts +82 -0
  126. package/src/fetchers/http.ts +38 -0
  127. package/src/fetchers/index.ts +30 -0
  128. package/src/index.ts +57 -0
  129. package/src/interpolate.ts +20 -0
  130. package/src/profile.ts +229 -0
  131. package/src/recipes/dns-txt.ts +46 -0
  132. package/src/recipes/github-gist.ts +53 -0
  133. package/src/recipes/index.ts +2 -0
  134. package/src/runner.ts +116 -0
  135. package/src/serviceProviders/activitypub.ts +84 -0
  136. package/src/serviceProviders/bsky.ts +73 -0
  137. package/src/serviceProviders/dns.ts +75 -0
  138. package/src/serviceProviders/github.ts +112 -0
  139. package/src/serviceProviders/index.ts +65 -0
  140. package/src/serviceProviders/npm.ts +116 -0
  141. package/src/serviceProviders/types.ts +121 -0
  142. package/src/types.ts +181 -0
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # @keytrace/runner
2
+
3
+ Core verification library for Keytrace identity claims. Matches claim URIs to service providers, fetches proofs, and verifies ownership.
4
+
5
+ This library is still very work in progress, and not fully built out for folks who want to run the full verification proofing system. You can use @keytrace/verify to get a list of claims and verify they are real based on public key encryption.
6
+
7
+ This would allow you to do the HTTP and DNS requests necessary to make the initial proof.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @keytrace/runner
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Verify a Claim
18
+
19
+ ```typescript
20
+ import { createClaim, verifyClaim, ClaimStatus } from '@keytrace/runner';
21
+
22
+ // Create and verify a claim
23
+ const claim = createClaim('https://gist.github.com/octocat/abc123', 'did:plc:xyz789');
24
+ const result = await verifyClaim(claim);
25
+
26
+ if (result.status === ClaimStatus.VERIFIED) {
27
+ console.log('Claim verified!');
28
+ console.log('Identity:', result.identity);
29
+ } else {
30
+ console.log('Verification failed:', result.errors);
31
+ }
32
+ ```
33
+
34
+ ### Fetch a User's Profile and Claims
35
+
36
+ ```typescript
37
+ import { fetchProfile, verifyAllClaims, getProfileSummary } from '@keytrace/runner';
38
+
39
+ // Fetch profile and claims from ATProto
40
+ const profile = await fetchProfile('alice.bsky.social');
41
+
42
+ // Verify all claims
43
+ const verified = await verifyAllClaims(profile);
44
+
45
+ // Get summary
46
+ const summary = getProfileSummary(verified);
47
+ console.log(`${summary.verified}/${summary.total} claims verified`);
48
+ ```
49
+
50
+ ### Match URIs to Service Providers
51
+
52
+ ```typescript
53
+ import { serviceProviders } from '@keytrace/runner';
54
+
55
+ const matches = serviceProviders.matchUri('https://gist.github.com/octocat/abc123');
56
+ // [{ provider: { id: 'github', name: 'GitHub', ... }, match: [...], isAmbiguous: false }]
57
+
58
+ const matches2 = serviceProviders.matchUri('dns:example.com');
59
+ // [{ provider: { id: 'dns', name: 'Domain', ... }, match: [...], isAmbiguous: false }]
60
+ ```
61
+
62
+ ## Service Providers
63
+
64
+ Built-in providers for identity verification:
65
+
66
+ | Provider | URI Pattern | Proof Location |
67
+ |----------|-------------|----------------|
68
+ | GitHub | `https://gist.github.com/user/id` | Gist content |
69
+ | DNS | `dns:example.com` | TXT record |
70
+ | Mastodon | `https://instance/@user` | Profile bio/fields |
71
+ | Bluesky | `https://bsky.app/profile/handle` | Profile bio |
72
+ | npm | `https://npmjs.com/package/keytrace-handle` | package.json |
73
+
74
+ ## API
75
+
76
+ ### Claims
77
+
78
+ ```typescript
79
+ // Create a claim
80
+ createClaim(uri: string, did: string): ClaimState
81
+
82
+ // Match claim to service providers
83
+ matchClaim(claim: ClaimState): void
84
+
85
+ // Verify claim by fetching proof
86
+ verifyClaim(claim: ClaimState, options?: VerifyOptions): Promise<ClaimVerificationResult>
87
+
88
+ // Check if claim matches multiple providers
89
+ isClaimAmbiguous(claim: ClaimState): boolean
90
+ ```
91
+
92
+ ### Profiles
93
+
94
+ ```typescript
95
+ // Fetch profile and claims from ATProto
96
+ fetchProfile(handleOrDid: string): Promise<FetchedProfile>
97
+
98
+ // Verify all claims in a profile
99
+ verifyAllClaims(profile: FetchedProfile): Promise<FetchedProfile>
100
+
101
+ // Get verification summary
102
+ getProfileSummary(profile: FetchedProfile): { total: number; verified: number; failed: number }
103
+ ```
104
+
105
+ ### Service Providers
106
+
107
+ ```typescript
108
+ import { serviceProviders } from '@keytrace/runner';
109
+
110
+ // Match URI to providers
111
+ serviceProviders.matchUri(uri: string): ServiceProviderMatch[]
112
+
113
+ // Get all providers
114
+ serviceProviders.all: ServiceProvider[]
115
+
116
+ // Get provider by ID
117
+ serviceProviders.get(id: string): ServiceProvider | undefined
118
+ ```
119
+
120
+ ## Claim Status
121
+
122
+ ```typescript
123
+ enum ClaimStatus {
124
+ INIT = 'init', // Created, not yet matched
125
+ MATCHED = 'matched', // URI matched to provider
126
+ VERIFIED = 'verified', // Proof verified successfully
127
+ FAILED = 'failed', // Proof verification failed
128
+ ERROR = 'error', // Error during verification
129
+ }
130
+ ```
131
+
132
+ ## Verification Options
133
+
134
+ ```typescript
135
+ interface VerifyOptions {
136
+ timeout?: number; // Request timeout in ms (default: 10000)
137
+ fetch?: typeof fetch; // Custom fetch function
138
+ }
139
+ ```
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Parse HTML and extract text content using a CSS selector.
3
+ * Uses cheerio for server-side HTML parsing.
4
+ */
5
+ export declare function cssSelect(html: string, selector: string): string;
6
+ //# sourceMappingURL=css-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-select.d.ts","sourceRoot":"","sources":["../../src/actions/css-select.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhE"}
@@ -0,0 +1,14 @@
1
+ import * as cheerio from "cheerio";
2
+ /**
3
+ * Parse HTML and extract text content using a CSS selector.
4
+ * Uses cheerio for server-side HTML parsing.
5
+ */
6
+ export function cssSelect(html, selector) {
7
+ const $ = cheerio.load(html);
8
+ const elements = $(selector);
9
+ if (elements.length === 0) {
10
+ throw new Error(`No elements matched selector: "${selector}"`);
11
+ }
12
+ return elements.first().text().trim();
13
+ }
14
+ //# sourceMappingURL=css-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-select.js","sourceRoot":"","sources":["../../src/actions/css-select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,QAAgB;IACtD,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,GAAG,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Perform a DNS TXT record lookup for a domain.
3
+ * Node only - throws a descriptive error in browser environments.
4
+ */
5
+ export declare function dnsTxt(domain: string): Promise<string[]>;
6
+ //# sourceMappingURL=dns-txt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-txt.d.ts","sourceRoot":"","sources":["../../src/actions/dns-txt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAW9D"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Perform a DNS TXT record lookup for a domain.
3
+ * Node only - throws a descriptive error in browser environments.
4
+ */
5
+ export async function dnsTxt(domain) {
6
+ let dns;
7
+ try {
8
+ dns = await import("node:dns/promises");
9
+ }
10
+ catch {
11
+ throw new Error("DNS TXT lookups are not available in the browser. " + "Use the server-side proxy endpoint (POST /api/proxy/dns) instead.");
12
+ }
13
+ const records = await dns.resolveTxt(domain);
14
+ // resolveTxt returns string[][] - flatten to string[]
15
+ return records.map((chunks) => chunks.join(""));
16
+ }
17
+ //# sourceMappingURL=dns-txt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-txt.js","sourceRoot":"","sources":["../../src/actions/dns-txt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc;IACzC,IAAI,GAAuC,CAAC;IAC5C,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oDAAoD,GAAG,mEAAmE,CAAC,CAAC;IAC9I,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7C,sDAAsD;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { FetchFn } from "../types.js";
2
+ /**
3
+ * Fetch a URL using the injected fetch function and return the response body as text.
4
+ */
5
+ export declare function httpGet(url: string, fetchFn: FetchFn, timeout?: number): Promise<string>;
6
+ //# sourceMappingURL=http-get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-get.d.ts","sourceRoot":"","sources":["../../src/actions/http-get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa9F"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Fetch a URL using the injected fetch function and return the response body as text.
3
+ */
4
+ export async function httpGet(url, fetchFn, timeout) {
5
+ const controller = new AbortController();
6
+ const timeoutId = timeout ? setTimeout(() => controller.abort(), timeout) : undefined;
7
+ try {
8
+ const response = await fetchFn(url, { signal: controller.signal });
9
+ if (!response.ok) {
10
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
11
+ }
12
+ return await response.text();
13
+ }
14
+ finally {
15
+ if (timeoutId !== undefined)
16
+ clearTimeout(timeoutId);
17
+ }
18
+ }
19
+ //# sourceMappingURL=http-get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-get.js","sourceRoot":"","sources":["../../src/actions/http-get.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,OAAgB,EAAE,OAAgB;IAC3E,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { httpGet } from "./http-get.js";
2
+ export { jsonPath } from "./json-path.js";
3
+ export { cssSelect } from "./css-select.js";
4
+ export { regexMatch } from "./regex-match.js";
5
+ export { dnsTxt } from "./dns-txt.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { httpGet } from "./http-get.js";
2
+ export { jsonPath } from "./json-path.js";
3
+ export { cssSelect } from "./css-select.js";
4
+ export { regexMatch } from "./regex-match.js";
5
+ export { dnsTxt } from "./dns-txt.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Extract data from a JSON string (or parsed object) using a simple dot-notation path.
3
+ *
4
+ * Supports paths like:
5
+ * "$.keytrace" -> obj.keytrace
6
+ * "$.data.name" -> obj.data.name
7
+ * "$.items[0].id" -> obj.items[0].id
8
+ *
9
+ * The leading "$." is optional.
10
+ */
11
+ export declare function jsonPath(data: string | object, selector: string): unknown;
12
+ //# sourceMappingURL=json-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-path.d.ts","sourceRoot":"","sources":["../../src/actions/json-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkBzE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Extract data from a JSON string (or parsed object) using a simple dot-notation path.
3
+ *
4
+ * Supports paths like:
5
+ * "$.keytrace" -> obj.keytrace
6
+ * "$.data.name" -> obj.data.name
7
+ * "$.items[0].id" -> obj.items[0].id
8
+ *
9
+ * The leading "$." is optional.
10
+ */
11
+ export function jsonPath(data, selector) {
12
+ const obj = typeof data === "string" ? JSON.parse(data) : data;
13
+ // Strip leading $. if present
14
+ const path = selector.startsWith("$.") ? selector.slice(2) : selector;
15
+ // Split on dots and bracket notation
16
+ const segments = path.split(/\.|\[(\d+)\]/).filter((s) => s !== "" && s !== undefined);
17
+ let current = obj;
18
+ for (const segment of segments) {
19
+ if (current == null || typeof current !== "object") {
20
+ return undefined;
21
+ }
22
+ current = current[segment];
23
+ }
24
+ return current;
25
+ }
26
+ //# sourceMappingURL=json-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-path.js","sourceRoot":"","sources":["../../src/actions/json-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAqB,EAAE,QAAgB;IAC9D,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE/D,8BAA8B;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEtE,qCAAqC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;IAEvF,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACnD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAI,OAAmC,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Match content against a regex pattern.
3
+ * Returns the first capture group if present, otherwise the full match.
4
+ */
5
+ export declare function regexMatch(content: string, pattern: string): string;
6
+ //# sourceMappingURL=regex-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex-match.d.ts","sourceRoot":"","sources":["../../src/actions/regex-match.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAQnE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Match content against a regex pattern.
3
+ * Returns the first capture group if present, otherwise the full match.
4
+ */
5
+ export function regexMatch(content, pattern) {
6
+ const regex = new RegExp(pattern);
7
+ const match = content.match(regex);
8
+ if (!match) {
9
+ throw new Error(`Pattern "${pattern}" did not match content`);
10
+ }
11
+ // Return first capture group if available, otherwise the full match
12
+ return match[1] ?? match[0];
13
+ }
14
+ //# sourceMappingURL=regex-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex-match.js","sourceRoot":"","sources":["../../src/actions/regex-match.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,OAAe;IACzD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,yBAAyB,CAAC,CAAC;IAChE,CAAC;IACD,oEAAoE;IACpE,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { ClaimStatus } from "./types.js";
2
+ import { type ServiceProviderMatch } from "./serviceProviders/index.js";
3
+ import type { VerifyOptions, ClaimVerificationResult } from "./types.js";
4
+ /**
5
+ * Validate a DID string. Accepts did:plc and did:web formats.
6
+ */
7
+ export declare function isValidDid(did: string): boolean;
8
+ /**
9
+ * A single identity claim linking a DID to an external account
10
+ */
11
+ export interface ClaimState {
12
+ uri: string;
13
+ did: string;
14
+ status: ClaimStatus;
15
+ matches: ServiceProviderMatch[];
16
+ errors: string[];
17
+ }
18
+ /**
19
+ * Create a new claim state
20
+ */
21
+ export declare function createClaim(uri: string, did: string): ClaimState;
22
+ /**
23
+ * Match the claim URI against known service providers
24
+ */
25
+ export declare function matchClaim(claim: ClaimState): void;
26
+ /**
27
+ * Check if the claim is ambiguous (matches multiple providers)
28
+ */
29
+ export declare function isClaimAmbiguous(claim: ClaimState): boolean;
30
+ /**
31
+ * Get the matched service provider (first unambiguous match, or first match)
32
+ */
33
+ export declare function getMatchedProvider(claim: ClaimState): ServiceProviderMatch | undefined;
34
+ /**
35
+ * Verify the claim by fetching proof and checking for DID
36
+ */
37
+ export declare function verifyClaim(claim: ClaimState, opts?: VerifyOptions): Promise<ClaimVerificationResult>;
38
+ //# sourceMappingURL=claim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim.d.ts","sourceRoot":"","sources":["../src/claim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAY,KAAK,oBAAoB,EAAuC,MAAM,6BAA6B,CAAC;AAEvH,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAqD,MAAM,YAAY,CAAC;AAO5H;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAWhE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAOlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,GAAG,SAAS,CAEtF;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0E/G"}
package/dist/claim.js ADDED
@@ -0,0 +1,253 @@
1
+ import { ClaimStatus } from "./types.js";
2
+ import { DEFAULT_TIMEOUT } from "./constants.js";
3
+ import { matchUri } from "./serviceProviders/index.js";
4
+ import * as fetchers from "./fetchers/index.js";
5
+ // did:plc identifiers are base32-encoded, lowercase
6
+ const DID_PLC_RE = /^did:plc:[a-z2-7]{24}$/;
7
+ // did:web uses a domain name (with optional port and path segments encoded as colons)
8
+ const DID_WEB_RE = /^did:web:[a-zA-Z0-9._:%-]+$/;
9
+ /**
10
+ * Validate a DID string. Accepts did:plc and did:web formats.
11
+ */
12
+ export function isValidDid(did) {
13
+ return DID_PLC_RE.test(did) || DID_WEB_RE.test(did);
14
+ }
15
+ /**
16
+ * Create a new claim state
17
+ */
18
+ export function createClaim(uri, did) {
19
+ if (!isValidDid(did)) {
20
+ throw new Error(`Invalid DID format: ${did}`);
21
+ }
22
+ return {
23
+ uri,
24
+ did,
25
+ status: ClaimStatus.INIT,
26
+ matches: [],
27
+ errors: [],
28
+ };
29
+ }
30
+ /**
31
+ * Match the claim URI against known service providers
32
+ */
33
+ export function matchClaim(claim) {
34
+ claim.matches = matchUri(claim.uri);
35
+ claim.status = claim.matches.length > 0 ? ClaimStatus.MATCHED : ClaimStatus.ERROR;
36
+ if (claim.matches.length === 0) {
37
+ claim.errors.push(`No service provider matched URI: ${claim.uri}`);
38
+ }
39
+ }
40
+ /**
41
+ * Check if the claim is ambiguous (matches multiple providers)
42
+ */
43
+ export function isClaimAmbiguous(claim) {
44
+ return claim.matches.length > 1 || (claim.matches.length === 1 && claim.matches[0].isAmbiguous);
45
+ }
46
+ /**
47
+ * Get the matched service provider (first unambiguous match, or first match)
48
+ */
49
+ export function getMatchedProvider(claim) {
50
+ return claim.matches[0];
51
+ }
52
+ /**
53
+ * Verify the claim by fetching proof and checking for DID
54
+ */
55
+ export async function verifyClaim(claim, opts = {}) {
56
+ if (claim.status === ClaimStatus.INIT) {
57
+ matchClaim(claim);
58
+ }
59
+ if (claim.matches.length === 0) {
60
+ return {
61
+ status: ClaimStatus.ERROR,
62
+ errors: claim.errors,
63
+ timestamp: new Date(),
64
+ };
65
+ }
66
+ // Track proof details for the response
67
+ let proofDetails;
68
+ // Try each matched provider until one succeeds
69
+ for (const match of claim.matches) {
70
+ try {
71
+ const config = match.provider.processURI(claim.uri, match.match);
72
+ const proofData = await fetchProof(config.proof.request, opts);
73
+ // Build proof details
74
+ const patterns = generateProofPatterns(claim.did);
75
+ const targetResults = checkProofWithDetails(proofData, config.proof.target, patterns);
76
+ proofDetails = {
77
+ fetchUrl: config.proof.request.uri,
78
+ fetcher: config.proof.request.fetcher,
79
+ content: truncateContent(proofData),
80
+ targets: targetResults,
81
+ patterns,
82
+ };
83
+ const verified = targetResults.some((t) => t.matched);
84
+ if (verified) {
85
+ claim.status = ClaimStatus.VERIFIED;
86
+ // Extract identity metadata via postprocess if available
87
+ let identity;
88
+ if (match.provider.postprocess) {
89
+ const metadata = match.provider.postprocess(proofData, match.match);
90
+ identity = {
91
+ subject: metadata.subject,
92
+ avatarUrl: metadata.avatarUrl,
93
+ profileUrl: metadata.profileUrl,
94
+ displayName: metadata.displayName,
95
+ };
96
+ }
97
+ return {
98
+ status: ClaimStatus.VERIFIED,
99
+ errors: [],
100
+ timestamp: new Date(),
101
+ identity,
102
+ proofDetails,
103
+ };
104
+ }
105
+ }
106
+ catch (err) {
107
+ claim.errors.push(`${match.provider.id}: ${err instanceof Error ? err.message : "Unknown error"}`);
108
+ }
109
+ // Stop on unambiguous match
110
+ if (!match.isAmbiguous)
111
+ break;
112
+ }
113
+ claim.status = ClaimStatus.FAILED;
114
+ return {
115
+ status: ClaimStatus.FAILED,
116
+ errors: claim.errors,
117
+ timestamp: new Date(),
118
+ proofDetails,
119
+ };
120
+ }
121
+ async function fetchProof(request, opts) {
122
+ const fetcher = fetchers.get(request.fetcher);
123
+ if (!fetcher) {
124
+ throw new Error(`Unknown fetcher: ${request.fetcher}`);
125
+ }
126
+ console.log(`[runner] Fetching proof: ${request.fetcher} ${request.uri} (format: ${request.format})`);
127
+ const data = await fetcher.fetch(request.uri, {
128
+ format: request.format,
129
+ timeout: opts.timeout ?? DEFAULT_TIMEOUT,
130
+ headers: request.options?.headers,
131
+ });
132
+ const fileKeys = data && typeof data === "object" && "files" in data ? Object.keys(data.files) : [];
133
+ console.log(`[runner] Fetched proof, files: ${JSON.stringify(fileKeys)}`);
134
+ return data;
135
+ }
136
+ function checkProofWithDetails(data, targets, patterns) {
137
+ console.log(`[runner] Checking proof, patterns: ${JSON.stringify(patterns)}`);
138
+ console.log(`[runner] Proof targets: ${JSON.stringify(targets.map((t) => t.path.join(".")))}`);
139
+ const results = [];
140
+ for (const target of targets) {
141
+ const values = extractValues(data, target.path);
142
+ console.log(`[runner] Target ${target.path.join(".")}: found ${values.length} value(s)${values.length > 0 ? `: ${JSON.stringify(values.map((v) => v.slice(0, 100)))}` : ""}`);
143
+ let matched = false;
144
+ for (const value of values) {
145
+ if (matchesPattern(value, patterns, target.relation)) {
146
+ console.log(`[runner] Match found at ${target.path.join(".")} (relation: ${target.relation})`);
147
+ matched = true;
148
+ break;
149
+ }
150
+ }
151
+ results.push({
152
+ path: target.path,
153
+ relation: target.relation,
154
+ valuesFound: values.map((v) => v.slice(0, 500)), // Truncate long values
155
+ matched,
156
+ });
157
+ }
158
+ if (!results.some((r) => r.matched)) {
159
+ console.log(`[runner] No match found in any target`);
160
+ }
161
+ return results;
162
+ }
163
+ function truncateContent(data) {
164
+ const MAX_LENGTH = 2000;
165
+ let content;
166
+ if (data === null || data === undefined) {
167
+ return "(no content returned)";
168
+ }
169
+ if (typeof data === "string") {
170
+ content = data;
171
+ }
172
+ else {
173
+ try {
174
+ content = JSON.stringify(data, null, 2);
175
+ }
176
+ catch {
177
+ content = String(data);
178
+ }
179
+ }
180
+ if (content.length > MAX_LENGTH) {
181
+ return content.slice(0, MAX_LENGTH) + "\n... (truncated)";
182
+ }
183
+ return content;
184
+ }
185
+ function generateProofPatterns(did) {
186
+ const patterns = [did];
187
+ if (did.startsWith("did:plc:")) {
188
+ patterns.push(did.replace("did:plc:", ""));
189
+ }
190
+ return patterns;
191
+ }
192
+ function extractValues(data, path) {
193
+ const results = [];
194
+ extractValuesRecursive(data, path, 0, results);
195
+ return results;
196
+ }
197
+ function extractValuesRecursive(data, path, index, results) {
198
+ if (data === null || data === undefined)
199
+ return;
200
+ if (index >= path.length) {
201
+ if (typeof data === "string") {
202
+ results.push(data);
203
+ }
204
+ else if (Array.isArray(data)) {
205
+ for (const item of data) {
206
+ if (typeof item === "string") {
207
+ results.push(item);
208
+ }
209
+ }
210
+ }
211
+ return;
212
+ }
213
+ const key = path[index];
214
+ if (key === "*") {
215
+ if (Array.isArray(data)) {
216
+ // Wildcard for arrays: iterate all items
217
+ for (const item of data) {
218
+ extractValuesRecursive(item, path, index + 1, results);
219
+ }
220
+ }
221
+ else if (typeof data === "object" && data !== null) {
222
+ // Wildcard for objects: iterate all values
223
+ const record = data;
224
+ for (const value of Object.values(record)) {
225
+ extractValuesRecursive(value, path, index + 1, results);
226
+ }
227
+ }
228
+ }
229
+ else if (typeof data === "object" && data !== null) {
230
+ const record = data;
231
+ extractValuesRecursive(record[key], path, index + 1, results);
232
+ }
233
+ }
234
+ function matchesPattern(value, patterns, relation) {
235
+ for (const pattern of patterns) {
236
+ switch (relation) {
237
+ case "contains":
238
+ if (value.includes(pattern))
239
+ return true;
240
+ break;
241
+ case "equals":
242
+ if (value === pattern)
243
+ return true;
244
+ break;
245
+ case "startsWith":
246
+ if (value.startsWith(pattern))
247
+ return true;
248
+ break;
249
+ }
250
+ }
251
+ return false;
252
+ }
253
+ //# sourceMappingURL=claim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim.js","sourceRoot":"","sources":["../src/claim.ts"],"names":[],"mappings":"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"}