diff --git a/backend/src/queues/reminders/sendSecretReminders.ts b/backend/src/queues/reminders/sendSecretReminders.ts index 50bede959..b593dd633 100644 --- a/backend/src/queues/reminders/sendSecretReminders.ts +++ b/backend/src/queues/reminders/sendSecretReminders.ts @@ -1,38 +1,54 @@ import Queue, { Job } from "bull"; -import { Secret, Workspace } from "../../models"; +import { IUser, Membership, Organization, Workspace } from "../../models"; import { Types } from "mongoose"; - +import { sendMail } from "../../helpers"; type TSendSecretReminders = { - workspaceId: string - secretId: string - cron: string - note: string | undefined | null -} + workspaceId: string; + secretId: string; + cron: string; + note: string | undefined | null; +}; type TDeleteSecretReminder = { - secretId: string - cron: string -} + secretId: string; + cron: string; +}; -export const sendSecretReminders = new Queue("send-secret-reminders", process.env.REDIS_URL as string); +export const sendSecretReminders = new Queue( + "send-secret-reminders", + process.env.REDIS_URL as string +); + +sendSecretReminders.process(async (job: Job) => { + const { workspaceId }: TSendSecretReminders = job.data; -sendSecretReminders.process(async (job: Job) => { - const { workspaceId, secretId }: TSendSecretReminders = job.data - const secret = await Secret.findById(new Types.ObjectId(secretId)); const workspace = await Workspace.findById(new Types.ObjectId(workspaceId)); + const organization = await Organization.findById(new Types.ObjectId(workspace?.organization)); - - if(!workspace || !secret) { - throw new Error("Workspace or secret not found") + if (!workspace) { + throw new Error("Workspace for reminder not found"); + } + if (!organization) { + throw new Error("Organization for reminder not found"); } + const memberships = await Membership.find({ + workspace: workspaceId + // We need to get the user and organization data for each membership. + }).populate<{ user: IUser }>("user"); - // Send email stuff here - - - -}) + await sendMail({ + template: "secretReminder.handlebars", + subjectLine: "Infisical secret reminder", + recipients: [...memberships.map((membership) => membership.user.email)], + substitutions: { + reminderNote: job.data.note, // May not exist. + workspaceName: workspace.name, + organizationName: organization.name + } + }); +}); export const createSecretReminderCron = (jobDetails: TSendSecretReminders) => { return sendSecretReminders.add(jobDetails, { @@ -40,21 +56,23 @@ export const createSecretReminderCron = (jobDetails: TSendSecretReminders) => { cron: jobDetails.cron }, jobId: `reminder-${jobDetails.secretId}`, - - }) -} + removeOnComplete: true, + removeOnFail: { + count: 20 + } + }); +}; export const deleteSecretReminderCron = (jobDetails: TDeleteSecretReminder) => { - return sendSecretReminders.removeRepeatable({ cron: jobDetails.cron, - "jobId": `reminder-${jobDetails.secretId}`, - }) -} + jobId: `reminder-${jobDetails.secretId}` + }); +}; export const updateSecretReminderCron = async (jobDetails: TSendSecretReminders) => { // We need to delete the potentially existing cron job first, or the new one won't be created. - await deleteSecretReminderCron(jobDetails) + await deleteSecretReminderCron(jobDetails); - await createSecretReminderCron(jobDetails) -} + await createSecretReminderCron(jobDetails); +};