This commit is contained in:
MathMan05
2026-02-26 14:51:11 -06:00
committed by Rory&
parent 98347bf1ab
commit 2ff656ef03
4 changed files with 90 additions and 11 deletions

View File

@@ -502,15 +502,11 @@ router.post(
// no await as it shouldnt block the message send function and silently catch error
postHandleMessage(message).catch((e) => console.error("[Message] post-message handler failed", e));
return res.json(
message.withSignedAttachments(
new NewUrlUserSignatureData({
ip: req.ip,
userAgent: req.headers["user-agent"] as string,
}),
),
);
const sign = new NewUrlUserSignatureData({
ip: req.ip,
userAgent: req.headers["user-agent"] as string,
});
return res.json(await Message.prototype.withSignedComponents.call(message.withSignedAttachments(sign), sign));
},
);

View File

@@ -163,8 +163,20 @@ async function processMedia(media: UnfurledMediaItem, messageId: string, batchId
}
const cloneRespBody = (await cloneResponse.json()) as { success: boolean; new_path: string };
const realAtt = Attachment.create({
filename: attEnt.userFilename,
url: `${Config.get().cdn.endpointPublic}/${cloneRespBody.new_path}`,
proxy_url: `${Config.get().cdn.endpointPublic}/${cloneRespBody.new_path}`,
size: attEnt.size,
height: attEnt.height,
width: attEnt.width,
content_type: attEnt.contentType || attEnt.userOriginalContentType,
});
await realAtt.save();
//TODO maybe this needs to be a new DB object? I don't see a reason to do this rn though, though this id *should* technically be different from the id of the attachment
media.id = attEnt.id;
media.id = realAtt.id;
media.proxy_url = `${Config.get().cdn.endpointPublic}/${cloneRespBody.new_path}`;
if (url.protocol !== "attachment") media.url = media.proxy_url;
media.height = attEnt.height;

View File

@@ -352,6 +352,17 @@ async function consume(this: WebSocket, opts: EventOpts) {
userAgent: this.userAgent,
}),
).attachments;
if (data["components"]) {
data["components"] = (
await Message.prototype.withSignedComponents.call(
data,
new NewUrlUserSignatureData({
ip: this.ipAddress,
userAgent: this.userAgent,
}),
)
).components;
}
break;
default:
break;

View File

@@ -29,7 +29,18 @@ import { Webhook } from "./Webhook";
import { Sticker } from "./Sticker";
import { Attachment } from "./Attachment";
import { NewUrlUserSignatureData } from "../Signing";
import { ApplicationCommandType, BaseMessageComponents, Embed, MessageSnapshot, MessageType, PartialMessage, Poll, Reaction } from "@spacebar/schemas";
import {
ApplicationCommandType,
BaseMessageComponents,
Embed,
MessageComponentType,
MessageSnapshot,
MessageType,
PartialMessage,
Poll,
Reaction,
UnfurledMediaItem,
} from "@spacebar/schemas";
import { MessageFlags } from "@spacebar/util";
import { JsonRemoveEmpty } from "../util/Decorators";
@@ -304,6 +315,55 @@ export class Message extends BaseClass {
attachments: this.attachments?.map((attachment: Attachment) => Attachment.prototype.signUrls.call(attachment, data)),
};
}
async withSignedComponents(data: NewUrlUserSignatureData) {
if (!this.components || !(this.flags & Number(MessageFlags.FLAGS.IS_COMPONENTS_V2))) return { ...this };
function signMedia(media: UnfurledMediaItem) {
Object.assign(media, Attachment.prototype.signUrls.call(media, data));
}
return {
...this,
components: this.components.map((comp) => {
comp = structuredClone(comp);
if (comp.type === MessageComponentType.Section) {
const accessory = comp.accessory;
if (accessory.type === MessageComponentType.Thumbnail) {
signMedia(accessory.media);
}
} else if (comp.type === MessageComponentType.MediaGallery) {
comp.items.forEach(({ media }) => signMedia(media));
} else if (comp.type === MessageComponentType.File) {
signMedia(comp.file);
} else if (comp.type === MessageComponentType.Container) {
for (const elm of comp.components) {
switch (elm.type) {
case MessageComponentType.Separator:
case MessageComponentType.TextDisplay:
case MessageComponentType.ActionRow:
break;
case MessageComponentType.Section: {
const accessory = elm.accessory;
if (accessory.type === MessageComponentType.Thumbnail) {
signMedia(accessory.media);
}
break;
}
case MessageComponentType.MediaGallery:
elm.items.forEach(({ media }) => signMedia(media));
break;
case MessageComponentType.File: {
signMedia(elm.file);
break;
}
default:
elm satisfies never;
}
}
}
return comp;
}),
};
}
static async createWithDefaults(opts: Partial<Message>): Promise<Message> {
const message = Message.create();