Unverified Commit 3d98cde5 authored by Hong Minhee's avatar Hong Minhee
Browse files

Cache unavailable keys as well

parent 2400eeb4
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -39,6 +39,19 @@ To be released.
     -  Added `-u`/--user-agent` option to `fedify lookup` subcommand.
     -  Added `-u`/--user-agent` option to `fedify node` subcommand.

 -  Fedify now caches unavailable keys of remote actors as well to avoid
    trying fetching the same unavailable key multiple times.

     -  The return type of the `KeyCache.get()` method became
        `Promise<CryptographicKey | MultiKey | null | undefined>` (was
        `Promise<CryptographicKey | MultiKey | null>`).
     -  The type of the `KeyCache.set()` method's second parameter became
        `CryptographicKey | MultiKey | null` (was `CryptographicKey | MultiKey`).
     -  Added `fetchKey()` function.
     -  Added `FetchKeyOptions` interface.
     -  Added `FetchKeyResult` interface.


[#162]: https://github.com/dahlia/fedify/issues/162


@@ -1794,8 +1807,6 @@ is now distributed under the [MIT License] to encourage wider adoption.
     -  Added `VerifyObjectOptions` interface.
     -  Added `verifyProof()` function.
     -  Added `VerifyProofOptions` interface.
     -  Added `fetchKey()` function.
     -  Added `FetchKeyOptions` interface.
     -  Added `SenderKeyPair` interface.
     -  The type of `Federation.sendActivity()` method's first parameter became
        `SenderKeyPair[]` (was `{ keyId: URL; privateKey: CryptoKey }`).
+1 −1
Original line number Diff line number Diff line
@@ -1177,7 +1177,7 @@ test("handleInbox()", async () => {
    ...inboxOptions,
  });
  assertEquals(onNotFoundCalled, null);
  assertEquals(response.status, 202);
  assertEquals([response.status, await response.text()], [202, ""]);

  response = await handleInbox(unsignedRequest, {
    recipient: null,
+15 −5
Original line number Diff line number Diff line
@@ -420,25 +420,35 @@ export async function handleInbox<TContextData>(
      headers: { "Content-Type": "text/plain; charset=utf-8" },
    });
  }
  const keyCache: KeyCache = {
  const keyCache: KeyCache & { nullKeys: Set<string> } = {
    nullKeys: new Set(),
    async get(keyId: URL) {
      if (this.nullKeys.has(keyId.href)) return null;
      const serialized = await kv.get([
        ...kvPrefixes.publicKey,
        keyId.href,
      ]);
      if (serialized == null) return null;
      if (serialized == null) return undefined;
      let object: Object;
      try {
        object = await Object.fromJsonLd(serialized, context);
      } catch {
        return null;
        await kv.delete([...kvPrefixes.publicKey, keyId.href]);
        return undefined;
      }
      if (object instanceof CryptographicKey || object instanceof Multikey) {
        return object;
      }
      return null;
      await kv.delete([...kvPrefixes.publicKey, keyId.href]);
      return undefined;
    },
    async set(keyId: URL, key: CryptographicKey | Multikey) {
    async set(keyId: URL, key: CryptographicKey | Multikey | null) {
      if (key == null) {
        this.nullKeys.add(keyId.href);
        await kv.delete([...kvPrefixes.publicKey, keyId.href]);
        return;
      }
      this.nullKeys.delete(keyId.href);
      const serialized = await key.toJsonLd(context);
      await kv.set([...kvPrefixes.publicKey, keyId.href], serialized);
    },
+3 −3
Original line number Diff line number Diff line
@@ -1004,7 +1004,7 @@ test("ContextImpl.sendActivity()", async (t) => {
      contextLoader: mockDocumentLoader,
      keyCache: {
        async get(keyId: URL) {
          const ctx = await federation.createContext(
          const ctx = federation.createContext(
            new URL("https://example.com/"),
            undefined,
          );
@@ -1016,9 +1016,9 @@ test("ContextImpl.sendActivity()", async (t) => {
              } else return key.cryptographicKey;
            }
          }
          return null;
          return undefined;
        },
        async set(_keyId: URL, _key: CryptographicKey | Multikey) {
        async set(_keyId: URL, _key: CryptographicKey | Multikey | null) {
        },
      } satisfies KeyCache,
    };
+2 −2
Original line number Diff line number Diff line
@@ -57,14 +57,14 @@ test("verifyRequest()", async () => {
        '+M6DrfkfQuUBw=="', // cSpell: enable
    },
  });
  const cache: Record<string, CryptographicKey | Multikey> = {};
  const cache: Record<string, CryptographicKey | Multikey | null> = {};
  const options: VerifyRequestOptions = {
    contextLoader: mockDocumentLoader,
    documentLoader: mockDocumentLoader,
    currentTime: Temporal.Instant.from("2024-03-05T07:49:44Z"),
    keyCache: {
      get(keyId) {
        return Promise.resolve(cache[keyId.href] ?? null);
        return Promise.resolve(cache[keyId.href]);
      },
      set(keyId, key) {
        cache[keyId.href] = key;
Loading