[backend] More mentions fixes

This commit is contained in:
Laura Hausmann 2023-10-14 17:11:21 +02:00
parent 588a39f17a
commit 8719a6922e
Signed by: zotan
GPG key ID: D044E84C5BE01605
10 changed files with 20 additions and 14 deletions

View file

@ -8,6 +8,7 @@ import { resolveMentionWithFallback } from "@/remote/resolve-user.js";
export async function toHtml(
nodes: mfm.MfmNode[] | null,
mentionedRemoteUsers: IMentionedRemoteUsers = [],
objectHost: string | null
) {
if (nodes == null) {
return null;
@ -118,7 +119,7 @@ export async function toHtml(
el.setAttribute("translate", "no");
const a = doc.createElement("a");
const { username, host, acct } = node.props;
a.href = await resolveMentionWithFallback(username, host, acct, mentionedRemoteUsers);
a.href = await resolveMentionWithFallback(username, host, objectHost, mentionedRemoteUsers);
a.className = "u-url mention";
const span = doc.createElement("span");
span.textContent = username;

View file

@ -4,5 +4,5 @@ import { toHtml } from "../../../mfm/to-html.js";
export default async function (note: Note) {
if (!note.text) return "";
return toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers));
return toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers), note.userHost);
}

View file

@ -73,7 +73,7 @@ export async function renderPerson(user: ILocalUser) {
preferredUsername: user.username,
name: user.name,
summary: profile.description
? await toHtml(mfm.parse(profile.description))
? await toHtml(mfm.parse(profile.description), [], profile.userHost)
: null,
icon: avatar ? renderImage(avatar) : null,
image: banner ? renderImage(banner) : null,

View file

@ -177,11 +177,15 @@ export async function resolveUser(
return user;
}
export async function resolveMentionWithFallback(username: string, host: string | null, acct: string, cache: IMentionedRemoteUsers): Promise<string> {
const fallback = `${config.url}/${acct}`;
export async function resolveMentionWithFallback(username: string, host: string | null, objectHost: string | null, cache: IMentionedRemoteUsers): Promise<string> {
let fallback = `${config.url}/@${username}`;
if (host !== null) fallback += `@${host}`;
else if (objectHost !== null) fallback += `@${objectHost}`;
const cached = cache.find(r => r.username.toLowerCase() === username.toLowerCase() && r.host === host);
if (cached) return cached.url ?? cached.uri;
if (host === null || host === config.domain) return fallback;
try {
const user = await resolveUser(username, host, false);
const profile = await UserProfiles.findOneBy({ userId: user.id });

View file

@ -6,7 +6,7 @@ export class AnnouncementConverter {
public static async encode(announcement: Announcement, isRead: boolean): Promise<MastodonEntity.Announcement> {
return {
id: announcement.id,
content: `<h1>${await MfmHelpers.toHtml(mfm.parse(announcement.title), []) ?? 'Announcement'}</h1>${await MfmHelpers.toHtml(mfm.parse(announcement.text), []) ?? ''}`,
content: `<h1>${await MfmHelpers.toHtml(mfm.parse(announcement.title), [], null) ?? 'Announcement'}</h1>${await MfmHelpers.toHtml(mfm.parse(announcement.text), [], null) ?? ''}`,
starts_at: null,
ends_at: null,
published: true,

View file

@ -117,7 +117,7 @@ export class NoteConverter {
in_reply_to_id: note.replyId,
in_reply_to_account_id: note.replyUserId,
reblog: reblog.then(reblog => note.text === null ? reblog : null),
content: text.then(async text => text !== null ? MfmHelpers.toHtml(mfm.parse(text), JSON.parse(note.mentionedRemoteUsers)).then(p => p ?? escapeMFM(text)) : ""),
content: text.then(async text => text !== null ? MfmHelpers.toHtml(mfm.parse(text), JSON.parse(note.mentionedRemoteUsers), note.userHost).then(p => p ?? escapeMFM(text)) : ""),
text: text,
created_at: note.createdAt.toISOString(),
emojis: noteEmoji,

View file

@ -31,7 +31,7 @@ export class UserConverter {
acctUrl = `https://${u.host}/@${u.username}`;
}
const profile = UserProfiles.findOneBy({ userId: u.id });
const bio = profile.then(profile => MfmHelpers.toHtml(mfm.parse(profile?.description ?? ""), []).then(p => p ?? escapeMFM(profile?.description ?? "")));
const bio = profile.then(profile => MfmHelpers.toHtml(mfm.parse(profile?.description ?? ""), [], u.host).then(p => p ?? escapeMFM(profile?.description ?? "")));
const avatar = u.avatarId
? (DriveFiles.findOneBy({ id: u.avatarId }))
.then(p => p?.url ?? Users.getIdenticonUrl(u.id))
@ -110,7 +110,7 @@ export class UserConverter {
private static async encodeField(f: Field, host: string | null): Promise<MastodonEntity.Field> {
return {
name: f.name,
value: await MfmHelpers.toHtml(mfm.parse(f.value), [], true) ?? escapeMFM(f.value),
value: await MfmHelpers.toHtml(mfm.parse(f.value), [], host, true) ?? escapeMFM(f.value),
verified_at: f.verified ? (new Date()).toISOString() : null,
}
}

View file

@ -9,7 +9,8 @@ export class MfmHelpers {
public static async toHtml(
nodes: mfm.MfmNode[] | null,
mentionedRemoteUsers: IMentionedRemoteUsers = [],
inline: boolean = false
objectHost: string | null,
inline: boolean = false,
) {
if (nodes == null) {
return null;
@ -138,7 +139,7 @@ export class MfmHelpers {
el.setAttribute("translate", "no");
const a = doc.createElement("a");
const { username, host, acct } = node.props;
a.href = await resolveMentionWithFallback(username, host, acct, mentionedRemoteUsers);
a.href = await resolveMentionWithFallback(username, host, objectHost, mentionedRemoteUsers);
a.className = "u-url mention";
const span = doc.createElement("span");
span.textContent = username;

View file

@ -201,7 +201,7 @@ export class NoteHelpers {
const files = DriveFiles.packMany(edit.fileIds);
const item = {
account: account,
content: MfmHelpers.toHtml(mfm.parse(edit.text ?? ''), JSON.parse(note.mentionedRemoteUsers)).then(p => p ?? ''),
content: MfmHelpers.toHtml(mfm.parse(edit.text ?? ''), JSON.parse(note.mentionedRemoteUsers), note.userHost).then(p => p ?? ''),
created_at: lastDate.toISOString(),
emojis: [],
sensitive: files.then(files => files.length > 0 ? files.some((f) => f.isSensitive) : false),

View file

@ -8,13 +8,13 @@ describe("toHtml", () => {
it("br", async () => {
const input = "foo\nbar\nbaz";
const output = "<p><span>foo<br>bar<br>baz</span></p>";
assert.equal(await toHtml(mfm.parse(input)), output);
assert.equal(await toHtml(mfm.parse(input), [], null), output);
});
it("br alt", async () => {
const input = "foo\r\nbar\rbaz";
const output = "<p><span>foo<br>bar<br>baz</span></p>";
assert.equal(await toHtml(mfm.parse(input)), output);
assert.equal(await toHtml(mfm.parse(input), [], null), output);
});
});