Loading CHANGES.md +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading federation/context.ts +14 −0 Original line number Diff line number Diff line Loading @@ -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>; } /** Loading federation/middleware.test.ts +20 −4 Original line number Diff line number Diff line import { sign } from "@fedify/fedify"; import { Temporal } from "@js-temporal/polyfill"; import { assertEquals, Loading @@ -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, Loading Loading @@ -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) => { Loading federation/middleware.ts +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, Loading Loading @@ -393,6 +394,9 @@ export class Federation<TContextData> { ...context, request, url, getSignedKey() { return verify(request, context.documentLoader); }, }; return reqCtx; } Loading testing/context.ts +1 −0 Original line number Diff line number Diff line Loading @@ -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)), }; } Loading
CHANGES.md +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
federation/context.ts +14 −0 Original line number Diff line number Diff line Loading @@ -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>; } /** Loading
federation/middleware.test.ts +20 −4 Original line number Diff line number Diff line import { sign } from "@fedify/fedify"; import { Temporal } from "@js-temporal/polyfill"; import { assertEquals, Loading @@ -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, Loading Loading @@ -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) => { Loading
federation/middleware.ts +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, Loading Loading @@ -393,6 +394,9 @@ export class Federation<TContextData> { ...context, request, url, getSignedKey() { return verify(request, context.documentLoader); }, }; return reqCtx; } Loading
testing/context.ts +1 −0 Original line number Diff line number Diff line Loading @@ -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)), }; }