Loading .zed/settings.json +13 −3 Original line number Diff line number Diff line Loading @@ -7,7 +7,13 @@ "format_on_save": "on", "formatter": "language_server", "languages": { "JSON": { "language_servers": ["deno", "!biome"] }, "JavaScript": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -17,6 +23,9 @@ ] }, "TypeScript": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -26,6 +35,9 @@ ] }, "TSX": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -36,7 +48,5 @@ } }, "show_wrap_guides": true, "wrap_guides": [ 80 ] "wrap_guides": [80] } CHANGES.md +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ To be released. - The `fetchKey()` function became to choose the public key of the actor if `keyId` has no fragment and the actor has only one public key. [[#211]] - Added an optional parameter with `GetKeyOwnerOptions` type to the `RequestContext.getSignedKeyOwner()` method. - Fixed a bug of the `fedify inbox` command where it had failed to render the web interface when the `fedify` command was installed using `deno install` command from JSR. Loading src/federation/context.ts +24 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import type { TracerProvider } from "@opentelemetry/api"; import type { GetNodeInfoOptions } from "../nodeinfo/client.ts"; import type { JsonValue, NodeInfo } from "../nodeinfo/types.ts"; import type { DocumentLoader } from "../runtime/docloader.ts"; import type { GetKeyOwnerOptions } from "../sig/owner.ts"; import type { Actor, Recipient } from "../vocab/actor.ts"; import type { LookupObjectOptions, Loading Loading @@ -456,6 +457,29 @@ export interface RequestContext<TContextData> extends Context<TContextData> { * @since 0.7.0 */ getSignedKeyOwner(): Promise<Actor | null>; /** * Gets the owner of the signed key, 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 * * @param options Options for getting the key owner. You usually may want to * specify the custom `documentLoader` so that making * an HTTP request to the key owner's server is signed with * your [instance actor]. * @returns The owner of the signed key, or `null` if the key is not verified * or the owner is not found. * @since 1.5.0 * * [instance actor]: https://swicg.github.io/activitypub-http-signature/#instance-actor */ getSignedKeyOwner( options: GetKeyOwnerOptions, ): Promise<Actor | null>; } /** Loading src/federation/middleware.ts +9 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import { import { verifyRequest } from "../sig/http.ts"; import { exportJwk, importJwk, validateCryptoKey } from "../sig/key.ts"; import { hasSignature, signJsonLd } from "../sig/ld.ts"; import { getKeyOwner } from "../sig/owner.ts"; import { getKeyOwner, type GetKeyOwnerOptions } from "../sig/owner.ts"; import { signObject, verifyObject } from "../sig/proof.ts"; import type { Actor, Recipient } from "../vocab/actor.ts"; import { Loading Loading @@ -3582,11 +3582,17 @@ class RequestContextImpl<TContextData> extends ContextImpl<TContextData> #signedKeyOwner: Actor | null | undefined = undefined; async getSignedKeyOwner(): Promise<Actor | null> { async getSignedKeyOwner( options: GetKeyOwnerOptions = {}, ): Promise<Actor | null> { if (this.#signedKeyOwner !== undefined) return this.#signedKeyOwner; const key = await this.getSignedKey(); if (key == null) return this.#signedKeyOwner = null; return this.#signedKeyOwner = await getKeyOwner(key, this); return this.#signedKeyOwner = await getKeyOwner(key, { contextLoader: options.contextLoader ?? this.contextLoader, documentLoader: options.documentLoader ?? this.documentLoader, tracerProvider: options.tracerProvider ?? this.tracerProvider, }); } } Loading Loading
.zed/settings.json +13 −3 Original line number Diff line number Diff line Loading @@ -7,7 +7,13 @@ "format_on_save": "on", "formatter": "language_server", "languages": { "JSON": { "language_servers": ["deno", "!biome"] }, "JavaScript": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -17,6 +23,9 @@ ] }, "TypeScript": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -26,6 +35,9 @@ ] }, "TSX": { "code_actions_on_format": { "source.sortImports": true }, "language_servers": [ "deno", "!typescript-language-server", Loading @@ -36,7 +48,5 @@ } }, "show_wrap_guides": true, "wrap_guides": [ 80 ] "wrap_guides": [80] }
CHANGES.md +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ To be released. - The `fetchKey()` function became to choose the public key of the actor if `keyId` has no fragment and the actor has only one public key. [[#211]] - Added an optional parameter with `GetKeyOwnerOptions` type to the `RequestContext.getSignedKeyOwner()` method. - Fixed a bug of the `fedify inbox` command where it had failed to render the web interface when the `fedify` command was installed using `deno install` command from JSR. Loading
src/federation/context.ts +24 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import type { TracerProvider } from "@opentelemetry/api"; import type { GetNodeInfoOptions } from "../nodeinfo/client.ts"; import type { JsonValue, NodeInfo } from "../nodeinfo/types.ts"; import type { DocumentLoader } from "../runtime/docloader.ts"; import type { GetKeyOwnerOptions } from "../sig/owner.ts"; import type { Actor, Recipient } from "../vocab/actor.ts"; import type { LookupObjectOptions, Loading Loading @@ -456,6 +457,29 @@ export interface RequestContext<TContextData> extends Context<TContextData> { * @since 0.7.0 */ getSignedKeyOwner(): Promise<Actor | null>; /** * Gets the owner of the signed key, 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 * * @param options Options for getting the key owner. You usually may want to * specify the custom `documentLoader` so that making * an HTTP request to the key owner's server is signed with * your [instance actor]. * @returns The owner of the signed key, or `null` if the key is not verified * or the owner is not found. * @since 1.5.0 * * [instance actor]: https://swicg.github.io/activitypub-http-signature/#instance-actor */ getSignedKeyOwner( options: GetKeyOwnerOptions, ): Promise<Actor | null>; } /** Loading
src/federation/middleware.ts +9 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import { import { verifyRequest } from "../sig/http.ts"; import { exportJwk, importJwk, validateCryptoKey } from "../sig/key.ts"; import { hasSignature, signJsonLd } from "../sig/ld.ts"; import { getKeyOwner } from "../sig/owner.ts"; import { getKeyOwner, type GetKeyOwnerOptions } from "../sig/owner.ts"; import { signObject, verifyObject } from "../sig/proof.ts"; import type { Actor, Recipient } from "../vocab/actor.ts"; import { Loading Loading @@ -3582,11 +3582,17 @@ class RequestContextImpl<TContextData> extends ContextImpl<TContextData> #signedKeyOwner: Actor | null | undefined = undefined; async getSignedKeyOwner(): Promise<Actor | null> { async getSignedKeyOwner( options: GetKeyOwnerOptions = {}, ): Promise<Actor | null> { if (this.#signedKeyOwner !== undefined) return this.#signedKeyOwner; const key = await this.getSignedKey(); if (key == null) return this.#signedKeyOwner = null; return this.#signedKeyOwner = await getKeyOwner(key, this); return this.#signedKeyOwner = await getKeyOwner(key, { contextLoader: options.contextLoader ?? this.contextLoader, documentLoader: options.documentLoader ?? this.documentLoader, tracerProvider: options.tracerProvider ?? this.tracerProvider, }); } } Loading