Skip to content

Commit 1fa4357

Browse files
committed
Extract WebFinger alias calculation
Move subject and alias construction into a helper so split-origin handling shares the same actor username and host inputs without repeating the surrounding calculations. #921 (comment) Assisted-by: Codex:gpt-5.5
1 parent ff302a1 commit 1fa4357

1 file changed

Lines changed: 58 additions & 27 deletions

File tree

packages/fedify/src/federation/webfinger.ts

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Link as LinkObject } from "@fedify/vocab";
1+
import { type LanguageString, Link as LinkObject } from "@fedify/vocab";
22
import type { Link, ResourceDescriptor } from "@fedify/webfinger";
33
import { getLogger } from "@logtape/logtape";
44
import type { Span, Tracer } from "@opentelemetry/api";
@@ -14,6 +14,53 @@ import type { RequestContext } from "./context.ts";
1414

1515
const logger = getLogger(["fedify", "webfinger", "server"]);
1616

17+
interface WebFingerSubjectAndAliasesOptions {
18+
resourceUrl: URL;
19+
actorUri: URL;
20+
preferredUsername: string | LanguageString | null | undefined;
21+
acctUsername: string | null;
22+
host: string | undefined;
23+
contextHost: string;
24+
}
25+
26+
function getWebFingerSubjectAndAliases(
27+
{
28+
resourceUrl,
29+
actorUri,
30+
preferredUsername,
31+
acctUsername,
32+
host,
33+
contextHost,
34+
}: WebFingerSubjectAndAliasesOptions,
35+
): Pick<ResourceDescriptor, "subject" | "aliases"> {
36+
const aliases: string[] = [];
37+
let subject = resourceUrl.href;
38+
if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
39+
aliases.push(`acct:${preferredUsername}@${host ?? contextHost}`);
40+
if (host != null && host !== contextHost) {
41+
aliases.push(`acct:${preferredUsername}@${contextHost}`);
42+
}
43+
}
44+
if (resourceUrl.href !== actorUri.href) {
45+
aliases.push(actorUri.href);
46+
}
47+
if (
48+
resourceUrl.protocol === "acct:" && host != null &&
49+
host !== contextHost &&
50+
!resourceUrl.href.endsWith(`@${host}`)
51+
) {
52+
subject = `acct:${preferredUsername ?? acctUsername}@${host}`;
53+
aliases.push(resourceUrl.href);
54+
if (
55+
preferredUsername != null && preferredUsername !== "" &&
56+
preferredUsername !== acctUsername
57+
) {
58+
aliases.push(`acct:${preferredUsername}@${contextHost}`);
59+
}
60+
}
61+
return { subject, aliases };
62+
}
63+
1764
/**
1865
* Parameters for {@link handleWebFinger}.
1966
*/
@@ -202,10 +249,11 @@ async function handleWebFingerInternal<TContextData>(
202249
logger.error("Actor {identifier} not found.", { identifier });
203250
return await onNotFound(request);
204251
}
252+
const actorUri = context.getActorUri(identifier);
205253
const links: Link[] = [
206254
{
207255
rel: "self",
208-
href: context.getActorUri(identifier).href,
256+
href: actorUri.href,
209257
type: "application/activity+json",
210258
},
211259
];
@@ -241,31 +289,14 @@ async function handleWebFingerInternal<TContextData>(
241289
}
242290
}
243291

244-
const aliases: string[] = [];
245-
let subject = resourceUrl.href;
246-
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
247-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context.url.host}`);
248-
if (host != null && host !== context.url.host) {
249-
aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
250-
}
251-
}
252-
if (resourceUrl.href !== context.getActorUri(identifier).href) {
253-
aliases.push(context.getActorUri(identifier).href);
254-
}
255-
if (
256-
resourceUrl.protocol === "acct:" && host != null &&
257-
host !== context.url.host &&
258-
!resourceUrl.href.endsWith(`@${host}`)
259-
) {
260-
subject = `acct:${actor.preferredUsername ?? acctUsername}@${host}`;
261-
aliases.push(resourceUrl.href);
262-
if (
263-
actor.preferredUsername != null && actor.preferredUsername !== "" &&
264-
actor.preferredUsername !== acctUsername
265-
) {
266-
aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
267-
}
268-
}
292+
const { subject, aliases } = getWebFingerSubjectAndAliases({
293+
resourceUrl,
294+
actorUri,
295+
preferredUsername: actor.preferredUsername,
296+
acctUsername,
297+
host,
298+
contextHost: context.url.host,
299+
});
269300
const jrd: ResourceDescriptor = {
270301
subject,
271302
aliases,

0 commit comments

Comments
 (0)