Unverified Commit 4d459c5d authored by Hong Minhee's avatar Hong Minhee
Browse files

RequestContext.getSignedKey() method

parent 6ef7c7a4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -10,7 +10,11 @@ To be released.

 -  Added `PUBLIC_COLLECTION` constant for [public addressing].

 -  Added `RequestContext.getSignedKey()` method for [authorized fetch]
    (also known as secure mode).

[public addressing]: https://www.w3.org/TR/activitypub/#public-addressing
[authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch


Version 0.6.0
+14 −0
Original line number Diff line number Diff line
@@ -141,6 +141,20 @@ export interface RequestContext<TContextData> extends Context<TContextData> {
   * The URL of the request.
   */
  readonly url: URL;

  /**
   * Gets the public key of the sender, if any exists and it is verified.
   * Otherwise, `null` is returned.
   *
   * This can be used for implementing [authorized fetch] (also known as
   * secure mode) in ActivityPub.
   *
   * [authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch
   *
   * @returns The public key of the sender, or `null` if the sender is not verified.
   * @since 0.7.0
   */
  getSignedKey(): Promise<CryptographicKey | null>;
}

/**
+20 −4
Original line number Diff line number Diff line
import { sign } from "@fedify/fedify";
import { Temporal } from "@js-temporal/polyfill";
import {
  assertEquals,
@@ -8,7 +7,7 @@ import {
} from "@std/assert";
import { dirname, join } from "@std/path";
import * as mf from "mock_fetch";
import { verify } from "../httpsig/mod.ts";
import { sign, verify } from "../httpsig/mod.ts";
import {
  FetchError,
  getAuthenticatedDocumentLoader,
@@ -169,14 +168,31 @@ Deno.test("Federation.createContext()", async (t) => {
    );
  });

  await t.step("RequestContext", () => {
    const federation = new Federation<number>({ kv, documentLoader });
  await t.step("RequestContext", async () => {
    const federation = new Federation<number>({
      kv,
      documentLoader: mockDocumentLoader,
    });
    const req = new Request("https://example.com/");
    const ctx = federation.createContext(req, 123);
    assertEquals(ctx.request, req);
    assertEquals(ctx.url, new URL("https://example.com/"));
    assertEquals(ctx.data, 123);
    assertEquals(await ctx.getSignedKey(), null);

    const signedReq = await sign(
      new Request("https://example.com/"),
      privateKey2,
      publicKey2.id!,
    );
    const signedCtx = federation.createContext(signedReq, 456);
    assertEquals(signedCtx.request, signedReq);
    assertEquals(signedCtx.url, new URL("https://example.com/"));
    assertEquals(signedCtx.data, 456);
    assertEquals(await signedCtx.getSignedKey(), publicKey2);
  });

  mf.uninstall();
});

Deno.test("Federation.setInboxListeners()", async (t) => {
+4 −0
Original line number Diff line number Diff line
import { Temporal } from "@js-temporal/polyfill";
import { exportJwk, importJwk, validateCryptoKey } from "../httpsig/key.ts";
import { verify } from "../httpsig/mod.ts";
import { handleNodeInfo, handleNodeInfoJrd } from "../nodeinfo/handler.ts";
import {
  type AuthenticatedDocumentLoaderFactory,
@@ -393,6 +394,9 @@ export class Federation<TContextData> {
      ...context,
      request,
      url,
      getSignedKey() {
        return verify(request, context.documentLoader);
      },
    };
    return reqCtx;
  }
+1 −0
Original line number Diff line number Diff line
@@ -55,5 +55,6 @@ export function createRequestContext<TContextData>(
    ...createContext(args),
    request: args.request ?? new Request(args.url),
    url: args.url,
    getSignedKey: args.getSignedKey ?? (() => Promise.resolve(null)),
  };
}