@fedify/vocab 2.4.0-dev.2233 → 2.4.0-dev.2245
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/deno.json +1 -1
- package/dist/mod.cjs +39 -26
- package/dist/mod.d.cts +15 -1
- package/dist/mod.d.ts +15 -1
- package/dist/mod.js +39 -26
- package/dist-tests/{actor-C8V9Eu9k.mjs → actor-CwM3qnho.mjs} +1 -1
- package/dist-tests/actor.test.mjs +1 -1
- package/dist-tests/gateway.test.mjs +3 -3
- package/dist-tests/{lookup-2QrSuQR0.mjs → lookup--QvDSQ8m.mjs} +39 -26
- package/dist-tests/lookup.test.mjs +1 -1
- package/dist-tests/portable-lookup.test.mjs +200 -2
- package/dist-tests/translation.test.mjs +2 -2
- package/dist-tests/vocab.test.mjs +16 -0
- package/package.json +4 -4
- package/src/gateway.test.ts +15 -12
- package/src/lookup.ts +89 -30
- package/src/portable-lookup.test.ts +266 -0
- package/src/vocab.test.ts +25 -0
package/deno.json
CHANGED
package/dist/mod.cjs
CHANGED
|
@@ -36,7 +36,7 @@ let _fedify_vocab_runtime_temporal = require("@fedify/vocab-runtime/temporal");
|
|
|
36
36
|
let es_toolkit = require("es-toolkit");
|
|
37
37
|
//#region deno.json
|
|
38
38
|
var name = "@fedify/vocab";
|
|
39
|
-
var version = "2.4.0-dev.
|
|
39
|
+
var version = "2.4.0-dev.2245+042b9587";
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/type.ts
|
|
42
42
|
function getTypeId(object) {
|
|
@@ -79546,7 +79546,9 @@ const MAX_PORTABLE_ATTEMPTS = 5;
|
|
|
79546
79546
|
*
|
|
79547
79547
|
* [FEP-ef61] portable objects, including portable actors found through
|
|
79548
79548
|
* WebFinger, are looked up only if the `verifyPortableObject` option is
|
|
79549
|
-
* given; see {@link LookupObjectOptions.verifyPortableObject}.
|
|
79549
|
+
* given; see {@link LookupObjectOptions.verifyPortableObject}. Pass
|
|
79550
|
+
* {@link LookupObjectOptions.gateways} to look up a portable ID without
|
|
79551
|
+
* `@gateway` location hints.
|
|
79550
79552
|
*
|
|
79551
79553
|
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
79552
79554
|
*
|
|
@@ -79604,7 +79606,8 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
79604
79606
|
if (candidate == null) return null;
|
|
79605
79607
|
return await lookupPortableObject(portable, candidate, void 0);
|
|
79606
79608
|
}
|
|
79607
|
-
|
|
79609
|
+
if (options.verifyPortableObject != null && (0, _fedify_vocab_runtime_internal_portable_dereference.parseCompatibleEf61Reference)(identifier) === null) return null;
|
|
79610
|
+
identifier = toAcctUrl(identifier) ?? (0, _fedify_vocab_runtime.parseIri)(identifier);
|
|
79608
79611
|
}
|
|
79609
79612
|
if ((0, _fedify_vocab_runtime_internal_portable_dereference.isPortableIri)(identifier)) {
|
|
79610
79613
|
let candidate;
|
|
@@ -79649,7 +79652,7 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
79649
79652
|
const candidate = parsePortableCandidate(l.href);
|
|
79650
79653
|
if (candidate == null) continue;
|
|
79651
79654
|
const gateways = webFingerGateway == null ? [] : [webFingerGateway];
|
|
79652
|
-
gateways.push(...(0, _fedify_vocab_runtime_internal_portable_dereference.getPortableGatewayCandidates)(candidate));
|
|
79655
|
+
if (options.gateways == null) gateways.push(...(0, _fedify_vocab_runtime_internal_portable_dereference.getPortableGatewayCandidates)(candidate));
|
|
79653
79656
|
const object = await lookupPortableObject(portable, candidate, gateways);
|
|
79654
79657
|
if (object != null) return object;
|
|
79655
79658
|
if (options.signal?.aborted) return null;
|
|
@@ -79701,10 +79704,13 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
79701
79704
|
if (claim === null) {
|
|
79702
79705
|
logger.debug("Refusing the document {documentUrl}, as it claims to be a portable object with a malformed compatible identifier.", { documentUrl: remoteDoc.documentUrl });
|
|
79703
79706
|
return null;
|
|
79704
|
-
} else if (claim != null)
|
|
79705
|
-
|
|
79706
|
-
|
|
79707
|
-
|
|
79707
|
+
} else if (claim != null) {
|
|
79708
|
+
const explicit = getExplicitGateways(portable, claim.id);
|
|
79709
|
+
return await dereference(portable, claim.id, claim.inferredGateways, explicit, {
|
|
79710
|
+
response: remoteDoc,
|
|
79711
|
+
contextLoader: snapshot.loader
|
|
79712
|
+
});
|
|
79713
|
+
}
|
|
79708
79714
|
}
|
|
79709
79715
|
if (object.id != null && (options.crossOrigin !== "trust" || (0, _fedify_vocab_runtime_internal_portable_dereference.isPortableIri)(object.id)) && !(0, _fedify_vocab_runtime.haveSameIriOrigin)(object.id, documentUrl) && !(0, _fedify_vocab_runtime.haveSameFe34Origin)(object.id, documentUrl)) {
|
|
79710
79716
|
if (options.crossOrigin === "throw") throw new Error(`The object's @id (${object.id.href}) has a different origin than the document URL (${remoteDoc.documentUrl}); refusing to return the object. If you want to bypass this check and are aware of the security implications, set the crossOrigin option to "trust".`);
|
|
@@ -79720,6 +79726,10 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
79720
79726
|
}
|
|
79721
79727
|
}
|
|
79722
79728
|
const PORTABLE_IRI_PATTERN = /^ap(?:\+ef61)?:/i;
|
|
79729
|
+
function getExplicitGateways(lookup, id) {
|
|
79730
|
+
if (lookup.options.gateways == null) return void 0;
|
|
79731
|
+
return lookup.explicitGateways ??= (0, _fedify_vocab_runtime_internal_portable_dereference.getPortableGatewayCandidates)(id, lookup.options.gateways);
|
|
79732
|
+
}
|
|
79723
79733
|
/**
|
|
79724
79734
|
* Parses a raw portable IRI. URL parsing normalizes dot segments in the
|
|
79725
79735
|
* opaque path, which would make the parsed IRI identify another portable
|
|
@@ -79773,29 +79783,29 @@ function getWebFingerGateway(identifier) {
|
|
|
79773
79783
|
}
|
|
79774
79784
|
/**
|
|
79775
79785
|
* Looks up a portable object through FEP-ef61 gateways.
|
|
79776
|
-
* @param
|
|
79777
|
-
*
|
|
79778
|
-
*
|
|
79786
|
+
* @param inferredGateways Gateways inferred from a compatible identifier or
|
|
79787
|
+
* WebFinger. If omitted, location hints in the IRI
|
|
79788
|
+
* are used unless explicit gateways were given.
|
|
79779
79789
|
*/
|
|
79780
|
-
async function lookupPortableObject(lookup, id,
|
|
79790
|
+
async function lookupPortableObject(lookup, id, inferredGateways) {
|
|
79781
79791
|
const { options } = lookup;
|
|
79782
79792
|
const iri = (0, _fedify_vocab_runtime.formatIri)(id);
|
|
79793
|
+
const explicitGateways = getExplicitGateways(lookup, id);
|
|
79783
79794
|
if (options.verifyPortableObject == null) {
|
|
79784
79795
|
logger.debug("Cannot look up the portable object {iri}, as the verifyPortableObject option is not given.", { iri });
|
|
79785
79796
|
return null;
|
|
79786
79797
|
}
|
|
79787
79798
|
const canonicalId = (0, _fedify_vocab_runtime.canonicalizePortableUri)(iri);
|
|
79788
|
-
|
|
79789
|
-
|
|
79790
|
-
|
|
79791
|
-
|
|
79792
|
-
|
|
79793
|
-
|
|
79794
|
-
|
|
79795
|
-
|
|
79796
|
-
|
|
79797
|
-
|
|
79798
|
-
} else candidates = [...gateways];
|
|
79799
|
+
const inferred = inferredGateways ?? (explicitGateways == null ? (0, _fedify_vocab_runtime_internal_portable_dereference.getPortableGatewayCandidates)(id) : []);
|
|
79800
|
+
const candidates = [...inferred];
|
|
79801
|
+
for (const gateway of explicitGateways ?? []) if (!candidates.some((candidate) => candidate.href === gateway.href)) candidates.push(gateway);
|
|
79802
|
+
if (candidates.length < 1 && inferredGateways == null) {
|
|
79803
|
+
const key = `${canonicalId} `;
|
|
79804
|
+
if (lookup.remaining < 1 || lookup.attempted.has(key)) return null;
|
|
79805
|
+
lookup.attempted.add(key);
|
|
79806
|
+
lookup.remaining--;
|
|
79807
|
+
return await dereference(lookup, id, [], explicitGateways == null ? void 0 : []);
|
|
79808
|
+
}
|
|
79799
79809
|
const selected = [];
|
|
79800
79810
|
for (const gateway of candidates) {
|
|
79801
79811
|
if (selected.length >= lookup.remaining) break;
|
|
@@ -79806,16 +79816,19 @@ async function lookupPortableObject(lookup, id, gateways) {
|
|
|
79806
79816
|
}
|
|
79807
79817
|
if (selected.length < 1) return null;
|
|
79808
79818
|
lookup.remaining -= selected.length;
|
|
79809
|
-
|
|
79819
|
+
const selectedInferred = selected.filter((candidate) => inferred.some((gateway) => gateway.href === candidate.href));
|
|
79820
|
+
const selectedExplicit = explicitGateways?.filter((gateway) => selected.some((candidate) => candidate.href === gateway.href));
|
|
79821
|
+
return await dereference(lookup, id, selectedInferred, selectedExplicit);
|
|
79810
79822
|
}
|
|
79811
|
-
async function dereference({ options, documentLoader }, id, gateways, extra = {}) {
|
|
79823
|
+
async function dereference({ options, documentLoader }, id, inferredGateways, gateways, extra = {}) {
|
|
79812
79824
|
const tracerProvider = options.tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
79813
79825
|
try {
|
|
79814
79826
|
return await (0, _fedify_vocab_runtime_internal_portable_dereference.dereferencePortableIri)(id, {
|
|
79815
79827
|
documentLoader,
|
|
79816
79828
|
contextLoader: extra.contextLoader ?? options.contextLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)({ userAgent: options.userAgent }),
|
|
79817
79829
|
tracerProvider,
|
|
79818
|
-
inferredGateways
|
|
79830
|
+
inferredGateways,
|
|
79831
|
+
...gateways == null ? {} : { gateways },
|
|
79819
79832
|
response: extra.response,
|
|
79820
79833
|
verifyPortableObject: options.verifyPortableObject,
|
|
79821
79834
|
crossOrigin: options.crossOrigin === "throw" ? "throw" : "ignore",
|
package/dist/mod.d.cts
CHANGED
|
@@ -24298,6 +24298,18 @@ interface LookupObjectOptions {
|
|
|
24298
24298
|
*/
|
|
24299
24299
|
signal?: AbortSignal;
|
|
24300
24300
|
/**
|
|
24301
|
+
* The [FEP-ef61] gateways to try when looking up a portable
|
|
24302
|
+
* (`ap:`/`ap+ef61:`) object, in order. Each must be an HTTP(S) origin.
|
|
24303
|
+
* An explicit list replaces `@gateway` location hints, including when
|
|
24304
|
+
* it is empty. The gateway named by a compatible identifier or the
|
|
24305
|
+
* WebFinger server is still tried first. At most five gateways are
|
|
24306
|
+
* requested per lookup, including those given here.
|
|
24307
|
+
*
|
|
24308
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
24309
|
+
* @since 2.4.0
|
|
24310
|
+
*/
|
|
24311
|
+
gateways?: readonly (string | URL)[];
|
|
24312
|
+
/**
|
|
24301
24313
|
* The [FEP-ef61] policy to apply to portable objects, typically
|
|
24302
24314
|
* `verifyPortableObject()` from `@fedify/fedify`, which
|
|
24303
24315
|
* `Context.lookupObject()` uses by default.
|
|
@@ -24355,7 +24367,9 @@ interface LookupObjectOptions {
|
|
|
24355
24367
|
*
|
|
24356
24368
|
* [FEP-ef61] portable objects, including portable actors found through
|
|
24357
24369
|
* WebFinger, are looked up only if the `verifyPortableObject` option is
|
|
24358
|
-
* given; see {@link LookupObjectOptions.verifyPortableObject}.
|
|
24370
|
+
* given; see {@link LookupObjectOptions.verifyPortableObject}. Pass
|
|
24371
|
+
* {@link LookupObjectOptions.gateways} to look up a portable ID without
|
|
24372
|
+
* `@gateway` location hints.
|
|
24359
24373
|
*
|
|
24360
24374
|
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
24361
24375
|
*
|
package/dist/mod.d.ts
CHANGED
|
@@ -24298,6 +24298,18 @@ interface LookupObjectOptions {
|
|
|
24298
24298
|
*/
|
|
24299
24299
|
signal?: AbortSignal;
|
|
24300
24300
|
/**
|
|
24301
|
+
* The [FEP-ef61] gateways to try when looking up a portable
|
|
24302
|
+
* (`ap:`/`ap+ef61:`) object, in order. Each must be an HTTP(S) origin.
|
|
24303
|
+
* An explicit list replaces `@gateway` location hints, including when
|
|
24304
|
+
* it is empty. The gateway named by a compatible identifier or the
|
|
24305
|
+
* WebFinger server is still tried first. At most five gateways are
|
|
24306
|
+
* requested per lookup, including those given here.
|
|
24307
|
+
*
|
|
24308
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
24309
|
+
* @since 2.4.0
|
|
24310
|
+
*/
|
|
24311
|
+
gateways?: readonly (string | URL)[];
|
|
24312
|
+
/**
|
|
24301
24313
|
* The [FEP-ef61] policy to apply to portable objects, typically
|
|
24302
24314
|
* `verifyPortableObject()` from `@fedify/fedify`, which
|
|
24303
24315
|
* `Context.lookupObject()` uses by default.
|
|
@@ -24355,7 +24367,9 @@ interface LookupObjectOptions {
|
|
|
24355
24367
|
*
|
|
24356
24368
|
* [FEP-ef61] portable objects, including portable actors found through
|
|
24357
24369
|
* WebFinger, are looked up only if the `verifyPortableObject` option is
|
|
24358
|
-
* given; see {@link LookupObjectOptions.verifyPortableObject}.
|
|
24370
|
+
* given; see {@link LookupObjectOptions.verifyPortableObject}. Pass
|
|
24371
|
+
* {@link LookupObjectOptions.gateways} to look up a portable ID without
|
|
24372
|
+
* `@gateway` location hints.
|
|
24359
24373
|
*
|
|
24360
24374
|
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
24361
24375
|
*
|
package/dist/mod.js
CHANGED
|
@@ -12,7 +12,7 @@ import { isTemporalDuration, isTemporalInstant } from "@fedify/vocab-runtime/tem
|
|
|
12
12
|
import { delay } from "es-toolkit";
|
|
13
13
|
//#region deno.json
|
|
14
14
|
var name = "@fedify/vocab";
|
|
15
|
-
var version = "2.4.0-dev.
|
|
15
|
+
var version = "2.4.0-dev.2245+042b9587";
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/type.ts
|
|
18
18
|
function getTypeId(object) {
|
|
@@ -75956,7 +75956,9 @@ const MAX_PORTABLE_ATTEMPTS = 5;
|
|
|
75956
75956
|
*
|
|
75957
75957
|
* [FEP-ef61] portable objects, including portable actors found through
|
|
75958
75958
|
* WebFinger, are looked up only if the `verifyPortableObject` option is
|
|
75959
|
-
* given; see {@link LookupObjectOptions.verifyPortableObject}.
|
|
75959
|
+
* given; see {@link LookupObjectOptions.verifyPortableObject}. Pass
|
|
75960
|
+
* {@link LookupObjectOptions.gateways} to look up a portable ID without
|
|
75961
|
+
* `@gateway` location hints.
|
|
75960
75962
|
*
|
|
75961
75963
|
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
75962
75964
|
*
|
|
@@ -76014,7 +76016,8 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
76014
76016
|
if (candidate == null) return null;
|
|
76015
76017
|
return await lookupPortableObject(portable, candidate, void 0);
|
|
76016
76018
|
}
|
|
76017
|
-
|
|
76019
|
+
if (options.verifyPortableObject != null && parseCompatibleEf61Reference(identifier) === null) return null;
|
|
76020
|
+
identifier = toAcctUrl(identifier) ?? parseIri(identifier);
|
|
76018
76021
|
}
|
|
76019
76022
|
if (isPortableIri(identifier)) {
|
|
76020
76023
|
let candidate;
|
|
@@ -76059,7 +76062,7 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
76059
76062
|
const candidate = parsePortableCandidate(l.href);
|
|
76060
76063
|
if (candidate == null) continue;
|
|
76061
76064
|
const gateways = webFingerGateway == null ? [] : [webFingerGateway];
|
|
76062
|
-
gateways.push(...getPortableGatewayCandidates(candidate));
|
|
76065
|
+
if (options.gateways == null) gateways.push(...getPortableGatewayCandidates(candidate));
|
|
76063
76066
|
const object = await lookupPortableObject(portable, candidate, gateways);
|
|
76064
76067
|
if (object != null) return object;
|
|
76065
76068
|
if (options.signal?.aborted) return null;
|
|
@@ -76111,10 +76114,13 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
76111
76114
|
if (claim === null) {
|
|
76112
76115
|
logger.debug("Refusing the document {documentUrl}, as it claims to be a portable object with a malformed compatible identifier.", { documentUrl: remoteDoc.documentUrl });
|
|
76113
76116
|
return null;
|
|
76114
|
-
} else if (claim != null)
|
|
76115
|
-
|
|
76116
|
-
|
|
76117
|
-
|
|
76117
|
+
} else if (claim != null) {
|
|
76118
|
+
const explicit = getExplicitGateways(portable, claim.id);
|
|
76119
|
+
return await dereference(portable, claim.id, claim.inferredGateways, explicit, {
|
|
76120
|
+
response: remoteDoc,
|
|
76121
|
+
contextLoader: snapshot.loader
|
|
76122
|
+
});
|
|
76123
|
+
}
|
|
76118
76124
|
}
|
|
76119
76125
|
if (object.id != null && (options.crossOrigin !== "trust" || isPortableIri(object.id)) && !haveSameIriOrigin(object.id, documentUrl) && !haveSameFe34Origin(object.id, documentUrl)) {
|
|
76120
76126
|
if (options.crossOrigin === "throw") throw new Error(`The object's @id (${object.id.href}) has a different origin than the document URL (${remoteDoc.documentUrl}); refusing to return the object. If you want to bypass this check and are aware of the security implications, set the crossOrigin option to "trust".`);
|
|
@@ -76130,6 +76136,10 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
76130
76136
|
}
|
|
76131
76137
|
}
|
|
76132
76138
|
const PORTABLE_IRI_PATTERN = /^ap(?:\+ef61)?:/i;
|
|
76139
|
+
function getExplicitGateways(lookup, id) {
|
|
76140
|
+
if (lookup.options.gateways == null) return void 0;
|
|
76141
|
+
return lookup.explicitGateways ??= getPortableGatewayCandidates(id, lookup.options.gateways);
|
|
76142
|
+
}
|
|
76133
76143
|
/**
|
|
76134
76144
|
* Parses a raw portable IRI. URL parsing normalizes dot segments in the
|
|
76135
76145
|
* opaque path, which would make the parsed IRI identify another portable
|
|
@@ -76183,29 +76193,29 @@ function getWebFingerGateway(identifier) {
|
|
|
76183
76193
|
}
|
|
76184
76194
|
/**
|
|
76185
76195
|
* Looks up a portable object through FEP-ef61 gateways.
|
|
76186
|
-
* @param
|
|
76187
|
-
*
|
|
76188
|
-
*
|
|
76196
|
+
* @param inferredGateways Gateways inferred from a compatible identifier or
|
|
76197
|
+
* WebFinger. If omitted, location hints in the IRI
|
|
76198
|
+
* are used unless explicit gateways were given.
|
|
76189
76199
|
*/
|
|
76190
|
-
async function lookupPortableObject(lookup, id,
|
|
76200
|
+
async function lookupPortableObject(lookup, id, inferredGateways) {
|
|
76191
76201
|
const { options } = lookup;
|
|
76192
76202
|
const iri = formatIri(id);
|
|
76203
|
+
const explicitGateways = getExplicitGateways(lookup, id);
|
|
76193
76204
|
if (options.verifyPortableObject == null) {
|
|
76194
76205
|
logger.debug("Cannot look up the portable object {iri}, as the verifyPortableObject option is not given.", { iri });
|
|
76195
76206
|
return null;
|
|
76196
76207
|
}
|
|
76197
76208
|
const canonicalId = canonicalizePortableUri(iri);
|
|
76198
|
-
|
|
76199
|
-
|
|
76200
|
-
|
|
76201
|
-
|
|
76202
|
-
|
|
76203
|
-
|
|
76204
|
-
|
|
76205
|
-
|
|
76206
|
-
|
|
76207
|
-
|
|
76208
|
-
} else candidates = [...gateways];
|
|
76209
|
+
const inferred = inferredGateways ?? (explicitGateways == null ? getPortableGatewayCandidates(id) : []);
|
|
76210
|
+
const candidates = [...inferred];
|
|
76211
|
+
for (const gateway of explicitGateways ?? []) if (!candidates.some((candidate) => candidate.href === gateway.href)) candidates.push(gateway);
|
|
76212
|
+
if (candidates.length < 1 && inferredGateways == null) {
|
|
76213
|
+
const key = `${canonicalId} `;
|
|
76214
|
+
if (lookup.remaining < 1 || lookup.attempted.has(key)) return null;
|
|
76215
|
+
lookup.attempted.add(key);
|
|
76216
|
+
lookup.remaining--;
|
|
76217
|
+
return await dereference(lookup, id, [], explicitGateways == null ? void 0 : []);
|
|
76218
|
+
}
|
|
76209
76219
|
const selected = [];
|
|
76210
76220
|
for (const gateway of candidates) {
|
|
76211
76221
|
if (selected.length >= lookup.remaining) break;
|
|
@@ -76216,16 +76226,19 @@ async function lookupPortableObject(lookup, id, gateways) {
|
|
|
76216
76226
|
}
|
|
76217
76227
|
if (selected.length < 1) return null;
|
|
76218
76228
|
lookup.remaining -= selected.length;
|
|
76219
|
-
|
|
76229
|
+
const selectedInferred = selected.filter((candidate) => inferred.some((gateway) => gateway.href === candidate.href));
|
|
76230
|
+
const selectedExplicit = explicitGateways?.filter((gateway) => selected.some((candidate) => candidate.href === gateway.href));
|
|
76231
|
+
return await dereference(lookup, id, selectedInferred, selectedExplicit);
|
|
76220
76232
|
}
|
|
76221
|
-
async function dereference({ options, documentLoader }, id, gateways, extra = {}) {
|
|
76233
|
+
async function dereference({ options, documentLoader }, id, inferredGateways, gateways, extra = {}) {
|
|
76222
76234
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
76223
76235
|
try {
|
|
76224
76236
|
return await dereferencePortableIri(id, {
|
|
76225
76237
|
documentLoader,
|
|
76226
76238
|
contextLoader: extra.contextLoader ?? options.contextLoader ?? getDocumentLoader({ userAgent: options.userAgent }),
|
|
76227
76239
|
tracerProvider,
|
|
76228
|
-
inferredGateways
|
|
76240
|
+
inferredGateways,
|
|
76241
|
+
...gateways == null ? {} : { gateways },
|
|
76229
76242
|
response: extra.response,
|
|
76230
76243
|
verifyPortableObject: options.verifyPortableObject,
|
|
76231
76244
|
crossOrigin: options.crossOrigin === "throw" ? "throw" : "ignore",
|
|
@@ -8,7 +8,7 @@ import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
|
8
8
|
import { domainToASCII, domainToUnicode } from "node:url";
|
|
9
9
|
//#region deno.json
|
|
10
10
|
var name = "@fedify/vocab";
|
|
11
|
-
var version = "2.4.0-dev.
|
|
11
|
+
var version = "2.4.0-dev.2245+042b9587";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/actor.ts
|
|
14
14
|
const ACTOR_DISCOVERY_HISTOGRAM_BUCKETS = [
|
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
globalThis.addEventListener = () => {};
|
|
3
3
|
import { F as Person, P as Organization, Q as __exportAll, U as Service, a as Application, b as Group } from "./vocab-D3C791xF.mjs";
|
|
4
4
|
import { t as esm_default } from "./esm-2_Uqq_my.mjs";
|
|
5
|
-
import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-
|
|
5
|
+
import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-CwM3qnho.mjs";
|
|
6
6
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
7
7
|
import { deepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
|
|
8
8
|
//#region ../../node_modules/.pnpm/fast-check@3.23.2/node_modules/fast-check/lib/esm/check/precondition/PreconditionFailure.js
|
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
globalThis.addEventListener = () => {};
|
|
3
3
|
import { F as Person, M as OrderedCollection, S as Image, c as CollectionPage, k as Note, s as Collection, u as Create } from "./vocab-D3C791xF.mjs";
|
|
4
4
|
import { t as esm_default } from "./esm-2_Uqq_my.mjs";
|
|
5
|
-
import { n as traverseCollection, t as lookupObject } from "./lookup
|
|
5
|
+
import { n as traverseCollection, t as lookupObject } from "./lookup--QvDSQ8m.mjs";
|
|
6
6
|
import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
|
|
7
7
|
import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
8
8
|
import { deepStrictEqual, ok, rejects } from "node:assert/strict";
|
|
@@ -1126,14 +1126,14 @@ test("accessors verify fetched documents that stand for portable objects", async
|
|
|
1126
1126
|
contextLoader: mockDocumentLoader,
|
|
1127
1127
|
verifyPortableObject: createVerifier()
|
|
1128
1128
|
}) instanceof Note, expected);
|
|
1129
|
-
|
|
1129
|
+
await rejects(() => createHttpActivity(plainUrl).then((activity) => activity.getObject({
|
|
1130
1130
|
documentLoader: createRedirectingLoader({ [plainUrl]: {
|
|
1131
1131
|
documentUrl: `ap://${did}/objects/x/../1`,
|
|
1132
1132
|
document: note()
|
|
1133
1133
|
} }),
|
|
1134
1134
|
contextLoader: mockDocumentLoader,
|
|
1135
1135
|
verifyPortableObject: createVerifier()
|
|
1136
|
-
}),
|
|
1136
|
+
})), TypeError);
|
|
1137
1137
|
});
|
|
1138
1138
|
await t.step("a malformed compatible final URL", async () => {
|
|
1139
1139
|
const malformed = `${compatibleNoteId}?@gateway=https%3A%2F%2Fgw2.example`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
globalThis.addEventListener = () => {};
|
|
3
3
|
import { A as Object$1 } from "./vocab-D3C791xF.mjs";
|
|
4
|
-
import { i as isActor, o as name, s as version } from "./actor-
|
|
4
|
+
import { i as isActor, o as name, s as version } from "./actor-CwM3qnho.mjs";
|
|
5
5
|
import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
|
|
6
6
|
import { canonicalizePortableUri, formatIri, getDocumentLoader, haveSameFe34Origin, haveSameIriOrigin, parseIri } from "@fedify/vocab-runtime";
|
|
7
7
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
@@ -142,7 +142,9 @@ const MAX_PORTABLE_ATTEMPTS = 5;
|
|
|
142
142
|
*
|
|
143
143
|
* [FEP-ef61] portable objects, including portable actors found through
|
|
144
144
|
* WebFinger, are looked up only if the `verifyPortableObject` option is
|
|
145
|
-
* given; see {@link LookupObjectOptions.verifyPortableObject}.
|
|
145
|
+
* given; see {@link LookupObjectOptions.verifyPortableObject}. Pass
|
|
146
|
+
* {@link LookupObjectOptions.gateways} to look up a portable ID without
|
|
147
|
+
* `@gateway` location hints.
|
|
146
148
|
*
|
|
147
149
|
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
148
150
|
*
|
|
@@ -200,7 +202,8 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
200
202
|
if (candidate == null) return null;
|
|
201
203
|
return await lookupPortableObject(portable, candidate, void 0);
|
|
202
204
|
}
|
|
203
|
-
|
|
205
|
+
if (options.verifyPortableObject != null && parseCompatibleEf61Reference(identifier) === null) return null;
|
|
206
|
+
identifier = toAcctUrl(identifier) ?? parseIri(identifier);
|
|
204
207
|
}
|
|
205
208
|
if (isPortableIri(identifier)) {
|
|
206
209
|
let candidate;
|
|
@@ -245,7 +248,7 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
245
248
|
const candidate = parsePortableCandidate(l.href);
|
|
246
249
|
if (candidate == null) continue;
|
|
247
250
|
const gateways = webFingerGateway == null ? [] : [webFingerGateway];
|
|
248
|
-
gateways.push(...getPortableGatewayCandidates(candidate));
|
|
251
|
+
if (options.gateways == null) gateways.push(...getPortableGatewayCandidates(candidate));
|
|
249
252
|
const object = await lookupPortableObject(portable, candidate, gateways);
|
|
250
253
|
if (object != null) return object;
|
|
251
254
|
if (options.signal?.aborted) return null;
|
|
@@ -297,10 +300,13 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
297
300
|
if (claim === null) {
|
|
298
301
|
logger.debug("Refusing the document {documentUrl}, as it claims to be a portable object with a malformed compatible identifier.", { documentUrl: remoteDoc.documentUrl });
|
|
299
302
|
return null;
|
|
300
|
-
} else if (claim != null)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
} else if (claim != null) {
|
|
304
|
+
const explicit = getExplicitGateways(portable, claim.id);
|
|
305
|
+
return await dereference(portable, claim.id, claim.inferredGateways, explicit, {
|
|
306
|
+
response: remoteDoc,
|
|
307
|
+
contextLoader: snapshot.loader
|
|
308
|
+
});
|
|
309
|
+
}
|
|
304
310
|
}
|
|
305
311
|
if (object.id != null && (options.crossOrigin !== "trust" || isPortableIri(object.id)) && !haveSameIriOrigin(object.id, documentUrl) && !haveSameFe34Origin(object.id, documentUrl)) {
|
|
306
312
|
if (options.crossOrigin === "throw") throw new Error(`The object's @id (${object.id.href}) has a different origin than the document URL (${remoteDoc.documentUrl}); refusing to return the object. If you want to bypass this check and are aware of the security implications, set the crossOrigin option to "trust".`);
|
|
@@ -316,6 +322,10 @@ async function lookupObjectInternal(identifier, options = {}) {
|
|
|
316
322
|
}
|
|
317
323
|
}
|
|
318
324
|
const PORTABLE_IRI_PATTERN = /^ap(?:\+ef61)?:/i;
|
|
325
|
+
function getExplicitGateways(lookup, id) {
|
|
326
|
+
if (lookup.options.gateways == null) return void 0;
|
|
327
|
+
return lookup.explicitGateways ??= getPortableGatewayCandidates(id, lookup.options.gateways);
|
|
328
|
+
}
|
|
319
329
|
/**
|
|
320
330
|
* Parses a raw portable IRI. URL parsing normalizes dot segments in the
|
|
321
331
|
* opaque path, which would make the parsed IRI identify another portable
|
|
@@ -369,29 +379,29 @@ function getWebFingerGateway(identifier) {
|
|
|
369
379
|
}
|
|
370
380
|
/**
|
|
371
381
|
* Looks up a portable object through FEP-ef61 gateways.
|
|
372
|
-
* @param
|
|
373
|
-
*
|
|
374
|
-
*
|
|
382
|
+
* @param inferredGateways Gateways inferred from a compatible identifier or
|
|
383
|
+
* WebFinger. If omitted, location hints in the IRI
|
|
384
|
+
* are used unless explicit gateways were given.
|
|
375
385
|
*/
|
|
376
|
-
async function lookupPortableObject(lookup, id,
|
|
386
|
+
async function lookupPortableObject(lookup, id, inferredGateways) {
|
|
377
387
|
const { options } = lookup;
|
|
378
388
|
const iri = formatIri(id);
|
|
389
|
+
const explicitGateways = getExplicitGateways(lookup, id);
|
|
379
390
|
if (options.verifyPortableObject == null) {
|
|
380
391
|
logger.debug("Cannot look up the portable object {iri}, as the verifyPortableObject option is not given.", { iri });
|
|
381
392
|
return null;
|
|
382
393
|
}
|
|
383
394
|
const canonicalId = canonicalizePortableUri(iri);
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
} else candidates = [...gateways];
|
|
395
|
+
const inferred = inferredGateways ?? (explicitGateways == null ? getPortableGatewayCandidates(id) : []);
|
|
396
|
+
const candidates = [...inferred];
|
|
397
|
+
for (const gateway of explicitGateways ?? []) if (!candidates.some((candidate) => candidate.href === gateway.href)) candidates.push(gateway);
|
|
398
|
+
if (candidates.length < 1 && inferredGateways == null) {
|
|
399
|
+
const key = `${canonicalId} `;
|
|
400
|
+
if (lookup.remaining < 1 || lookup.attempted.has(key)) return null;
|
|
401
|
+
lookup.attempted.add(key);
|
|
402
|
+
lookup.remaining--;
|
|
403
|
+
return await dereference(lookup, id, [], explicitGateways == null ? void 0 : []);
|
|
404
|
+
}
|
|
395
405
|
const selected = [];
|
|
396
406
|
for (const gateway of candidates) {
|
|
397
407
|
if (selected.length >= lookup.remaining) break;
|
|
@@ -402,16 +412,19 @@ async function lookupPortableObject(lookup, id, gateways) {
|
|
|
402
412
|
}
|
|
403
413
|
if (selected.length < 1) return null;
|
|
404
414
|
lookup.remaining -= selected.length;
|
|
405
|
-
|
|
415
|
+
const selectedInferred = selected.filter((candidate) => inferred.some((gateway) => gateway.href === candidate.href));
|
|
416
|
+
const selectedExplicit = explicitGateways?.filter((gateway) => selected.some((candidate) => candidate.href === gateway.href));
|
|
417
|
+
return await dereference(lookup, id, selectedInferred, selectedExplicit);
|
|
406
418
|
}
|
|
407
|
-
async function dereference({ options, documentLoader }, id, gateways, extra = {}) {
|
|
419
|
+
async function dereference({ options, documentLoader }, id, inferredGateways, gateways, extra = {}) {
|
|
408
420
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
409
421
|
try {
|
|
410
422
|
return await dereferencePortableIri(id, {
|
|
411
423
|
documentLoader,
|
|
412
424
|
contextLoader: extra.contextLoader ?? options.contextLoader ?? getDocumentLoader({ userAgent: options.userAgent }),
|
|
413
425
|
tracerProvider,
|
|
414
|
-
inferredGateways
|
|
426
|
+
inferredGateways,
|
|
427
|
+
...gateways == null ? {} : { gateways },
|
|
415
428
|
response: extra.response,
|
|
416
429
|
verifyPortableObject: options.verifyPortableObject,
|
|
417
430
|
crossOrigin: options.crossOrigin === "throw" ? "throw" : "ignore",
|
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
globalThis.addEventListener = () => {};
|
|
3
3
|
import { A as Object$1, F as Person, k as Note, s as Collection } from "./vocab-D3C791xF.mjs";
|
|
4
4
|
import { t as esm_default } from "./esm-2_Uqq_my.mjs";
|
|
5
|
-
import { n as traverseCollection, t as lookupObject } from "./lookup
|
|
5
|
+
import { n as traverseCollection, t as lookupObject } from "./lookup--QvDSQ8m.mjs";
|
|
6
6
|
import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
|
|
7
7
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
8
8
|
import { deepStrictEqual, equal, ok, rejects } from "node:assert/strict";
|