Skip to content

Commit 637cbc2

Browse files
authored
[Closes #434] Adds Mailcatcher to Docker supporting services for local email development (#436)
* Add Mailcatcher to Docker supporting services * Change default email transport config to smtp to Mailcatcher * Ran prettier * Revert "Ran prettier" This reverts commit 1cb07f2. * Ran prettier after node_modules removed * Update README and mock env vars * Fix formatting
1 parent aea652d commit 637cbc2

File tree

8 files changed

+68
-14
lines changed

8 files changed

+68
-14
lines changed

.env.example

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@ S3_USER_UPLOADS_ACCESS_KEY_ID=minioadmin
1616
S3_USER_UPLOADS_SECRET_ACCESS_KEY=minioadmin
1717
S3_USER_UPLOADS_BUCKET_NAME=compass-files
1818

19-
EMAIL=no.reply.project.compass@gmail.com
20-
EMAIL_PASS=
19+
EMAIL_SERVICE=smtp
20+
EMAIL_AUTH_USER=
21+
EMAIL_AUTH_PASS=
22+
EMAIL_FROM=no-reply@compassiep.org
23+
EMAIL_HOST=localhost
24+
EMAIL_PORT=1025

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,35 @@ To update GOOGLE_CLIENT_SECRET:
113113

114114
- Copy the google client secret after creation of the client id
115115

116+
### Email
117+
118+
**Option 1: Use Mailcatcher in Docker**
119+
120+
If you're following _Option 1_ above to run supporting services in Docker, the `.env.example` file is already configured to send email to the Mailcatcher server running on port 1025 for SMTP. The Mailcatcher server will "catch" all email sent and save it in memory to be viewed in its web-based interface running on port 1080. Open it in your web browser at: http://localhost:1080
121+
122+
**Option 2: Configure a live mail server**
123+
124+
If you're not running supporting services in Docker, or wish to test email sending to some test accounts (please take care not to send test emails to real people!), you can configure the following variables in your `.env` file:
125+
126+
1. For an SMTP server
127+
```
128+
EMAIL_SERVICE=smtp
129+
EMAIL_AUTH_USER=[username for your SMTP server]
130+
EMAIL_AUTH_PASS=[password for your SMTP server]
131+
EMAIL_FROM=no-reply@compassiep.org
132+
EMAIL_HOST=[host name for your SMTP server]
133+
EMAIL_PORT=[port for your SMTP server- typically 587 or 465 for secure connections]
134+
```
135+
2. For a Gmail account
136+
```
137+
EMAIL_SERVICE=gmail
138+
EMAIL_AUTH_USER=[your Gmail address]
139+
EMAIL_AUTH_PASS=[your Gmail password]
140+
EMAIL_FROM=[your Gmail address]
141+
EMAIL_HOST=
142+
EMAIL_PORT=
143+
```
144+
116145
### Running tests
117146

118147
The database container does not need to be started to run tests, but Docker Desktop must be running in the background.

src/backend/lib/nodemailer.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import { createTransport } from "nodemailer";
2+
import SMTPTransport from "nodemailer/lib/smtp-transport";
23
import { Env } from "./types";
34

4-
export const getTransporter = (environment: Env) =>
5-
createTransport({
6-
service: "gmail",
5+
export const getTransporter = (env: Env) => {
6+
const options: SMTPTransport.Options = {
7+
service: env.EMAIL_SERVICE,
78
auth: {
8-
user: environment.EMAIL,
9-
pass: environment.EMAIL_PASS,
9+
user: env.EMAIL_AUTH_USER,
10+
pass: env.EMAIL_AUTH_PASS,
1011
},
11-
});
12+
};
13+
if (env.EMAIL_SERVICE === "smtp") {
14+
options.host = env.EMAIL_HOST;
15+
options.port = parseInt(env.EMAIL_PORT, 10);
16+
}
17+
return createTransport(options);
18+
};

src/backend/lib/types/env.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export interface Env {
55
S3_USER_UPLOADS_ACCESS_KEY_ID: string;
66
S3_USER_UPLOADS_SECRET_ACCESS_KEY: string;
77
S3_USER_UPLOADS_BUCKET_NAME: string;
8-
EMAIL: string;
9-
EMAIL_PASS: string;
8+
EMAIL_SERVICE: string;
9+
EMAIL_AUTH_USER: string;
10+
EMAIL_AUTH_PASS: string;
11+
EMAIL_FROM: string;
12+
EMAIL_HOST: string;
13+
EMAIL_PORT: string;
1014
}

src/backend/routers/case_manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export const case_manager = router({
165165
req.input,
166166
req.ctx.db,
167167
req.ctx.auth.session.user?.name ?? "",
168-
req.ctx.env.EMAIL,
168+
req.ctx.env.EMAIL_FROM,
169169
req.input.email,
170170
req.ctx.env
171171
);

src/backend/routers/para.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const para = router({
4949
req.input,
5050
req.ctx.db,
5151
req.ctx.auth.session.user?.name ?? "",
52-
req.ctx.env.EMAIL,
52+
req.ctx.env.EMAIL_FROM,
5353
email,
5454
req.ctx.env
5555
);

src/backend/tests/fixtures/get-test-server.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ export const getTestServer = async (
3838
S3_USER_UPLOADS_ACCESS_KEY_ID: minio.accessKey,
3939
S3_USER_UPLOADS_SECRET_ACCESS_KEY: minio.secretKey,
4040
S3_USER_UPLOADS_BUCKET_NAME: minio.bucket,
41-
EMAIL: "example string",
42-
EMAIL_PASS: "example string",
41+
EMAIL_SERVICE: "smtp",
42+
EMAIL_FROM: "no-reply@compassiep.org",
43+
EMAIL_AUTH_USER: "", // note that these server settings will not be used, nodemailer is mocked
44+
EMAIL_AUTH_PASS: "",
45+
EMAIL_HOST: "localhost",
46+
EMAIL_PORT: "1025",
4347
};
4448

4549
// 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).

supporting_services/docker-compose.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ services:
1111
volumes:
1212
- postgres:/var/lib/postgresql/data
1313

14+
mailcatcher:
15+
image: dockage/mailcatcher:0.9.0
16+
ports:
17+
- "1025:1025"
18+
- "1080:1080"
19+
1420
minio:
1521
image: minio/minio:RELEASE.2023-05-18T00-05-36Z
1622
ports:

0 commit comments

Comments
 (0)