@fedify/fedify 2.1.0-dev.503 → 2.1.0-dev.513
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/dist/{builder-BHUnSQtB.js → builder-DSYM2n7q.js} +9 -3
- package/dist/compat/mod.d.cts +3 -3
- package/dist/compat/mod.d.ts +3 -3
- package/dist/compat/transformers.test.js +12 -12
- package/dist/{context-DZJhUmzF.d.ts → context--RwChtri.d.ts} +54 -2
- package/dist/{context-D3QkEtZd.d.cts → context-DL0cPpPV.d.cts} +54 -2
- package/dist/{deno-BYerLnry.js → deno-aj03PJW6.js} +1 -1
- package/dist/{docloader-MSkogD2T.js → docloader-tMQxWuTM.js} +2 -2
- package/dist/federation/builder.test.js +14 -3
- package/dist/federation/handler.test.js +97 -13
- package/dist/federation/idempotency.test.js +12 -12
- package/dist/federation/inbox.test.js +2 -2
- package/dist/federation/keycache.test.js +46 -2
- package/dist/federation/middleware.test.js +206 -12
- package/dist/federation/mod.cjs +4 -4
- package/dist/federation/mod.d.cts +4 -4
- package/dist/federation/mod.d.ts +4 -4
- package/dist/federation/mod.js +4 -4
- package/dist/federation/send.test.js +5 -5
- package/dist/federation/webfinger.test.js +12 -12
- package/dist/{http-DkHdFfrc.d.ts → http-BbfOqHGG.d.ts} +80 -8
- package/dist/{http-CSX1-Mgi.js → http-CoM8qFZV.js} +295 -101
- package/dist/{http-Cz3MlXAZ.d.cts → http-DsqqmkXi.d.cts} +80 -8
- package/dist/{http-DJT6NciB.cjs → http-_l2XRk4S.cjs} +305 -99
- package/dist/{http-S2U3qDwN.js → http-pa5yLKK7.js} +153 -57
- package/dist/{inbox-BaA0g5I_.js → inbox-EI2EtQri.js} +1 -1
- package/dist/{key-DCdTVZiK.js → key-j1AjF3HL.js} +145 -47
- package/dist/keycache-C7k8s1Bk.js +102 -0
- package/dist/{kv-cache-CQPL_aGY.js → kv-cache-CMk-kfWp.js} +1 -1
- package/dist/{kv-cache-Vtxhbo1W.cjs → kv-cache-D0IkOVYm.cjs} +1 -1
- package/dist/{ld-CrX7pQda.js → ld-CD48Tb3_.js} +2 -2
- package/dist/middleware-BQhgZunR.cjs +12 -0
- package/dist/{middleware-MlO5iUeZ.js → middleware-BRIM_AL5.js} +158 -22
- package/dist/{middleware-C8PKuPrm.js → middleware-CWMuqleA.js} +4 -4
- package/dist/{middleware-D4S6i4A_.cjs → middleware-D1Awtgcf.cjs} +158 -22
- package/dist/{middleware-BelSJK7m.js → middleware-DbmQ5-Ph.js} +100 -24
- package/dist/{middleware-CfI9C9Xy.js → middleware-b9jiK13s.js} +12 -12
- package/dist/{mod-CwZXZJ9d.d.ts → mod-BugwI0JN.d.ts} +1 -1
- package/dist/{mod-DPkRU3EK.d.cts → mod-CFBU2OT3.d.cts} +1 -1
- package/dist/{mod-DUWcVv49.d.ts → mod-CvxylbuV.d.ts} +1 -1
- package/dist/{mod-DVwHUI_x.d.cts → mod-DE8MYisy.d.cts} +1 -1
- package/dist/{mod-DXsQakeS.d.cts → mod-DKG0ovjR.d.cts} +1 -1
- package/dist/{mod-DnSsduJF.d.ts → mod-DcfFNgYf.d.ts} +1 -1
- package/dist/{mod-Di3W5OdP.d.cts → mod-Dp0kK0hO.d.cts} +1 -1
- package/dist/{mod-DosD6NsG.d.ts → mod-Z7lIaCfo.d.ts} +1 -1
- package/dist/mod.cjs +8 -4
- package/dist/mod.d.cts +8 -8
- package/dist/mod.d.ts +8 -8
- package/dist/mod.js +7 -5
- package/dist/nodeinfo/handler.test.js +12 -12
- package/dist/otel/exporter.test.js +43 -2
- package/dist/otel/mod.cjs +7 -1
- package/dist/otel/mod.d.cts +12 -0
- package/dist/otel/mod.d.ts +12 -0
- package/dist/otel/mod.js +7 -1
- package/dist/{owner-BAlnLKMO.js → owner-ZjRdCtVA.js} +1 -1
- package/dist/{proof-BgUVmaJz.js → proof-CQfh4S5r.js} +1 -1
- package/dist/{proof-CR5RUAmy.cjs → proof-D2auLGZD.cjs} +1 -1
- package/dist/{proof-DMgHaXNJ.js → proof-gmdzyEsv.js} +2 -2
- package/dist/{send-B2aZYf9A.js → send-1lNwij0f.js} +2 -2
- package/dist/sig/http.test.js +85 -5
- package/dist/sig/key.test.js +70 -3
- package/dist/sig/ld.test.js +3 -3
- package/dist/sig/mod.cjs +4 -2
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.js +3 -3
- package/dist/sig/proof.test.js +3 -3
- package/dist/testing/mod.d.ts +92 -0
- package/dist/utils/docloader.test.js +4 -4
- package/dist/utils/mod.cjs +2 -2
- package/dist/utils/mod.d.cts +2 -2
- package/dist/utils/mod.d.ts +2 -2
- package/dist/utils/mod.js +2 -2
- package/package.json +5 -5
- package/dist/keycache-DRxpZ5r9.js +0 -48
- package/dist/middleware-D4XcpSBG.cjs +0 -12
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
globalThis.addEventListener = () => {};
|
|
5
5
|
|
|
6
|
-
import { deno_default } from "./deno-
|
|
6
|
+
import { deno_default } from "./deno-aj03PJW6.js";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
9
|
-
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
9
|
+
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
10
10
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
11
11
|
|
|
12
12
|
//#region src/sig/key.ts
|
|
@@ -89,24 +89,10 @@ async function importJwk(jwk, type) {
|
|
|
89
89
|
validateCryptoKey(key, type);
|
|
90
90
|
return key;
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
* If the given URL contains an {@link Actor} object, it tries to find
|
|
95
|
-
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
96
|
-
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
97
|
-
* or {@link Multikey}.
|
|
98
|
-
* @param keyId The URL of the key.
|
|
99
|
-
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
100
|
-
* or {@link Multikey}.
|
|
101
|
-
* @param options Options for fetching the key. See {@link FetchKeyOptions}.
|
|
102
|
-
* @returns The fetched key or `null` if the key is not found.
|
|
103
|
-
* @since 1.3.0
|
|
104
|
-
*/
|
|
105
|
-
function fetchKey(keyId, cls, options = {}) {
|
|
106
|
-
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
92
|
+
async function withFetchKeySpan(keyId, tracerProvider, fetcher) {
|
|
93
|
+
tracerProvider ??= trace.getTracerProvider();
|
|
107
94
|
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
108
|
-
|
|
109
|
-
return tracer.startActiveSpan("activitypub.fetch_key", {
|
|
95
|
+
return await tracer.startActiveSpan("activitypub.fetch_key", {
|
|
110
96
|
kind: SpanKind.CLIENT,
|
|
111
97
|
attributes: {
|
|
112
98
|
"http.method": "GET",
|
|
@@ -119,7 +105,7 @@ function fetchKey(keyId, cls, options = {}) {
|
|
|
119
105
|
}
|
|
120
106
|
}, async (span) => {
|
|
121
107
|
try {
|
|
122
|
-
const result = await
|
|
108
|
+
const result = await fetcher();
|
|
123
109
|
span.setAttribute("activitypub.actor.key.cached", result.cached);
|
|
124
110
|
return result;
|
|
125
111
|
} catch (e) {
|
|
@@ -133,43 +119,105 @@ function fetchKey(keyId, cls, options = {}) {
|
|
|
133
119
|
}
|
|
134
120
|
});
|
|
135
121
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL.
|
|
124
|
+
* If the given URL contains an {@link Actor} object, it tries to find
|
|
125
|
+
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
126
|
+
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
127
|
+
* or {@link Multikey}.
|
|
128
|
+
* @param keyId The URL of the key.
|
|
129
|
+
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
130
|
+
* or {@link Multikey}.
|
|
131
|
+
* @param options Options for fetching the key. See {@link FetchKeyOptions}.
|
|
132
|
+
* @returns The fetched key or `null` if the key is not found.
|
|
133
|
+
* @since 1.3.0
|
|
134
|
+
*/
|
|
135
|
+
function fetchKey(keyId, cls, options = {}) {
|
|
136
|
+
keyId = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
137
|
+
return withFetchKeySpan(keyId, options.tracerProvider, () => fetchKeyInternal(keyId, cls, options));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL,
|
|
141
|
+
* preserving transport-level fetch failures for callers that need to inspect
|
|
142
|
+
* why the key could not be loaded.
|
|
143
|
+
*
|
|
144
|
+
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
145
|
+
* or {@link Multikey}.
|
|
146
|
+
* @param keyId The URL of the key.
|
|
147
|
+
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
148
|
+
* or {@link Multikey}.
|
|
149
|
+
* @param options Options for fetching the key.
|
|
150
|
+
* @returns The fetched key, or detailed fetch failure information.
|
|
151
|
+
* @since 2.1.0
|
|
152
|
+
*/
|
|
153
|
+
async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
142
154
|
const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
return await withFetchKeySpan(cacheKey, options.tracerProvider, async () => {
|
|
156
|
+
return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey$1, keyId$1, keyCache, logger) => {
|
|
157
|
+
const fetchError = await keyCache?.getFetchError?.(cacheKey$1);
|
|
158
|
+
if (fetchError != null) {
|
|
159
|
+
logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId: keyId$1 });
|
|
160
|
+
return {
|
|
161
|
+
key: null,
|
|
162
|
+
cached: true,
|
|
163
|
+
fetchError
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId: keyId$1 });
|
|
148
167
|
return {
|
|
149
|
-
key:
|
|
168
|
+
key: null,
|
|
150
169
|
cached: true
|
|
151
170
|
};
|
|
152
|
-
}
|
|
153
|
-
logger.debug("
|
|
171
|
+
}, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
|
|
172
|
+
logger.debug("Failed to fetch key {keyId}.", {
|
|
173
|
+
keyId: keyId$1,
|
|
174
|
+
error
|
|
175
|
+
});
|
|
176
|
+
await keyCache?.set(cacheKey$1, null);
|
|
177
|
+
if (error instanceof FetchError && error.response != null) {
|
|
178
|
+
const fetchError$1 = {
|
|
179
|
+
status: error.response.status,
|
|
180
|
+
response: error.response.clone()
|
|
181
|
+
};
|
|
182
|
+
await keyCache?.setFetchError?.(cacheKey$1, fetchError$1);
|
|
183
|
+
return {
|
|
184
|
+
key: null,
|
|
185
|
+
cached: false,
|
|
186
|
+
fetchError: fetchError$1
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const fetchError = { error: error instanceof Error ? error : new Error(String(error)) };
|
|
190
|
+
await keyCache?.setFetchError?.(cacheKey$1, fetchError);
|
|
154
191
|
return {
|
|
155
192
|
key: null,
|
|
156
|
-
cached:
|
|
193
|
+
cached: false,
|
|
194
|
+
fetchError
|
|
157
195
|
};
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
|
|
200
|
+
if (keyCache == null) return null;
|
|
201
|
+
const cachedKey = await keyCache.get(cacheKey);
|
|
202
|
+
if (cachedKey instanceof cls && cachedKey.publicKey != null) {
|
|
203
|
+
logger.debug("Key {keyId} found in cache.", { keyId });
|
|
204
|
+
return {
|
|
205
|
+
key: cachedKey,
|
|
206
|
+
cached: true
|
|
207
|
+
};
|
|
208
|
+
} else if (cachedKey === null) {
|
|
209
|
+
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
168
210
|
return {
|
|
169
211
|
key: null,
|
|
170
|
-
cached:
|
|
212
|
+
cached: true
|
|
171
213
|
};
|
|
172
214
|
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
218
|
+
await keyCache?.setFetchError?.(keyId, null);
|
|
219
|
+
}
|
|
220
|
+
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
173
221
|
let object;
|
|
174
222
|
try {
|
|
175
223
|
object = await Object$1.fromJsonLd(document, {
|
|
@@ -189,6 +237,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
189
237
|
if (e$1 instanceof TypeError) {
|
|
190
238
|
logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
|
|
191
239
|
await keyCache?.set(cacheKey, null);
|
|
240
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
192
241
|
return {
|
|
193
242
|
key: null,
|
|
194
243
|
cached: false
|
|
@@ -227,6 +276,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
227
276
|
actorType: object.constructor.name
|
|
228
277
|
});
|
|
229
278
|
await keyCache?.set(cacheKey, null);
|
|
279
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
230
280
|
return {
|
|
231
281
|
key: null,
|
|
232
282
|
cached: false
|
|
@@ -235,6 +285,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
235
285
|
} else {
|
|
236
286
|
logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
|
|
237
287
|
await keyCache?.set(cacheKey, null);
|
|
288
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
238
289
|
return {
|
|
239
290
|
key: null,
|
|
240
291
|
cached: false
|
|
@@ -243,6 +294,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
243
294
|
if (key.publicKey == null) {
|
|
244
295
|
logger.debug("Failed to verify; key {keyId} has no publicKeyPem field.", { keyId });
|
|
245
296
|
await keyCache?.set(cacheKey, null);
|
|
297
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
246
298
|
return {
|
|
247
299
|
key: null,
|
|
248
300
|
cached: false
|
|
@@ -252,11 +304,57 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
252
304
|
await keyCache.set(cacheKey, key);
|
|
253
305
|
logger.debug("Key {keyId} cached.", { keyId });
|
|
254
306
|
}
|
|
307
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
255
308
|
return {
|
|
256
309
|
key,
|
|
257
310
|
cached: false
|
|
258
311
|
};
|
|
259
312
|
}
|
|
313
|
+
async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, onFetchError) {
|
|
314
|
+
const logger = getLogger([
|
|
315
|
+
"fedify",
|
|
316
|
+
"sig",
|
|
317
|
+
"key"
|
|
318
|
+
]);
|
|
319
|
+
const keyId = cacheKey.href;
|
|
320
|
+
const keyCache = options.keyCache;
|
|
321
|
+
const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
|
|
322
|
+
if (cached?.key === null && cached.cached) return await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
|
|
323
|
+
if (cached != null) return cached;
|
|
324
|
+
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
325
|
+
let document;
|
|
326
|
+
try {
|
|
327
|
+
const remoteDocument = await (options.documentLoader ?? getDocumentLoader())(keyId);
|
|
328
|
+
document = remoteDocument.document;
|
|
329
|
+
} catch (error) {
|
|
330
|
+
return await onFetchError(error, cacheKey, keyId, keyCache, logger);
|
|
331
|
+
}
|
|
332
|
+
return await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
|
|
333
|
+
}
|
|
334
|
+
async function fetchKeyInternal(keyId, cls, options = {}) {
|
|
335
|
+
const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
336
|
+
return await fetchKeyWithResult(cacheKey, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
|
|
337
|
+
return {
|
|
338
|
+
key: null,
|
|
339
|
+
cached: true
|
|
340
|
+
};
|
|
341
|
+
}, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
|
|
342
|
+
logger.debug("Failed to fetch key {keyId}.", {
|
|
343
|
+
keyId: keyId$1,
|
|
344
|
+
error
|
|
345
|
+
});
|
|
346
|
+
await keyCache?.set(cacheKey$1, null);
|
|
347
|
+
if (error instanceof FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey$1, {
|
|
348
|
+
status: error.response.status,
|
|
349
|
+
response: error.response.clone()
|
|
350
|
+
});
|
|
351
|
+
else await keyCache?.setFetchError?.(cacheKey$1, { error: error instanceof Error ? error : new Error(String(error)) });
|
|
352
|
+
return {
|
|
353
|
+
key: null,
|
|
354
|
+
cached: false
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
}
|
|
260
358
|
|
|
261
359
|
//#endregion
|
|
262
|
-
export { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey };
|
|
360
|
+
export { exportJwk, fetchKey, fetchKeyDetailed, generateCryptoKeyPair, importJwk, validateCryptoKey };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
+
import { URLPattern } from "urlpattern-polyfill";
|
|
4
|
+
globalThis.addEventListener = () => {};
|
|
5
|
+
|
|
6
|
+
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
7
|
+
|
|
8
|
+
//#region src/federation/keycache.ts
|
|
9
|
+
var KvKeyCache = class {
|
|
10
|
+
kv;
|
|
11
|
+
prefix;
|
|
12
|
+
options;
|
|
13
|
+
unavailableKeyTtl;
|
|
14
|
+
nullKeys;
|
|
15
|
+
constructor(kv, prefix, options = {}) {
|
|
16
|
+
this.kv = kv;
|
|
17
|
+
this.prefix = prefix;
|
|
18
|
+
this.options = options;
|
|
19
|
+
this.unavailableKeyTtl = options.unavailableKeyTtl ?? Temporal.Duration.from({ minutes: 10 });
|
|
20
|
+
this.nullKeys = /* @__PURE__ */ new Map();
|
|
21
|
+
}
|
|
22
|
+
#getFetchErrorKey(keyId) {
|
|
23
|
+
return [
|
|
24
|
+
...this.prefix,
|
|
25
|
+
"__fetchError",
|
|
26
|
+
keyId.href
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
async get(keyId) {
|
|
30
|
+
const negativeExpiration = this.nullKeys.get(keyId.href);
|
|
31
|
+
if (negativeExpiration != null) {
|
|
32
|
+
if (Temporal.Now.instant().until(negativeExpiration).sign >= 0) return null;
|
|
33
|
+
this.nullKeys.delete(keyId.href);
|
|
34
|
+
}
|
|
35
|
+
const serialized = await this.kv.get([...this.prefix, keyId.href]);
|
|
36
|
+
if (serialized === void 0) return void 0;
|
|
37
|
+
if (serialized === null) {
|
|
38
|
+
this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return await CryptographicKey.fromJsonLd(serialized, this.options);
|
|
43
|
+
} catch {
|
|
44
|
+
try {
|
|
45
|
+
return await Multikey.fromJsonLd(serialized, this.options);
|
|
46
|
+
} catch {
|
|
47
|
+
await this.kv.delete([...this.prefix, keyId.href]);
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async set(keyId, key) {
|
|
53
|
+
if (key == null) {
|
|
54
|
+
this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
|
|
55
|
+
await this.kv.set([...this.prefix, keyId.href], null, { ttl: this.unavailableKeyTtl });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.nullKeys.delete(keyId.href);
|
|
59
|
+
const serialized = await key.toJsonLd(this.options);
|
|
60
|
+
await this.kv.set([...this.prefix, keyId.href], serialized);
|
|
61
|
+
}
|
|
62
|
+
async getFetchError(keyId) {
|
|
63
|
+
const cached = await this.kv.get(this.#getFetchErrorKey(keyId));
|
|
64
|
+
if (cached == null || typeof cached !== "object") return void 0;
|
|
65
|
+
if ("status" in cached && typeof cached.status === "number" && "statusText" in cached && typeof cached.statusText === "string" && "headers" in cached && Array.isArray(cached.headers) && "body" in cached && typeof cached.body === "string") return {
|
|
66
|
+
status: cached.status,
|
|
67
|
+
response: new Response(cached.body, {
|
|
68
|
+
status: cached.status,
|
|
69
|
+
statusText: cached.statusText,
|
|
70
|
+
headers: cached.headers
|
|
71
|
+
})
|
|
72
|
+
};
|
|
73
|
+
else if ("errorName" in cached && typeof cached.errorName === "string" && "errorMessage" in cached && typeof cached.errorMessage === "string") {
|
|
74
|
+
const error = new Error(cached.errorMessage);
|
|
75
|
+
error.name = cached.errorName;
|
|
76
|
+
return { error };
|
|
77
|
+
}
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
async setFetchError(keyId, error) {
|
|
81
|
+
if (error == null) {
|
|
82
|
+
await this.kv.delete(this.#getFetchErrorKey(keyId));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if ("status" in error) {
|
|
86
|
+
await this.kv.set(this.#getFetchErrorKey(keyId), {
|
|
87
|
+
status: error.status,
|
|
88
|
+
statusText: error.response.statusText,
|
|
89
|
+
headers: Array.from(error.response.headers.entries()),
|
|
90
|
+
body: await error.response.clone().text()
|
|
91
|
+
}, { ttl: this.unavailableKeyTtl });
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
await this.kv.set(this.#getFetchErrorKey(keyId), {
|
|
95
|
+
errorName: error.error.name,
|
|
96
|
+
errorMessage: error.error.message
|
|
97
|
+
}, { ttl: this.unavailableKeyTtl });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
export { KvKeyCache };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
|
|
5
|
-
import { doubleKnock, validateCryptoKey } from "./http-
|
|
5
|
+
import { doubleKnock, validateCryptoKey } from "./http-CoM8qFZV.js";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { curry } from "es-toolkit";
|
|
8
8
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
4
4
|
|
|
5
5
|
const require_chunk = require('./chunk-CGaQZ11T.cjs');
|
|
6
|
-
const require_http = require('./http-
|
|
6
|
+
const require_http = require('./http-_l2XRk4S.cjs');
|
|
7
7
|
const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
|
|
8
8
|
const es_toolkit = require_chunk.__toESM(require("es-toolkit"));
|
|
9
9
|
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
globalThis.addEventListener = () => {};
|
|
5
5
|
|
|
6
|
-
import { deno_default } from "./deno-
|
|
7
|
-
import { fetchKey, validateCryptoKey } from "./key-
|
|
6
|
+
import { deno_default } from "./deno-aj03PJW6.js";
|
|
7
|
+
import { fetchKey, validateCryptoKey } from "./key-j1AjF3HL.js";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
9
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
10
10
|
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
const { Temporal } = require("@js-temporal/polyfill");
|
|
3
|
+
const { URLPattern } = require("urlpattern-polyfill");
|
|
4
|
+
|
|
5
|
+
require('./transformers-3g8GZwkZ.cjs');
|
|
6
|
+
require('./http-_l2XRk4S.cjs');
|
|
7
|
+
const require_middleware = require('./middleware-D1Awtgcf.cjs');
|
|
8
|
+
require('./proof-D2auLGZD.cjs');
|
|
9
|
+
require('./types-Cd_hszr_.cjs');
|
|
10
|
+
require('./kv-cache-D0IkOVYm.cjs');
|
|
11
|
+
|
|
12
|
+
exports.FederationImpl = require_middleware.FederationImpl;
|