feat: responsive HTML email templates with DreamHost SMTP
- Add professional HTML email template matching CV aesthetic - Implement multipart emails (HTML + plain text fallback) - Configure DreamHost SMTP with SSL (port 465) - Add "light only" color scheme for Gmail iOS compatibility - Include Reply-To header for easy sender response - Add email validation and integration tests - Update .env.example with DreamHost/Gmail SMTP examples - Add .env to .gitignore to protect credentials - Document email template customization and dark mode approach
This commit is contained in:
+87
-12
@@ -338,26 +338,49 @@ mux.HandleFunc("/contact", contactHandler.ShowContactForm)
|
||||
|
||||
## Step 5: Configure Email Service
|
||||
|
||||
### Option 1: SMTP (Gmail, Office 365, etc.)
|
||||
### Option 1: DreamHost SMTP (Recommended)
|
||||
|
||||
**Environment variables:**
|
||||
```bash
|
||||
# DreamHost uses port 465 with SSL (implicit TLS)
|
||||
SMTP_HOST=smtp.dreamhost.com
|
||||
SMTP_PORT=465
|
||||
SMTP_USER=your-email@yourdomain.com
|
||||
SMTP_PASSWORD=your-email-password
|
||||
SMTP_FROM_EMAIL=your-email@yourdomain.com
|
||||
CONTACT_EMAIL=recipient@example.com
|
||||
```
|
||||
|
||||
### Option 2: Gmail SMTP
|
||||
|
||||
**Environment variables:**
|
||||
```bash
|
||||
# Gmail uses port 587 with STARTTLS
|
||||
# Requires App Password (enable 2FA first)
|
||||
# https://myaccount.google.com/apppasswords
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@gmail.com
|
||||
SMTP_PASS=your-app-specific-password
|
||||
SMTP_FROM=noreply@yourdomain.com
|
||||
CONTACT_EMAIL=contact@yourdomain.com
|
||||
SMTP_PASSWORD=your-app-specific-password
|
||||
SMTP_FROM_EMAIL=your-email@gmail.com
|
||||
CONTACT_EMAIL=recipient@example.com
|
||||
```
|
||||
|
||||
### Option 2: SendGrid
|
||||
### Port Reference
|
||||
|
||||
| Port | Protocol | Description |
|
||||
|------|----------|-------------|
|
||||
| 465 | SSL/TLS | Implicit TLS - direct encrypted connection |
|
||||
| 587 | STARTTLS | Plain connection upgraded to TLS |
|
||||
|
||||
### Option 3: SendGrid
|
||||
|
||||
```bash
|
||||
SENDGRID_API_KEY=your-api-key
|
||||
CONTACT_EMAIL=contact@yourdomain.com
|
||||
```
|
||||
|
||||
### Option 3: AWS SES
|
||||
### Option 4: AWS SES
|
||||
|
||||
```bash
|
||||
AWS_REGION=us-east-1
|
||||
@@ -467,11 +490,14 @@ grep "BLOCKED" /var/log/cv-app/security.log | jq -r '.ip' | sort | uniq -c | sor
|
||||
```bash
|
||||
GO_ENV=production
|
||||
ALLOWED_ORIGINS=juan.andres.morenorub.io
|
||||
SMTP_HOST=...
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=...
|
||||
SMTP_PASS=...
|
||||
CONTACT_EMAIL=...
|
||||
|
||||
# DreamHost SMTP Configuration
|
||||
SMTP_HOST=smtp.dreamhost.com
|
||||
SMTP_PORT=465
|
||||
SMTP_USER=info@drolosoft.com
|
||||
SMTP_PASSWORD=your-password
|
||||
SMTP_FROM_EMAIL=info@drolosoft.com
|
||||
CONTACT_EMAIL=your-personal-email@example.com
|
||||
```
|
||||
|
||||
### 2. Configure Nginx Rate Limiting
|
||||
@@ -500,7 +526,56 @@ sudo vi /etc/logrotate.d/cv-app
|
||||
|
||||
---
|
||||
|
||||
## That's It! 🎉
|
||||
---
|
||||
|
||||
## Email Templates
|
||||
|
||||
The contact form uses a professional HTML email template that matches the CV's aesthetic.
|
||||
|
||||
### Features
|
||||
|
||||
- **Responsive design** - Works on desktop, tablet, and mobile
|
||||
- **Light-only color scheme** - Forces consistent rendering across all email clients
|
||||
- **Bracket aesthetic** - `{ CV Contact }` header matching CV design
|
||||
- **Green accent color** - `#27ae60` consistent with CV highlights
|
||||
- **Multipart format** - Includes both HTML and plain text versions
|
||||
- **Reply-To header** - Automatically set to the sender's email
|
||||
|
||||
### Dark Mode Compatibility
|
||||
|
||||
The template uses `<meta name="color-scheme" content="light only">` to prevent
|
||||
email clients (especially Gmail iOS) from unpredictably inverting colors in dark mode.
|
||||
|
||||
**Why not support dark mode?**
|
||||
- Gmail iOS ignores CSS `@media (prefers-color-scheme: dark)` rules
|
||||
- It applies its own color inversion algorithm that breaks designs
|
||||
- Using "light only" ensures the email looks identical everywhere
|
||||
|
||||
Reference: [How emails react to dark mode](https://www.hteumeuleu.com/2021/emails-react-to-dark-mode/)
|
||||
|
||||
### Template Files
|
||||
|
||||
- `internal/services/email_theme.go` - CSS theme and HTML template
|
||||
- `internal/services/email.go` - Email service with multipart support
|
||||
|
||||
### Customization
|
||||
|
||||
To customize the email template, edit `email_theme.go`:
|
||||
|
||||
```go
|
||||
// Change accent color
|
||||
color: #27ae60; // Green - change to your brand color
|
||||
|
||||
// Change header text
|
||||
<span class="bracket">{</span> CV Contact <span class="bracket">}</span>
|
||||
|
||||
// Modify footer link
|
||||
<a href="https://your-domain.com" class="email-footer-link">your-domain.com</a>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## That's It!
|
||||
|
||||
All security middleware is already implemented and tested:
|
||||
- ✅ CSRF protection
|
||||
|
||||
Reference in New Issue
Block a user