Unverified Commit 71a0a1a7 authored by Hong Minhee's avatar Hong Minhee
Browse files

Add Context.lookupWebFinger() method

parent 4007daa6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -8,6 +8,11 @@ Version 1.6.0

To be released.

 -  Added `Context.lookupWebFinger()` method to make WebFinger lookups
    accessible from the context.  [[#227]]

[#227]: https://github.com/fedify-dev/fedify/issues/227


Version 1.5.1
-------------
+45 −0
Original line number Diff line number Diff line
@@ -413,6 +413,51 @@ const note = await ctx.lookupObject(
> section for details.


WebFinger lookups
-----------------

*This API is available since Fedify 1.6.0.*

The `Context` provides a dedicated method for WebFinger lookups when you need
to find information about accounts and resources across federated networks.
The `~Context.lookupWebFinger()` method allows you to query a remote server's
WebFinger endpoint directly:

~~~~ typescript twoslash
import { type Context } from "@fedify/fedify";
const ctx = null as unknown as Context<void>;
// ---cut-before---
const webfingerData = await ctx.lookupWebFinger("acct:fedify@hollo.social");
~~~~

If the lookup fails or the account doesn't exist, the method returns `null`.
The returned WebFinger document contains links to various resources associated 
with the account, such as profile pages, ActivityPub actor URIs, and more:

~~~~ typescript twoslash
import { type Context } from "@fedify/fedify";
const ctx = null as unknown as Context<void>;
// ---cut-before---
const webfingerData = await ctx.lookupWebFinger("acct:fedify@hollo.social");

// Find the ActivityPub actor URI
const activityPubActorLink = webfingerData?.links.find(link => 
  link.rel === "self" && link.type === "application/activity+json"
);

if (activityPubActorLink?.href) {
  const actor = await ctx.lookupObject(activityPubActorLink.href);
  // Work with the actor...
}
~~~~

> [!NOTE]
> In most cases, you can use the higher-level `~Context.lookupObject()` method
> which automatically performs WebFinger lookups when given a handle.
> Use `~Context.lookupWebFinger()` when you need the raw WebFinger data or
> want more direct control over the lookup process.


Traversing remote collections
-----------------------------

+18 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ import type {
  Multikey,
  Object,
} from "../vocab/vocab.ts";
import type { ResourceDescriptor } from "../webfinger/jrd.ts";
import type { LookupWebFingerOptions } from "../webfinger/lookup.ts";
import type { SenderKeyPair } from "./send.ts";

/**
@@ -327,6 +329,22 @@ export interface Context<TContextData> {
    options?: GetNodeInfoOptions & { parse: "none" },
  ): Promise<JsonValue | undefined>;

  /**
   * Looks up a WebFinger resource.
   *
   * It's almost the same as the {@link lookupWebFinger} function, but it uses
   * the context's configuration by default.
   *
   * @param resource The resource URL to look up.
   * @param options Extra options for looking up the resource.
   * @returns The resource descriptor, or `null` if not found.
   * @since 1.6.0
   */
  lookupWebFinger(
    resource: URL | string,
    options?: LookupWebFingerOptions,
  ): Promise<ResourceDescriptor | null>;

  /**
   * Sends an activity to recipients' inboxes.
   * @param sender The sender's identifier or the sender's username or
+17 −0
Original line number Diff line number Diff line
@@ -56,6 +56,11 @@ import {
  type Object,
} from "../vocab/vocab.ts";
import { handleWebFinger } from "../webfinger/handler.ts";
import type { ResourceDescriptor } from "../webfinger/jrd.ts";
import {
  lookupWebFinger,
  type LookupWebFingerOptions,
} from "../webfinger/lookup.ts";
import type {
  ActorAliasMapper,
  ActorDispatcher,
@@ -3212,6 +3217,18 @@ export class ContextImpl<TContextData> implements Context<TContextData> {
      });
  }

  lookupWebFinger(
    resource: URL | string,
    options: LookupWebFingerOptions = {},
  ): Promise<ResourceDescriptor | null> {
    return lookupWebFinger(resource, {
      ...options,
      userAgent: options.userAgent ?? this.federation.userAgent,
      tracerProvider: options.tracerProvider ?? this.tracerProvider,
      allowPrivateAddress: this.federation.allowPrivateAddress,
    });
  }

  sendActivity(
    sender:
      | SenderKeyPair
+5 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ import {
  lookupObject as globalLookupObject,
  traverseCollection as globalTraverseCollection,
} from "../vocab/lookup.ts";
import { lookupWebFinger as globalLookupWebFinger } from "../webfinger/lookup.ts";
import { mockDocumentLoader } from "./docloader.ts";

export function createContext<TContextData>(
@@ -35,6 +36,7 @@ export function createContext<TContextData>(
    lookupObject,
    traverseCollection,
    lookupNodeInfo,
    lookupWebFinger,
    sendActivity,
    routeActivity,
  }: Partial<Context<TContextData>> & { url?: URL; data: TContextData },
@@ -88,6 +90,9 @@ export function createContext<TContextData>(
    lookupNodeInfo: lookupNodeInfo ?? ((_params) => {
      throw new Error("Not implemented");
    }),
    lookupWebFinger: lookupWebFinger ?? ((resource, options = {}) => {
      return globalLookupWebFinger(resource, options);
    }),
    sendActivity: sendActivity ?? ((_params) => {
      throw new Error("Not implemented");
    }),