diff options
| author | James Elliott <james-d-elliott@users.noreply.github.com> | 2024-08-17 14:02:32 +1000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-17 14:02:32 +1000 | 
| commit | 224f7112c5bb71a8d30ac3323a3a473758426e86 (patch) | |
| tree | 8b5e2d33b1729aa074169054632336f0f8e931d4 /internal/templates/src/emails | |
| parent | cbafce182227e1f4c457bc1cc941894b4b2826c2 (diff) | |
fix: email template ux (#7654)
Adjusts the email templates to use a well known email HTML generator called react email. This also adds a very useful preview option for the templates for testing purposes.
Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Brynn Crowley <littlehill723@gmail.com>
Diffstat (limited to 'internal/templates/src/emails')
| -rw-r--r-- | internal/templates/src/emails/Event.tsx | 88 | ||||
| -rw-r--r-- | internal/templates/src/emails/IdentityVerificationJWT.tsx | 172 | ||||
| -rw-r--r-- | internal/templates/src/emails/IdentityVerificationOTC.tsx | 155 | 
3 files changed, 415 insertions, 0 deletions
diff --git a/internal/templates/src/emails/Event.tsx b/internal/templates/src/emails/Event.tsx new file mode 100644 index 000000000..c404b4a25 --- /dev/null +++ b/internal/templates/src/emails/Event.tsx @@ -0,0 +1,88 @@ +import { +	Body, +	Container, +	Column, +	Head, +	Heading, +	Hr, +	Html, +	Preview, +	Row, +	Section, +	Text, +	Tailwind, Link, +} from "@react-email/components"; +import * as React from "react"; + +interface EventProps { +	title?: string; +	displayName?: string; +	remoteIP?: string; +	detailsKey?: string; +	detailsValue?: string; +	detailsPrefix?: string; +	detailsSuffix?: string; +} + +export const Event = ({ +						  title, +						  displayName, +						  remoteIP, +						  detailsKey, +						  detailsValue, +						  detailsPrefix, +						  detailsSuffix, +					  }: EventProps) => { +	return ( +		<Html lang="en" dir="ltr"> +			<Head /> +			<Preview>An important event has occurred with your account</Preview> +			<Tailwind> +				<Body className="bg-white my-auto mx-auto font-sans px-2"> +					<Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] max-w-[465px]"> +						{title ? <Text className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0">{title}</Text> : null} +						<Text className="text-black text-[14px] leading-[24px]"> +							Hi {displayName}, +						</Text> +						<Text className="text-black text-[14px] leading-[24px]"> +							This notification has been sent to you in order to notify you that a new <strong><i>{title}</i></strong>  +						</Text> +						<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +						<Text>Event Details:</Text> +						{detailsPrefix} +						<Section className="text-center"> +							<Row> +								<Column> +									<Text><strong>{detailsKey}</strong></Text> +								</Column> +								<Column>{detailsValue}</Column> +							</Row> +						</Section> +						{detailsSuffix} +						<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +						<Text className="text-[#666666] text-[12px] leading-[24px] text-center"> +							This notification was intended for <span className="text-black">{displayName}</span>. This +							event notification was generated due to an action from <span className="text-black">{remoteIP}</span>. +							If you do not believe that your actions could have triggered this event or if you are +							concerned about your account's safety, please change your password and reach out to an +							administrator. +						</Text> +					</Container> +					<Text className="text-[#666666] text-[10px] leading-[24px] text-center text-muted"> +						Powered by <Link href="https://www.authelia.com" target="_blank" className="text-[#666666]">Authelia</Link> +					</Text> +				</Body> +			</Tailwind> +		</Html> +	); +}; + +Event.PreviewProps = { +	displayName: "John Doe", +	detailsKey: "Example Detail", +	detailsValue: "Example Value", +	title: "Second Factor Method Added", +	remoteIP: "127.0.0.1", +} as EventProps; + +export default Event; diff --git a/internal/templates/src/emails/IdentityVerificationJWT.tsx b/internal/templates/src/emails/IdentityVerificationJWT.tsx new file mode 100644 index 000000000..24c1e4277 --- /dev/null +++ b/internal/templates/src/emails/IdentityVerificationJWT.tsx @@ -0,0 +1,172 @@ +import { +    Body, +    Container, +    Head, +    Heading, +    Hr, +    Html, +    Preview, +    Section, +    Text, +    Tailwind, +    Button, +    Link, +} from '@react-email/components'; +import * as React from 'react'; + +interface IdentityVerificationJWTProps { +    title?: string; +    displayName?: string; +    remoteIP?: string; +    link?: string; +    linkText?: string; +    revocationLinkURL?: string; +    revocationLinkText?: string; +} + +export const IdentityVerificationJWT = ({ +    title, +    displayName, +    remoteIP, +    link, +    linkText, +    revocationLinkURL, +    revocationLinkText, +}: IdentityVerificationJWTProps) => { +    return ( +        <Html lang="en" dir="ltr"> +            <Head /> +            <Preview>{title ? title : 'Confirm an action'}</Preview> +            <Tailwind> +                <Body className="bg-white my-auto mx-auto font-sans px-2"> +                    <Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] max-w-[465px]"> +                        <Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0"> +                            A <strong>one-time link</strong> has been generated +                            to complete a requested action +                        </Heading> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            Hi {displayName}, +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            We would like to confirm a{' '} +                            <strong>requested action </strong>related to the{' '} +                            <strong>security of your account</strong> at{' '} +                            <i>EXAMPLE.COM.</i> +                            <Text className="text-black text-[14px] leading-[24px] text-center"> +                                <strong> +                                    Do not share this notification or the +                                    content of this notification with anyone. +                                </strong> +                            </Text> +                        </Text> +                        <Hr className="border border-solid border-[#eaeaea] my-[12px] mx-0 w-full" /> +                        <Section className="text-center"> +                            <Text className="text-black text-[14px] leading-[24px]"> +                                If you made this request, click the validation +                                link below. +                            </Text> +                        </Section> +                        <Section className="text-center"> +                            <Button +                                id="link" +                                href={link} +                                className="bg-[#1976d2] rounded text-white text-[12px] font-semibold no-underline text-center px-5 py-3" +                            > +                                {linkText} +                            </Button> +                        </Section> + +                        <Text className="text-black text-[14px] leading-[24px] text-center"> +                            Alternatively, copy and paste this URL into your +                            browser: +                        </Text> +                        <Section className="text-center"> +                            <Link +                                href={link} +                                className="text-blue-600 no-underline" +                            > +                                {link} +                            </Link> +                        </Section> + +                        <Text> +                            <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +                            If you did NOT initiate this request, your +                            credentials may have been compromised and you +                            should: +                        </Text> + +                        <Section className="text-black text-[14px] leading-[22px]"> +                            <ol> +                                <li> +                                    Revoke the validation link using the +                                    provided links below +                                </li> +                                <li> +                                    Reset your password or other login +                                    credentials +                                </li> +                                <li>Contact an Administrator</li> +                            </ol> +                        </Section> +                        <Section className="text-center"> +                            <Button +                                id="link-revoke" +                                href={revocationLinkURL} +                                className="bg-[#f50057] rounded text-white text-[12px] font-semibold no-underline text-center px-5 py-3" +                            > +                                {revocationLinkText} +                            </Button> +                        </Section> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            To revoke the code click the above button or +                            alternatively copy and paste this URL into your +                            browser: +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px] text-center"> +                            <Link +                                href={revocationLinkURL} +                                className="text-blue-600 no-underline" +                            > +                                {revocationLinkURL} +                            </Link> +                        </Text> +                        <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +                        <Text className="text-[#666666] text-[12px] leading-[24px] text-center"> +                            This email was intended for{' '} +                            <span className="text-black">{displayName}</span>. +                            This event was generated due to an action from{' '} +                            <span className="text-black">{remoteIP}</span>. If +                            you do not believe that your actions could have +                            triggered this event or if you are concerned about +                            your account's safety, please follow the explicit +                            directions in this notification. +                        </Text> +                    </Container> +                    <Text className="text-[#666666] text-[10px] leading-[24px] text-center text-muted"> +                        Powered by{' '} +                        <Link +                            href="https://www.authelia.com" +                            target="_blank" +                            className="text-[#666666]" +                        > +                            Authelia +                        </Link> +                    </Text> +                </Body> +            </Tailwind> +        </Html> +    ); +}; + +IdentityVerificationJWT.PreviewProps = { +    title: 'Reset your password', +    displayName: 'John Doe', +    link: 'https://auth.example.com', +    linkText: 'Validate', +    revocationLinkURL: 'https://auth.example.com', +    revocationLinkText: 'Revoke', +    remoteIP: '127.0.0.1', +} as IdentityVerificationJWTProps; + +export default IdentityVerificationJWT; diff --git a/internal/templates/src/emails/IdentityVerificationOTC.tsx b/internal/templates/src/emails/IdentityVerificationOTC.tsx new file mode 100644 index 000000000..b8d9a3afc --- /dev/null +++ b/internal/templates/src/emails/IdentityVerificationOTC.tsx @@ -0,0 +1,155 @@ +import { +    Body, +    Container, +    Head, +    Heading, +    Hr, +    Html, +    Preview, +    Section, +    Text, +    Tailwind, +    Button, +    Link, +} from '@react-email/components'; +import * as React from 'react'; + +interface IdentityVerificationOTCProps { +    title?: string; +    displayName?: string; +    remoteIP?: string; +    oneTimeCode?: string; +    revocationLinkURL?: string; +    revocationLinkText?: string; +} + +export const IdentityVerificationOTC = ({ +    title, +    displayName, +    remoteIP, +    oneTimeCode, +    revocationLinkURL, +    revocationLinkText, +}: IdentityVerificationOTCProps) => { +    return ( +        <Html lang="en" dir="ltr"> +            <Head /> +            <Preview> +                A one-time code has been generated for session elevation +            </Preview> +            <Tailwind> +                <Body className="bg-white my-auto mx-auto font-sans px-2"> +                    <Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] max-w-[465px]"> +                        <Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0"> +                            A <strong>one-time code</strong> has been generated +                            to complete a requested action +                        </Heading> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            Hi {displayName}, +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            This notification has been sent to you in order to +                            verify your identity to{' '} +                            <strong>change security details</strong> for your +                            account.{' '} +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px] text-center"> +                            <strong> +                                Do not share this notification or the content of +                                this notification with anyone. +                            </strong> +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            {' '} +                            The following <i>one-time code</i> should only be +                            used in the prompt displayed in your browser. +                        </Text> + +                        <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +                        <Section> +                            <Text +                                id="one-time-code" +                                className="text-black text-center tracking-[0.5rem] font-bold text-lg" +                                style={{ marginRight: '-0.5rem !important' }} +                            > +                                {oneTimeCode} +                            </Text> +                        </Section> +                        <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +                        <Text className="text-black text-[14px] leading-[24px]"> +                            If you did not initiate the process your credentials +                            may have been compromised and you should: +                        </Text> +                        <Section className="text-black text-[14px] leading-[22px]"> +                            <ol> +                                <li> +                                    Revoke this code using the provided links +                                    below +                                </li> +                                <li> +                                    Reset your password or other login +                                    credentials +                                </li> +                                <li>Contact an Administrator</li> +                            </ol> +                        </Section> +                        <Section className="text-center"> +                            <Button +                                id="link-revoke" +                                href={revocationLinkURL} +                                className="bg-[#f50057] rounded text-white text-[12px] font-semibold no-underline text-center px-5 py-3" +                            > +                                {revocationLinkText} +                            </Button> +                        </Section> +                        <Text className="text-black text-[14px] leading-[24px] text-center"> +                            To revoke the code click the above button or +                            alternatively copy and paste this URL into your +                            browser:{' '} +                        </Text> +                        <Text className="text-black text-[14px] leading-[24px] text-center"> +                            <Link +                                href={revocationLinkURL} +                                className="text-blue-600 no-underline" +                            > +                                {revocationLinkURL} +                            </Link> +                        </Text> +                        <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> +                        <Text className="text-[#666666] text-[12px] leading-[24px] text-center"> +                            This notification was intended for{' '} +                            <span className="text-black">{displayName}</span>. +                            This one-time code was generated due to an action +                            from <span className="text-black">{remoteIP}</span>. +                            If you do not believe that your actions could have +                            triggered this event or if you are concerned about +                            your account's safety, please follow the explicit +                            directions in this notification. +                        </Text> +                    </Container> +                    <Text className="text-[#666666] text-[10px] leading-[24px] text-center text-muted"> +                        Powered by{' '} +                        <Link +                            href="https://www.authelia.com" +                            target="_blank" +                            className="text-[#666666]" +                        > +                            Authelia +                        </Link> +                    </Text> +                </Body> +            </Tailwind> +        </Html> +    ); +}; + +IdentityVerificationOTC.PreviewProps = { +    title: 'Confirm your identity', +    displayName: 'John Doe', +    oneTimeCode: 'ABC123', +    revocationLinkURL: 'https://auth.example.com', +    revocationLinkText: 'Revoke', +    remoteIP: '127.0.0.1', +} as IdentityVerificationOTCProps; + +export default IdentityVerificationOTC;  | 
