diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index c845de988..feff0c9a6 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -645,7 +645,8 @@ export const registerRoutes = async ( const webhookService = webhookServiceFactory({ permissionService, webhookDAL, - projectEnvDAL + projectEnvDAL, + projectDAL }); const secretTagService = secretTagServiceFactory({ secretTagDAL, permissionService }); diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index afcb3a6bd..0f0645f58 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -642,7 +642,7 @@ export const secretQueueFactory = ({ }); queueService.start(QueueName.SecretWebhook, async (job) => { - await fnTriggerWebhook({ ...job.data, projectEnvDAL, webhookDAL }); + await fnTriggerWebhook({ ...job.data, projectEnvDAL, webhookDAL, projectDAL }); }); return { diff --git a/backend/src/services/webhook/webhook-fns.ts b/backend/src/services/webhook/webhook-fns.ts index 2439c7d65..4690edba9 100644 --- a/backend/src/services/webhook/webhook-fns.ts +++ b/backend/src/services/webhook/webhook-fns.ts @@ -9,6 +9,7 @@ import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption"; import { BadRequestError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; +import { TProjectDALFactory } from "../project/project-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TWebhookDALFactory } from "./webhook-dal"; import { WebhookType } from "./webhook-types"; @@ -66,11 +67,16 @@ export const triggerWebhookRequest = async (webhook: TWebhooks, data: Record { + const { workspaceName, workspaceId, environment, secretPath, type } = details; + switch (type) { case WebhookType.SLACK: return { @@ -80,8 +86,8 @@ export const getWebhookPayload = ( color: "#E7F256", fields: [ { - title: "Workspace ID", - value: workspaceId, + title: "Project", + value: workspaceName, short: false }, { @@ -117,7 +123,9 @@ export type TFnTriggerWebhookDTO = { environment: string; webhookDAL: Pick; projectEnvDAL: Pick; + projectDAL: Pick; }; + // this is reusable function // used in secret queue to trigger webhook and update status when secrets changes export const fnTriggerWebhook = async ({ @@ -125,7 +133,8 @@ export const fnTriggerWebhook = async ({ secretPath, projectId, webhookDAL, - projectEnvDAL + projectEnvDAL, + projectDAL }: TFnTriggerWebhookDTO) => { const webhooks = await webhookDAL.findAllWebhooks(projectId, environment); const toBeTriggeredHooks = webhooks.filter( @@ -134,9 +143,19 @@ export const fnTriggerWebhook = async ({ ); if (!toBeTriggeredHooks.length) return; logger.info("Secret webhook job started", { environment, secretPath, projectId }); + const project = await projectDAL.findById(projectId); const webhooksTriggered = await Promise.allSettled( toBeTriggeredHooks.map((hook) => - triggerWebhookRequest(hook, getWebhookPayload("secrets.modified", projectId, environment, secretPath, hook.type)) + triggerWebhookRequest( + hook, + getWebhookPayload("secrets.modified", { + workspaceName: project.name, + workspaceId: projectId, + environment, + secretPath, + type: hook.type + }) + ) ) ); diff --git a/backend/src/services/webhook/webhook-service.ts b/backend/src/services/webhook/webhook-service.ts index 272c9de90..41dacd34b 100644 --- a/backend/src/services/webhook/webhook-service.ts +++ b/backend/src/services/webhook/webhook-service.ts @@ -6,6 +6,7 @@ import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { BadRequestError } from "@app/lib/errors"; +import { TProjectDALFactory } from "../project/project-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TWebhookDALFactory } from "./webhook-dal"; import { decryptWebhookDetails, getWebhookPayload, triggerWebhookRequest } from "./webhook-fns"; @@ -20,12 +21,18 @@ import { type TWebhookServiceFactoryDep = { webhookDAL: TWebhookDALFactory; projectEnvDAL: TProjectEnvDALFactory; + projectDAL: Pick; permissionService: Pick; }; export type TWebhookServiceFactory = ReturnType; -export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionService }: TWebhookServiceFactoryDep) => { +export const webhookServiceFactory = ({ + webhookDAL, + projectEnvDAL, + permissionService, + projectDAL +}: TWebhookServiceFactoryDep) => { const createWebhook = async ({ actor, actorId, @@ -124,13 +131,21 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); + const project = await projectDAL.findById(webhook.projectId); + + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); let webhookError: string | undefined; try { await triggerWebhookRequest( webhook, - getWebhookPayload("test", webhook.projectId, webhook.environment.slug, webhook.secretPath, webhook.type) + getWebhookPayload("test", { + workspaceName: project.name, + workspaceId: webhook.projectId, + environment: webhook.environment.slug, + secretPath: webhook.secretPath, + type: webhook.type + }) ); } catch (err) { webhookError = (err as Error).message;