diff --git a/apps/api/src/controllers/Contacts.ts b/apps/api/src/controllers/Contacts.ts index 382b2d2..6e662c1 100644 --- a/apps/api/src/controllers/Contacts.ts +++ b/apps/api/src/controllers/Contacts.ts @@ -315,6 +315,7 @@ export class Contacts { @Middleware([requireAuth, requireEmailVerified]) @CatchAsync public async getImportStatus(req: Request, res: Response, _next: NextFunction) { + const auth = res.locals.auth; const jobId = req.params.jobId; if (!jobId) { @@ -322,7 +323,7 @@ export class Contacts { } try { - const status = await QueueService.getImportJobStatus(jobId); + const status = await QueueService.getImportJobStatus(jobId, auth.projectId!); if (!status) { return res.status(404).json({error: 'Import job not found'}); @@ -502,6 +503,7 @@ export class Contacts { @Middleware([requireAuth, requireEmailVerified]) @CatchAsync public async getBulkActionStatus(req: Request, res: Response, _next: NextFunction) { + const auth = res.locals.auth; const jobId = req.params.jobId; if (!jobId) { @@ -509,7 +511,7 @@ export class Contacts { } try { - const status = await QueueService.getBulkActionJobStatus(jobId); + const status = await QueueService.getBulkActionJobStatus(jobId, auth.projectId!); if (!status) { return res.status(404).json({error: 'Bulk action job not found'}); diff --git a/apps/api/src/services/QueueService.ts b/apps/api/src/services/QueueService.ts index f1c1d92..89ddf12 100644 --- a/apps/api/src/services/QueueService.ts +++ b/apps/api/src/services/QueueService.ts @@ -282,14 +282,22 @@ export class QueueService { /** * Get import job status and progress + * @param jobId - The job ID + * @param projectId - The project ID to verify authorization + * @returns Job status or null if not found or unauthorized */ - public static async getImportJobStatus(jobId: string) { + public static async getImportJobStatus(jobId: string, projectId: string) { const job = await importQueue.getJob(jobId); if (!job) { return null; } + // Security: Verify that the job belongs to the requesting project + if (job.data.projectId !== projectId) { + return null; + } + const state = await job.getState(); const progress = job.progress; const returnValue = job.returnvalue; @@ -324,14 +332,22 @@ export class QueueService { /** * Get bulk action job status and progress + * @param jobId - The job ID + * @param projectId - The project ID to verify authorization + * @returns Job status or null if not found or unauthorized */ - public static async getBulkActionJobStatus(jobId: string) { + public static async getBulkActionJobStatus(jobId: string, projectId: string) { const job = await bulkContactQueue.getJob(jobId); if (!job) { return null; } + // Security: Verify that the job belongs to the requesting project + if (job.data.projectId !== projectId) { + return null; + } + const state = await job.getState(); const progress = job.progress; const returnValue = job.returnvalue;