diff --git a/.env.example b/.env.example index 1d033f81..296ae0f0 100644 --- a/.env.example +++ b/.env.example @@ -16,5 +16,9 @@ S3_USER_UPLOADS_ACCESS_KEY_ID=minioadmin S3_USER_UPLOADS_SECRET_ACCESS_KEY=minioadmin S3_USER_UPLOADS_BUCKET_NAME=compass-files -EMAIL=no.reply.project.compass@gmail.com -EMAIL_PASS= \ No newline at end of file +EMAIL_SERVICE=smtp +EMAIL_AUTH_USER= +EMAIL_AUTH_PASS= +EMAIL_FROM=no-reply@compassiep.org +EMAIL_HOST=localhost +EMAIL_PORT=1025 diff --git a/src/backend/lib/nodemailer.ts b/src/backend/lib/nodemailer.ts index 0062aa67..877f5723 100644 --- a/src/backend/lib/nodemailer.ts +++ b/src/backend/lib/nodemailer.ts @@ -1,11 +1,18 @@ import { createTransport } from "nodemailer"; +import SMTPTransport from "nodemailer/lib/smtp-transport"; import { Env } from "./types"; -export const getTransporter = (environment: Env) => - createTransport({ - service: "gmail", +export const getTransporter = (env: Env) => { + const options: SMTPTransport.Options = { + service: env.EMAIL_SERVICE, auth: { - user: environment.EMAIL, - pass: environment.EMAIL_PASS, + user: env.EMAIL_AUTH_USER, + pass: env.EMAIL_AUTH_PASS, }, - }); + }; + if (env.EMAIL_SERVICE === "smtp") { + options.host = env.EMAIL_HOST; + options.port = parseInt(env.EMAIL_PORT, 10); + } + return createTransport(options); +}; diff --git a/src/backend/lib/types/env.ts b/src/backend/lib/types/env.ts index 209280bd..07f0e859 100644 --- a/src/backend/lib/types/env.ts +++ b/src/backend/lib/types/env.ts @@ -5,6 +5,10 @@ export interface Env { S3_USER_UPLOADS_ACCESS_KEY_ID: string; S3_USER_UPLOADS_SECRET_ACCESS_KEY: string; S3_USER_UPLOADS_BUCKET_NAME: string; - EMAIL: string; - EMAIL_PASS: string; + EMAIL_SERVICE: string; + EMAIL_AUTH_USER: string; + EMAIL_AUTH_PASS: string; + EMAIL_FROM: string; + EMAIL_HOST: string; + EMAIL_PORT: string; } diff --git a/src/backend/routers/case_manager.ts b/src/backend/routers/case_manager.ts index aaa5d91a..13b4154f 100644 --- a/src/backend/routers/case_manager.ts +++ b/src/backend/routers/case_manager.ts @@ -28,7 +28,7 @@ export const case_manager = router({ const studentData = await req.ctx.db .selectFrom("iep") .fullJoin("student", (join) => - join.onRef("student.student_id", "=", "iep.student_id") + join.onRef("student.student_id", "=", "iep.student_id"), ) .where("assigned_case_manager_id", "=", userId) .select([ @@ -57,7 +57,7 @@ export const case_manager = router({ last_name: z.string(), email: z.string().email(), grade: z.number(), - }) + }), ) .mutation(async (req) => { const { userId } = req.ctx.auth; @@ -80,7 +80,7 @@ export const case_manager = router({ last_name: z.string(), email: z.string().email(), grade: z.number(), - }) + }), ) .mutation(async (req) => { const { student_id, first_name, last_name, email, grade } = req.input; @@ -119,7 +119,7 @@ export const case_manager = router({ .input( z.object({ student_id: z.string(), - }) + }), ) .mutation(async (req) => { const { student_id } = req.input; @@ -139,7 +139,7 @@ export const case_manager = router({ .innerJoin( "paras_assigned_to_case_manager", "user.user_id", - "paras_assigned_to_case_manager.para_id" + "paras_assigned_to_case_manager.para_id", ) .where("paras_assigned_to_case_manager.case_manager_id", "=", userId) .selectAll() @@ -158,22 +158,22 @@ export const case_manager = router({ first_name: z.string(), last_name: z.string(), email: z.string().email(), - }) + }), ) .mutation(async (req) => { const para = await createPara( req.input, req.ctx.db, req.ctx.auth.userId, - req.ctx.env.EMAIL, + req.ctx.env.EMAIL_FROM, req.input.email, - req.ctx.env + req.ctx.env, ); return await assignParaToCaseManager( para?.user_id || "", req.ctx.auth.userId, - req.ctx.db + req.ctx.db, ); }), @@ -184,13 +184,13 @@ export const case_manager = router({ .input( z.object({ para_id: z.string(), - }) + }), ) .mutation(async (req) => { await assignParaToCaseManager( req.input.para_id, req.ctx.auth.userId, - req.ctx.db + req.ctx.db, ); return; }), @@ -202,7 +202,7 @@ export const case_manager = router({ first_name: z.string(), last_name: z.string(), email: z.string().email(), - }) + }), ) .mutation(async (req) => { const { para_id, first_name, last_name, email } = req.input; @@ -214,7 +214,7 @@ export const case_manager = router({ .innerJoin( "paras_assigned_to_case_manager", "user.user_id", - "paras_assigned_to_case_manager.para_id" + "paras_assigned_to_case_manager.para_id", ) .where("paras_assigned_to_case_manager.case_manager_id", "=", userId) .selectAll(); @@ -240,7 +240,7 @@ export const case_manager = router({ .input( z.object({ para_id: z.string(), - }) + }), ) .mutation(async (req) => { const { para_id } = req.input; diff --git a/src/backend/routers/para.ts b/src/backend/routers/para.ts index 2a5ac7e0..0f7a6cbb 100644 --- a/src/backend/routers/para.ts +++ b/src/backend/routers/para.ts @@ -40,7 +40,7 @@ export const para = router({ first_name: z.string(), last_name: z.string(), email: z.string().email(), - }) + }), ) .mutation(async (req) => { const { email } = req.input; @@ -49,9 +49,9 @@ export const para = router({ req.input, req.ctx.db, req.ctx.auth.session.user?.name ?? "", - req.ctx.env.EMAIL, + req.ctx.env.EMAIL_FROM, email, - req.ctx.env + req.ctx.env, ); return para; @@ -90,7 +90,7 @@ export const para = router({ .where("trial_data.created_by_user_id", "=", userId) .where("trial_data.submitted", "=", true) .select(({ fn }) => - fn.count("trial_data.trial_data_id").as("completed_trials") + fn.count("trial_data.trial_data_id").as("completed_trials"), ) .as("completed_trials"), ]) diff --git a/src/backend/tests/fixtures/get-test-server.ts b/src/backend/tests/fixtures/get-test-server.ts index a53e8331..5ae94b79 100644 --- a/src/backend/tests/fixtures/get-test-server.ts +++ b/src/backend/tests/fixtures/get-test-server.ts @@ -18,7 +18,7 @@ export interface GetTestServerOptions { export const getTestServer = async ( t: ExecutionContext, - { authenticateAs }: GetTestServerOptions = {} + { authenticateAs }: GetTestServerOptions = {}, ) => { const [ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment @@ -38,8 +38,12 @@ export const getTestServer = async ( S3_USER_UPLOADS_ACCESS_KEY_ID: minio.accessKey, S3_USER_UPLOADS_SECRET_ACCESS_KEY: minio.secretKey, S3_USER_UPLOADS_BUCKET_NAME: minio.bucket, - EMAIL: "example string", - EMAIL_PASS: "example string", + EMAIL_SERVICE: "example string", + EMAIL_FROM: "example string", + EMAIL_AUTH_USER: "example string", + EMAIL_AUTH_PASS: "example string", + EMAIL_HOST: "example string", + EMAIL_PORT: "example string", }; // Use statically-built Next.js fixture (if multiple instances of the built-in next() dev server are running, they try to concurrently mutate the same files).