Enhance the email support feature with better UX and debugging capabilities: - **Fix input field styling**: Update all form inputs to use project-standard 'form-input' class and consistent checkbox styling matching other admin pages for uniform appearance across the application - **Add comprehensive logging**: Implement detailed logging throughout email operations with clear prefixes ([EMAIL TEST], [EMAIL CONFIG]) to track: - Email configuration changes and validation - Test email sending process step-by-step - SMTP connection details and status - Success/failure indicators (✓/✗) for quick troubleshooting - **Auto-reload after save**: Page now automatically refreshes 1.5 seconds after successfully saving email configuration to ensure UI reflects the latest settings and eliminate stale data These improvements provide better visual consistency, easier debugging of email issues, and smoother user experience when configuring email settings. Files modified: - app/templates/admin/email_support.html - app/utils/email.py - app/routes/admin.py
11 KiB
Email Configuration Guide
This guide explains how to configure and use the email functionality in TimeTracker.
Overview
TimeTracker includes built-in email support for:
- Test emails to verify configuration
- Invoice notifications
- Task assignment notifications
- Weekly time summaries
- Comment mentions
- System alerts
Configuration Methods
TimeTracker supports two ways to configure email:
1. Database Configuration (Recommended)
Configure email settings through the admin web interface. Settings are saved to the database and persist between sessions.
Advantages:
- No server restart required for changes
- Easy to update via web interface
- Settings persist in database
- Can be changed by admins without server access
To Use:
- Navigate to Admin → Email Configuration
- Check "Enable Database Email Configuration"
- Fill in the form and save
2. Environment Variables (Fallback)
Configure email settings through environment variables. These serve as defaults when database configuration is disabled.
Advantages:
- More secure for sensitive credentials
- Standard configuration method
- Works without database access
To Use:
Add settings to your .env file or environment
Configuration Hierarchy
Email settings are loaded in this order (highest priority first):
- Database Settings (when
mail_enabledisTruein settings table) - Environment Variables (fallback)
- Default Values
Database Configuration
Email settings are configured through environment variables. Add these to your .env file or set them in your environment:
Basic SMTP Configuration
# SMTP Server Settings
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USE_SSL=false
# Authentication
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
# Sender Information
MAIL_DEFAULT_SENDER=noreply@yourdomain.com
# Optional: Maximum emails per connection
MAIL_MAX_EMAILS=100
Configuration Options
| Variable | Description | Default | Required |
|---|---|---|---|
MAIL_SERVER |
SMTP server hostname | localhost |
Yes |
MAIL_PORT |
SMTP server port | 587 |
Yes |
MAIL_USE_TLS |
Use TLS encryption | true |
No |
MAIL_USE_SSL |
Use SSL encryption | false |
No |
MAIL_USERNAME |
SMTP username for authentication | None | Yes (for most providers) |
MAIL_PASSWORD |
SMTP password | None | Yes (for most providers) |
MAIL_DEFAULT_SENDER |
Default "From" address | noreply@timetracker.local |
Yes |
MAIL_MAX_EMAILS |
Max emails per SMTP connection | 100 |
No |
Common Email Providers
Gmail
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_DEFAULT_SENDER=your-email@gmail.com
Important: Gmail requires an App Password when 2-factor authentication is enabled.
Outlook / Office 365
MAIL_SERVER=smtp.office365.com
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=your-email@outlook.com
MAIL_PASSWORD=your-password
MAIL_DEFAULT_SENDER=your-email@outlook.com
SendGrid
MAIL_SERVER=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=apikey
MAIL_PASSWORD=your-sendgrid-api-key
MAIL_DEFAULT_SENDER=noreply@yourdomain.com
Amazon SES
MAIL_SERVER=email-smtp.us-east-1.amazonaws.com
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=your-smtp-username
MAIL_PASSWORD=your-smtp-password
MAIL_DEFAULT_SENDER=noreply@yourdomain.com
Replace us-east-1 with your AWS region.
Mailgun
MAIL_SERVER=smtp.mailgun.org
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=postmaster@yourdomain.mailgun.org
MAIL_PASSWORD=your-mailgun-password
MAIL_DEFAULT_SENDER=noreply@yourdomain.com
Testing Email Configuration
Using the Admin Panel (Database Configuration)
- Log in as an administrator
- Navigate to Admin → Email Configuration
- Configure Settings:
- Check "Enable Database Email Configuration"
- Fill in: Mail Server, Port, Username, Password, etc.
- Click "Save Configuration"
- Test Configuration:
- Review the configuration status (should show "configured")
- Enter your email address in the test form
- Click "Send Test Email"
- Check your inbox for the test email
Using Environment Variables
- Set environment variables in
.env - Restart the application
- Navigate to Admin → Email Configuration
- Review the configuration status
- Send a test email
Using the Command Line
You can also test email configuration programmatically:
from app import create_app
from app.utils.email import send_test_email
app = create_app()
with app.app_context():
success, message = send_test_email('your-email@example.com', 'Test')
print(f"Success: {success}")
print(f"Message: {message}")
Troubleshooting
Email Not Sending
-
Check Configuration Status
- Go to Admin → Email Configuration
- Review any errors or warnings displayed
-
Verify Credentials
- Ensure username and password are correct
- For Gmail, use an App Password, not your regular password
-
Check Firewall Rules
- Ensure outbound connections to SMTP port are allowed
- Test connectivity:
telnet smtp.gmail.com 587
-
Review Logs
- Check application logs for email-related errors
- Look for SMTP authentication or connection errors
-
TLS/SSL Configuration
- Don't enable both
MAIL_USE_TLSandMAIL_USE_SSL - Use TLS (port 587) for most modern SMTP servers
- Use SSL (port 465) only if required by your provider
- Don't enable both
Common Error Messages
"Mail server not configured"
- Set
MAIL_SERVERenvironment variable - Ensure it's not set to
localhost
"Authentication failed"
- Verify
MAIL_USERNAMEandMAIL_PASSWORD - For Gmail, generate an App Password
- Check if your account requires 2FA
"Connection refused"
- Check firewall rules
- Verify SMTP port is correct (587 for TLS, 465 for SSL, 25 for unencrypted)
- Ensure server can reach SMTP host
"TLS/SSL handshake failed"
- Check
MAIL_USE_TLSandMAIL_USE_SSLsettings - Ensure only one is enabled
- Verify port matches TLS/SSL setting
Security Best Practices
-
Use App Passwords
- Never use your main account password
- Generate app-specific passwords for Gmail, Outlook, etc.
-
Use Environment Variables
- Never commit email credentials to version control
- Use
.envfile (excluded from git) - Use secrets management in production
-
Use Dedicated Email Service
- For production, use SendGrid, Amazon SES, or similar
- These provide better deliverability and monitoring
- Personal email accounts may have sending limits
-
Configure SPF/DKIM/DMARC
- Set up proper DNS records for your sending domain
- Improves email deliverability
- Reduces likelihood of emails being marked as spam
-
Limit Default Sender
- Use a proper noreply address
- Don't use personal email as default sender
Email Templates
Email templates are located in app/templates/email/. Available templates:
test_email.html- Test email templateoverdue_invoice.html- Overdue invoice notificationtask_assigned.html- Task assignment notificationweekly_summary.html- Weekly time summarycomment_mention.html- Comment mention notification
Customizing Templates
To customize email templates:
- Navigate to
app/templates/email/ - Edit the HTML template files
- Use Jinja2 syntax for dynamic content
- Test your changes using the admin panel
Example:
<!DOCTYPE html>
<html>
<body>
<h1>Hello {{ user.display_name }}!</h1>
<p>{{ message }}</p>
</body>
</html>
API Reference
send_email(subject, recipients, text_body, html_body=None, sender=None, attachments=None)
Send an email message.
Parameters:
subject(str): Email subject linerecipients(list): List of recipient email addressestext_body(str): Plain text email bodyhtml_body(str, optional): HTML email bodysender(str, optional): Sender email address (defaults toMAIL_DEFAULT_SENDER)attachments(list, optional): List of (filename, content_type, data) tuples
Example:
from app.utils.email import send_email
send_email(
subject='Welcome to TimeTracker',
recipients=['user@example.com'],
text_body='Welcome to our application!',
html_body='<p>Welcome to our application!</p>'
)
test_email_configuration()
Test email configuration and return status.
Returns:
dict: Configuration status with keys:configured(bool): Whether email is properly configuredsettings(dict): Current email settingserrors(list): Configuration errorswarnings(list): Configuration warnings
Example:
from app.utils.email import test_email_configuration
status = test_email_configuration()
if status['configured']:
print("Email is configured!")
else:
print("Errors:", status['errors'])
send_test_email(recipient_email, sender_name='TimeTracker Admin')
Send a test email to verify configuration.
Parameters:
recipient_email(str): Email address to send test tosender_name(str, optional): Name of sender
Returns:
tuple: (success: bool, message: str)
Example:
from app.utils.email import send_test_email
success, message = send_test_email('test@example.com')
if success:
print("Test email sent!")
else:
print("Error:", message)
Docker Configuration
Option 1: Database Configuration (Recommended)
- Start TimeTracker with Docker
- Log in as administrator
- Navigate to Admin → Email Configuration
- Configure email through the web interface
- No restart needed!
Option 2: Environment Variables
When running TimeTracker in Docker, add email configuration to your docker-compose.yml:
services:
app:
environment:
- MAIL_SERVER=smtp.gmail.com
- MAIL_PORT=587
- MAIL_USE_TLS=true
- MAIL_USERNAME=${MAIL_USERNAME}
- MAIL_PASSWORD=${MAIL_PASSWORD}
- MAIL_DEFAULT_SENDER=${MAIL_DEFAULT_SENDER}
Then set the values in your .env file:
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_DEFAULT_SENDER=noreply@yourdomain.com
Note: Database configuration (Option 1) takes precedence when enabled.
Advanced Configuration
Rate Limiting
The email test endpoint is rate-limited to 5 requests per minute to prevent abuse.
Asynchronous Sending
Emails are sent asynchronously in background threads to avoid blocking the main application. This is handled automatically.
Connection Pooling
Flask-Mail manages SMTP connection pooling automatically based on MAIL_MAX_EMAILS setting.
Support
For issues with email configuration:
- Check the GitHub Issues
- Review application logs
- Test with a simple SMTP client to verify credentials
- Check your email provider's documentation