Skip to content

Commit aa0d72b

Browse files
committed
Add Header band, Footer with legal links, and per-template security lines to emails
1 parent 511ad32 commit aa0d72b

23 files changed

Lines changed: 271 additions & 130 deletions

File tree

application/AppGateway/appsettings.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@
165165
"HostnameKey": "App"
166166
}
167167
},
168+
"email-static-assets": {
169+
"ClusterId": "main-static",
170+
"Match": {
171+
"Path": "/email/{**catch-all}"
172+
},
173+
"Metadata": {
174+
"HostnameKey": "*"
175+
},
176+
"Transforms": [
177+
{
178+
"ResponseHeader": "Cache-Control",
179+
"Set": "public, max-age=2592000, immutable"
180+
}
181+
]
182+
},
168183
"account-federation": {
169184
"ClusterId": "account-static",
170185
"Match": {

application/account/WebApp/emails/lingui.config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ const config: LinguiConfig = {
1010
catalogs: [
1111
{
1212
path: "<rootDir>/translations/locale/{locale}",
13-
include: ["<rootDir>/templates/**/*.tsx", "<rootDir>/templates/**/*.ts"],
13+
// Include shared components so user-facing strings inside @repo/emails (e.g. <Footer>) extract
14+
// into each system's catalog. The email build only loads one system's catalog at render time,
15+
// so each system needs its own copy of any shared translations.
16+
include: [
17+
"<rootDir>/templates/**/*.tsx",
18+
"<rootDir>/templates/**/*.ts",
19+
"<rootDir>/../../../shared-webapp/emails/components/**/*.tsx",
20+
"<rootDir>/../../../shared-webapp/emails/components/**/*.ts"
21+
],
1422
exclude: ["**/node_modules/**", "**/dist/**", "**/*.d.ts"]
1523
}
1624
],

application/account/WebApp/emails/templates/InviteUser.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ export default function InviteUser({ locale }: Readonly<InviteUserProps>) {
3232
and login using <Value path="Email" sample="invitee@example.com" />.
3333
</Trans>
3434
</Text>
35+
36+
<Text className="email-muted m-[0px] mt-[16px] text-center text-[12px] leading-[20px] text-[#64748b]">
37+
<Trans>If you don't recognize the sender, you can safely ignore this email.</Trans>
38+
</Text>
3539
</TransactionalEmail>
3640
);
3741
}

application/account/WebApp/emails/templates/ResendEmailLogin.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ type ResendEmailLoginProps = {
1313

1414
export default function ResendEmailLogin({ locale }: Readonly<ResendEmailLoginProps>) {
1515
return (
16-
<TransactionalEmail locale={locale} preview="Your verification code (resend)">
16+
<TransactionalEmail
17+
locale={locale}
18+
preview="Your verification code (resend)"
19+
otpAutofill={<OtpAutofill code="OneTimePassword" domain="Domain" />}
20+
>
1721
<Subject>
1822
<Trans>Your verification code (resend)</Trans>
1923
</Subject>
@@ -36,7 +40,9 @@ export default function ResendEmailLogin({ locale }: Readonly<ResendEmailLoginPr
3640
<Trans>This code will expire in a few minutes.</Trans>
3741
</Text>
3842

39-
<OtpAutofill code="OneTimePassword" domain="Domain" />
43+
<Text className="email-muted m-[0px] mt-[16px] text-center text-[12px] leading-[20px] text-[#64748b]">
44+
<Trans>If you didn't request a new code, you can safely ignore this email.</Trans>
45+
</Text>
4046
</TransactionalEmail>
4147
);
4248
}

application/account/WebApp/emails/templates/StartLogin.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ type StartLoginProps = {
1313

1414
export default function StartLogin({ locale }: Readonly<StartLoginProps>) {
1515
return (
16-
<TransactionalEmail locale={locale} preview="PlatformPlatform login verification code">
16+
<TransactionalEmail
17+
locale={locale}
18+
preview="PlatformPlatform login verification code"
19+
otpAutofill={<OtpAutofill code="OneTimePassword" domain="Domain" />}
20+
>
1721
<Subject>
1822
<Trans>PlatformPlatform login verification code</Trans>
1923
</Subject>
@@ -32,7 +36,9 @@ export default function StartLogin({ locale }: Readonly<StartLoginProps>) {
3236
</Text>
3337
</Section>
3438

35-
<OtpAutofill code="OneTimePassword" domain="Domain" />
39+
<Text className="email-muted m-[0px] mt-[16px] text-center text-[12px] leading-[20px] text-[#64748b]">
40+
<Trans>If you didn't try to log in, you can safely ignore this email — your account is secure.</Trans>
41+
</Text>
3642
</TransactionalEmail>
3743
);
3844
}

application/account/WebApp/emails/templates/StartSignup.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ type StartSignupProps = {
1313

1414
export default function StartSignup({ locale }: Readonly<StartSignupProps>) {
1515
return (
16-
<TransactionalEmail locale={locale} preview="Confirm your email address">
16+
<TransactionalEmail
17+
locale={locale}
18+
preview="Confirm your email address"
19+
otpAutofill={<OtpAutofill code="OneTimePassword" domain="Domain" />}
20+
>
1721
<Subject>
1822
<Trans>Confirm your email address</Trans>
1923
</Subject>
@@ -32,7 +36,9 @@ export default function StartSignup({ locale }: Readonly<StartSignupProps>) {
3236
</Text>
3337
</Section>
3438

35-
<OtpAutofill code="OneTimePassword" domain="Domain" />
39+
<Text className="email-muted m-[0px] mt-[16px] text-center text-[12px] leading-[20px] text-[#64748b]">
40+
<Trans>If you didn't request to sign up, you can safely ignore this email.</Trans>
41+
</Text>
3642
</TransactionalEmail>
3743
);
3844
}

application/account/WebApp/emails/templates/UnknownUser.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export default function UnknownUser({ locale }: Readonly<UnknownUserProps>) {
3737
.
3838
</Trans>
3939
</Text>
40+
41+
<Text className="email-muted m-[0px] mt-[16px] text-center text-[12px] leading-[20px] text-[#64748b]">
42+
<Trans>If this wasn't you, no action is needed — no account was created.</Trans>
43+
</Text>
4044
</TransactionalEmail>
4145
);
4246
}

application/account/WebApp/emails/translations/locale/da-DK.po

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,45 @@ msgstr ""
1616
msgid "<0/> invited you to join PlatformPlatform."
1717
msgstr "<0/> har inviteret dig til at deltage i PlatformPlatform."
1818

19+
msgid "Compliance"
20+
msgstr "Compliance"
21+
1922
msgid "Confirm your email address"
2023
msgstr "Bekræft din e-mailadresse"
2124

25+
msgid "DPA"
26+
msgstr "DPA"
27+
2228
msgid "Enter it in your open browser window. It is only valid for a few minutes."
2329
msgstr "Indtast den i dit åbne browservindue. Den er kun gyldig i få minutter."
2430

2531
msgid "Here's your new verification code"
2632
msgstr "Her er din nye bekræftelseskode"
2733

34+
msgid "If this wasn't you, no action is needed — no account was created."
35+
msgstr "Hvis det ikke var dig, behøver du ikke gøre noget — der blev ikke oprettet en konto."
36+
37+
msgid "If you didn't request a new code, you can safely ignore this email."
38+
msgstr "Hvis du ikke har anmodet om en ny kode, kan du roligt ignorere denne e-mail."
39+
40+
msgid "If you didn't request to sign up, you can safely ignore this email."
41+
msgstr "Hvis du ikke har anmodet om at oprette en konto, kan du roligt ignorere denne e-mail."
42+
43+
msgid "If you didn't try to log in, you can safely ignore this email — your account is secure."
44+
msgstr "Hvis du ikke har forsøgt at logge ind, kan du roligt ignorere denne e-mail — din konto er sikker."
45+
46+
msgid "If you don't recognize the sender, you can safely ignore this email."
47+
msgstr "Hvis du ikke kender afsenderen, kan du roligt ignorere denne e-mail."
48+
2849
msgid "PlatformPlatform login verification code"
2950
msgstr "PlatformPlatform-bekræftelseskode til login"
3051

52+
msgid "Privacy"
53+
msgstr "Privatliv"
54+
55+
msgid "Terms"
56+
msgstr "Vilkår"
57+
3158
msgid "This code will expire in a few minutes."
3259
msgstr "Denne kode udløber om få minutter."
3360

application/account/WebApp/emails/translations/locale/en-US.po

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,45 @@ msgstr ""
1616
msgid "<0/> invited you to join PlatformPlatform."
1717
msgstr "<0/> invited you to join PlatformPlatform."
1818

19+
msgid "Compliance"
20+
msgstr "Compliance"
21+
1922
msgid "Confirm your email address"
2023
msgstr "Confirm your email address"
2124

25+
msgid "DPA"
26+
msgstr "DPA"
27+
2228
msgid "Enter it in your open browser window. It is only valid for a few minutes."
2329
msgstr "Enter it in your open browser window. It is only valid for a few minutes."
2430

2531
msgid "Here's your new verification code"
2632
msgstr "Here's your new verification code"
2733

34+
msgid "If this wasn't you, no action is needed — no account was created."
35+
msgstr "If this wasn't you, no action is needed — no account was created."
36+
37+
msgid "If you didn't request a new code, you can safely ignore this email."
38+
msgstr "If you didn't request a new code, you can safely ignore this email."
39+
40+
msgid "If you didn't request to sign up, you can safely ignore this email."
41+
msgstr "If you didn't request to sign up, you can safely ignore this email."
42+
43+
msgid "If you didn't try to log in, you can safely ignore this email — your account is secure."
44+
msgstr "If you didn't try to log in, you can safely ignore this email — your account is secure."
45+
46+
msgid "If you don't recognize the sender, you can safely ignore this email."
47+
msgstr "If you don't recognize the sender, you can safely ignore this email."
48+
2849
msgid "PlatformPlatform login verification code"
2950
msgstr "PlatformPlatform login verification code"
3051

52+
msgid "Privacy"
53+
msgstr "Privacy"
54+
55+
msgid "Terms"
56+
msgstr "Terms"
57+
3158
msgid "This code will expire in a few minutes."
3259
msgstr "This code will expire in a few minutes."
3360

application/account/WebApp/routes/components/-components/EmailsPreview.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Trans } from "@lingui/react/macro";
22
import { Button } from "@repo/ui/components/Button";
3+
import { ExternalLinkIcon } from "lucide-react";
34
import { useState } from "react";
45

56
const TEMPLATES = ["StartSignup", "StartLogin", "ResendEmailLogin", "UnknownUser", "InviteUser"] as const;
@@ -60,6 +61,22 @@ export function EmailsPreview() {
6061
className="block h-[40rem] w-full border-0 bg-white"
6162
/>
6263
</div>
64+
65+
<p className="text-sm text-muted-foreground">
66+
<Trans>
67+
Need a new building block? Browse the MIT-licensed recipes at{" "}
68+
<a
69+
href="https://react.email/components"
70+
target="_blank"
71+
rel="noopener noreferrer"
72+
className="inline-flex items-center gap-1 underline"
73+
>
74+
react.email/components
75+
<ExternalLinkIcon className="size-[0.875rem]" />
76+
</a>{" "}
77+
and copy the source into <code>application/shared-webapp/emails/components/</code>.
78+
</Trans>
79+
</p>
6380
</div>
6481
);
6582
}

0 commit comments

Comments
 (0)