[backend] Federate outgoing invalid mentions as text
This commit is contained in:
parent
5dcd4c4fff
commit
4920b0c768
3 changed files with 27 additions and 34 deletions
|
@ -3,7 +3,7 @@ import type * as mfm from "mfm-js";
|
|||
import config from "@/config/index.js";
|
||||
import { intersperse } from "@/prelude/array.js";
|
||||
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
|
||||
import { resolveMentionWithFallback } from "@/remote/resolve-user.js";
|
||||
import { resolveMentionFromCache } from "@/remote/resolve-user.js";
|
||||
|
||||
export async function toHtml(
|
||||
nodes: mfm.MfmNode[] | null,
|
||||
|
@ -113,19 +113,26 @@ export async function toHtml(
|
|||
return a;
|
||||
},
|
||||
|
||||
async mention(node) {
|
||||
const el = doc.createElement("span");
|
||||
el.setAttribute("class", "h-card");
|
||||
el.setAttribute("translate", "no");
|
||||
const a = doc.createElement("a");
|
||||
mention(node) {
|
||||
const { username, host, acct } = node.props;
|
||||
a.href = await resolveMentionWithFallback(username, host, objectHost, mentionedRemoteUsers);
|
||||
a.className = "u-url mention";
|
||||
const span = doc.createElement("span");
|
||||
span.textContent = username;
|
||||
a.textContent = '@';
|
||||
a.appendChild(span);
|
||||
el.appendChild(a);
|
||||
const href = resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers);
|
||||
|
||||
const el = doc.createElement("span");
|
||||
if (href === null) {
|
||||
el.textContent = acct;
|
||||
} else {
|
||||
el.setAttribute("class", "h-card");
|
||||
el.setAttribute("translate", "no");
|
||||
const a = doc.createElement("a");
|
||||
a.href = href;
|
||||
a.className = "u-url mention";
|
||||
const span = doc.createElement("span");
|
||||
span.textContent = username;
|
||||
a.textContent = '@';
|
||||
a.appendChild(span);
|
||||
el.appendChild(a);
|
||||
}
|
||||
|
||||
return el;
|
||||
},
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import { IMentionedRemoteUsers } from "@/models/entities/note.js";
|
|||
|
||||
const logger = remoteLogger.createSubLogger("resolve-user");
|
||||
const uriHostCache = new Cache<string>("resolveUserUriHost", 60 * 60 * 24);
|
||||
const mentionUriCache = new Cache<string>("resolveMentionUserUri", 60 * 60 * 72);
|
||||
|
||||
export async function resolveUser(
|
||||
username: string,
|
||||
|
@ -207,24 +206,13 @@ export function getMentionFallbackUri(username: string, host: string | null, obj
|
|||
return fallback;
|
||||
}
|
||||
|
||||
export async function resolveMentionWithFallback(username: string, host: string | null, objectHost: string | null, cache: IMentionedRemoteUsers, cachedOnly: boolean = false): Promise<string> {
|
||||
export function resolveMentionFromCache(username: string, host: string | null, objectHost: string | null, cache: IMentionedRemoteUsers): string | null {
|
||||
const fallback = getMentionFallbackUri(username, host, objectHost);
|
||||
|
||||
const cached = cache.find(r => r.username.toLowerCase() === username.toLowerCase() && r.host === host);
|
||||
if (cached) return cached.url ?? cached.uri ?? fallback;
|
||||
if ((host === null && objectHost === null) || host === config.domain) return fallback;
|
||||
if (cachedOnly) return fallback;
|
||||
|
||||
return mentionUriCache.fetch(fallback, async () => {
|
||||
try {
|
||||
const user = await resolveUser(username, host ?? objectHost, false);
|
||||
const profile = await UserProfiles.findOneBy({ userId: user.id });
|
||||
return profile?.url ?? user.uri ?? fallback;
|
||||
}
|
||||
catch {
|
||||
return fallback;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function getSubjectHostFromUri(uri: string): Promise<string | null> {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { JSDOM } from "jsdom";
|
|||
import config from "@/config/index.js";
|
||||
import { intersperse } from "@/prelude/array.js";
|
||||
import mfm from "mfm-js";
|
||||
import { resolveMentionWithFallback } from "@/remote/resolve-user.js";
|
||||
import { resolveMentionFromCache } from "@/remote/resolve-user.js";
|
||||
|
||||
export class MfmHelpers {
|
||||
public static async toHtml(
|
||||
|
@ -135,20 +135,18 @@ export class MfmHelpers {
|
|||
return a;
|
||||
},
|
||||
|
||||
async mention(node) {
|
||||
mention(node) {
|
||||
const { username, host, acct } = node.props;
|
||||
const fallback = await resolveMentionWithFallback(username, host, objectHost, mentionedRemoteUsers, true);
|
||||
const isLocal = (host === null && objectHost === null) || host === config.domain;
|
||||
const isInvalid = fallback.startsWith(config.url) && !isLocal;
|
||||
const href = resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers);
|
||||
|
||||
const el = doc.createElement("span");
|
||||
if (isInvalid) {
|
||||
if (href === null) {
|
||||
el.textContent = acct;
|
||||
} else {
|
||||
el.setAttribute("class", "h-card");
|
||||
el.setAttribute("translate", "no");
|
||||
const a = doc.createElement("a");
|
||||
a.href = fallback;
|
||||
a.href = href;
|
||||
a.className = "u-url mention";
|
||||
const span = doc.createElement("span");
|
||||
span.textContent = username;
|
||||
|
|
Loading…
Reference in a new issue