@@ -12,7 +12,7 @@ import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponse
1212import { isSupportedMediaContentType } from '@pkgs/mime_utils/src/ContentTypeUtils' ;
1313import type { IVirusScanService } from '@pkgs/virus_scan/src/IVirusScanService' ;
1414import { temporaryFile } from 'tempy' ;
15- import { createAttachmentID } from '../../../BrandedTypes' ;
15+ import { createAttachmentID , type UserID } from '../../../BrandedTypes' ;
1616import { Config } from '../../../Config' ;
1717import type { MessageAttachment } from '../../../database/types/MessageTypes' ;
1818import { contentModerationService , type ModerationContext } from '../../../infrastructure/ContentModerationService' ;
@@ -54,6 +54,7 @@ interface ProcessAttachmentParams {
5454 message : Message ;
5555 attachment : AttachmentToProcess ;
5656 index : number ;
57+ uploadUserId : UserID ;
5758 channel ?: Channel ;
5859 guild ?: GuildResponse | null ;
5960 member ?: GuildMemberResponse | null ;
@@ -88,6 +89,7 @@ export class AttachmentProcessingService {
8889 async computeAttachments ( params : {
8990 message : Message ;
9091 attachments : Array < AttachmentToProcess > ;
92+ uploadUserId : UserID ;
9193 channel ?: Channel ;
9294 guild ?: GuildResponse | null ;
9395 member ?: GuildMemberResponse | null ;
@@ -105,6 +107,7 @@ export class AttachmentProcessingService {
105107 message : params . message ,
106108 attachment,
107109 index,
110+ uploadUserId : params . uploadUserId ,
108111 channel : params . channel ,
109112 guild : params . guild ,
110113 member : params . member ,
@@ -132,26 +135,30 @@ export class AttachmentProcessingService {
132135 }
133136 } ) ,
134137 ) ;
135- await Promise . all (
136- results . map ( async ( result ) => {
137- const bound = await this . attachmentUploadTraceRepository . bindAttachment (
138+ const bindingResults = await Promise . all (
139+ results . map ( async ( result , index ) => ( {
140+ index,
141+ result,
142+ bound : await this . attachmentUploadTraceRepository . bindAttachment (
138143 result . copyOperation . sourceKey ,
139144 result . attachment . attachment_id ,
140- ) ;
141- if ( ! bound ) {
142- Logger . warn (
143- {
144- attachmentId : result . attachment . attachment_id . toString ( ) ,
145- uploadKey : result . copyOperation . sourceKey ,
146- } ,
147- 'Missing attachment upload trace while binding processed attachment' ,
148- ) ;
149- }
150- } ) ,
145+ ) ,
146+ } ) ) ,
151147 ) ;
152148 for ( const result of results ) {
153149 void this . deleteUploadObject ( result . copyOperation . sourceBucket , result . copyOperation . sourceKey ) ;
154150 }
151+ const unboundResult = bindingResults . find ( ( { bound} ) => bound === null ) ;
152+ if ( unboundResult ) {
153+ for ( const result of results ) {
154+ this . deleteUploadObject ( result . copyOperation . destinationBucket , result . copyOperation . destinationKey ) ;
155+ }
156+ throw InputValidationError . fromCode (
157+ `attachments.${ unboundResult . index } .upload_filename` ,
158+ ValidationErrorCodes . UPLOADED_ATTACHMENT_NOT_FOUND ,
159+ { filename : unboundResult . result . attachment . filename } ,
160+ ) ;
161+ }
155162 const processedAttachments : Array < MessageAttachment > = results . map ( ( result , index ) => {
156163 const finalObject = copyResults [ index ] ;
157164 if ( result . applyFinalObjectMetadata && finalObject ) {
@@ -171,6 +178,18 @@ export class AttachmentProcessingService {
171178
172179 private async processAttachment ( params : ProcessAttachmentParams ) : Promise < ProcessedAttachment > {
173180 const { message, attachment, index, nsfwMode} = params ;
181+ const pendingUpload = await this . attachmentUploadTraceRepository . getPendingUpload ( {
182+ uploadKey : attachment . upload_filename ,
183+ userId : params . uploadUserId ,
184+ channelId : message . channelId ,
185+ } ) ;
186+ if ( ! pendingUpload ) {
187+ throw InputValidationError . fromCode (
188+ `attachments.${ index } .upload_filename` ,
189+ ValidationErrorCodes . UPLOADED_ATTACHMENT_NOT_FOUND ,
190+ { filename : attachment . filename } ,
191+ ) ;
192+ }
174193 const uploadedFile = await this . storageService . getObjectMetadata (
175194 Config . s3 . buckets . uploads ,
176195 attachment . upload_filename ,
0 commit comments