mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 13:26:31 +00:00
feat(notifications): secret scan alert notifications
This commit is contained in:
@@ -21,6 +21,8 @@ import { decryptAppConnection } from "@app/services/app-connection/app-connectio
|
|||||||
import { TAppConnection } from "@app/services/app-connection/app-connection-types";
|
import { TAppConnection } from "@app/services/app-connection/app-connection-types";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
|
import { TNotificationServiceFactory } from "@app/services/notification/notification-service";
|
||||||
|
import { NotificationType } from "@app/services/notification/notification-types";
|
||||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||||
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
||||||
import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
|
import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
|
||||||
@@ -52,6 +54,7 @@ type TSecretRotationV2QueueServiceFactoryDep = {
|
|||||||
appConnectionDAL: Pick<TAppConnectionDALFactory, "updateById">;
|
appConnectionDAL: Pick<TAppConnectionDALFactory, "updateById">;
|
||||||
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
|
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
|
||||||
keyStore: Pick<TKeyStoreFactory, "acquireLock" | "getItem">;
|
keyStore: Pick<TKeyStoreFactory, "acquireLock" | "getItem">;
|
||||||
|
notificationService: Pick<TNotificationServiceFactory, "createUserNotifications">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TSecretScanningV2QueueServiceFactory = Awaited<ReturnType<typeof secretScanningV2QueueServiceFactory>>;
|
export type TSecretScanningV2QueueServiceFactory = Awaited<ReturnType<typeof secretScanningV2QueueServiceFactory>>;
|
||||||
@@ -65,7 +68,8 @@ export const secretScanningV2QueueServiceFactory = async ({
|
|||||||
kmsService,
|
kmsService,
|
||||||
auditLogService,
|
auditLogService,
|
||||||
keyStore,
|
keyStore,
|
||||||
appConnectionDAL
|
appConnectionDAL,
|
||||||
|
notificationService
|
||||||
}: TSecretRotationV2QueueServiceFactoryDep) => {
|
}: TSecretRotationV2QueueServiceFactoryDep) => {
|
||||||
const queueDataSourceFullScan = async (
|
const queueDataSourceFullScan = async (
|
||||||
dataSource: TSecretScanningDataSourceWithConnection,
|
dataSource: TSecretScanningDataSourceWithConnection,
|
||||||
@@ -592,16 +596,38 @@ export const secretScanningV2QueueServiceFactory = async ({
|
|||||||
|
|
||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
|
|
||||||
|
const subjectLine =
|
||||||
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
|
? "Incident Alert: Secret(s) Leaked"
|
||||||
|
: `Secret Scanning Failed`;
|
||||||
|
|
||||||
|
await notificationService.createUserNotifications(
|
||||||
|
recipients.map((member) => ({
|
||||||
|
userId: member.userId,
|
||||||
|
orgId: project.orgId,
|
||||||
|
type:
|
||||||
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
|
? NotificationType.SECRET_SCANNING_SECRETS_DETECTED
|
||||||
|
: NotificationType.SECRET_SCANNING_SCAN_FAILED,
|
||||||
|
title: subjectLine,
|
||||||
|
body:
|
||||||
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
|
? `Uncovered **${payload.numberOfSecrets}** secret(s) ${payload.isDiffScan ? " from a recent commit to" : " in"} **${resourceName}**.`
|
||||||
|
: `Encountered an error while attempting to scan the resource **${resourceName}**: ${payload.errorMessage}`,
|
||||||
|
link:
|
||||||
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
|
? `/projects/secret-scanning/${projectId}/findings?search=scanId:${payload.scanId}`
|
||||||
|
: `/projects/secret-scanning/${projectId}/data-sources/${dataSource.type}/${dataSource.id}`
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
await smtpService.sendMail({
|
await smtpService.sendMail({
|
||||||
recipients: recipients.map((member) => member.user.email!).filter(Boolean),
|
recipients: recipients.map((member) => member.user.email!).filter(Boolean),
|
||||||
template:
|
template:
|
||||||
payload.status === SecretScanningScanStatus.Completed
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
? SmtpTemplates.SecretScanningV2SecretsDetected
|
? SmtpTemplates.SecretScanningV2SecretsDetected
|
||||||
: SmtpTemplates.SecretScanningV2ScanFailed,
|
: SmtpTemplates.SecretScanningV2ScanFailed,
|
||||||
subjectLine:
|
subjectLine,
|
||||||
payload.status === SecretScanningScanStatus.Completed
|
|
||||||
? "Incident Alert: Secret(s) Leaked"
|
|
||||||
: `Secret Scanning Failed`,
|
|
||||||
substitutions:
|
substitutions:
|
||||||
payload.status === SecretScanningScanStatus.Completed
|
payload.status === SecretScanningScanStatus.Completed
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -2030,7 +2030,8 @@ export const registerRoutes = async (
|
|||||||
smtpService,
|
smtpService,
|
||||||
kmsService,
|
kmsService,
|
||||||
keyStore,
|
keyStore,
|
||||||
appConnectionDAL
|
appConnectionDAL,
|
||||||
|
notificationService
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretScanningV2Service = secretScanningV2ServiceFactory({
|
const secretScanningV2Service = secretScanningV2ServiceFactory({
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ export enum NotificationType {
|
|||||||
ACCESS_POLICY_BYPASSED = "access-policy-bypassed",
|
ACCESS_POLICY_BYPASSED = "access-policy-bypassed",
|
||||||
SECRET_CHANGE_REQUEST = "secret-change-request",
|
SECRET_CHANGE_REQUEST = "secret-change-request",
|
||||||
SECRET_CHANGE_POLICY_BYPASSED = "secret-change-policy-bypassed",
|
SECRET_CHANGE_POLICY_BYPASSED = "secret-change-policy-bypassed",
|
||||||
SECRET_ROTATION_FAILED = "secret-rotation-failed"
|
SECRET_ROTATION_FAILED = "secret-rotation-failed",
|
||||||
|
SECRET_SCANNING_SECRETS_DETECTED = "secret-scanning-secrets-detected",
|
||||||
|
SECRET_SCANNING_SCAN_FAILED = "secret-scanning-scan-failed"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TCreateUserNotificationDTO {
|
export interface TCreateUserNotificationDTO {
|
||||||
|
|||||||
Reference in New Issue
Block a user