Documentation Index Fetch the complete documentation index at: https://mintlify.com/Ishaq74/concordia/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Concordia uses nodemailer for email delivery with support for multiple SMTP providers. The email system handles authentication flows (email verification, password reset) and can be extended for notifications.
SMTP Service Architecture
The SMTP service (src/lib/smtp/smtp.ts) provides:
Multi-provider support - Pre-configured for 10+ popular providers
Connection pooling - Efficient email delivery with rate limiting
Error classification - Distinguishes retryable vs permanent failures
Validation - Email address and content validation
Mock mode - Testing without sending real emails
Environment Configuration
Add SMTP settings to your .env file:
# SMTP Configuration
SMTP_PROVIDER = provider
SMTP_USER = contact@provider.com
SMTP_PASS = your_password_here
SMTP_FROM = contact@provider.com
# Optional: Override defaults
# SMTP_HOST=smtp.provider.com
# SMTP_PORT=587
# SMTP_SECURE=false
# SMTP_POOL=true
# SMTP_MAX_CONNECTIONS=5
# SMTP_RATE_DELTA=1000
# SMTP_RATE_LIMIT=5
# Alternative: Resend API
RESEND_API_KEY = your_resend_api_key_here
Supported Providers
Concordia includes pre-configured settings for these providers:
IONOS
Gmail
Outlook
Resend
SendGrid
Mailgun
Postmark
AWS SES
{
name : 'IONOS' ,
host : 'smtp.ionos.fr' ,
port : 587 ,
secure : false ,
requireTLS : true
}
List All Providers
View all supported providers:
npm run smtp:check providers
Provider Setup
Option 1: Use Provider Preset
Set SMTP_PROVIDER to auto-configure:
SMTP_PROVIDER = resend
SMTP_USER = your-api-key
SMTP_PASS = your-api-key
SMTP_FROM = noreply@yourdomain.com
Option 2: Manual Configuration
Override individual settings:
SMTP_HOST = smtp.custom-provider.com
SMTP_PORT = 465
SMTP_SECURE = true
SMTP_USER = user@example.com
SMTP_PASS = password123
SMTP_FROM = noreply@example.com
Advanced Settings
Connection Pooling
Optimize delivery with connection pooling:
# Enable connection pool (default: true)
SMTP_POOL = true
# Max concurrent connections (default: 5)
SMTP_MAX_CONNECTIONS = 5
# Rate limiting
SMTP_RATE_DELTA = 1000 # 1 second
SMTP_RATE_LIMIT = 5 # 5 emails per second
These settings prevent overwhelming SMTP servers and help avoid rate limit errors.
SSL/TLS Configuration
# For port 465 (implicit SSL)
SMTP_PORT = 465
SMTP_SECURE = true
# For port 587 (explicit TLS/STARTTLS)
SMTP_PORT = 587
SMTP_SECURE = false
Most modern providers use port 587 with STARTTLS. The service automatically configures requireTLS based on the provider preset.
Testing Email Configuration
Connection Test
Verify SMTP configuration:
Output shows:
Provider name and server
Connection status (secure, TLS, pool)
Connection test result
Send Test Email
Send a test message:
npm run smtp:check your-email@example.com
This sends a test email and confirms delivery.
Test Output Example
🔍 SMTP Universal Checker
Provider : Resend
Serveur : smtp.resend.com:587
Secure : false
RequireTLS : true
Pool : true
⏳ Test de connexion...
✅ Connexion OK
⏳ Test d'envoi à user@example.com...
✅ Email envoyé
ID: <message-id@resend.com>
🏁 Terminé
Email Service Usage
Basic Email Sending
import { smtp } from '@/lib/smtp/smtp' ;
const result = await smtp . send ({
to: 'user@example.com' ,
subject: 'Welcome to Concordia' ,
text: 'Plain text version' ,
html: '<h1>Welcome!</h1><p>HTML version</p>' ,
from: 'noreply@yourdomain.com' , // Optional, uses SMTP_FROM by default
replyTo: 'support@yourdomain.com' // Optional
});
if ( result . success ) {
console . log ( 'Email sent:' , result . messageId );
} else {
console . error ( 'Send failed:' , result . error );
}
Batch Email Sending
Send multiple emails with concurrency control:
const results = await smtp . sendBatch (
[
{ to: 'user1@example.com' , subject: 'Hello' , text: 'Message 1' },
{ to: 'user2@example.com' , subject: 'Hello' , text: 'Message 2' },
{ to: 'user3@example.com' , subject: 'Hello' , text: 'Message 3' },
],
3 // Concurrency: send 3 at a time
);
results . forEach (( result , i ) => {
if ( result . success ) {
console . log ( `Email ${ i + 1 } sent` );
} else {
console . error ( `Email ${ i + 1 } failed:` , result . error );
}
});
Error Handling
The service classifies errors:
const result = await smtp . send ( payload );
if ( ! result . success ) {
const { error } = result ;
console . log ( 'Error code:' , error . code );
console . log ( 'Message:' , error . message );
console . log ( 'Retryable:' , error . retryable );
console . log ( 'Provider:' , error . provider );
if ( error . code === 'AUTH_FAILED' ) {
// Handle authentication errors
} else if ( error . retryable ) {
// Retry connection errors (ECONNREFUSED, ETIMEDOUT, etc.)
}
}
Authentication Emails
Concordia uses Better Auth for authentication, which integrates with the SMTP service for:
Email verification - Confirm user email addresses
Password reset - Send reset links
Magic links - Passwordless login (if configured)
Email Templates
Auth emails use Better Auth’s built-in templates. Customize them in your auth configuration:
import { betterAuth } from 'better-auth' ;
export const auth = betterAuth ({
// ... other config
emailAndPassword: {
enabled: true ,
sendResetPassword : async ({ user , url }) => {
await smtp . send ({
to: user . email ,
subject: 'Reset your password' ,
html: `<p>Click to reset: <a href=" ${ url } "> ${ url } </a></p>`
});
},
},
});
Provider-Specific Notes
Gmail
Gmail requires App Passwords when 2FA is enabled. Do not use your regular Gmail password. Generate App Password: Google Account Settings
SMTP_PROVIDER = gmail
SMTP_USER = your-email@gmail.com
SMTP_PASS = your-app-password # 16-character app password
SMTP_FROM = your-email@gmail.com
Resend
Resend offers both API and SMTP. For SMTP:
SMTP_PROVIDER = resend
SMTP_USER = resend
SMTP_PASS = re_your_api_key
SMTP_FROM = noreply@yourdomain.com
Resend requires domain verification before sending. Add DNS records in your Resend dashboard.
SendGrid
SMTP_PROVIDER = sendgrid
SMTP_USER = apikey # Literally "apikey"
SMTP_PASS = your-sendgrid-api-key
SMTP_FROM = verified@yourdomain.com
AWS SES
SMTP_PROVIDER = aws
SMTP_USER = your-smtp-username # From SES SMTP settings
SMTP_PASS = your-smtp-password
SMTP_FROM = verified@yourdomain.com
AWS SES starts in sandbox mode. Request production access to send to unverified addresses.
Mock Mode (Testing)
Disable real email sending during development:
SMTP_MOCK = 1
# or
NODE_ENV = test
In mock mode:
SMTP service initializes but doesn’t send real emails
Logs show “Mode MOCK activé”
Perfect for running tests without email side effects
Troubleshooting
Authentication Failed
Error: AUTH_FAILED - Authentication failed: 535 Authentication failed
Solutions:
Verify SMTP_USER and SMTP_PASS are correct
Check if provider requires app-specific passwords (Gmail)
Ensure account isn’t locked or suspended
For IONOS: The service automatically uses authMethod: 'LOGIN'
Connection Timeout
Error: ETIMEDOUT - Connection timed out
Solutions:
Check firewall allows outbound SMTP (ports 587/465)
Verify SMTP_HOST is correct
Try alternate port (587 vs 465)
Check if your hosting blocks SMTP
Rate Limit Exceeded
Error: 550 - Too many emails sent
Solutions:
Reduce SMTP_RATE_LIMIT in .env
Increase SMTP_RATE_DELTA to slow sending
Upgrade provider plan for higher limits
Use sendBatch() with lower concurrency
SSL/TLS Errors
Error: unable to verify the first certificate
Solutions:
For port 587: Set SMTP_SECURE=false
For port 465: Set SMTP_SECURE=true
Check provider documentation for correct settings
Production Checklist
Choose provider
Select SMTP provider based on volume and budget.
Configure credentials
Add SMTP_PROVIDER, SMTP_USER, SMTP_PASS, and SMTP_FROM to production environment.
Verify domain
Add DNS records (SPF, DKIM, DMARC) for your sending domain.
Test connection
npm run smtp:check your-email@example.com
Configure rate limits
Set SMTP_RATE_LIMIT based on provider limits.
Monitor deliverability
Track bounces and spam reports in provider dashboard.
Next Steps
Database Setup Configure PostgreSQL for production
Hosting Deploy your application to production