From 873107f90d44f907f5964b8c0a95261224a74759 Mon Sep 17 00:00:00 2001 From: TomatoCake <60300461+DEVTomatoCake@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:16:50 +0200 Subject: [PATCH] Perms for GET webhook, url property --- assets/openapi.json | Bin 604064 -> 604136 bytes assets/schemas.json | Bin 22032984 -> 22041912 bytes .../webhooks/#webhook_id/#token/index.ts | 9 +++-- src/api/routes/webhooks/#webhook_id/index.ts | 34 +++++++++++++----- src/api/util/handlers/Message.ts | 1 - src/util/entities/Webhook.ts | 8 +++-- 6 files changed, 37 insertions(+), 15 deletions(-) diff --git a/assets/openapi.json b/assets/openapi.json index 9bcb54a53686b0b09ffc6b43f05d4ade613597f3..5cf313273185976af200242369f0c2d3c2ff14c9 100644 GIT binary patch delta 132 zcmZ4RUggDmm4+>hA7ZEP4`Yd){vnp}>U8-u7WU~APBM#4UoXYTG5wt>qr~)v<%~*` z9bTJF|G%4&XZrKqjP}zN%2*VqZ#c~8*KVA^2*gZ4%)H$=fhE#_TOlzoMWG}=J2g*l hav`(Gc7cB^a*XZ!C$a!BD-g2*G5hxY6FD9(1po;0G`#=- delta 154 zcmaFyUS+|1m4+>hA7ZCZ5MpwjY#`!3yAOW%ok_#HS z&>#mziWZsixdgP`*s)yOQEX?l1p%2U3`G=TwTs4~8nm5u4&Wcq-5;`667DD8@80|D z^WtCkuiCVo`P8Q95=q-$^VQ)Lsynd!3Y7~sE2wUFoP>US@AFx-dEmN?9={a0o(|<3 zl^~D!J8$7mr_F%VX;#uS6h?J+izTI3tUtOUT9bq#IVzU`l}ndyLSgh6*xGW+3>hdh zY&1wo#=7 z1o~2a-bP}z7k#1jqF)@+q?a@RyrhA_NVTSEwnxOBQfWCAqZSA1Z$EJ zrKq-W4b~yhU>&MQO6ps~#WY`SNTB}uC9%{kSLA9;lu4;McSR<*bCVW!ZVGEk#aUs$ z3HsKEmB_hgTp9)AQk~~6gc@53^f}R>&snw>lP`un>v#p8b;K0mOg8wB#1awLp^SwN zWn4OPG-c$^C^<`oDDprB7VzmV~=~0GBxZS(f!0ug% z>K(X(m~XEI^X+x2-y*r)a|3MmeC<&tPO`3SBh;0>j_Nm-9Pz*#ARgFcjV$9j|0G!F zpR7TaqN^kYx=J>CBe9siREX)*TW|xFEAdT-65kB$lI&8v1zd`^s*om2d*6i8-fe$H zW-@PaCgd&N(S%e>FMJEq3$qfDOY-ynKfv?;o%4`t8GhN2;g^HOZWial&Eh|H;o5*3 z>D>(@y?JjUO&V4CU{vi%L>9oi@NMue+$0);kxRbt;nIA zTT}$OMep_?O;&UlLq&H<4sN#P;#B(~PF1>W8*U2fD(9f9ylenxk{x&|MBMX%a(F&) zz!SUsnq;%o2FOw$G9aU5x}ZD2H(^?+k}W3>D#7T=Xv-}ujme+rQ$tvrMy{7kJuc;vl zr$$$qnxypS0(%$gUU5c4+ppQpp_O0HaWm?aa$5MVLcw-&KGdu`A)!V20nSt&>AQfM zPy6`L=CQL2seHpy4|;sIr-)wlbXvromCv5yU3!+?Ke0<-*ZxWkH zi!Ss}{ho;W|4HmR^<9HrA|@*8E@)>>{^}GbqQ`%6U=QvN45XbC&hw|ubVkM~C!cdP zHrv=!_ru2`XmjLk1s(FvcjQ=)D|*@a)jpjhG3ZHEiwhIj9{zzaBH?GE5zM0o0+*r~oT1luZv3F452e ziH25xOitMW=GHeC;np{oPGX!gjGdXFJsAFhDFwrN%iEy0{BmdpVwPuE(&)#KH2OCI z8QV7PC$LT1ej91B^pF6hhpu9=rlC)vY3Q@oUu%+MS8D8aja{u>|8XrMA@vq6t*ism z%5Hp#jI5ylb13NlLW@klRmeZVD&(dN(*(SQo*(*3$|W0aL9*dXB+D@t&JT5_BQF}K zBvZp~Luy!eGIDLUs_Fr&s$LDI6Ihh&m?-ATOn0En)HfF?`7r$7@G$)AK};Fh!X>Zl z2YKbd2AmpYn22i``46;=4A$cIkdv&GI}$krMm+JLVYg;t))5_TSY@+T`*Zr%~z})=-7{B&eW2=#$F+& zy0c=JsZWI-GUe2pL3>4<5T%<<#51@~{#)qeA9`gW+L;wJ>d7OBdh(qD8ERwP7&OLx z|7|)>t*6lpJ&lhyAl0&;{ui>Jjwd5A=lCb!9RD;4i9wwOpl(8gnW|VfPF?&*PdtO@ ziRTNDlIIeBf^!M~^T%P+l796+gJ1nGN*sHz`g%$3W@1k%;ye{BT+kvJm3fm3^Get$?j r5%z~9kWOU!>kqCZLjA#43F;ipTlkj2RYYhRTuruM{FYf}*zEg1s5&i2 delta 7267 zcmb7JYgAO%6JlEjcE(UwqmV_rh1}F zxe}I~nj!;=1yKPBxKW7LR9lTz!6wmI!n0CpQ^6u()FSrI(6!oMVfV+ZdE9UB^X=!^ z=S*|W=QiIwzGhRnUIm^9f6V3{D`7dYf-$W%d&*WG)NXT*HjdWm> z1q^JOV!df{^f4m~*Lx}Hf!3*TpjEOeb#f7LfkZniNVKzFxDkV9p7yU~)KM=5N4-r5 zYJmxn&Sn{OHp|me@T=UG+rn+RvR;c3IjH9@>FxSZM$oNb4_m=u4T=m^%N#*1o4yQX zEgjdr1>-uW4{>O#CTFl}av4DIE-|u`DwQ+4));Ik)+r^-_E#3ufDcMoZNc*8Q(TG@ zr2cGaU-nEx!UZ{rE#@}68LocqLS`_|!PC8XnHxvzE(ojwXq1@~}2>**{F{dG1KWA0?rC20=%xm+g8#*sk~Ag+u2y2S9FfU=)H0Z)74`LL(LPAyTnmK5l`R z84KZMMvw}HF424@p;e8+P}R67JZ*A+@jpnkLCz;Cw3h-fHcE}z{Q4`+8Kgl$8)aa%_s zZ0lI-gVXIC@Gdw9Bn`iZ(p^-v9*T;RacN8!_iup3{Trv^d~zc+6>fy4g`m=x?mMc5 zeMi%Map(oTI#|$~VZ^-vC2gf9!CmRBKwp8JKk{bLTqy}$0 zgVTNR(ED)k(2o-Is92^A{20;(elioKn~7*^Dhta6S=e@GlnAXU`~YeScihJ%BI)}n zkiMT~<8(g_-U&~G^Ad1wync8WTtEDa2RJ4kUAw`f>z6?~lp7x{%7;gb_HIU{mZ5E< zKe48Fjuyb3qxD>=Ly&q=d+L2?(0dNdC7`X*yLnouq$v*lP#fL_G zcL*ZBJ3J4u(~He(DDnslMIJ3e@n)iK36-5F1lb9`9F@nczU-nk>++V&G0j{dOxdS% zXZ10~JLr&}gCV`$^9_^xK%7XD@;8Af8G8CeDV#oW@(Yx|>9Da3hK+^@ly0{7#TjcV#8iL~b7}~YF=8Zk zKH^lYeXKK-T?-6!HxJA`XHHAmvLJ~m0{%?=#8!J(4%o3-fFTts3xQ$|DmN1q!gR%5- zXx8L)`kzU+<>eJ^P|T?2_i{Lo6RlnpGh{R>d{kzGb#R82KE8k>53-_?RTv zVCf&ER1$pyB+gDR@N0!7u=A*eiM;;?Q>+h0F`_SX-Q z^L_5RN07Vj&t0fAVt*}FxS3j52s2bZS;4rP4ol{#u{CcbO!K|c$=t_k@8nE;D0F>) zhWVE+%~Y5FUIg5$?tpvM-=?7QgVv69LhV@BN!-|SKdA@qC-r8a?4eNI2T=W&l{hB* z#~#D}vHmY{x;x?rpdU?&-@^w|Tyx188j^K^5Fkf-y;R!3^XTq2}4_>c&cO}wYXmk6E`KjMSh&3V&F zR%qK8Kt4e=Zr*f?6^1UnO@5BLYBFfEgNTBE!7U)d3vMCl#<4O<3EJ#n;()`CURgwh z(JLXu4`+qxcqLTZE+)9kAwDlNOpIFQ5;7AP1&^k1B6u_{B?UM>UeaYm@RBYk^H6w} zEt&7c%Eun7i#>Kv{1-8}K}_Rv?PV1cDx~hr)6&+F6142DQieOE)1kLh6toKmf%i?{5ql`!a5R9^axTP87*w~{2O1| BY*7FJ diff --git a/src/api/routes/webhooks/#webhook_id/#token/index.ts b/src/api/routes/webhooks/#webhook_id/#token/index.ts index 49c47cca..6d1449eb 100644 --- a/src/api/routes/webhooks/#webhook_id/#token/index.ts +++ b/src/api/routes/webhooks/#webhook_id/#token/index.ts @@ -20,7 +20,7 @@ const router = Router(); router.get( "/", route({ - description: "Returns a webhook object for the given id.", + description: "Returns a webhook object for the given id and token.", responses: { 200: { body: "APIWebhook", @@ -45,7 +45,12 @@ router.get( throw DiscordApiErrors.INVALID_WEBHOOK_TOKEN_PROVIDED; } - return res.json(webhook); + const instanceUrl = + Config.get().api.endpointPublic || "http://localhost:3001"; + return res.json({ + ...webhook, + url: instanceUrl + "/webhooks/" + webhook.id + "/" + webhook.token, + }); }, ); diff --git a/src/api/routes/webhooks/#webhook_id/index.ts b/src/api/routes/webhooks/#webhook_id/index.ts index 7d528dbf..98faaac1 100644 --- a/src/api/routes/webhooks/#webhook_id/index.ts +++ b/src/api/routes/webhooks/#webhook_id/index.ts @@ -1,5 +1,10 @@ import { route } from "@spacebar/api"; -import { Webhook } from "@spacebar/util"; +import { + Config, + DiscordApiErrors, + getPermission, + Webhook, +} from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -15,18 +20,29 @@ router.get( }, }), async (req: Request, res: Response) => { - // TODO: Permission check const { webhook_id } = req.params; const webhook = await Webhook.findOneOrFail({ where: { id: webhook_id }, - relations: [ - "user", - "guild", - "source_guild", - "application" /*"source_channel"*/, - ], + relations: ["channel", "guild", "application", "user"], + }); + + if (webhook.guild_id) { + const permission = await getPermission( + req.user_id, + webhook.guild_id, + ); + + if (!permission.has("MANAGE_WEBHOOKS")) + throw DiscordApiErrors.UNKNOWN_WEBHOOK; + } else if (webhook.user_id != req.user_id) + throw DiscordApiErrors.UNKNOWN_WEBHOOK; + + const instanceUrl = + Config.get().api.endpointPublic || "http://localhost:3001"; + return res.json({ + ...webhook, + url: instanceUrl + "/webhooks/" + webhook.id + "/" + webhook.token, }); - return res.json(webhook); }, ); diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index 461cddb4..f037417a 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -149,7 +149,6 @@ export async function handleMessage(opts: MessageOptions): Promise { `/avatars/${opts.webhook_id}`, dataUri as string, ); - console.log(message.avatar); message.author.avatar = message.avatar; } } else { diff --git a/src/util/entities/Webhook.ts b/src/util/entities/Webhook.ts index b7fba53a..8b1585ad 100644 --- a/src/util/entities/Webhook.ts +++ b/src/util/entities/Webhook.ts @@ -38,20 +38,20 @@ export class Webhook extends BaseClass { name: string; @Column({ nullable: true }) - avatar?: string; + avatar: string; @Column({ nullable: true }) token?: string; @Column({ nullable: true }) @RelationId((webhook: Webhook) => webhook.guild) - guild_id: string; + guild_id?: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { onDelete: "CASCADE", }) - guild: Guild; + guild?: Guild; @Column({ nullable: true }) @RelationId((webhook: Webhook) => webhook.channel) @@ -92,4 +92,6 @@ export class Webhook extends BaseClass { onDelete: "CASCADE", }) source_guild: Guild; + + url?: string; }