diff --git a/packages/frontpage/lib/data/atproto/did.ts b/packages/frontpage/lib/data/atproto/did.ts index 3268fd7f..7121aa19 100644 --- a/packages/frontpage/lib/data/atproto/did.ts +++ b/packages/frontpage/lib/data/atproto/did.ts @@ -1,15 +1,18 @@ import { cache } from "react"; import { z } from "zod"; -import { PlcDidDocumentResolver } from "@atcute/identity-resolver"; -import type { DidDocument } from "@atcute/identity"; +import { + CompositeDidDocumentResolver, + PlcDidDocumentResolver, + WebDidDocumentResolver, +} from "@atcute/identity-resolver"; +import { type DidDocument, isAtprotoDid } from "@atcute/identity"; import { FRONTPAGE_APPVIEW_USER_AGENT } from "@/lib/constants"; type Brand = K & { __brand: T }; -export type DID = Brand<`did:plc:${string}`, "DID">; +export type DID = Brand<`did:${"plc" | "web"}:${string}`, "DID">; export function isDid(s: string): s is DID { - // We don't support did:web yet - return s.startsWith("did:plc:"); + return isAtprotoDid(s); } export const didSchema = z.string().refine((s) => isDid(s), { @@ -23,19 +26,38 @@ export function parseDid(s: string): DID | null { return s; } -const didResolver = new PlcDidDocumentResolver({ - apiUrl: process.env.PLC_DIRECTORY_URL ?? "https://plc.directory", - fetch: (request) => - fetch(request, { - headers: { - "User-Agent": FRONTPAGE_APPVIEW_USER_AGENT, - }, - next: { - // TODO: Also revalidate this when we receive an identity change event - // That would allow us to extend the revalidation time to 1 day - revalidate: 60 * 60, // 1 hour +const didResolver = new CompositeDidDocumentResolver({ + methods: { + plc: new PlcDidDocumentResolver({ + apiUrl: process.env.PLC_DIRECTORY_URL ?? "https://plc.directory", + fetch: (request) => + fetch(request, { + headers: { + "User-Agent": FRONTPAGE_APPVIEW_USER_AGENT, + }, + next: { + // TODO: Also revalidate this when we receive an identity change event + // That would allow us to extend the revalidation time to 1 day + revalidate: 60 * 60, // 1 hour + }, + }), + }), + + web: new WebDidDocumentResolver({ + fetch: (request) => { + const signal = AbortSignal.timeout(1500); + return fetch(request, { + headers: { + "User-Agent": FRONTPAGE_APPVIEW_USER_AGENT, + }, + signal, + next: { + revalidate: 60 * 60, // 1 hour + }, + }); }, }), + }, }); export const getDidDoc = cache(async (did: DID): Promise => {