[backend] Use correct capitalization when rendering mentions

This commit is contained in:
Laura Hausmann 2023-10-17 21:16:17 +02:00
parent 4920b0c768
commit b8bd0c9f3b
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 33 additions and 15 deletions

View file

@ -113,21 +113,21 @@ export async function toHtml(
return a; return a;
}, },
mention(node) { async mention(node) {
const { username, host, acct } = node.props; const { username, host, acct } = node.props;
const href = resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers); const resolved = await resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers);
const el = doc.createElement("span"); const el = doc.createElement("span");
if (href === null) { if (resolved === null) {
el.textContent = acct; el.textContent = acct;
} else { } else {
el.setAttribute("class", "h-card"); el.setAttribute("class", "h-card");
el.setAttribute("translate", "no"); el.setAttribute("translate", "no");
const a = doc.createElement("a"); const a = doc.createElement("a");
a.href = href; a.href = resolved.href;
a.className = "u-url mention"; a.className = "u-url mention";
const span = doc.createElement("span"); const span = doc.createElement("span");
span.textContent = username; span.textContent = resolved.username;
a.textContent = '@'; a.textContent = '@';
a.appendChild(span); a.appendChild(span);
el.appendChild(a); el.appendChild(a);

View file

@ -13,6 +13,7 @@ import { IMentionedRemoteUsers } from "@/models/entities/note.js";
const logger = remoteLogger.createSubLogger("resolve-user"); const logger = remoteLogger.createSubLogger("resolve-user");
const uriHostCache = new Cache<string>("resolveUserUriHost", 60 * 60 * 24); const uriHostCache = new Cache<string>("resolveUserUriHost", 60 * 60 * 24);
const localUsernameCache = new Cache<string | null>("localUserNameCapitalization", 60 * 60 * 24);
export async function resolveUser( export async function resolveUser(
username: string, username: string,
@ -184,7 +185,6 @@ export async function resolveUser(
export async function resolveMentionToUserAndProfile(username: string, host: string | null, objectHost: string | null) { export async function resolveMentionToUserAndProfile(username: string, host: string | null, objectHost: string | null) {
try { try {
//const fallback = getMentionFallbackUri(username, host, objectHost);
const user = await resolveUser(username, host ?? objectHost, false); const user = await resolveUser(username, host ?? objectHost, false);
const profile = await UserProfiles.findOneBy({ userId: user.id }); const profile = await UserProfiles.findOneBy({ userId: user.id });
const data = { username, host: host ?? objectHost }; const data = { username, host: host ?? objectHost };
@ -206,12 +206,30 @@ export function getMentionFallbackUri(username: string, host: string | null, obj
return fallback; return fallback;
} }
export function resolveMentionFromCache(username: string, host: string | null, objectHost: string | null, cache: IMentionedRemoteUsers): string | null { async function getLocalUsernameCached(username: string): Promise<string | null> {
const fallback = getMentionFallbackUri(username, host, objectHost); return localUsernameCache.fetch(username.toLowerCase(), () =>
Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })
.then(p => p ? p.username : null));
}
export async function resolveMentionFromCache(username: string, host: string | null, objectHost: string | null, cache: IMentionedRemoteUsers): Promise<{ username: string, href: string } | null> {
const isLocal = (host === null && objectHost === null) || host === config.domain;
if (isLocal) {
const finalUsername = await getLocalUsernameCached(username);
if (finalUsername === null) return null;
username = finalUsername;
}
try {
if (isLocal) username = await resolveUser(username, null).then(p => p?.username ?? username);
} catch {
return null;
}
const fallback = getMentionFallbackUri(username, host, objectHost);
const cached = cache.find(r => r.username.toLowerCase() === username.toLowerCase() && r.host === host); const cached = cache.find(r => r.username.toLowerCase() === username.toLowerCase() && r.host === host);
if (cached) return cached.url ?? cached.uri ?? fallback; const href = cached?.url ?? cached?.uri;
if ((host === null && objectHost === null) || host === config.domain) return fallback; if (cached && href != null) return { username: cached.username, href: href };
if (isLocal) return { username: username, href: fallback };
return null; return null;
} }

View file

@ -135,21 +135,21 @@ export class MfmHelpers {
return a; return a;
}, },
mention(node) { async mention(node) {
const { username, host, acct } = node.props; const { username, host, acct } = node.props;
const href = resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers); const resolved = await resolveMentionFromCache(username, host, objectHost, mentionedRemoteUsers);
const el = doc.createElement("span"); const el = doc.createElement("span");
if (href === null) { if (resolved === null) {
el.textContent = acct; el.textContent = acct;
} else { } else {
el.setAttribute("class", "h-card"); el.setAttribute("class", "h-card");
el.setAttribute("translate", "no"); el.setAttribute("translate", "no");
const a = doc.createElement("a"); const a = doc.createElement("a");
a.href = href; a.href = resolved.href;
a.className = "u-url mention"; a.className = "u-url mention";
const span = doc.createElement("span"); const span = doc.createElement("span");
span.textContent = username; span.textContent = resolved.username;
a.textContent = '@'; a.textContent = '@';
a.appendChild(span); a.appendChild(span);
el.appendChild(a); el.appendChild(a);