@fedify/fedify 2.4.0-pr.936.41 → 2.5.0-dev.2271
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/README.md +50 -39
- package/dist/{assert-CJ1KXcvv.mjs → assert-D1Eafmd_.mjs} +1 -1
- package/dist/{assert_equals-BV7oLMxm.mjs → assert_equals-Z6IcEbWU.mjs} +2 -28
- package/dist/assert_exists-cffSpJ7X.mjs +28 -0
- package/dist/assert_false-CPdRnc3E.mjs +23 -0
- package/dist/assert_greater_or_equal-BlafOF4-.mjs +31 -0
- package/dist/{assert_instance_of-Q9KTBnrf.mjs → assert_instance_of-mrXWWNY-.mjs} +1 -1
- package/dist/{assert_not_equals-EPJPoxuf.mjs → assert_not_equals-CpPK2t89.mjs} +2 -1
- package/dist/assert_rejects-CTptdYck.mjs +39 -0
- package/dist/{assert_strict_equals-Ec20AUwa.mjs → assert_strict_equals-CYvBmkpC.mjs} +2 -1
- package/dist/{assert_throws-NiFfqbnH.mjs → assert_throws-BYITOvPO.mjs} +2 -1
- package/dist/assertion_error-B-cx0fFA.mjs +31 -0
- package/dist/audience-CHQ-FlLD.mjs +95 -0
- package/dist/{builder-DonuxRl_.mjs → builder-Bda6LK7A.mjs} +169 -14
- package/dist/{circuit-breaker-CBGyz5F7.mjs → circuit-breaker-XJ53md4S.mjs} +224 -17
- package/dist/circuit-breaker-test-utils-DW6YC_Pe.mjs +14 -0
- package/dist/{client-CjF5IYQS.mjs → client-CEnNz8O7.mjs} +144 -8
- package/dist/{codec-BBga-FWI.mjs → codec-C6rTrpIp.mjs} +26 -3
- package/dist/{collection-BIhlldqK.mjs → collection-CnnP1UAv.mjs} +1 -1
- package/dist/compat/mod.cjs +1 -1
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/mod.js +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +71 -3
- package/dist/compat/public-audience.test.mjs +14 -5
- package/dist/compat/secured-document.test.d.mts +2 -0
- package/dist/compat/secured-document.test.mjs +58 -0
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/compound-proof-B-9mXxFW.mjs +989 -0
- package/dist/{context-Zii1f5xS.d.ts → context-7NyiqIcg.d.ts} +1600 -25
- package/dist/{context-BJXxPElm.mjs → context-8Tu9kea0.mjs} +21 -63
- package/dist/{context-lxX6I7as.d.cts → context-tsYPJ2Ew.d.cts} +1600 -25
- package/dist/{deno-BHzKn9Ig.mjs → deno-oR5aJKpU.mjs} +1 -1
- package/dist/dist-DJQM4u7i.mjs +189 -0
- package/dist/docloader-DBoYbvYW.mjs +87 -0
- package/dist/{esm-yYQfPhIY.mjs → esm-BHXXx4Wx.mjs} +13 -6
- package/dist/federation/audience.test.d.mts +2 -0
- package/dist/federation/audience.test.mjs +130 -0
- package/dist/federation/builder.test.mjs +54 -5
- package/dist/federation/circuit-breaker.test.mjs +838 -7
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/compound-fanout.test.d.mts +2 -0
- package/dist/federation/compound-fanout.test.mjs +228 -0
- package/dist/federation/handler-compound-proof.test.d.mts +2 -0
- package/dist/federation/handler-compound-proof.test.mjs +384 -0
- package/dist/federation/handler.test.mjs +385 -15
- package/dist/federation/hashlink-media.test.d.mts +2 -0
- package/dist/federation/hashlink-media.test.mjs +422 -0
- package/dist/federation/idempotency.test.mjs +6 -6
- package/dist/federation/inbox-report.test.d.mts +2 -0
- package/dist/federation/inbox-report.test.mjs +475 -0
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +215 -14
- package/dist/federation/kv.test.mjs +3 -3
- package/dist/federation/metrics.test.mjs +5 -5
- package/dist/federation/middleware.test.mjs +967 -35
- package/dist/federation/mod.cjs +18 -261
- package/dist/federation/mod.d.cts +5 -5
- package/dist/federation/mod.d.ts +5 -5
- package/dist/federation/mod.js +279 -1
- package/dist/federation/mq.test.mjs +123 -47
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/outgoing-proof.test.d.mts +2 -0
- package/dist/federation/outgoing-proof.test.mjs +931 -0
- package/dist/federation/portable-actor.test.d.mts +2 -0
- package/dist/federation/portable-actor.test.mjs +496 -0
- package/dist/federation/portable-chain.test.d.mts +2 -0
- package/dist/federation/portable-chain.test.mjs +370 -0
- package/dist/federation/portable-collection.test.d.mts +2 -0
- package/dist/federation/portable-collection.test.mjs +832 -0
- package/dist/federation/portable-delivery.test.d.mts +2 -0
- package/dist/federation/portable-delivery.test.mjs +746 -0
- package/dist/federation/portable-gateway-keys.test.d.mts +2 -0
- package/dist/federation/portable-gateway-keys.test.mjs +686 -0
- package/dist/federation/portable-inbox.test.d.mts +2 -0
- package/dist/federation/portable-inbox.test.mjs +1535 -0
- package/dist/federation/portable-parse-uri.test.d.mts +2 -0
- package/dist/federation/portable-parse-uri.test.mjs +348 -0
- package/dist/federation/portable-route-activity.test.d.mts +2 -0
- package/dist/federation/portable-route-activity.test.mjs +259 -0
- package/dist/federation/portable.test.d.mts +2 -0
- package/dist/federation/portable.test.mjs +1072 -0
- package/dist/federation/retry.test.mjs +4 -3
- package/dist/federation/router.test.mjs +9 -159
- package/dist/federation/send.test.mjs +245 -27
- package/dist/federation/tasks/codec.test.mjs +4 -4
- package/dist/federation/tasks/enqueue.test.mjs +42 -4
- package/dist/federation/tasks/tasks.test.mjs +7 -6
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +275 -12
- package/dist/{middleware-FrSMAYEx.cjs → federation-CkZiAcWY.cjs} +8640 -3722
- package/dist/http-B5JT115n.cjs +10630 -0
- package/dist/http-DydWCB7R.js +6527 -0
- package/dist/{http-CPVMUgsW.mjs → http-siciWkmx.mjs} +397 -168
- package/dist/key-BspPiXqn.mjs +951 -0
- package/dist/key-C1nv7_jD.d.ts +1125 -0
- package/dist/key-DYxuyd-s.d.cts +1125 -0
- package/dist/key-owner-evidence-APB6NpSk.mjs +108 -0
- package/dist/keycache-Da8A8mZa.mjs +200 -0
- package/dist/{kv-D6hNiMTK.d.ts → kv-B2mzK5tl.d.cts} +3 -2
- package/dist/{kv-gJ8LYbxX.d.cts → kv-B2mzK5tl.d.ts} +3 -2
- package/dist/kv-DBRWVx3Q.mjs +104 -0
- package/dist/{kv-cache-KyGqJqSp.mjs → kv-cache-BF1hnW65.mjs} +1 -1
- package/dist/{kv-cache-5bnX3-Jq.js → kv-cache-CTQr1tbn.js} +54 -16
- package/dist/{kv-cache-DQ29C4XL.cjs → kv-cache-DCac1nEU.cjs} +55 -19
- package/dist/{ld-Cj9F_5AP.mjs → ld-CzaP-hJl.mjs} +44 -12
- package/dist/map-local-context-conflict-DOYEEJ3u.mjs +204 -0
- package/dist/map-local-create-note-B0SeXJms.mjs +214 -0
- package/dist/{metrics-DMk-nTxI.mjs → metrics-CYg9yxBL.mjs} +3 -2
- package/dist/metrics-DVKYY6K1.d.cts +36 -0
- package/dist/metrics-DoRtI0qU.d.ts +36 -0
- package/dist/{middleware-Y-kpsp6S.js → middleware-CsDDXKuL.js} +5493 -1103
- package/dist/{middleware-CvwTUgnP.mjs → middleware-D7_LO-Vs.mjs} +3157 -272
- package/dist/{middleware-CEctxBN6.mjs → middleware-DWjrfpcz.mjs} +1 -1
- package/dist/{mod-gOlPDuT8.d.cts → mod-BojP2Bw3.d.cts} +1 -1
- package/dist/mod-CavhAgLw.d.cts +320 -0
- package/dist/mod-CtpF2BU5.d.ts +320 -0
- package/dist/{mod-BtEaIEcD.d.cts → mod-DEZXwV6J.d.ts} +10 -4
- package/dist/{mod-UMmveiO0.d.ts → mod-Dw-nPxQh.d.cts} +10 -4
- package/dist/{mod-DLc2Ot6f.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
- package/dist/mod.cjs +40 -39
- package/dist/mod.d.cts +10 -11
- package/dist/mod.d.ts +10 -11
- package/dist/mod.js +9 -9
- package/dist/{mq-llHKivST.mjs → mq-Dm1Wmtm-.mjs} +6 -0
- package/dist/nodeinfo/client.test.mjs +139 -4
- package/dist/nodeinfo/handler.test.mjs +5 -5
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.d.cts +1 -1
- package/dist/nodeinfo/mod.d.ts +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/types.test.mjs +4 -4
- package/dist/otel/exporter.test.mjs +3 -3
- package/dist/otel/mod.cjs +0 -1
- package/dist/otel/mod.d.cts +1 -1
- package/dist/otel/mod.d.ts +1 -1
- package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-4IJqPYos.mjs} +12 -10
- package/dist/{owner-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
- package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
- package/dist/owner-DYgfTFHy.mjs +267 -0
- package/dist/portable-collection-BpsVsRov.js +670 -0
- package/dist/portable-collection-C74P1vtC.mjs +418 -0
- package/dist/portable-collection-DZd2bm7M.cjs +686 -0
- package/dist/portable-key-BIMLrAP4.mjs +549 -0
- package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
- package/dist/proof-Dxy6ByqI.mjs +1299 -0
- package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--klBIOk1.mjs} +15 -10
- package/dist/router-u5O5KCQr.mjs +156 -0
- package/dist/runtime/mod.cjs +1 -1
- package/dist/runtime/mod.js +1 -1
- package/dist/secured-document-CxzZZ9nL.mjs +35 -0
- package/dist/send-C4dDpAxm.mjs +495 -0
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
- package/dist/sig/compound-proof-discovery.test.mjs +331 -0
- package/dist/sig/compound-proof-producer.test.d.mts +2 -0
- package/dist/sig/compound-proof-producer.test.mjs +107 -0
- package/dist/sig/compound-proof-verification.test.d.mts +2 -0
- package/dist/sig/compound-proof-verification.test.mjs +833 -0
- package/dist/sig/compound-proof.test.d.mts +2 -0
- package/dist/sig/compound-proof.test.mjs +411 -0
- package/dist/sig/http.test.mjs +702 -31
- package/dist/sig/key-owner-evidence.test.d.mts +2 -0
- package/dist/sig/key-owner-evidence.test.mjs +100 -0
- package/dist/sig/key.test.mjs +220 -8
- package/dist/sig/ld.test.mjs +65 -7
- package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
- package/dist/sig/mitra-receive-interop.test.mjs +260 -0
- package/dist/sig/mitra-send-interop.test.d.mts +2 -0
- package/dist/sig/mitra-send-interop.test.mjs +461 -0
- package/dist/sig/mod.cjs +18 -16
- package/dist/sig/mod.d.cts +4 -4
- package/dist/sig/mod.d.ts +4 -4
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +108 -9
- package/dist/sig/portable-collection.test.d.mts +2 -0
- package/dist/sig/portable-collection.test.mjs +697 -0
- package/dist/sig/portable-interop.test.d.mts +2 -0
- package/dist/sig/portable-interop.test.mjs +156 -0
- package/dist/sig/portable-key-id.test.d.mts +2 -0
- package/dist/sig/portable-key-id.test.mjs +67 -0
- package/dist/sig/portable-key.test.d.mts +2 -0
- package/dist/sig/portable-key.test.mjs +1439 -0
- package/dist/sig/proof.test.mjs +1753 -16
- package/dist/sig/tootik-request-interop.test.d.mts +2 -0
- package/dist/sig/tootik-request-interop.test.mjs +190 -0
- package/dist/sig/tootik-send-interop.test.d.mts +2 -0
- package/dist/sig/tootik-send-interop.test.mjs +331 -0
- package/dist/sig/verification.test.d.mts +2 -0
- package/dist/sig/verification.test.mjs +310 -0
- package/dist/std__assert-DvMDRPes.mjs +8 -0
- package/dist/{testing-CO7ftO8A.mjs → tasks-IG3pHfvZ.mjs} +2 -2
- package/dist/{temporal-fsXO5IvD.mjs → temporal-D0KJI4NF.mjs} +3 -3
- package/dist/testing/context.test.d.mts +2 -0
- package/dist/testing/context.test.mjs +19 -0
- package/dist/testing/kv.test.d.mts +2 -0
- package/dist/testing/kv.test.mjs +101 -0
- package/dist/testing/mod.d.mts +1617 -48
- package/dist/testing/mod.mjs +6 -3
- package/dist/testing-t8xDeJZ5.mjs +8 -0
- package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
- package/dist/{types-DC1pNgJA.js → types-_S2_MeLF.js} +144 -8
- package/dist/{types-CPym83zc.cjs → types-poIao40f.cjs} +160 -7
- package/dist/utils/docloader.test.mjs +530 -8
- package/dist/utils/kv-cache.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/dist/verification-C3954hQh.mjs +5 -0
- package/dist/verification-Dpfcw8ml.mjs +105 -0
- package/dist/vocab/cjs.test.mjs +1 -1
- package/package.json +8 -8
- package/dist/assert_rejects-EgstcQy5.mjs +0 -82
- package/dist/docloader-e1khNUKy.mjs +0 -49
- package/dist/http-CsmQ-BQ4.js +0 -2483
- package/dist/http-VyDTd4G3.d.cts +0 -553
- package/dist/http-hlIjmewS.cjs +0 -2694
- package/dist/http-lf8Hsd91.d.ts +0 -553
- package/dist/key-DfPsX8hv.mjs +0 -453
- package/dist/keycache-_DHqz5z_.mjs +0 -97
- package/dist/metrics-CoUJLQhZ.d.cts +0 -276
- package/dist/metrics-Dc4jR-IC.d.ts +0 -276
- package/dist/mod-B0hW12_O.d.cts +0 -307
- package/dist/mod-COIAjwRS.d.ts +0 -307
- package/dist/owner-Br9YYzn_.mjs +0 -120
- package/dist/proof-B4ngoaNQ.mjs +0 -316
- package/dist/proof-B6E0XUXJ.js +0 -1415
- package/dist/proof-NN4xCQGL.cjs +0 -1562
- package/dist/send-CxHKUNzv.mjs +0 -239
- package/dist/std__assert-B2NnY9bq.mjs +0 -79
- package/dist/temporal-polyfill-BCdTHexd.cjs +0 -3565
- /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
- /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
- /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
- /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
- /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
- /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
- /package/dist/{negotiation-RuwrPFqi.mjs → negotiation-CCocWT_N.mjs} +0 -0
- /package/dist/{retry-DgFqeS5k.mjs → retry-zX5xw5e0.mjs} +0 -0
- /package/dist/{chunk-D5IdezsZ.js → rolldown-runtime-BC-Eo5Mj.js} +0 -0
- /package/dist/{chunk-Czpeue4M.cjs → rolldown-runtime-Dmm3t92W.cjs} +0 -0
- /package/dist/{transformers-DXze6FUB.js → transformers-DAtXl_Kc.js} +0 -0
- /package/dist/{types-CrtdVuDP.mjs → types-DE_LV1JB.mjs} +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { isActor } from "@fedify/vocab";
|
|
5
|
+
import { canonicalizePortableUri, formatIri, fromCompatibleEf61Id, getFe34Origin, parseIri, toCompatibleEf61Id } from "@fedify/vocab-runtime";
|
|
6
|
+
import { isCompatibleEf61Iri } from "@fedify/vocab-runtime/internal/portable-dereference";
|
|
7
|
+
//#region src/sig/portable-key-id.ts
|
|
8
|
+
const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
|
|
9
|
+
const RAW_PORTABLE_URI_PATTERN = /^ap(?:\+ef61)?:\/\//i;
|
|
10
|
+
const RAW_COMPATIBLE_ID_PREFIX_PATTERN = /^https?:\/\/[^/?#]*\/\.well-known\/apgateway\/(?=did(?::|%3A))/i;
|
|
11
|
+
/**
|
|
12
|
+
* Checks whether the URL is an `ap:` or `ap+ef61:` URI.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
function isPortableUri(url) {
|
|
16
|
+
return url.protocol === "ap:" || url.protocol === "ap+ef61:";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Checks whether an ID identifies an [FEP-ef61] portable object, i.e., it is
|
|
20
|
+
* an `ap:` or `ap+ef61:` URI, or looks like a compatible identifier.
|
|
21
|
+
* A malformed compatible identifier counts too, so that it is rejected as
|
|
22
|
+
* a portable object that no proof can match, rather than trusted by its web
|
|
23
|
+
* origin.
|
|
24
|
+
*
|
|
25
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
function isPortableId(id) {
|
|
29
|
+
if (typeof id === "string") {
|
|
30
|
+
if (/^ap(?:\+ef61)?:\/\//i.test(id)) return true;
|
|
31
|
+
} else if (isPortableUri(id)) return true;
|
|
32
|
+
return isCompatibleEf61Iri(id);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets the DID, i.e., the FEP-fe34 cryptographic origin, of an `ap:` or
|
|
36
|
+
* `ap+ef61:` URI, a DID URL, or a compatible identifier.
|
|
37
|
+
* @returns The DID, or `null` if the ID is none of them, or is malformed.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
function getPortableDid(id) {
|
|
41
|
+
try {
|
|
42
|
+
const raw = typeof id === "string" ? id : id.href;
|
|
43
|
+
if (/^(?:did:|ap(?:\+ef61)?:\/\/)/i.test(raw)) return getFe34Origin(id);
|
|
44
|
+
const portable = fromCompatibleEf61Id(id);
|
|
45
|
+
return portable == null ? null : getFe34Origin(portable);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error instanceof TypeError) return null;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Checks whether an activity is performed by an FEP-ef61 portable actor,
|
|
53
|
+
* i.e., any of its actors has an `ap:` or `ap+ef61:` ID, or a compatible
|
|
54
|
+
* identifier.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
function hasPortableActor(activity) {
|
|
58
|
+
return activity.actorIds.some((id) => isPortableId(id));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Checks whether a key ID looks like an [FEP-ef61] compatible identifier,
|
|
62
|
+
* i.e., an HTTP(S) URL under a gateway's `/.well-known/apgateway/did:` path.
|
|
63
|
+
* Such a key ID may name a key that a gateway holds for a portable actor,
|
|
64
|
+
* which only HTTP Signatures accept, so what it resolves to is cached apart
|
|
65
|
+
* for each purpose, never under the key ID itself.
|
|
66
|
+
*
|
|
67
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
function isCompatibleKeyId(keyId) {
|
|
71
|
+
return (keyId.protocol === "http:" || keyId.protocol === "https:") && COMPATIBLE_KEY_ID_PATH_PATTERN.test(keyId.pathname);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Checks whether a key ID may name a key that is valid only for HTTP
|
|
75
|
+
* Signatures: a gateway key at an [FEP-ef61] compatible identifier, or a key
|
|
76
|
+
* of a portable actor at an `ap:` or `ap+ef61:` URI. Neither ever makes or
|
|
77
|
+
* verifies an Object Integrity Proof or a Linked Data Signature: a portable
|
|
78
|
+
* object's proof is made by its DID, and a proof made with a gateway key
|
|
79
|
+
* would claim that the gateway authored the object.
|
|
80
|
+
*
|
|
81
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
function isPortableKeyId(keyId) {
|
|
85
|
+
return isPortableUri(keyId) || isCompatibleKeyId(keyId);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Gets the canonical portable ID of an actor ID that is either an `ap:` or
|
|
89
|
+
* `ap+ef61:` URI or a compatible identifier.
|
|
90
|
+
* @returns The canonical portable ID, or `null` if the ID is neither, or is
|
|
91
|
+
* malformed.
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
function getCanonicalPortableId(id) {
|
|
95
|
+
try {
|
|
96
|
+
if (isPortableUri(id)) return canonicalizePortableUri(formatIri(id));
|
|
97
|
+
const portable = fromCompatibleEf61Id(id);
|
|
98
|
+
if (portable == null) return null;
|
|
99
|
+
return canonicalizePortableUri(formatIri(portable));
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error instanceof TypeError) return null;
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets the [FEP-fe34] origin of an ID for same-origin checks. The origin of
|
|
107
|
+
* an `ap:` or `ap+ef61:` URI, or of a compatible identifier on any gateway,
|
|
108
|
+
* is the DID of its canonical portable ID, as FEP-ef61 treats a compatible
|
|
109
|
+
* identifier as the portable ID it stands for; unlike `getFe34Origin()`,
|
|
110
|
+
* which gives a compatible identifier the web origin of its gateway. The
|
|
111
|
+
* origin of any other HTTP(S) URL is its web origin, and that of a DID URL
|
|
112
|
+
* is its DID.
|
|
113
|
+
*
|
|
114
|
+
* Only the parsed `URL` is validated, so dot segments that URL parsing has
|
|
115
|
+
* already resolved cannot be detected here.
|
|
116
|
+
*
|
|
117
|
+
* [FEP-fe34]: https://w3id.org/fep/fe34
|
|
118
|
+
* @returns The origin, or `null` if the ID has none that is supported, or is
|
|
119
|
+
* a malformed portable ID or compatible identifier.
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
function getAuthenticationOrigin(id) {
|
|
123
|
+
try {
|
|
124
|
+
if (isPortableId(id)) {
|
|
125
|
+
const canonical = getCanonicalPortableId(id);
|
|
126
|
+
return canonical == null ? null : getFe34Origin(canonical);
|
|
127
|
+
}
|
|
128
|
+
return getFe34Origin(id);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (error instanceof TypeError) return null;
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Checks whether two IDs identify the same object. Two portable IDs, i.e.,
|
|
136
|
+
* `ap:` or `ap+ef61:` URIs or compatible identifiers, are compared by their
|
|
137
|
+
* canonical portable IDs, so that the same object on different gateways and
|
|
138
|
+
* with different location hints matches. Other IDs have to be equal as
|
|
139
|
+
* they are.
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
function isSameObjectId(a, b) {
|
|
143
|
+
const aPortable = isPortableId(a);
|
|
144
|
+
if (aPortable !== isPortableId(b)) return false;
|
|
145
|
+
if (!aPortable) return a.href === b.href;
|
|
146
|
+
const canonical = getCanonicalPortableId(a);
|
|
147
|
+
return canonical != null && canonical === getCanonicalPortableId(b);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Gets the canonical portable ID of an `ap:` or `ap+ef61:` URI or
|
|
151
|
+
* a compatible identifier as it is written, before any URL parsing.
|
|
152
|
+
* Parsing an ID into a `URL` resolves dot segments in its path, which would
|
|
153
|
+
* make it identify another portable object, e.g.,
|
|
154
|
+
* `ap://did:key:z6Mk…/x/../actor` would become `ap://did:key:z6Mk…/actor`.
|
|
155
|
+
* Such an ID has no canonical portable ID here.
|
|
156
|
+
* @param raw The ID as it is written.
|
|
157
|
+
* @returns The canonical portable ID, fragment included, or `null` if the ID
|
|
158
|
+
* is neither an `ap:` or `ap+ef61:` URI nor a compatible identifier,
|
|
159
|
+
* is malformed, or would identify another object once parsed.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
function getRawCanonicalPortableId(raw) {
|
|
163
|
+
let canonical;
|
|
164
|
+
let parsed;
|
|
165
|
+
try {
|
|
166
|
+
if (RAW_PORTABLE_URI_PATTERN.test(raw)) {
|
|
167
|
+
canonical = canonicalizePortableUri(raw);
|
|
168
|
+
parsed = canonicalizePortableUri(formatIri(parseIri(raw)));
|
|
169
|
+
} else {
|
|
170
|
+
const prefix = raw.match(RAW_COMPATIBLE_ID_PREFIX_PATTERN);
|
|
171
|
+
if (prefix == null || !URL.canParse(raw)) return null;
|
|
172
|
+
canonical = canonicalizePortableUri("ap://" + raw.slice(prefix[0].length));
|
|
173
|
+
parsed = getCanonicalPortableId(new URL(raw));
|
|
174
|
+
}
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (error instanceof TypeError) return null;
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
return canonical === parsed ? canonical : null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Parses a key ID, e.g., the `keyId` of an HTTP Signature, into a `URL`.
|
|
183
|
+
* An `ap:` or `ap+ef61:` key ID is parsed into the internal `URL` form of
|
|
184
|
+
* portable URIs. A portable or compatible key ID that is malformed, or
|
|
185
|
+
* whose identity URL parsing would change, e.g., by resolving dot segments in
|
|
186
|
+
* its path, is refused, so that it can never be taken for, or looked up in
|
|
187
|
+
* the key cache as, the key of another object.
|
|
188
|
+
* @param raw The key ID as it is written.
|
|
189
|
+
* @returns The parsed key ID, or `null` if it is invalid.
|
|
190
|
+
* @internal
|
|
191
|
+
*/
|
|
192
|
+
function parseKeyIdString(raw) {
|
|
193
|
+
if (RAW_PORTABLE_URI_PATTERN.test(raw)) return getRawCanonicalPortableId(raw) == null ? null : parseIri(raw);
|
|
194
|
+
if (!URL.canParse(raw)) return null;
|
|
195
|
+
const url = new URL(raw);
|
|
196
|
+
if (isPortableUri(url)) return null;
|
|
197
|
+
if (!RAW_COMPATIBLE_ID_PREFIX_PATTERN.test(raw)) return isCompatibleKeyId(url) ? null : url;
|
|
198
|
+
return getRawCanonicalPortableId(raw) == null ? null : url;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Builds the base of the key IDs of a gateway's keys for a portable actor:
|
|
202
|
+
* the actor's compatible identifier on the gateway.
|
|
203
|
+
* @param actorId The portable actor's ID, either an `ap:` or `ap+ef61:` URI
|
|
204
|
+
* or a compatible identifier. It must not have a fragment.
|
|
205
|
+
* @param gateway The gateway's origin, e.g., `https://example.com`.
|
|
206
|
+
* @returns The compatible identifier without query and fragment.
|
|
207
|
+
* @throws {TypeError} If the actor ID is not a portable ID, or has
|
|
208
|
+
* a fragment.
|
|
209
|
+
* @internal
|
|
210
|
+
*/
|
|
211
|
+
function getGatewayKeyBase(actorId, gateway) {
|
|
212
|
+
let portable;
|
|
213
|
+
if (isPortableUri(actorId)) portable = actorId;
|
|
214
|
+
else try {
|
|
215
|
+
portable = fromCompatibleEf61Id(actorId);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
if (!(error instanceof TypeError)) throw error;
|
|
218
|
+
portable = null;
|
|
219
|
+
}
|
|
220
|
+
if (portable == null) throw new TypeError(`The portable actor ID ${actorId.href} must be an ap: or ap+ef61: URI, or an FEP-ef61 compatible identifier.`);
|
|
221
|
+
if (portable.hash !== "") throw new TypeError(`The portable actor ID ${actorId.href} must not have a fragment.`);
|
|
222
|
+
const base = toCompatibleEf61Id(portable, gateway);
|
|
223
|
+
base.search = "";
|
|
224
|
+
base.hash = "";
|
|
225
|
+
return base;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Tells whether a parsed document is a portable actor, i.e., an actor whose
|
|
229
|
+
* ID is an `ap:` or `ap+ef61:` URI or a compatible identifier. Such an actor
|
|
230
|
+
* is never authenticated by the web origin that served it; at a compatible
|
|
231
|
+
* key ID, it makes the key a gateway key that only
|
|
232
|
+
* {@link verifyPortableGatewayKeyDocument} can vouch for.
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
function isPortableActorDocument(object) {
|
|
236
|
+
return isActor(object) && object.id != null && isPortableId(object.id);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Compares two public keys by their key material.
|
|
240
|
+
* @internal
|
|
241
|
+
*/
|
|
242
|
+
async function isSamePublicKey(a, b) {
|
|
243
|
+
if (a.algorithm.name !== b.algorithm.name) return false;
|
|
244
|
+
const [x, y] = await Promise.all([crypto.subtle.exportKey("jwk", a), crypto.subtle.exportKey("jwk", b)]);
|
|
245
|
+
return x.kty === y.kty && x.crv === y.crv && x.n === y.n && x.e === y.e && x.x === y.x && x.y === y.y;
|
|
246
|
+
}
|
|
247
|
+
//#endregion
|
|
248
|
+
export { getRawCanonicalPortableId as a, isPortableActorDocument as c, isPortableUri as d, isSameObjectId as f, getPortableDid as i, isPortableId as l, parseKeyIdString as m, getCanonicalPortableId as n, hasPortableActor as o, isSamePublicKey as p, getGatewayKeyBase as r, isCompatibleKeyId as s, getAuthenticationOrigin as t, isPortableKeyId as u };
|