From 8375383e5c8128cd1e22923bc2738bc219b2a5dc Mon Sep 17 00:00:00 2001 From: afeuerstein <32029275+afeuerstein@users.noreply.github.com> Date: Sat, 22 May 2021 19:35:53 +0200 Subject: [PATCH 1/4] throw GUILD_ROLE_DELETE event --- src/routes/guilds/#guild_id/roles.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/routes/guilds/#guild_id/roles.ts b/src/routes/guilds/#guild_id/roles.ts index 940058b9..e9360847 100644 --- a/src/routes/guilds/#guild_id/roles.ts +++ b/src/routes/guilds/#guild_id/roles.ts @@ -8,7 +8,8 @@ import { Snowflake, MemberModel, GuildRoleCreateEvent, - GuildRoleUpdateEvent + GuildRoleUpdateEvent, + GuildRoleDeleteEvent } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; import { emitEvent } from "../../../util/Event"; @@ -85,6 +86,15 @@ router.delete("/:role_id", async (req: Request, res: Response) => { guild_id: guild_id }).exec(); + await emitEvent({ + event: "GUILD_ROLE_DELETE", + guild_id, + data: { + guild_id, + role_id + } + } as GuildRoleDeleteEvent); + res.sendStatus(204); }); From 4e7d4af433c4fe988935486b6eb640a54b74384a Mon Sep 17 00:00:00 2001 From: afeuerstein <32029275+afeuerstein@users.noreply.github.com> Date: Sat, 22 May 2021 19:37:08 +0200 Subject: [PATCH 2/4] remove patchfile --- package-lock.json | Bin 767322 -> 762214 bytes package.json | 4 +- patches/i18next-http-middleware+3.1.1.patch | 274 -------------------- 3 files changed, 1 insertion(+), 277 deletions(-) delete mode 100644 patches/i18next-http-middleware+3.1.1.patch diff --git a/package-lock.json b/package-lock.json index 4308952bbaeeb2af9b3058db73cda0adc7449791..81fd6eb22f982bf8949f29be51aa187a5a3b0e5f 100644 GIT binary patch delta 5303 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 delta 8373 zcmdT}dw3I7+J9y;lbK9CcV?-J-A05>6(sOr^jyB*$kSN2h%@I?{#HZ;$pr^BI4>d$aLi%%W6M1`ZiY19`1u%U_$MIRJX z=`@*IYG4<71MG6xFoQZIofT6`O+Yq&<7sny2zofhbSfVt)~LOu$b-j9UlzK;{-X7h3*`>0*1Z_f^U{F zA@KbQb}w1cyNa3Tn~ed@Edmb{MeRGw* zkVESRZ6#R(e=#2PE7`wEibPnE9!k36Kqh_12t`V-M+>NJ=MMra5Up6xvAJ*suntB~i=_iJi?YjjcGVSQA^CVXaXS4p|Er z79QVAC#Bl1yQ;Yjr;r;>C2Bz%$;DM$s@rU}8bfThvtD22$#0$6 zQlI0gvpF-;>XKVaDjGcwv#ZcjS6^E`+g4RtID1i-qoBp8ZktiuY{~P?Xf|Xz^(DFj zV@4&ct)ioYZLNvcMQtr6DGBP5G)XDmO4}%SbEhEpeyWR1ype2bXS2n+z|m}JZ?d+k z2X}d74;u!qSNN2$p>4(64W5vwgYyqEaaHcLmRd`mMcbV0$aYq?SoP_~?7ZSdHnpLC zkuJL^r(vco%@VIRSI^F<*XdeY6jxPeT1k0_ZB|9w98Kz?f}%EKms;y= z&}glNxv-`R2i?uC0rxIrCi7`Ax24A{UL4~!wL~MflU^PmIdspjX}es?rdhwCSIMQD zX069NwtDzI;5Ui(hhtv)8Oi0*ribaAK}TQm0M4+P8A^XRvykzFtR;L9xTdhv#nlS< zRX6_RNdlIBr1Tjy*l%w=46n=;v!@$GO(xbp| zm_9*5)%XUzh2$-1CBiEUhm&a}sLFUbeE7MbKnLEWKch*V+qZ|0hQ=OtJPAGL0$PsL zZ_$5}6R~{Bzx+Kc+THKdBU3&)PG2F(`f!2}fd)RH{a9a(j0M$6EPmN3T1S&qyyPo( zESxmR7&vy2Up?$A8$P8ET&4*ifRpzrQiF(>VaFJ9IB>6(jgQhM)~6J@bw!Tanrusp z#Zg(&RcEMh=H%HcT3cZSOOF%n8w#I1Peq~XQ?ksEVQJXLCR1l3G%ukeAZ9n45+=R3 zb~(-X7~eB&-bhWXb{1RPt7myExw)-rv-2uuyNfeAwZ;}}imr8*J3YIxMwgS)YSZV` z7ANP{RnN-N<+bZfGb$VG1y#xMP4(FYxt(p9@w((9Yg1ZNWqEN&TDG%|Bn3%8N(=7M zbQJpVqU=QUupYQD=5gXR=#6m38bs2!{5^%8g5GW__l2pbjMI z3F2TF0)>!C0k%Re+GAoqrA2Rrwf@52ysn~f=nfDjL6(6LKxJnb^iL~uU=*=&Q=G5> z#$9G3Vd1?@9Ne*jiGVdrnQJitDQBw13H;!ro4HPzKA zY5C4duW4_b6dtI{%Q&TcAiXL_U|leU$ik^K*nD1=96e&ZP6V=7y(gxDsfEQ^&OOUq zZEUPI=QdRtH60nY0!^bqZ_hI}yFA5Z8P=3qyLx7oHm|~(U!c{+TXG8>X;oIe(V??< zrWU#JYk=`8y% z@(@{SQW{X(<)KixQ}Fl4_K{ZON`kB7+Wlj~uTqsbhikia5oG^^9?!WP;=t|RmrA1o zu3D#t#8;^VujT*)P2<=%Nw%CH&A#k6av2yWu@X9gti8-QI>Yck%w5XuHJ19*wZhJlHu#Yo(E}lAignn2>dsZ z-1$^(OqG3RZb?(Kz0_HgVzOA;X6x;iVt4b*_KN({oR0E2=0c;}qfhe~YUX5=+Dh|X z&O&3V-BwpuQkjx(FKutn$kWx9%xuwg#hZ;K1rB3vv13l5RPO?PPA+P0sTR&JXA+_R zc{bYrDxtmFZ@(s5+o_UI?oMEnK>q~8qRcH!e}wO%$n_$Vlu9xXMs=g$x9=$wkZ_MM z23;OtGGrv%#;Di{u<|0a*T;Y`uI{JCqLtq=&yFRfU~Vw`zO))G2w`agHQ~}$Ar!3- zWm_0g?cw0JU5JEDQ`kT>cQm^s8k*8D1p48U5R5RITs90OO>i!q7yz;Faucd+jHUG{hWccWw!)P^$IzlFbIr=B(Nw27YKpQe zZANQHTbo|1HK%HGO$K}6Y?H~-P+Ak;S>2|ss4Z*Ct4?*-mld=&xoUE)j`~hLMo1Z% z+2A%a6TBz=qtN71b`z<(=GIKt3+#^5%->W!Bq4HGtmx4-Q=OE6u{p$F48 zUb1MIM1aJ`@Ggnw9Lh>(#2E@sUIpU;0iswt`K#IpLDnF#bMTEOP-cu$~%3MMK|@ zyH;~}apd(hgyyVbABvRx;E`i8e-yceZ3`nV;Ip0oKK2zdMA+RQ*e@lY0_;=4$hDs} z4PJZ*YEDIoe`Jd%lM0IoeyPqcJ7pLy&y~v{8i}GhxKd--1Uw;82o2o zMSKy-?d4!+9CrbBP2hH+riol0jSf!YN_iBi;nq0o|X>O$&z) z2IP2yB5oH2$1m`q-5Nev1mz*^Uhxl1su-NgLN`d-3Cb)OLD!eQ$gf%tXX)u4U z!0B-=H~JQ+IfplTX9cHJ!lUDa5O31lK)~&uN>uv*w^@NgfSV(ePJ{V1N}NNz)O=87 zDKUF5<|e}O;|v4KDCLGBDH0${%O594WhL|HV8=pb1X7<6a4$v_6ov;MPvvp1;WtNd z0e|z9&;eJb2vK6xE5VV$zXbuwT+!4K zUuY-O|CEe}E=BX7`H{2rM=)DbWYT{k+U$K#_>2ht%y)_y=zm{0G<5%SXPJxhY8ow@35(nYN$`nenG2oucw?rsx51$m0FMQ|| zWzgV}dj3^8xsb1s0=SVf7qTd9(Chig>N)(!%ztX&kr>|;HB;I z2srqOTmippP)@x;ZzQN(nD`6zMwTCy$H1ysDj1eskqJs1^*+k#+9QO*)@jNxn5yLi z0mpa%*zV*vpy2uZRv8?B49Ca&CjPa5gVxCSS=?A~T#?nY-^FZQ#+5Pvrp+-*`aFnTe6f{YK2J6u|!jdMnA=KmLJV%^*0y z|46~MgZvI;dWpBc_w$<;r(FCPQS+fx8rrvB5gZiYDB}Oc*XX4PZ>>?;v?LV2aQSr=|#peO5e8Y>cfX zwFo%KTFfip$EkuGF2@Tye6!oD4Wc$aX7)bS^F3+tik1>q?OM8aFd2e^I0X_e@#BCr$x zi^WtMDnAh-7)-%apmLL38+bJZPl2@_`S|KzgoJm(ilg%ApRn-gNy2DY;Li;L5_Bd{}*ufG;FzDzE?uku=O+Hd!nhnG-W94oQu2p`n$OxSfIzeSpwrfL24nSqE~;3 zKNaz~Sd9E&*%@I(L4zab1ObyoIS& 0 && arguments[0] !== undefined ? arguments[0] : {}; -- options.getPath = options.getPath || getPath; -- options.getOriginalUrl = options.getOriginalUrl || getOriginalUrl; -- options.getUrl = options.getUrl || getUrl; -- options.setUrl = options.setUrl || setUrl; -- options.getParams = options.getParams || getParams; -- options.getSession = options.getSession || getSession; -- options.getQuery = options.getQuery || getQuery; -- options.getCookies = options.getCookies || getCookies; -- options.getBody = options.getBody || getBody; -- options.getHeaders = options.getHeaders || getHeaders; -- options.getHeader = options.getHeader || getHeader; -- options.setHeader = options.setHeader || setHeader; -- options.setContentType = options.setContentType || setContentType; -- options.setStatus = options.setStatus || setStatus; -- options.send = options.send || send; -- return options; -+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; -+ options.getPath = options.getPath || getPath; -+ options.getOriginalUrl = options.getOriginalUrl || getOriginalUrl; -+ options.getUrl = options.getUrl || getUrl; -+ options.setUrl = options.setUrl || setUrl; -+ options.getParams = options.getParams || getParams; -+ options.getSession = options.getSession || getSession; -+ options.getQuery = options.getQuery || getQuery; -+ options.getCookies = options.getCookies || getCookies; -+ options.getBody = options.getBody || getBody; -+ options.getHeaders = options.getHeaders || getHeaders; -+ options.getHeader = options.getHeader || getHeader; -+ options.setHeader = options.setHeader || setHeader; -+ options.setContentType = options.setContentType || setContentType; -+ options.setStatus = options.setStatus || setStatus; -+ options.send = options.send || send; -+ return options; - }; - - exports.extendOptionsWithDefaults = extendOptionsWithDefaults; -\ No newline at end of file From b5f8a2e4e1ee52025886d8404a8a277737e634c0 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Sat, 22 May 2021 21:13:14 +0200 Subject: [PATCH 3/4] :sparkles: reactions bulk remove --- .../messages/#message_id/reactions.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts index be635197..f61977f4 100644 --- a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -5,6 +5,8 @@ import { MemberModel, MessageModel, MessageReactionAddEvent, + MessageReactionRemoveAllEvent, + MessageReactionRemoveEmojiEvent, MessageReactionRemoveEvent, PartialEmoji, PublicUserProjection, @@ -33,6 +35,66 @@ function getEmoji(emoji: string): PartialEmoji { }; } +router.delete("/", async (req, res) => { + const { message_id, channel_id } = req.params; + + const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true }).exec(); + if (!channel) throw new HTTPError("Channel not found", 404); + + const permissions = await getPermission(req.user_id, undefined, channel_id); + permissions.hasThrow("MANAGE_MESSAGES"); + + const message = await MessageModel.findOneAndUpdate({ id: message_id, channel_id }, { reactions: [] }).exec(); + if (!message) throw new HTTPError("Message not found", 404); + + await emitEvent({ + event: "MESSAGE_REACTION_REMOVE_ALL", + channel_id, + guild_id: channel.guild_id, + data: { + channel_id, + message_id, + guild_id: channel.guild_id + } + } as MessageReactionRemoveAllEvent); + + res.sendStatus(204); +}); + +router.delete("/:emoji", async (req, res) => { + const { message_id, channel_id } = req.params; + const emoji = getEmoji(req.params.emoji); + + const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true }).exec(); + if (!channel) throw new HTTPError("Channel not found", 404); + + const permissions = await getPermission(req.user_id, undefined, channel_id); + permissions.hasThrow("MANAGE_MESSAGES"); + + const message = await MessageModel.findOne({ id: message_id, channel_id }).exec(); + if (!message) throw new HTTPError("Message not found", 404); + + const already_added = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name); + if (!already_added) throw new HTTPError("Reaction not found", 404); + message.reactions.remove(already_added); + + await MessageModel.updateOne({ id: message_id, channel_id }, message).exec(); + + await emitEvent({ + event: "MESSAGE_REACTION_REMOVE_EMOJI", + channel_id, + guild_id: channel.guild_id, + data: { + channel_id, + message_id, + guild_id: channel.guild_id, + emoji + } + } as MessageReactionRemoveEmojiEvent); + + res.sendStatus(204); +}); + router.get("/:emoji", async (req, res) => { const { message_id, channel_id } = req.params; const emoji = getEmoji(req.params.emoji); From 71c0050a54b11fec132a5a015da14922eed04cfe Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Sat, 22 May 2021 22:06:18 +0200 Subject: [PATCH 4/4] :sparkles: Message edit --- .../#channel_id/messages/#message_id/index.ts | 40 ++++++++++++++++++- .../messages/#message_id/reactions.ts | 2 +- src/schema/Message.ts | 18 +++++---- src/util/Message.ts | 12 +++--- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/routes/channels/#channel_id/messages/#message_id/index.ts b/src/routes/channels/#channel_id/messages/#message_id/index.ts index 88b8d89b..5a61b4ad 100644 --- a/src/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/routes/channels/#channel_id/messages/#message_id/index.ts @@ -1,11 +1,47 @@ -import { ChannelModel, getPermission, MessageDeleteEvent, MessageModel } from "@fosscord/server-util"; +import { ChannelModel, getPermission, MessageDeleteEvent, MessageModel, MessageUpdateEvent, toObject } from "@fosscord/server-util"; import { Router } from "express"; import { HTTPError } from "lambert-server"; +import { MessageCreateSchema } from "../../../../../schema/Message"; import { emitEvent } from "../../../../../util/Event"; import { check } from "../../../../../util/instanceOf"; +import { handleMessage } from "../../../../../util/Message"; const router = Router(); -// TODO: + +router.patch("/", check(MessageCreateSchema), async (req, res) => { + const { message_id, channel_id } = req.params; + var body = req.body as MessageCreateSchema; + + var message = await MessageModel.findOne({ id: message_id, channel_id }, { author_id: true }).exec(); + if (!message) throw new HTTPError("Message not found", 404); + + const permissions = await getPermission(req.user_id, undefined, channel_id); + + if (req.user_id !== message.author_id) { + permissions.hasThrow("MANAGE_MESSAGES"); + body = { flags: body.flags }; + } + + const opts = await handleMessage({ + ...body, + author_id: message.author_id, + channel_id, + id: message_id, + edited_timestamp: new Date() + }); + + message = await MessageModel.findOneAndUpdate({ id: message_id }, opts).populate("author").exec(); + if (!message) throw new HTTPError("Message not found", 404); + + await emitEvent({ + event: "MESSAGE_UPDATE", + channel_id, + guild_id: message.guild_id, + data: { ...toObject(message), nonce: undefined } + } as MessageUpdateEvent); + + return res.json(toObject(message)); +}); router.delete("/", async (req, res) => { const { message_id, channel_id } = req.params; diff --git a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts index f61977f4..1bfaae39 100644 --- a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -13,7 +13,7 @@ import { toObject, UserModel } from "@fosscord/server-util"; -import { Request, Response, Router } from "express"; +import { Router } from "express"; import { HTTPError } from "lambert-server"; import { emitEvent } from "../../../../../util/Event"; diff --git a/src/schema/Message.ts b/src/schema/Message.ts index 9b62edcf..e6aa42b3 100644 --- a/src/schema/Message.ts +++ b/src/schema/Message.ts @@ -5,6 +5,7 @@ export const MessageCreateSchema = { $content: new Length(String, 0, 2000), $nonce: String, $tts: Boolean, + $flags: BigInt, $embed: { $title: new Length(String, 0, 256), //title of embed $type: String, // type of embed (always "rich" for webhook embeds) @@ -15,48 +16,49 @@ export const MessageCreateSchema = { $footer: { text: new Length(String, 0, 2048), icon_url: String, - proxy_icon_url: String, + proxy_icon_url: String }, // footer object footer information $image: EmbedImage, // image object image information $thumbnail: EmbedImage, // thumbnail object thumbnail information $video: EmbedImage, // video object video information $provider: { name: String, - url: String, + url: String }, // provider object provider information $author: { name: new Length(String, 0, 256), url: String, icon_url: String, - proxy_icon_url: String, + proxy_icon_url: String }, // author object author information $fields: new Length( [ { name: new Length(String, 0, 256), value: new Length(String, 0, 1024), - $inline: Boolean, - }, + $inline: Boolean + } ], 0, 25 - ), + ) }, $allowed_mentions: [], $message_reference: { message_id: String, channel_id: String, $guild_id: String, - $fail_if_not_exists: Boolean, + $fail_if_not_exists: Boolean }, $payload_json: String, - $file: Object, + $file: Object }; export interface MessageCreateSchema { content?: string; nonce?: string; tts?: boolean; + flags?: bigint; embed?: Embed & { timestamp?: string }; allowed_mentions?: []; message_reference?: { diff --git a/src/util/Message.ts b/src/util/Message.ts index 8e9f98cd..0d3cdac7 100644 --- a/src/util/Message.ts +++ b/src/util/Message.ts @@ -9,7 +9,7 @@ import { HTTPError } from "lambert-server"; import { emitEvent } from "./Event"; // TODO: check webhook, application, system author -export async function sendMessage(opts: Partial) { +export async function handleMessage(opts: Partial) { const channel = await ChannelModel.findOne({ id: opts.channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec(); if (!channel || !opts.channel_id) throw new HTTPError("Channel not found", 404); // TODO: are tts messages allowed in dm channels? should permission be checked? @@ -28,10 +28,8 @@ export async function sendMessage(opts: Partial) { } // TODO: check and put it all in the body - const message: Message = { + return { ...opts, - id: Snowflake.generate(), - timestamp: new Date(), guild_id: channel.guild_id, channel_id: opts.channel_id, // TODO: generate mentions and check permissions @@ -43,10 +41,14 @@ export async function sendMessage(opts: Partial) { reactions: opts.reactions || [], type: opts.type ?? 0 }; +} + +export async function sendMessage(opts: Partial) { + const message = await handleMessage({ ...opts, id: Snowflake.generate(), timestamp: new Date() }); const data = toObject(await new MessageModel(message).populate({ path: "member", select: PublicMemberProjection }).save()); - await emitEvent({ event: "MESSAGE_CREATE", channel_id: opts.channel_id, data, guild_id: channel.guild_id } as MessageCreateEvent); + await emitEvent({ event: "MESSAGE_CREATE", channel_id: opts.channel_id, data, guild_id: message.guild_id } as MessageCreateEvent); return data; }