[mastodon-client] Correctly parse invalid remote mentions

This commit is contained in:
Laura Hausmann 2023-10-12 21:31:41 +02:00
parent 0616edffa8
commit 0e39313ac4
Signed by: zotan
GPG key ID: D044E84C5BE01605
5 changed files with 14 additions and 11 deletions

View file

@ -6,7 +6,7 @@ export class AnnouncementConverter {
public static encode(announcement: Announcement, isRead: boolean): MastodonEntity.Announcement {
return {
id: announcement.id,
content: `<h1>${MfmHelpers.toHtml(mfm.parse(announcement.title), []) ?? 'Announcement'}</h1>${MfmHelpers.toHtml(mfm.parse(announcement.text), []) ?? ''}`,
content: `<h1>${MfmHelpers.toHtml(mfm.parse(announcement.title), [], null) ?? 'Announcement'}</h1>${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(text => text !== null ? MfmHelpers.toHtml(mfm.parse(text), JSON.parse(note.mentionedRemoteUsers)) ?? escapeMFM(text) : ""),
content: text.then(async text => text !== null ? await host.then(host => MfmHelpers.toHtml(mfm.parse(text), JSON.parse(note.mentionedRemoteUsers), host)) ?? 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 ?? "")) ?? escapeMFM(profile?.description ?? ""));
const bio = profile.then(profile => MfmHelpers.toHtml(mfm.parse(profile?.description ?? ""), [], u.host) ?? escapeMFM(profile?.description ?? ""));
const avatar = u.avatarId
? (DriveFiles.findOneBy({ id: u.avatarId }))
.then(p => p?.url ?? Users.getIdenticonUrl(u.id))
@ -92,7 +92,7 @@ export class UserConverter {
header_static: banner,
emojis: populateEmojis(u.emojis, u.host).then(emoji => emoji.map((e) => EmojiConverter.encode(e))),
moved: null, //FIXME
fields: profile.then(profile => profile?.fields.map(p => this.encodeField(p)) ?? []),
fields: profile.then(profile => profile?.fields.map(p => this.encodeField(p, u.host)) ?? []),
bot: u.isBot,
discoverable: u.isExplorable
}).then(p => {
@ -107,10 +107,10 @@ export class UserConverter {
return Promise.all(encoded);
}
private static encodeField(f: Field): MastodonEntity.Field {
private static encodeField(f: Field, host: string | null): MastodonEntity.Field {
return {
name: f.name,
value: MfmHelpers.toHtml(mfm.parse(f.value), undefined, true) ?? escapeMFM(f.value),
value: MfmHelpers.toHtml(mfm.parse(f.value), [], host, true) ?? escapeMFM(f.value),
verified_at: f.verified ? (new Date()).toISOString() : null,
}
}

View file

@ -8,6 +8,7 @@ export class MfmHelpers {
public static toHtml(
nodes: mfm.MfmNode[] | null,
mentionedRemoteUsers: IMentionedRemoteUsers = [],
objectHost: string | null,
inline: boolean = false
) {
if (nodes == null) {
@ -142,7 +143,7 @@ export class MfmHelpers {
remoteUser.username === username && remoteUser.host === host,
);
const localpart = `@${username}`;
const isLocal = host === config.domain || host === null;
const isLocal = host === config.domain || (host == null && objectHost == null);
const acct = isLocal ? localpart: node.props.acct;
a.href = remoteUserInfo
? remoteUserInfo.url
@ -150,7 +151,9 @@ export class MfmHelpers {
: remoteUserInfo.uri
: isLocal
? `${config.url}/${acct}`
: `https://${host}/${localpart}`;
: host == null
? `https://${objectHost}/${localpart}`
: `https://${host}/${localpart}`;
a.className = "u-url mention";
const span = doc.createElement("span");
span.textContent = username;

View file

@ -179,8 +179,8 @@ export class NoteHelpers {
}
public static async getNoteEditHistory(note: Note, ctx: MastoContext): Promise<MastodonEntity.StatusEdit[]> {
const account = Promise.resolve(note.user ?? await UserHelpers.getUserCached(note.userId, ctx))
.then(p => UserConverter.encode(p, ctx));
const user = Promise.resolve(note.user ?? await UserHelpers.getUserCached(note.userId, ctx));
const account = user.then(p => UserConverter.encode(p, ctx));
const edits = await NoteEdits.find({ where: { noteId: note.id }, order: { id: "ASC" } });
const history: Promise<MastodonEntity.StatusEdit>[] = [];
@ -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)) ?? '',
content: user.then(user => MfmHelpers.toHtml(mfm.parse(edit.text ?? ''), JSON.parse(note.mentionedRemoteUsers), user.host) ?? ''),
created_at: lastDate.toISOString(),
emojis: [],
sensitive: files.then(files => files.length > 0 ? files.some((f) => f.isSensitive) : false),