Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions apps/web/src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,15 @@ export const authLib = betterAuth({
const locale =
"locale" in user ? (user.locale as string) : await getLocale();

await (await getEmailClient(locale)).sendTemplate("ResetPasswordEmail", {
to: user.email,
props: {
resetLink: url,
await (await getEmailClient({ locale })).sendTemplate(
"ResetPasswordEmail",
{
to: user.email,
props: {
resetLink: url,
},
},
});
);
},
onPasswordReset: async ({ user }) => {
posthog()?.capture({
Expand Down Expand Up @@ -149,7 +152,7 @@ export const authLib = betterAuth({
overrideDefaultEmailVerification: true,
async sendVerificationOTP({ email, otp, type }) {
const locale = await getLocale(); // TODO: Get locale from email
const emailClient = await getEmailClient(locale);
const emailClient = await getEmailClient({ locale });
switch (type) {
// We're not actually using the sign-in type anymore since we just we have `autoSignInAfterVerification` enabled.
// This lets us keep things a bit simpler since we share the same verification flow for both login and registration.
Expand Down
14 changes: 9 additions & 5 deletions apps/web/src/trpc/routers/polls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ export const polls = router({
});

if (user) {
const emailClient = await getEmailClient(
ctx.user.locale ?? undefined,
);
const emailClient = await getEmailClient({
locale: ctx.user.locale ?? undefined,
});
after(() =>
emailClient.sendTemplate("NewPollEmail", {
to: user.email,
Expand Down Expand Up @@ -917,7 +917,9 @@ export const polls = router({

const hostEmail = poll.user.email;
const hostName = poll.user.name;
const emailClient = await getEmailClient(poll.user.locale ?? undefined);
const emailClient = await getEmailClient({
locale: poll.user.locale ?? undefined,
});
after(() =>
emailClient.sendTemplate("FinalizeHostEmail", {
to: hostEmail,
Expand Down Expand Up @@ -954,7 +956,9 @@ export const polls = router({
timeZone: scheduledEvent.timeZone,
inviteeTimeZone: p.timeZone,
});
const emailClient = await getEmailClient(p.locale ?? undefined);
const emailClient = await getEmailClient({
locale: p.locale ?? undefined,
});
after(() =>
emailClient.sendTemplate("FinalizeParticipantEmail", {
to: p.email,
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/trpc/routers/polls/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ export const comments = router({
});

if (recipient) {
const emailClient = await getEmailClient(
recipient.locale ?? undefined,
);
const emailClient = await getEmailClient({
locale: recipient.locale ?? undefined,
});
after(() =>
emailClient.sendTemplate("NewCommentEmail", {
to: recipient.email,
Expand Down
26 changes: 22 additions & 4 deletions apps/web/src/trpc/routers/polls/participants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ async function sendNewResponseNotificationEmail({
return;
}

const emailClient = await getEmailClient(recipient.locale ?? undefined);
const emailClient = await getEmailClient({
locale: recipient.locale ?? undefined,
});
await emailClient.sendTemplate("NewParticipantEmail", {
to: recipient.email,
props: {
Expand Down Expand Up @@ -286,6 +288,13 @@ export const participants = router({
select: {
id: true,
title: true,
space: {
select: {
showBranding: true,
primaryColor: true,
image: true,
},
},
},
},
},
Expand All @@ -296,9 +305,18 @@ export const participants = router({
if (email) {
const token = await createParticipantEditToken(ctx.user.id);

const emailClient = await getEmailClient(
ctx.user.locale ?? undefined,
);
const space = participant.poll.space;
const emailClient = await getEmailClient({
locale: ctx.user.locale ?? undefined,
...(space?.showBranding
? {
primaryColor: space.primaryColor ?? undefined,
logoUrl: space.image
? absoluteUrl(`/api/storage/${space.image}`)
: undefined,
}
: {}),
});

after(() =>
emailClient.sendTemplate("NewParticipantConfirmationEmail", {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/trpc/routers/spaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,9 @@ export const spaces = router({
},
});

const emailClient = await getEmailClient(
existingUser?.locale ?? ctx.user.locale,
);
const emailClient = await getEmailClient({
locale: existingUser?.locale ?? ctx.user.locale,
});

try {
await emailClient.sendTemplate("SpaceInviteEmail", {
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/trpc/routers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ export const user = router({
},
);

const emailClient = await getEmailClient(currentUser.locale ?? undefined);
const emailClient = await getEmailClient({
locale: currentUser.locale ?? undefined,
});

emailClient.sendTemplate("ChangeEmailRequest", {
to: input.email,
Expand Down
12 changes: 8 additions & 4 deletions apps/web/src/utils/emails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { getInstanceBrandingConfig } from "@/features/branding/queries";

const logger = createLogger("emails");

export const getEmailClient = async (locale?: string) => {
export const getEmailClient = async (options?: {
locale?: string;
primaryColor?: string;
logoUrl?: string;
}) => {
const brandingConfig = await getInstanceBrandingConfig();

return new EmailClient({
Expand All @@ -23,15 +27,15 @@ export const getEmailClient = async (locale?: string) => {
},
},
config: {
logoUrl: brandingConfig.logoIcon,
logoUrl: options?.logoUrl ?? brandingConfig.logoIcon,
baseUrl: absoluteUrl(),
domain: absoluteUrl().replace(/(^\w+:|^)\/\//, ""),
supportEmail: env.SUPPORT_EMAIL,
primaryColor: brandingConfig.primaryColor.light,
primaryColor: options?.primaryColor ?? brandingConfig.primaryColor.light,
appName: brandingConfig.appName,
hideAttribution: brandingConfig.hideAttribution,
},
locale,
locale: options?.locale,
onError: (e) => {
logger.error({ error: e }, "Email client error");
Sentry.captureException(e);
Expand Down
1 change: 1 addition & 0 deletions packages/emails/src/components/email-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const EmailLayout = ({
height="42"
style={{
marginBottom: 32,
borderRadius: 6,
}}
alt={ctx.appName}
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/emails/src/components/styled-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const Button = (
className={props.className}
style={{
backgroundColor: props.color ?? "#4F46E5",
borderRadius: "4px",
borderRadius: "6px",
padding: "14px",
fontFamily,
boxSizing: "border-box",
Expand Down Expand Up @@ -148,7 +148,7 @@ export const Card = (props: SectionProps) => {
<Section
{...props}
style={{
borderRadius: "4px",
borderRadius: "6px",
backgroundColor: "#F9FAFB",
paddingRight: "16px",
paddingLeft: "16px",
Expand Down
Loading