summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-12-29 10:14:44 +0900
committerGitHub <noreply@github.com>2022-12-29 10:14:44 +0900
commit912791b3ab6a7cb6cbfda2aa9e15d95115770a5e (patch)
treee36053e09364ad0475fae453089eea455e29d71e /packages/backend/src
parent:art: (diff)
downloadmisskey-912791b3ab6a7cb6cbfda2aa9e15d95115770a5e.tar.gz
misskey-912791b3ab6a7cb6cbfda2aa9e15d95115770a5e.tar.bz2
misskey-912791b3ab6a7cb6cbfda2aa9e15d95115770a5e.zip
refactor: 絵文字URLを引き回すのをやめる (#9423)
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/entities/EmojiEntityService.ts8
-rw-r--r--packages/backend/src/models/schema/emoji.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/meta.ts3
-rw-r--r--packages/backend/src/server/web/ClientServerService.ts32
4 files changed, 39 insertions, 6 deletions
diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts
index 08d83a2753..f9419c5398 100644
--- a/packages/backend/src/core/entities/EmojiEntityService.ts
+++ b/packages/backend/src/core/entities/EmojiEntityService.ts
@@ -6,8 +6,8 @@ import type { Packed } from '@/misc/schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { Emoji } from '@/models/entities/Emoji.js';
-import { UserEntityService } from './UserEntityService.js';
import { bindThis } from '@/decorators.js';
+import { UserEntityService } from './UserEntityService.js';
@Injectable()
export class EmojiEntityService {
@@ -22,6 +22,7 @@ export class EmojiEntityService {
@bindThis
public async pack(
src: Emoji['id'] | Emoji,
+ opts: { omitUrl?: boolean } = {},
): Promise<Packed<'Emoji'>> {
const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
@@ -32,15 +33,16 @@ export class EmojiEntityService {
category: emoji.category,
host: emoji.host,
// ?? emoji.originalUrl してるのは後方互換性のため
- url: emoji.publicUrl ?? emoji.originalUrl,
+ url: opts.omitUrl ? undefined : (emoji.publicUrl ?? emoji.originalUrl),
};
}
@bindThis
public packMany(
emojis: any[],
+ opts: { omitUrl?: boolean } = {},
) {
- return Promise.all(emojis.map(x => this.pack(x)));
+ return Promise.all(emojis.map(x => this.pack(x, opts)));
}
}
diff --git a/packages/backend/src/models/schema/emoji.ts b/packages/backend/src/models/schema/emoji.ts
index e97fdd5ef6..9a52609b68 100644
--- a/packages/backend/src/models/schema/emoji.ts
+++ b/packages/backend/src/models/schema/emoji.ts
@@ -31,7 +31,7 @@ export const packedEmojiSchema = {
},
url: {
type: 'string',
- optional: false, nullable: false,
+ optional: true, nullable: false,
},
},
} as const;
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 05da011979..66c9f0620a 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -309,6 +309,7 @@ export const paramDef = {
type: 'object',
properties: {
detail: { type: 'boolean', default: true },
+ omitEmojiUrl: { type: 'boolean', default: false },
},
required: [],
} as const;
@@ -390,7 +391,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
backgroundImageUrl: instance.backgroundImageUrl,
logoImageUrl: instance.logoImageUrl,
maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため
- emojis: await this.emojiEntityService.packMany(emojis),
+ emojis: await this.emojiEntityService.packMany(emojis, { omitUrl: ps.omitEmojiUrl }),
defaultLightTheme: instance.defaultLightTheme,
defaultDarkTheme: instance.defaultDarkTheme,
ads: ads.map(ad => ({
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts
index 2b3f0ce0f5..af1ff91ac9 100644
--- a/packages/backend/src/server/web/ClientServerService.ts
+++ b/packages/backend/src/server/web/ClientServerService.ts
@@ -26,7 +26,7 @@ import { PageEntityService } from '@/core/entities/PageEntityService.js';
import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js';
import { ClipEntityService } from '@/core/entities/ClipEntityService.js';
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
-import type { ChannelsRepository, ClipsRepository, GalleryPostsRepository, NotesRepository, PagesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
+import type { ChannelsRepository, ClipsRepository, EmojisRepository, GalleryPostsRepository, NotesRepository, PagesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js';
import manifest from './manifest.json' assert { type: 'json' };
@@ -70,6 +70,9 @@ export class ClientServerService {
@Inject(DI.pagesRepository)
private pagesRepository: PagesRepository,
+ @Inject(DI.emojisRepository)
+ private emojisRepository: EmojisRepository,
+
private userEntityService: UserEntityService,
private noteEntityService: NoteEntityService,
private pageEntityService: PageEntityService,
@@ -217,6 +220,33 @@ export class ClientServerService {
return reply.sendFile('/apple-touch-icon.png', staticAssets);
});
+ fastify.get<{ Params: { path: string } }>('/emoji/:path(.*)', async (request, reply) => {
+ const path = request.params.path;
+
+ if (!path.match(/^[a-zA-Z0-9\-_@\.]+?\.webp$/)) {
+ reply.code(404);
+ return;
+ }
+
+ const name = path.split('@')[0].replace('.webp', '');
+ const host = path.split('@')[1]?.replace('.webp', '');
+
+ const emoji = await this.emojisRepository.findOneBy({
+ host: host == null ? IsNull() : host,
+ name: name,
+ });
+
+ if (emoji == null) {
+ reply.code(404);
+ return;
+ }
+
+ reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
+
+ // ?? emoji.originalUrl してるのは後方互換性のため
+ return await reply.redirect(301, emoji.publicUrl ?? emoji.originalUrl);
+ });
+
fastify.get<{ Params: { path: string } }>('/fluent-emoji/:path(.*)', async (request, reply) => {
const path = request.params.path;