- Rebranding: BRAND_NAME env var (default AcadeDoc) replaces hardcoded "DocAdenice" in index.html title/meta, PWA manifest, app-header logo text, email footer/body - lib/config.ts: getAppName() reads BRAND_NAME; new getBrandLogoUrl/PrimaryColor/AccentColor helpers - vite.config.ts: BRAND_* vars exposed via define block to client - brand-theme.ts: getBrandTheme() generates 10-shade MantineColorsTuple from hex (no @mantine/colors-generator dep); merged into MantineProvider at boot - theme/__tests__/brand-theme.test.ts: 11 vitest tests (generateColorTuple + getBrandTheme) - Workspace branding: migration adds primary_color/accent_color to workspaces table WorkspaceBrandingService + WorkspaceBrandingController (POST /workspace/branding, POST /workspace/branding/update — admin only) + DTO hex validation - Settings: /settings/branding page (WorkspaceBranding) + sidebar entry (admin-only) - workspace-branding.spec.ts: 13 vitest tests (service + controller + DTO validation) - SMTP Brevo: .env.example preset block + transactional/README.md ops guide (key gen, port 587 STARTTLS, 300/day free limit, swaks/curl test) - environment.service.ts: getMailFromName() falls back to BRAND_NAME if MAIL_FROM_NAME unset - vitest.config.ts server: include pattern extended to src/core/workspace/spec/** - i18n: 11 branding keys added to en-US and fr-FR translations - 0 TypeScript errors client + server, 11 client + 13 server new tests all green Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| css | ||
| emails | ||
| partials | ||
| utils | ||
| README.md | ||
Transactional Mail — AcadeDoc
Architecture
AcadeDoc uses NestJS + nodemailer for transactional email. Emails are rendered
with react-email and enqueued via BullMQ. The driver is selected at boot time
from MAIL_DRIVER (smtp | postmark | log).
All email templates live in emails/. Partials (header, footer, button) are
in partials/. CSS helpers are in css/.
Configuring Brevo (SMTP relay)
Brevo (ex-Sendinblue) is the recommended SMTP relay for AcadeDoc selfhost.
1. Create a Brevo account
Go to https://app.brevo.com and register.
2. Generate an SMTP key
- Log in to Brevo dashboard.
- Navigate to Settings > SMTP & API > SMTP.
- Click Generate a new SMTP key.
- Copy the key — it is shown only once.
This key is your
SMTP_PASSWORD. It is NOT your account password.
3. Set the environment variables
MAIL_DRIVER=smtp
SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_USERNAME=<your-brevo-login-email>
SMTP_PASSWORD=<smtp-master-key-from-step-2>
SMTP_SECURE=false
SMTP_IGNORETLS=false
MAIL_FROM_ADDRESS=noreply@yourdomain.com
MAIL_FROM_NAME=AcadeDoc
SMTP_SECURE=false + SMTP_IGNORETLS=false instructs nodemailer to upgrade
the connection to TLS via STARTTLS on port 587. This is the correct mode for
Brevo (port 587 is STARTTLS, port 465 is implicit TLS / SMTP_SECURE=true).
4. Brevo free plan limits
| Metric | Free plan |
|---|---|
| Emails/day | 300 |
| Emails/month | 9 000 |
| Contacts | Unlimited |
| SMTP relay | Yes |
For internal team usage (< 50 members), 300 emails/day is more than enough. Upgrade if you need more capacity.
5. Test from the server
After deploying, send a test from the container/server shell:
# Using swaks (SMTP Swiss Army Knife)
swaks \
--to test@example.com \
--from noreply@yourdomain.com \
--server smtp-relay.brevo.com:587 \
--auth LOGIN \
--auth-user "<your-brevo-login-email>" \
--auth-password "<smtp-key>" \
--tls \
--header "Subject: AcadeDoc SMTP test"
Or via curl (base64-encode credentials):
curl --url "smtp://smtp-relay.brevo.com:587" \
--ssl-reqd \
--mail-from "noreply@yourdomain.com" \
--mail-rcpt "test@example.com" \
--user "<login>:<smtp-key>" \
-T - <<EOF
From: noreply@yourdomain.com
To: test@example.com
Subject: AcadeDoc SMTP test
Test email from AcadeDoc.
EOF
If swaks/curl are not available in the container, trigger a password-reset from the AcadeDoc UI with a real user email and check delivery.
STARTTLS vs TLS notes
| Env variable | Value | Effect |
|---|---|---|
| SMTP_SECURE | false | Port 587 / STARTTLS (recommended) |
| SMTP_SECURE | true | Port 465 / implicit TLS |
| SMTP_IGNORETLS | false | Allow STARTTLS upgrade (default) |
| SMTP_IGNORETLS | true | Disable TLS entirely (insecure, dev only) |
Brevo port 587 requires STARTTLS. Do not set SMTP_SECURE=true on port 587.