All files / apps/web/src/providers email.ts

13.33% Statements 2/15
0% Branches 0/8
0% Functions 0/2
13.33% Lines 2/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54                                          6x   6x                                                            
import * as postmark from "postmark";
 
import type { UnauthorizedContext } from "~web/handlers/context";
import { env } from "~web/utils/env";
 
export type Email = {
	address: string;
	subject: string;
	body: string;
};
 
export type EmailOptions = {
	getActive: () => boolean;
	setActive: (next: boolean) => void;
	mock?: EmailClient;
};
 
type EmailClient = {
	send: (email: Email) => Promise<void>;
};
 
let emailClient: EmailClient | undefined = undefined;
 
export const getEmailClient = (ctx: UnauthorizedContext): EmailClient => {
	if (ctx.emailOptions.mock) {
		return ctx.emailOptions.mock;
	}
	if (emailClient) {
		return emailClient;
	}
	const { MAILER_SENDER, MAILER_TOKEN } = env;
	if (!MAILER_SENDER) {
		throw new Error("Expected to have env.MAILER_SENDER variable!");
	}
	if (!MAILER_TOKEN) {
		throw new Error("Expected to have env.MAILER_TOKEN variable!");
	}
 
	const postmarkClient = new postmark.ServerClient(MAILER_TOKEN);
	emailClient = {
		send: async (email: Email) => {
			await postmarkClient.sendEmail({
				From: MAILER_SENDER,
				To: email.address,
				Subject: email.subject,
				HtmlBody: email.body,
				TextBody: email.body,
				MessageStream: "outbound",
			});
		},
	};
	return emailClient;
};