From 4a55ecbe129ab5462dd086c987c51309ab555d25 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Wed, 30 Jul 2025 18:14:35 -0700 Subject: [PATCH 1/2] improvement: simplify email design, refactor link/button to re-usable components and improve design --- .../emails/AccessApprovalRequestTemplate.tsx | 24 ++++++---------- .../src/services/smtp/emails/BaseButton.tsx | 17 +++++++++++ .../services/smtp/emails/BaseEmailWrapper.tsx | 20 ++++++------- backend/src/services/smtp/emails/BaseLink.tsx | 15 ++++++++++ .../services/smtp/emails/EmailMfaTemplate.tsx | 9 ++---- .../smtp/emails/EmailVerificationTemplate.tsx | 8 ++---- .../emails/ExternalImportFailedTemplate.tsx | 10 +++---- .../emails/IntegrationSyncFailedTemplate.tsx | 16 ++++------- .../smtp/emails/NewDeviceLoginTemplate.tsx | 7 ++--- .../OrgAdminBreakglassAccessTemplate.tsx | 8 ++---- .../OrgAdminProjectGrantAccessTemplate.tsx | 5 ++-- .../emails/OrganizationInvitationTemplate.tsx | 19 ++++++------- .../smtp/emails/PasswordResetTemplate.tsx | 20 +++++-------- .../smtp/emails/PasswordSetupTemplate.tsx | 15 +++++----- .../emails/ProjectAccessRequestTemplate.tsx | 23 ++++++--------- .../smtp/emails/ProjectInvitationTemplate.tsx | 14 ++++------ .../emails/ScimUserProvisionedTemplate.tsx | 14 ++++------ .../SecretApprovalRequestBypassedTemplate.tsx | 22 ++++++--------- ...cretApprovalRequestNeedsReviewTemplate.tsx | 14 ++++------ .../emails/SecretLeakIncidentTemplate.tsx | 28 ++++++------------- .../emails/SecretRequestCompletedTemplate.tsx | 14 ++++------ .../emails/SecretRotationFailedTemplate.tsx | 16 +++++------ .../SecretScanningScanFailedTemplate.tsx | 16 ++++------- .../SecretScanningSecretsDetectedTemplate.tsx | 28 ++++++------------- .../smtp/emails/SecretSyncFailedTemplate.tsx | 16 ++++------- .../ServiceTokenExpiryNoticeTemplate.tsx | 14 ++++------ .../SignupEmailVerificationTemplate.tsx | 8 ++---- .../smtp/emails/UnlockAccountTemplate.tsx | 14 ++++------ 28 files changed, 184 insertions(+), 250 deletions(-) create mode 100644 backend/src/services/smtp/emails/BaseButton.tsx create mode 100644 backend/src/services/smtp/emails/BaseLink.tsx diff --git a/backend/src/services/smtp/emails/AccessApprovalRequestTemplate.tsx b/backend/src/services/smtp/emails/AccessApprovalRequestTemplate.tsx index fef072546..bdefc8b86 100644 --- a/backend/src/services/smtp/emails/AccessApprovalRequestTemplate.tsx +++ b/backend/src/services/smtp/emails/AccessApprovalRequestTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface AccessApprovalRequestTemplateProps extends Omit { projectName: string; @@ -38,18 +40,15 @@ export const AccessApprovalRequestTemplate = ({ You have a new access approval request pending review for the project {projectName} -
+
- {requesterFullName} ( - - {requesterEmail} - - ) has requested {isTemporary ? "temporary" : "permanent"} access to {secretPath} in the{" "} + {requesterFullName} ({requesterEmail}) + has requested {isTemporary ? "temporary" : "permanent"} access to {secretPath} in the{" "} {environment} environment. {isTemporary && ( - + This access will expire {expiresIn} after approval. )} @@ -67,13 +66,8 @@ export const AccessApprovalRequestTemplate = ({ )}
-
- +
+ Review Request
); diff --git a/backend/src/services/smtp/emails/BaseButton.tsx b/backend/src/services/smtp/emails/BaseButton.tsx new file mode 100644 index 000000000..8fa20ce22 --- /dev/null +++ b/backend/src/services/smtp/emails/BaseButton.tsx @@ -0,0 +1,17 @@ +import { Button } from "@react-email/components"; + +type Props = { + href: string; + children: string; +}; + +export const BaseButton = ({ href, children }: Props) => { + return ( + + ); +}; diff --git a/backend/src/services/smtp/emails/BaseEmailWrapper.tsx b/backend/src/services/smtp/emails/BaseEmailWrapper.tsx index 01bf779c5..d6312bbfd 100644 --- a/backend/src/services/smtp/emails/BaseEmailWrapper.tsx +++ b/backend/src/services/smtp/emails/BaseEmailWrapper.tsx @@ -16,23 +16,21 @@ export const BaseEmailWrapper = ({ title, preview, children, siteUrl }: BaseEmai {preview} -
-
-
- Infisical Logo -
+
+ Infisical Logo
+
{children}

Email sent via{" "} - + Infisical diff --git a/backend/src/services/smtp/emails/BaseLink.tsx b/backend/src/services/smtp/emails/BaseLink.tsx new file mode 100644 index 000000000..f2a8763e6 --- /dev/null +++ b/backend/src/services/smtp/emails/BaseLink.tsx @@ -0,0 +1,15 @@ +import { Link } from "@react-email/components"; +import React from "react"; + +type Props = { + href: string; + children: string; +}; + +export const BaseLink = ({ href, children }: Props) => { + return ( + + {children} + + ); +}; diff --git a/backend/src/services/smtp/emails/EmailMfaTemplate.tsx b/backend/src/services/smtp/emails/EmailMfaTemplate.tsx index b01e2f8af..a5d1fdf03 100644 --- a/backend/src/services/smtp/emails/EmailMfaTemplate.tsx +++ b/backend/src/services/smtp/emails/EmailMfaTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface EmailMfaTemplateProps extends Omit { code: string; @@ -25,11 +26,7 @@ export const EmailMfaTemplate = ({ code, siteUrl, isCloud }: EmailMfaTemplatePro Not you?{" "} {isCloud ? ( <> - Contact us at{" "} - - support@infisical.com - {" "} - immediately + Contact us at support@infisical.com immediately ) : ( "Contact your administrator immediately" diff --git a/backend/src/services/smtp/emails/EmailVerificationTemplate.tsx b/backend/src/services/smtp/emails/EmailVerificationTemplate.tsx index fc32b01b0..313601e6a 100644 --- a/backend/src/services/smtp/emails/EmailVerificationTemplate.tsx +++ b/backend/src/services/smtp/emails/EmailVerificationTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface EmailVerificationTemplateProps extends Omit { code: string; @@ -29,10 +30,7 @@ export const EmailVerificationTemplate = ({ code, siteUrl, isCloud }: EmailVerif Questions about Infisical?{" "} {isCloud ? ( <> - Email us at{" "} - - support@infisical.com - + Email us at support@infisical.com ) : ( "Contact your administrator" diff --git a/backend/src/services/smtp/emails/ExternalImportFailedTemplate.tsx b/backend/src/services/smtp/emails/ExternalImportFailedTemplate.tsx index 3cca41721..28bccc9d5 100644 --- a/backend/src/services/smtp/emails/ExternalImportFailedTemplate.tsx +++ b/backend/src/services/smtp/emails/ExternalImportFailedTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface ExternalImportFailedTemplateProps extends Omit { error: string; @@ -21,12 +22,9 @@ export const ExternalImportFailedTemplate = ({ error, siteUrl, provider }: Exter If your issue persists, you can contact the Infisical team at{" "} - - support@infisical.com - - . + support@infisical.com. - + Error: "{error}"
diff --git a/backend/src/services/smtp/emails/IntegrationSyncFailedTemplate.tsx b/backend/src/services/smtp/emails/IntegrationSyncFailedTemplate.tsx index c2fb78ae0..3263d4928 100644 --- a/backend/src/services/smtp/emails/IntegrationSyncFailedTemplate.tsx +++ b/backend/src/services/smtp/emails/IntegrationSyncFailedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface IntegrationSyncFailedTemplateProps extends Omit { @@ -30,7 +31,7 @@ export const IntegrationSyncFailedTemplate = ({ {count} integration(s) failed to sync -
+
Project {projectName} Environment @@ -38,15 +39,10 @@ export const IntegrationSyncFailedTemplate = ({ Secret Path {secretPath} Failure Reason: - "{syncMessage}" + "{syncMessage}"
-
- +
+ View Integrations
); diff --git a/backend/src/services/smtp/emails/NewDeviceLoginTemplate.tsx b/backend/src/services/smtp/emails/NewDeviceLoginTemplate.tsx index 9692bc77d..da1049096 100644 --- a/backend/src/services/smtp/emails/NewDeviceLoginTemplate.tsx +++ b/backend/src/services/smtp/emails/NewDeviceLoginTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface NewDeviceLoginTemplateProps extends Omit { email: string; @@ -42,9 +43,7 @@ export const NewDeviceLoginTemplate = ({ If you believe that this login is suspicious, please contact{" "} {isCloud ? ( - - support@infisical.com - + support@infisical.com ) : ( "your administrator" )}{" "} diff --git a/backend/src/services/smtp/emails/OrgAdminBreakglassAccessTemplate.tsx b/backend/src/services/smtp/emails/OrgAdminBreakglassAccessTemplate.tsx index 1d2ecc1a3..ee09574b6 100644 --- a/backend/src/services/smtp/emails/OrgAdminBreakglassAccessTemplate.tsx +++ b/backend/src/services/smtp/emails/OrgAdminBreakglassAccessTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface OrgAdminBreakglassAccessTemplateProps extends Omit { email: string; @@ -35,10 +36,7 @@ export const OrgAdminBreakglassAccessTemplate = ({ {userAgent} If you'd like to disable Admin SSO Bypass, please visit{" "} - - Organization Security Settings - - . + Organization Security Settings.
diff --git a/backend/src/services/smtp/emails/OrgAdminProjectGrantAccessTemplate.tsx b/backend/src/services/smtp/emails/OrgAdminProjectGrantAccessTemplate.tsx index bec22575c..1cf875d1c 100644 --- a/backend/src/services/smtp/emails/OrgAdminProjectGrantAccessTemplate.tsx +++ b/backend/src/services/smtp/emails/OrgAdminProjectGrantAccessTemplate.tsx @@ -2,6 +2,7 @@ import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface OrgAdminProjectGrantAccessTemplateProps extends Omit { email: string; @@ -24,8 +25,8 @@ export const OrgAdminProjectGrantAccessTemplate = ({
- The organization admin {email} has self-issued direct access to the project{" "} - {projectName}. + The organization admin {email} has self-issued direct access to + the project {projectName}.
diff --git a/backend/src/services/smtp/emails/OrganizationInvitationTemplate.tsx b/backend/src/services/smtp/emails/OrganizationInvitationTemplate.tsx index 27092a843..9c57548ce 100644 --- a/backend/src/services/smtp/emails/OrganizationInvitationTemplate.tsx +++ b/backend/src/services/smtp/emails/OrganizationInvitationTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface OrganizationInvitationTemplateProps extends Omit { metadata?: string; @@ -36,15 +38,13 @@ export const OrganizationInvitationTemplate = ({
{organizationName} on Infisical -
+
{inviterFirstName && inviterUsername ? ( <> {inviterFirstName} ( - - {inviterUsername} - - ) has invited you to collaborate on {organizationName}. + {inviterUsername}) has invited you to collaborate + on {organizationName}. ) : ( <> @@ -53,13 +53,12 @@ export const OrganizationInvitationTemplate = ({ )}
-
- +
diff --git a/backend/src/services/smtp/emails/PasswordResetTemplate.tsx b/backend/src/services/smtp/emails/PasswordResetTemplate.tsx index 7486b29d9..2cfa00508 100644 --- a/backend/src/services/smtp/emails/PasswordResetTemplate.tsx +++ b/backend/src/services/smtp/emails/PasswordResetTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface PasswordResetTemplateProps extends Omit { email: string; @@ -20,16 +22,13 @@ export const PasswordResetTemplate = ({ email, isCloud, siteUrl, callback_url, t Account Recovery -
+
A password reset was requested for your Infisical account. If you did not initiate this request, please contact{" "} {isCloud ? ( <> - us immediately at{" "} - - support@infisical.com - + us immediately at support@infisical.com ) : ( "your administrator immediately" @@ -37,13 +36,8 @@ export const PasswordResetTemplate = ({ email, isCloud, siteUrl, callback_url, t .
-
- +
+ Reset Password
); diff --git a/backend/src/services/smtp/emails/PasswordSetupTemplate.tsx b/backend/src/services/smtp/emails/PasswordSetupTemplate.tsx index c8a986c8c..78164bed2 100644 --- a/backend/src/services/smtp/emails/PasswordSetupTemplate.tsx +++ b/backend/src/services/smtp/emails/PasswordSetupTemplate.tsx @@ -1,6 +1,8 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Button, Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseLink } from "@app/services/smtp/emails/BaseLink"; + import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface PasswordSetupTemplateProps extends Omit { @@ -16,19 +18,16 @@ export const PasswordSetupTemplate = ({ email, isCloud, siteUrl, callback_url, t Password Setup -
+
Someone requested to set up a password for your Infisical account. - + Make sure you are already logged in to Infisical in the current browser before clicking the link below. If you did not initiate this request, please contact{" "} {isCloud ? ( <> - us immediately at{" "} - - support@infisical.com - + us immediately at support@infisical.com ) : ( "your administrator immediately" @@ -36,7 +35,7 @@ export const PasswordSetupTemplate = ({ email, isCloud, siteUrl, callback_url, t .
-
+
+
+ Grant Access
); diff --git a/backend/src/services/smtp/emails/ProjectInvitationTemplate.tsx b/backend/src/services/smtp/emails/ProjectInvitationTemplate.tsx index 1745dc8e5..2105e967a 100644 --- a/backend/src/services/smtp/emails/ProjectInvitationTemplate.tsx +++ b/backend/src/services/smtp/emails/ProjectInvitationTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface ProjectInvitationTemplateProps extends Omit { @@ -18,18 +19,13 @@ export const ProjectInvitationTemplate = ({ callback_url, workspaceName, siteUrl You've been invited to join a project on Infisical -
+
You've been invited to join the project {workspaceName}.
-
- +
+ Join Project
diff --git a/backend/src/services/smtp/emails/ScimUserProvisionedTemplate.tsx b/backend/src/services/smtp/emails/ScimUserProvisionedTemplate.tsx index bbd41818e..df60afba3 100644 --- a/backend/src/services/smtp/emails/ScimUserProvisionedTemplate.tsx +++ b/backend/src/services/smtp/emails/ScimUserProvisionedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface ScimUserProvisionedTemplateProps extends Omit { @@ -24,18 +25,13 @@ export const ScimUserProvisionedTemplate = ({
{organizationName} on Infisical -
+
You've been invited to collaborate on {organizationName}.
-
- +
+ Accept Invite
diff --git a/backend/src/services/smtp/emails/SecretApprovalRequestBypassedTemplate.tsx b/backend/src/services/smtp/emails/SecretApprovalRequestBypassedTemplate.tsx index a07110aa3..ebbbeda15 100644 --- a/backend/src/services/smtp/emails/SecretApprovalRequestBypassedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretApprovalRequestBypassedTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface SecretApprovalRequestBypassedTemplateProps extends Omit { @@ -35,13 +37,10 @@ export const SecretApprovalRequestBypassedTemplate = ({ A secret approval request has been bypassed in the project {projectName} -
+
- {requesterFullName} ( - - {requesterEmail} - - ) has {requestType === "change" ? "merged" : "accessed"} a secret {requestType === "change" ? "to" : "in"}{" "} + {requesterFullName} ({requesterEmail}) + has {requestType === "change" ? "merged" : "accessed"} a secret {requestType === "change" ? "to" : "in"}{" "} {secretPath} in the {environment} environment without obtaining the required approval. @@ -50,13 +49,8 @@ export const SecretApprovalRequestBypassedTemplate = ({ {bypassReason}"
-
- +
+ Review Bypass
); diff --git a/backend/src/services/smtp/emails/SecretApprovalRequestNeedsReviewTemplate.tsx b/backend/src/services/smtp/emails/SecretApprovalRequestNeedsReviewTemplate.tsx index b4a7c306a..000614e00 100644 --- a/backend/src/services/smtp/emails/SecretApprovalRequestNeedsReviewTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretApprovalRequestNeedsReviewTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface SecretApprovalRequestNeedsReviewTemplateProps @@ -27,20 +28,15 @@ export const SecretApprovalRequestNeedsReviewTemplate = ({ A secret approval request for the project {projectName} requires review -
+
Hello {firstName}, You have a new secret change request pending your review for the project {projectName} in the organization {organizationName}.
-
- +
+ Review Changes
); diff --git a/backend/src/services/smtp/emails/SecretLeakIncidentTemplate.tsx b/backend/src/services/smtp/emails/SecretLeakIncidentTemplate.tsx index 631013756..fa60deb11 100644 --- a/backend/src/services/smtp/emails/SecretLeakIncidentTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretLeakIncidentTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface SecretLeakIncidentTemplateProps extends Omit { numberOfSecrets: number; @@ -24,7 +26,7 @@ export const SecretLeakIncidentTemplate = ({ Infisical has uncovered {numberOfSecrets} secret(s) from a recent commit -
+
You are receiving this notification because one or more leaked secrets have been detected in a recent commit {(pusher_email || pusher_name) && ( @@ -33,11 +35,7 @@ export const SecretLeakIncidentTemplate = ({ pushed by {pusher_name ?? "Unknown Pusher"}{" "} {pusher_email && ( <> - ( - - {pusher_email} - - ) + ({pusher_email}) )} @@ -49,24 +47,16 @@ export const SecretLeakIncidentTemplate = ({ a comment in the given programming language. This will prevent future notifications from being sent out for these secrets. - + If these are production secrets, please rotate them immediately. Once you have taken action, be sure to update the status of the risk in the{" "} - - Infisical Dashboard - - . + Infisical Dashboard.
-
- +
+ View Leaked Secrets
); diff --git a/backend/src/services/smtp/emails/SecretRequestCompletedTemplate.tsx b/backend/src/services/smtp/emails/SecretRequestCompletedTemplate.tsx index 4adeec636..37e758661 100644 --- a/backend/src/services/smtp/emails/SecretRequestCompletedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretRequestCompletedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface SecretRequestCompletedTemplateProps extends Omit { @@ -20,7 +21,7 @@ export const SecretRequestCompletedTemplate = ({ A secret has been shared with you -
+
{respondentUsername ? {respondentUsername} : "Someone"} shared a secret{" "} {name && ( @@ -31,13 +32,8 @@ export const SecretRequestCompletedTemplate = ({ with you.
-
- +
+ View Secret
); diff --git a/backend/src/services/smtp/emails/SecretRotationFailedTemplate.tsx b/backend/src/services/smtp/emails/SecretRotationFailedTemplate.tsx index 52e58986d..04cc95c56 100644 --- a/backend/src/services/smtp/emails/SecretRotationFailedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretRotationFailedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface SecretRotationFailedTemplateProps extends Omit { @@ -28,7 +29,7 @@ export const SecretRotationFailedTemplate = ({ Your {rotationType} rotation {rotationName} failed to rotate -
+
Name {rotationName} Type @@ -40,15 +41,12 @@ export const SecretRotationFailedTemplate = ({ Secret Path {secretPath} Reason: - {content} + {content}
-
- +
); diff --git a/backend/src/services/smtp/emails/SecretScanningScanFailedTemplate.tsx b/backend/src/services/smtp/emails/SecretScanningScanFailedTemplate.tsx index 2e212cb82..5b56b574a 100644 --- a/backend/src/services/smtp/emails/SecretScanningScanFailedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretScanningScanFailedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface SecretScanningScanFailedTemplateProps extends Omit { @@ -30,7 +31,7 @@ export const SecretScanningScanFailedTemplate = ({ Infisical encountered an error while attempting to scan the resource {resourceName} -
+
Resource {resourceName} Data Source @@ -40,15 +41,10 @@ export const SecretScanningScanFailedTemplate = ({ Timestamp {timestamp} Error - {errorMessage} + {errorMessage}
-
- +
+ View in Infisical
); diff --git a/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx b/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx index b7c0d8a14..5211c196a 100644 --- a/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx @@ -1,7 +1,9 @@ -import { Button, Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface SecretScanningSecretsDetectedTemplateProps extends Omit { @@ -32,7 +34,7 @@ export const SecretScanningSecretsDetectedTemplate = ({ Infisical has uncovered {numberOfSecrets} secret(s) {isDiffScan ? " from a recent commit to" : " in"} {resourceName} -
+
You are receiving this notification because one or more leaked secrets have been detected {isDiffScan && " in a recent commit"} @@ -43,11 +45,7 @@ export const SecretScanningSecretsDetectedTemplate = ({ pushed by {authorName ?? "Unknown Pusher"}{" "} {authorEmail && ( <> - ( - - {authorEmail} - - ) + ({authorEmail}) )} @@ -65,24 +63,16 @@ export const SecretScanningSecretsDetectedTemplate = ({ a comment in the given programming language. This will prevent future notifications from being sent out for these secrets. - + If these are production secrets, please rotate them immediately. Once you have taken action, be sure to update the finding status in the{" "} - - Infisical Dashboard - - . + Infisical Dashboard.
-
- +
+ View Leaked Secrets
); diff --git a/backend/src/services/smtp/emails/SecretSyncFailedTemplate.tsx b/backend/src/services/smtp/emails/SecretSyncFailedTemplate.tsx index 01d909219..4abbf8f99 100644 --- a/backend/src/services/smtp/emails/SecretSyncFailedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretSyncFailedTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface SecretSyncFailedTemplateProps extends Omit { @@ -28,7 +29,7 @@ export const SecretSyncFailedTemplate = ({ Your {syncDestination} sync {syncName} failed to complete -
+
Name {syncName} Destination @@ -50,17 +51,12 @@ export const SecretSyncFailedTemplate = ({ {failureMessage && ( <> Reason: - {failureMessage} + {failureMessage} )}
-
- +
+ View in Infisical
); diff --git a/backend/src/services/smtp/emails/ServiceTokenExpiryNoticeTemplate.tsx b/backend/src/services/smtp/emails/ServiceTokenExpiryNoticeTemplate.tsx index 8f8deb63a..a4c171f86 100644 --- a/backend/src/services/smtp/emails/ServiceTokenExpiryNoticeTemplate.tsx +++ b/backend/src/services/smtp/emails/ServiceTokenExpiryNoticeTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface ServiceTokenExpiryNoticeTemplateProps extends Omit { @@ -24,20 +25,15 @@ export const ServiceTokenExpiryNoticeTemplate = ({ Service token expiry notice -
+
Your service token {tokenName} for the project {projectName} will expire within 24 hours. If this token is still needed for your workflow, please create a new one before it expires.
-
- +
+ Create New Token
); diff --git a/backend/src/services/smtp/emails/SignupEmailVerificationTemplate.tsx b/backend/src/services/smtp/emails/SignupEmailVerificationTemplate.tsx index 0a3da75f9..4c0ab133f 100644 --- a/backend/src/services/smtp/emails/SignupEmailVerificationTemplate.tsx +++ b/backend/src/services/smtp/emails/SignupEmailVerificationTemplate.tsx @@ -1,7 +1,8 @@ -import { Heading, Link, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; +import { BaseLink } from "./BaseLink"; interface SignupEmailVerificationTemplateProps extends Omit { code: string; @@ -29,10 +30,7 @@ export const SignupEmailVerificationTemplate = ({ code, siteUrl, isCloud }: Sign Questions about setting up Infisical?{" "} {isCloud ? ( <> - Email us at{" "} - - support@infisical.com - + Email us at support@infisical.com ) : ( "Contact your administrator" diff --git a/backend/src/services/smtp/emails/UnlockAccountTemplate.tsx b/backend/src/services/smtp/emails/UnlockAccountTemplate.tsx index b0b4f2086..7ec1be3f4 100644 --- a/backend/src/services/smtp/emails/UnlockAccountTemplate.tsx +++ b/backend/src/services/smtp/emails/UnlockAccountTemplate.tsx @@ -1,6 +1,7 @@ -import { Button, Heading, Section, Text } from "@react-email/components"; +import { Heading, Section, Text } from "@react-email/components"; import React from "react"; +import { BaseButton } from "./BaseButton"; import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper"; interface UnlockAccountTemplateProps extends Omit { @@ -18,19 +19,14 @@ export const UnlockAccountTemplate = ({ token, siteUrl, callback_url }: UnlockAc Unlock your Infisical account -
+
Your account has been temporarily locked due to multiple failed login attempts. If these attempts were not made by you, reset your password immediately.
-
- +
+ Unlock Account
); From 9fbdede82c0e52bcd333e2eb5588820046e6f6a8 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Fri, 1 Aug 2025 17:01:51 -0700 Subject: [PATCH 2/2] improvements: address feedback --- backend/src/services/smtp/emails/BaseEmailWrapper.tsx | 6 +++--- .../smtp/emails/SecretScanningSecretsDetectedTemplate.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/services/smtp/emails/BaseEmailWrapper.tsx b/backend/src/services/smtp/emails/BaseEmailWrapper.tsx index d6312bbfd..3e908db18 100644 --- a/backend/src/services/smtp/emails/BaseEmailWrapper.tsx +++ b/backend/src/services/smtp/emails/BaseEmailWrapper.tsx @@ -16,12 +16,12 @@ export const BaseEmailWrapper = ({ title, preview, children, siteUrl }: BaseEmai {preview} -
+
Infisical Logo

diff --git a/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx b/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx index 5211c196a..6bd4e8aa7 100644 --- a/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx +++ b/backend/src/services/smtp/emails/SecretScanningSecretsDetectedTemplate.tsx @@ -68,7 +68,7 @@ export const SecretScanningSecretsDetectedTemplate = ({ Once you have taken action, be sure to update the finding status in the{" "} - Infisical Dashboard. + Infisical Dashboard.