Merge pull request #4614 from Infisical/feat/send-email-confirmation-on-account-deletion

feat: Adds account deletion confirmation email
This commit is contained in:
Piyush Gupta
2025-10-06 23:20:17 +05:30
committed by GitHub
4 changed files with 59 additions and 2 deletions

View File

@@ -0,0 +1,36 @@
import { Heading, Section, Text } from "@react-email/components";
import React from "react";
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
interface AccountDeletionConfirmationTemplateProps
extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
email: string;
}
export const AccountDeletionConfirmationTemplate = ({ email, siteUrl }: AccountDeletionConfirmationTemplateProps) => {
return (
<BaseEmailWrapper
title="Your Infisical Account Has Been Deleted"
preview="Confirmation that your account and associated data have been deleted."
siteUrl={siteUrl}
>
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
Account Deleted
</Heading>
<Section className="px-[24px] mt-[20px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
<Text className="text-[14px]">
This email confirms that your Infisical account <strong>{email}</strong> has been deleted, including all
associated data.
</Text>
</Section>
</BaseEmailWrapper>
);
};
export default AccountDeletionConfirmationTemplate;
AccountDeletionConfirmationTemplate.PreviewProps = {
email: "test@infisical.com",
siteUrl: "https://infisical.com"
} as AccountDeletionConfirmationTemplateProps;

View File

@@ -1,5 +1,6 @@
export * from "./AccessApprovalRequestTemplate";
export * from "./AccessApprovalRequestUpdatedTemplate";
export * from "./AccountDeletionConfirmationTemplate";
export * from "./EmailMfaTemplate";
export * from "./EmailVerificationTemplate";
export * from "./ExternalImportFailedTemplate";

View File

@@ -9,6 +9,7 @@ import { logger } from "@app/lib/logger";
import {
AccessApprovalRequestTemplate,
AccessApprovalRequestUpdatedTemplate,
AccountDeletionConfirmationTemplate,
EmailMfaTemplate,
EmailVerificationTemplate,
ExternalImportFailedTemplate,
@@ -83,7 +84,8 @@ export enum SmtpTemplates {
OrgAdminBreakglassAccess = "orgAdminBreakglassAccess",
ServiceTokenExpired = "serviceTokenExpired",
SecretScanningV2ScanFailed = "secretScanningV2ScanFailed",
SecretScanningV2SecretsDetected = "secretScanningV2SecretsDetected"
SecretScanningV2SecretsDetected = "secretScanningV2SecretsDetected",
AccountDeletionConfirmation = "accountDeletionConfirmation"
}
export enum SmtpHost {
@@ -128,7 +130,8 @@ const EmailTemplateMap: Record<SmtpTemplates, React.FC<any>> = {
[SmtpTemplates.SetupPassword]: PasswordSetupTemplate,
[SmtpTemplates.PkiExpirationAlert]: PkiExpirationAlertTemplate,
[SmtpTemplates.SecretScanningV2ScanFailed]: SecretScanningScanFailedTemplate,
[SmtpTemplates.SecretScanningV2SecretsDetected]: SecretScanningSecretsDetectedTemplate
[SmtpTemplates.SecretScanningV2SecretsDetected]: SecretScanningSecretsDetectedTemplate,
[SmtpTemplates.AccountDeletionConfirmation]: AccountDeletionConfirmationTemplate
};
export const smtpServiceFactory = (cfg: TSmtpConfig) => {

View File

@@ -347,6 +347,23 @@ export const userServiceFactory = ({
const deleteUser = async (userId: string) => {
const user = await userDAL.deleteById(userId);
try {
if (user?.email) {
// Send email to user to confirm account deletion
await smtpService.sendMail({
template: SmtpTemplates.AccountDeletionConfirmation,
subjectLine: "Your Infisical account has been deleted",
recipients: [user.email],
substitutions: {
email: user.email
}
});
}
} catch (error) {
logger.error(error, `Failed to send account deletion confirmation email to ${user.email}`);
}
return user;
};