Unverified Commit 18deb475 authored by Hong Minhee's avatar Hong Minhee
Browse files

Fix few bugs in double-knocking

parent e257f948
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
import { Command, CompletionsCommand, HelpCommand } from "@cliffy/command";
import { configure, getConsoleSink, getFileSink } from "@logtape/logtape";
import { AsyncLocalStorage } from "node:async_hooks";
import { DEFAULT_CACHE_DIR, setCacheDir } from "./cache.ts";
import metadata from "./deno.json" with { type: "json" };
import { command as inbox } from "./inbox.tsx";
@@ -46,6 +47,7 @@ const command = new Command()
          },
        ],
        reset: true,
        contextLocalStorage: new AsyncLocalStorage(),
      });
    },
  })
+1 −9
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@ import metadata from "../deno.json" with { type: "json" };
import {
  doubleKnock,
  type HttpMessageSignaturesSpecDeterminer,
  signRequest,
} from "../sig/http.ts";
import type { Recipient } from "../vocab/actor.ts";

@@ -201,7 +200,7 @@ async function sendActivityInternal(
  const logger = getLogger(["fedify", "federation", "outbox"]);
  headers = new Headers(headers);
  headers.set("Content-Type", "application/activity+json");
  let request = new Request(inbox, {
  const request = new Request(inbox, {
    method: "POST",
    headers,
    body: JSON.stringify(activity),
@@ -227,13 +226,6 @@ async function sendActivityInternal(
        })),
      },
    );
  } else {
    request = await signRequest(
      request,
      rsaKey.privateKey,
      rsaKey.keyId,
      { tracerProvider },
    );
  }
  let response: Response;
  try {
+1 −5
Original line number Diff line number Diff line
@@ -1230,11 +1230,7 @@ test("doubleKnock() function with successful first attempt", async () => {
    "rfc9421",
    "First attempt should use RFC 9421",
  );
  assertEquals(
    specDeterminer.usedSpec,
    null,
    "rememberSpec should not be called on first success",
  );
  assertEquals(specDeterminer.usedSpec, "rfc9421", "Spec should be remembered");
  assertExists(loggedRequest, "Request should be logged");
  assert(
    loggedRequest?.headers.has("Signature-Input"),
+9 −7
Original line number Diff line number Diff line
@@ -1239,7 +1239,7 @@ export async function doubleKnock(
  ) {
    const location = response.headers.get("Location")!;
    const body = request.method !== "GET" && request.method !== "HEAD"
      ? request.clone().body
      ? await request.clone().arrayBuffer()
      : undefined;
    return doubleKnock(
      new Request(location, {
@@ -1249,7 +1249,6 @@ export async function doubleKnock(
        redirect: "manual",
        signal: request.signal,
        mode: request.mode,
        cache: request.cache,
        credentials: request.credentials,
        referrer: request.referrer,
        referrerPolicy: request.referrerPolicy,
@@ -1262,17 +1261,18 @@ export async function doubleKnock(
  } else if (response.status === 400 || response.status === 401) {
    // verification failed; retry with the other spec of HTTP Signatures
    // (double-knocking; see https://swicg.github.io/activitypub-http-signature/#how-to-upgrade-supported-versions)
    const spec = firstTrySpec === "draft-cavage-http-signatures-12"
      ? "rfc9421"
      : "draft-cavage-http-signatures-12";
    getLogger(["fedify", "sig", "http"]).debug(
      "Failed to verify with the spec {spec} ({status} {statusText}); retrying with the other spec... (double-knocking)",
      "Failed to verify with the spec {spec} ({status} {statusText}); retrying with spec {secondSpec}... (double-knocking)",
      {
        spec: firstTrySpec,
        secondSpec: spec,
        status: response.status,
        statusText: response.statusText,
      },
    );
    const spec = firstTrySpec === "draft-cavage-http-signatures-12"
      ? "rfc9421"
      : "draft-cavage-http-signatures-12";
    signedRequest = await signRequest(
      request,
      identity.privateKey,
@@ -1301,8 +1301,10 @@ export async function doubleKnock(
        options,
      );
    } else if (response.status !== 400 && response.status !== 401) {
      specDeterminer?.rememberSpec(origin, spec);
      await specDeterminer?.rememberSpec(origin, spec);
    }
  } else {
    await specDeterminer?.rememberSpec(origin, firstTrySpec);
  }
  return response;
}