From 54e3fccd8763c1138af71ad129ed138e06765d84 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Jan 2023 14:19:25 +0900 Subject: [PATCH] enhance(server): refactor and tweak emoji proxy --- packages/backend/assets/emoji-unknown.png | Bin 0 -> 3518 bytes packages/backend/src/server/ServerService.ts | 43 +++++++++++++++++- .../src/server/web/ClientServerService.ts | 42 ----------------- 3 files changed, 41 insertions(+), 44 deletions(-) create mode 100644 packages/backend/assets/emoji-unknown.png diff --git a/packages/backend/assets/emoji-unknown.png b/packages/backend/assets/emoji-unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..ab29bef2b17ba5aaca78d8f809a010bc29970225 GIT binary patch literal 3518 zcmbtX3pkW%8=jdhB%-8bI*duP4w+LD^Bcx7VkF0LN@LEMlR3o5VJPE})fR1Aim)U@ zY=vZ{(ym{TN>NGKoYFW{T9rZnH?+0;xBLIs_5a^>ecycVdq2Qf z@X3@&ng|v_W3ae*_;`II9LA#J;enfpXd>T<#$>t03TVEuUVfC=NQw;=Zf~b)8-oJ~ zI5ZI%7QOH6BJn?)b2xuWLnw0D0|@a^)IY`a`v-)65b?oLkL0v?^k1~8$|R!5k-i<1?`#>&b9i=0mdC>##(Wzi+h zWD#J6MPo4*7_yotQJIlP;Bj+N20 zWQj*#M2Gi*15GQ6_zz07j*dp!-%E&7CVbuEUuU*0bQIhKNJu$?x2V>>esW5bQwOnN|C3xKF|u!IdkLT4O>^`mwNc%Eimh2gI)9V&wof%mNC?( zebS*F9li_iK1;glHmBbDO&WuHT zw;&-1v{+AdgF(kn7=S?PM()lIelaITPlRmOb674tT@33As6E7uJtBjb6dJi2nPGmV zvkTn^z?*;BnwV2Lbt--7R}N50;gS6&JL+8JcXpewNSYpZYHBX98u}EOT!J3okZwu zO4af3@Tj*Z7W+g-Ms_E@5MAnPK3EG}H8q``odH#?@H?dv$<*NBV14vB0)e1WQm%iclmP3UcyDE8waq;OdrVDT{iN5|6=kKq;)y}xbHmrYZ z&Aw;+(k0Jcy?gxlM1Z`yd(`k7**1=7N6&z%``wA5_VC68B4$V)Sea)RAM9)&0KT^Y zmfez>ndwO+?r68&vL*V%?2I$q0WVB1bt9M^iGB0@&b4cf$6lv87JR)ukIms6F-?pr zbs<>g#!tU{Rm*#Nzuv6NUl$1PaObkzwQ42M}KayI9 zCj857^4nK_<7(a+O7=7A9k_Wkad!F)Nf;6mqNk^)A9)u25|VticVvW}0-bsHstBf` z&$UEdff&0Ru3M+h3f{01TqS*c58>94Zx`>=!~wr#GmV#-juGm6xK_Ej$B)AgxtT0~ zWMgEO&9+kZHS5%NhlPSKfL3^4?`kYAE^cgm%C;JxW|%BDT(c%DEX+UWg`%sn7b2}c z1=Pnp!(Q^bzape|)<(HsH@9ui+p(}>#snZ)ub%T2h$kX@x_AB7tk8y7|I;@U?*{}1 z?zPP;DM7qn)G;hd@8~K1YNNEzI;)SW2FzbOsOk??_~r6aDQRPgNgnPB#L}>>I6iq35-DV2T*0~uZal`j&D^|LSrS~D{#; zt5&aGZD8;~k?!x|ar5LqqWkU1ffvji4;#O~IzZ5u!!HDnzMmL6>2><)cz9@NYtK4X zb@2Izj~}Wo(+{i&_#skw_|c~#3Wb8v?{LzG2wvLS+uC|+y#GxRh&|SC&8-A)2j@I_ zX!@e^MpDKCc6JEO|9aA4;|9ru>m8$Bh~FzH;lS|l@Gf-eb6uCW+5?1d0trj0*kdg% z?!}R&bc|WK%?$1OT*OE)PrmBnqh8hms|$bc8|V_d7)4gEN*FcSh1@*SY1tRWY0fD zMk&_cLj*dndbqW*vfRB<=!II^+NNRokcH4D@8Z%A2O71Zkeu25$@arXbf6GHNZ~)V z&dTM!mj+krS}o9Z?AM|D)tfu){C+8aawO>3p`lwR%_BF6$ga{hx?*_v;g)i_+@o!8 z(THpnc>lL~d3lqQlMpb6!)a(}(3hubzUVWD*_XoK7b4vdeJ*9OgkiGDcVYNnM)LvYCNu1 zh{$eH{ALzA?yp^SZ((uAaH`I_K|HXY9CX*(##{+Kc>S=nrKRN>5B75erh3$^2Gy$Z z;PK-(${D4s?bfXo4PXt8Rt-{ESR4Jk01gCHcc4IH6C@xYfa+Q(JqJrn3%Y)@LW*90 zs;(}G{=@y<7IPwjnxn*Gu~NpeG(7OLPf{%NYNoWT%gkDBPL7t9m1ze0!!z3!4rrt{g$ofVU+&PFWB>pF literal 0 HcmV?d00001 diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index beb26e43d1..fac8497b5e 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -1,12 +1,11 @@ import cluster from 'node:cluster'; import * as fs from 'node:fs'; -import * as http from 'node:http'; import { Inject, Injectable } from '@nestjs/common'; import Fastify from 'fastify'; import { IsNull } from 'typeorm'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import type { Config } from '@/config.js'; -import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { EmojisRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import type Logger from '@/logger.js'; import { envOption } from '@/env.js'; @@ -39,6 +38,9 @@ export class ServerService { @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, + @Inject(DI.emojisRepository) + private emojisRepository: EmojisRepository, + private userEntityService: UserEntityService, private apiServerService: ApiServerService, private streamingApiServerService: StreamingApiServerService, @@ -77,6 +79,43 @@ export class ServerService { fastify.register(this.nodeinfoServerService.createServer); fastify.register(this.wellKnownServerService.createServer); + fastify.get<{ Params: { path: string }; Querystring: { static?: any; }; }>('/emoji/:path(.*)', async (request, reply) => { + const path = request.params.path; + + if (!path.match(/^[a-zA-Z0-9\-_@\.]+?\.webp$/)) { + reply.code(404); + return; + } + + reply.header('Cache-Control', 'public, max-age=86400'); + + const name = path.split('@')[0].replace('.webp', ''); + const host = path.split('@')[1]?.replace('.webp', ''); + + const emoji = await this.emojisRepository.findOneBy({ + // `@.` is the spec of ReactionService.decodeReaction + host: (host == null || host === '.') ? IsNull() : host, + name: name, + }); + + reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\''); + + if (emoji == null) { + return await reply.redirect('/static-assets/emoji-unknown.png'); + } + + const url = new URL('/proxy/emoji.webp', this.config.url); + // || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ) + url.searchParams.set('url', emoji.publicUrl || emoji.originalUrl); + url.searchParams.set('emoji', '1'); + if ('static' in request.query) url.searchParams.set('static', '1'); + + return await reply.redirect( + 301, + url.toString(), + ); + }); + fastify.get<{ Params: { acct: string } }>('/avatar/@:acct', async (request, reply) => { const { username, host } = Acct.parse(request.params.acct); const user = await this.usersRepository.findOne({ diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index a7701e1b24..c69975fd79 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -1,6 +1,5 @@ import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { PathOrFileDescriptor, readFileSync } from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { createBullBoard } from '@bull-board/api'; import { BullAdapter } from '@bull-board/api/bullAdapter.js'; @@ -71,9 +70,6 @@ export class ClientServerService { @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, - @Inject(DI.emojisRepository) - private emojisRepository: EmojisRepository, - @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, @@ -225,44 +221,6 @@ export class ClientServerService { return reply.sendFile('/apple-touch-icon.png', staticAssets); }); - fastify.get<{ Params: { path: string }; Querystring: { static?: any; }; }>('/emoji/:path(.*)', async (request, reply) => { - const path = request.params.path; - - if (!path.match(/^[a-zA-Z0-9\-_@\.]+?\.webp$/)) { - reply.code(404); - return; - } - - reply.header('Cache-Control', 'public, max-age=86400'); - - const name = path.split('@')[0].replace('.webp', ''); - const host = path.split('@')[1]?.replace('.webp', ''); - - const emoji = await this.emojisRepository.findOneBy({ - // `@.` is the spec of ReactionService.decodeReaction - host: (host == null || host === '.') ? IsNull() : host, - name: name, - }); - - if (emoji == null) { - reply.code(404); - return; - } - - reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\''); - - const url = new URL('/proxy/emoji.webp', this.config.url); - // || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ) - url.searchParams.set('url', emoji.publicUrl || emoji.originalUrl); - url.searchParams.set('emoji', '1'); - if ('static' in request.query) url.searchParams.set('static', '1'); - - return await reply.redirect( - 301, - url.toString(), - ); - }); - fastify.get<{ Params: { path: string } }>('/fluent-emoji/:path(.*)', async (request, reply) => { const path = request.params.path;