mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
fix(federation): 🐛 Fix remote emojis being incorrectly marked as local
This commit is contained in:
parent
c94dd7c59d
commit
cbbf49905b
|
|
@ -2,7 +2,7 @@ import { emojiValidatorWithColons, emojiValidatorWithIdentifiers } from "@/api";
|
||||||
import { proxyUrl } from "@/response";
|
import { proxyUrl } from "@/response";
|
||||||
import type { Emoji as APIEmoji } from "@versia/client/types";
|
import type { Emoji as APIEmoji } from "@versia/client/types";
|
||||||
import type { CustomEmojiExtension } from "@versia/federation/types";
|
import type { CustomEmojiExtension } from "@versia/federation/types";
|
||||||
import { db } from "@versia/kit/db";
|
import { type Instance, db } from "@versia/kit/db";
|
||||||
import { Emojis, Instances } from "@versia/kit/tables";
|
import { Emojis, Instances } from "@versia/kit/tables";
|
||||||
import {
|
import {
|
||||||
type InferInsertModel,
|
type InferInsertModel,
|
||||||
|
|
@ -12,10 +12,10 @@ import {
|
||||||
desc,
|
desc,
|
||||||
eq,
|
eq,
|
||||||
inArray,
|
inArray,
|
||||||
|
isNull,
|
||||||
} from "drizzle-orm";
|
} from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { BaseInterface } from "./base.ts";
|
import { BaseInterface } from "./base.ts";
|
||||||
import { Instance } from "./instance.ts";
|
|
||||||
|
|
||||||
type EmojiWithInstance = InferSelectModel<typeof Emojis> & {
|
type EmojiWithInstance = InferSelectModel<typeof Emojis> & {
|
||||||
instance: InferSelectModel<typeof Instances> | null;
|
instance: InferSelectModel<typeof Instances> | null;
|
||||||
|
|
@ -135,7 +135,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
|
|
||||||
public static async fetchFromRemote(
|
public static async fetchFromRemote(
|
||||||
emojiToFetch: CustomEmojiExtension["emojis"][0],
|
emojiToFetch: CustomEmojiExtension["emojis"][0],
|
||||||
host?: string,
|
instance: Instance,
|
||||||
): Promise<Emoji> {
|
): Promise<Emoji> {
|
||||||
const existingEmoji = await db
|
const existingEmoji = await db
|
||||||
.select()
|
.select()
|
||||||
|
|
@ -144,7 +144,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(Emojis.shortcode, emojiToFetch.name),
|
eq(Emojis.shortcode, emojiToFetch.name),
|
||||||
host ? eq(Instances.baseUrl, host) : undefined,
|
eq(Instances.id, instance.id),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
@ -159,9 +159,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundInstance = host ? await Instance.resolve(host) : null;
|
return await Emoji.fromVersia(emojiToFetch, instance);
|
||||||
|
|
||||||
return await Emoji.fromVersia(emojiToFetch, foundInstance?.id ?? null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get id(): string {
|
public get id(): string {
|
||||||
|
|
@ -181,9 +179,12 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Emoji.manyFromSql(
|
return Emoji.manyFromSql(
|
||||||
inArray(
|
and(
|
||||||
Emojis.shortcode,
|
inArray(
|
||||||
matches.map((match) => match.replace(/:/g, "")),
|
Emojis.shortcode,
|
||||||
|
matches.map((match) => match.replace(/:/g, "")),
|
||||||
|
),
|
||||||
|
isNull(Emojis.instanceId),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +217,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
|
|
||||||
public static fromVersia(
|
public static fromVersia(
|
||||||
emoji: CustomEmojiExtension["emojis"][0],
|
emoji: CustomEmojiExtension["emojis"][0],
|
||||||
instanceId: string | null,
|
instance: Instance,
|
||||||
): Promise<Emoji> {
|
): Promise<Emoji> {
|
||||||
// Extracts the shortcode from the emoji name (e.g. :shortcode: -> shortcode)
|
// Extracts the shortcode from the emoji name (e.g. :shortcode: -> shortcode)
|
||||||
const shortcode = [
|
const shortcode = [
|
||||||
|
|
@ -233,7 +234,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
alt: Object.entries(emoji.url)[0][1].description || undefined,
|
alt: Object.entries(emoji.url)[0][1].description || undefined,
|
||||||
contentType: Object.keys(emoji.url)[0],
|
contentType: Object.keys(emoji.url)[0],
|
||||||
visibleInPicker: true,
|
visibleInPicker: true,
|
||||||
instanceId,
|
instanceId: instance.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import type {
|
||||||
Delete as VersiaDelete,
|
Delete as VersiaDelete,
|
||||||
Note as VersiaNote,
|
Note as VersiaNote,
|
||||||
} from "@versia/federation/types";
|
} from "@versia/federation/types";
|
||||||
import { type Instance, Notification, db } from "@versia/kit/db";
|
import { Instance, Notification, db } from "@versia/kit/db";
|
||||||
import {
|
import {
|
||||||
Attachments,
|
Attachments,
|
||||||
EmojiToNote,
|
EmojiToNote,
|
||||||
|
|
@ -715,6 +715,11 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
||||||
*/
|
*/
|
||||||
public static async saveFromRemote(uri: string): Promise<Note | null> {
|
public static async saveFromRemote(uri: string): Promise<Note | null> {
|
||||||
let note: VersiaNote | null = null;
|
let note: VersiaNote | null = null;
|
||||||
|
const instance = await Instance.resolve(uri);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
if (!URL.canParse(uri)) {
|
if (!URL.canParse(uri)) {
|
||||||
|
|
@ -741,7 +746,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
||||||
throw new Error("Invalid object author");
|
throw new Error("Invalid object author");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Note.fromVersia(note, author);
|
return await Note.fromVersia(note, author, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -753,19 +758,21 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
||||||
public static async fromVersia(
|
public static async fromVersia(
|
||||||
note: VersiaNote,
|
note: VersiaNote,
|
||||||
author: User,
|
author: User,
|
||||||
|
instance: Instance,
|
||||||
): Promise<Note> {
|
): Promise<Note> {
|
||||||
const emojis: Emoji[] = [];
|
const emojis: Emoji[] = [];
|
||||||
const logger = getLogger(["federation", "resolvers"]);
|
const logger = getLogger(["federation", "resolvers"]);
|
||||||
|
|
||||||
for (const emoji of note.extensions?.["pub.versia:custom_emojis"]
|
for (const emoji of note.extensions?.["pub.versia:custom_emojis"]
|
||||||
?.emojis ?? []) {
|
?.emojis ?? []) {
|
||||||
const resolvedEmoji = await Emoji.fetchFromRemote(emoji).catch(
|
const resolvedEmoji = await Emoji.fetchFromRemote(
|
||||||
(e) => {
|
emoji,
|
||||||
logger.error`${e}`;
|
instance,
|
||||||
sentry?.captureException(e);
|
).catch((e) => {
|
||||||
return null;
|
logger.error`${e}`;
|
||||||
},
|
sentry?.captureException(e);
|
||||||
);
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
if (resolvedEmoji) {
|
if (resolvedEmoji) {
|
||||||
emojis.push(resolvedEmoji);
|
emojis.push(resolvedEmoji);
|
||||||
|
|
|
||||||
|
|
@ -667,7 +667,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
const userEmojis =
|
const userEmojis =
|
||||||
data.extensions?.["pub.versia:custom_emojis"]?.emojis ?? [];
|
data.extensions?.["pub.versia:custom_emojis"]?.emojis ?? [];
|
||||||
const emojis = await Promise.all(
|
const emojis = await Promise.all(
|
||||||
userEmojis.map((emoji) => Emoji.fromVersia(emoji, instance.id)),
|
userEmojis.map((emoji) => Emoji.fromVersia(emoji, instance)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (emojis.length > 0) {
|
if (emojis.length > 0) {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import type {
|
||||||
User as VersiaUser,
|
User as VersiaUser,
|
||||||
} from "@versia/federation/types";
|
} from "@versia/federation/types";
|
||||||
import {
|
import {
|
||||||
type Instance,
|
Instance,
|
||||||
Like,
|
Like,
|
||||||
Note,
|
Note,
|
||||||
Notification,
|
Notification,
|
||||||
|
|
@ -277,6 +277,14 @@ export class InboxProcessor {
|
||||||
private async processNote(): Promise<Response | null> {
|
private async processNote(): Promise<Response | null> {
|
||||||
const note = this.body as VersiaNote;
|
const note = this.body as VersiaNote;
|
||||||
const author = await User.resolve(note.author);
|
const author = await User.resolve(note.author);
|
||||||
|
const instance = await Instance.resolve(note.uri);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Instance not found" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!author) {
|
if (!author) {
|
||||||
return Response.json(
|
return Response.json(
|
||||||
|
|
@ -285,7 +293,7 @@ export class InboxProcessor {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Note.fromVersia(note, author);
|
await Note.fromVersia(note, author, instance);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue