A flexible and customizable contact form backend API built with .NET 8 Minimal API. This service enables easy integration of contact forms on websites by providing a robust email sending service with multiple SMTP configurations, customizable templates, and attachment support.
- Multiple SMTP configurations with failover support
- Customizable email templates (Default, Modern, Minimal, Professional, Alert)
- HTML email support with rich formatting
- Attachment handling with base64 encoding
- Email priority levels (Low, Normal, High, Urgent)
- AWS Lambda deployment support
- Environment variable configuration for secure credential management
- Advanced email tracking with rate limiting and progressive timeout
- Error handling middleware
- CORS configuration for cross-domain integration
- Optional username field for anonymous submissions
- Services Layer: Core services for email sending, SMTP testing, and template management
- Interfaces: Clean separation of concerns using dependency injection
- Models: Data models for email requests and SMTP configuration
- Middleware: Error handling and request processing
- Controllers: RESTful API endpoints
- AWS Lambda Integration: Support for serverless deployment
The project includes a comprehensive test suite in the ContactForm.Tests
project, covering all aspects of the application:
-
Unit Tests:
ModelsTests
: Validates data models and their validation rulesServicesTests
: Tests individual services in isolation with mocked dependenciesEmailServiceTests
: Email generation and sending functionalityEmailTrackingServiceTests
: Rate limiting and usage trackingIpProtectionServiceTests
: IP blocking, expiration, and abuse detectionRateLimitingMiddlewareTests
: Request throttling, IP blocking, and rate limit checks
ControllersTests
: Ensures API endpoints function correctly with mocked services
-
Integration Tests:
IntegrationTests
: End-to-end tests usingApplicationFactory
to simulate real API interactionsSecurityHeadersTests
: Validates security headers and CORS configurations across requestsRateLimitingIntegrationTests
: Tests rate limiting functionality with real HTTP requestsIpSpoofingTests
: Detects and blocks suspicious IP spoofing attempts
-
Performance and Concurrency Tests:
RateLimitingPerformanceTests
: Measures overhead of rate limiting middlewareIpProtectionServiceConcurrencyTests
: Validates thread safety under concurrent traffic
The test project uses xUnit and ASPNET Core testing framework for thorough testing coverage.
To execute all tests in the ContactForm.MinimalAPI
directory, run the following command:
dotnet test
POST /api/v1/email/{smtpId}
- Send an email using specified SMTP configurationPOST /api/v1/email/{smtpId}/test
- Send a test email using test email addressGET /api/v1/email/configs
- Get all available SMTP configurationsGET /api/v{version}/versiontest
- Test v1 and v2 versioningGET /test
- Test if the API is running
The API supports 3 methods of versioning
- URL Path: Using
/api/v1/resource
format (recommended) - Query String: Using
?api-version=1.0
parameter - Header: Using
X-Version: 1.0
header
The API implements a dual-layer rate limiting system to prevent spam and abuse:
- Tracks email usage per SMTP configuration
- Implements adaptive timeout periods based on usage count
- First submission has no delay
- Subsequent submissions have an increasing timeout (1 hour per usage count)
- Different SMTP configurations are tracked separately
- IP-based rate limiting with 10 requests per minute per IP
- Advanced traffic pattern analysis to detect abuse:
- Burst detection (20+ requests in 5 seconds) triggers automatic 1-hour block
- Excessive requests (100+ in 10 minutes) triggers automatic 6-hour block
- In-memory IP tracking with automatic cleanup
- Returns appropriate HTTP status codes:
- 429 Too Many Requests for rate limiting
- 403 Forbidden for blocked IPs
- No persistent IP storage - data is cleared on application restart
The API documentation is available in two formats:
- Detailed Documentation: See the DOCS.md file for comprehensive API documentation including request/response formats, templates, and configuration details.
- Interactive Swagger UI: When running the API locally, access the Swagger documentation at the root URL
http://localhost:5108/
on navigator. Swagger provides an interactive interface to explore and test all API endpoints.
Required for this project:
- .NET SDK 8.0+
- SMTP server access for sending emails
- Environment variables for SMTP configurations
"SmtpSettings": {
"Configurations": [
{
"Host": "smtp.example.com", // SMTP SERVER HOSTNAME
"Port": 465, // SMTP SERVER PORT (TYPICALLY 465 FOR SSL, 587 FOR TLS)
"Email": "[email protected]", // PRIMARY EMAIL ADDRESS FOR SENDING EMAILS
"TestEmail": "[email protected]", // TEST EMAIL ADDRESS FOR TESTING FUNCTIONALITY
"Description": "Main contact email", // DESCRIPTION FOR IDENTIFYING THIS CONFIGURATION
"Index": 1 // UNIQUE INDEX FOR REFERENCING THIS CONFIGURATION
},
{
"Host": "smtp.example.com", // SECOND SMTP SERVER (CAN BE SAME HOST)
"Port": 465, // SECOND SMTP PORT
"Email": "[email protected]", // SECONDARY EMAIL FOR SENDING
"TestEmail": "[email protected]", // SECONDARY TEST EMAIL
"Description": "Second contact email", // DESCRIPTION FOR SECOND CONFIGURATION
"Index": 2 // UNIQUE INDEX FOR SECOND CONFIGURATION (MUST BE DIFFERENT)
}
],
"ReceptionEmail": "[email protected]", // DEFAULT RECIPIENT EMAIL FOR TESTING
"CatchAllEmail": "[email protected]" // FALLBACK EMAIL FOR CATCHING UNDELIVERABLE MESSAGES
}
# MAIN REGULAR EMAIL PASSWORD
SMTP_1_PASSWORD=password_value_here
# MAIN TEST EMAIL PASSWORD
SMTP_1_PASSWORD_TEST=test_password_value_here
# SECOND REGULAR EMAIL PASSWORD
SMTP_2_PASSWORD=password_value_here
# SECOND TEST EMAIL PASSWORD
SMTP_2_PASSWORD_TEST=test_password_value_here
# CLONE THE REPOSITORY
git clone https://github.com/BabylooPro/ContactForm.csharp.git
# NAVIGATE TO PROJECT DIRECTORY
cd ContactForm.csharp/ContactForm.MinimalAPI
# CREATE .ENV FILE ON MACOS/LINUX
cat > .env << EOF
# MAIN REGULAR EMAIL PASSWORD
SMTP_1_PASSWORD=password_value_here
# MAIN TEST EMAIL PASSWORD
SMTP_1_PASSWORD_TEST=test_password_value_here
# SECOND REGULAR EMAIL PASSWORD
SMTP_2_PASSWORD=password_value_here
# SECOND TEST EMAIL PASSWORD
SMTP_2_PASSWORD_TEST=test_password_value_here
EOF
# OR CREATE .ENV FILE ON WINDOWS (POWERSHELL)
@"
# MAIN REGULAR EMAIL PASSWORD
SMTP_1_PASSWORD=password_value_here
# MAIN TEST EMAIL PASSWORD
SMTP_1_PASSWORD_TEST=test_password_value_here
# SECOND REGULAR EMAIL PASSWORD
SMTP_2_PASSWORD=password_value_here
# SECOND TEST EMAIL PASSWORD
SMTP_2_PASSWORD_TEST=test_password_value_here
"@ | Out-File -FilePath .env -Encoding utf8
# RESTORE DEPENDENCIES
dotnet restore
# CLEAN SOLUTION
dotnet clean
# BUILD SOLUTION
dotnet build
# RUN TESTS
dotnet test
# RUN PROJECT
dotnet run
The project includes AWS Lambda integration via the LambdaEntryPoint.cs
class and is deployed automatically through GitHub Actions.
Deployment is fully automated using the GitHub Actions workflow defined in .github/workflows/aws-deploy.yml.
This workflow includes:
- Builds and packages the application
- Creates necessary IAM roles and permissions for Lambda execution
- Deploys to AWS Lambda with proper environment variables
- Configures API Gateway with REST endpoints and proxy resources
- Sets up usage plans, throttling limits, and API keys
- Configures CORS for cross-domain access
- Preserves API Gateway ID across deployments for endpoint stability
Workflow Structure:
- First creates OIDC role for GitHub Actions with necessary permissions
- Runs tests for the application (optional)
- Builds and packages the .NET application for Lambda
- Creates IAM execution roles for Lambda function
- Deploys Lambda function with environment configuration
- Creates or reuses API Gateway with proper resources and methods
- Sets up Lambda permissions for API Gateway invocation
- Configures CORS headers for all API resources
- Creates or reuses API keys and usage plans
For detailed documentation of this deployment workflow, see this README.
To trigger deployment:
- Manually trigger the "Deploy to AWS Lambda" workflow from the GitHub Actions tab
https://github.com/[OWNER]/[REPO]/actions/workflows/aws-deploy.yml
and clickRun workflow
button.
Required GitHub secrets:
AWS_ACCESS_KEY_ID
- AWS access key with deployment permissionsAWS_SECRET_ACCESS_KEY
- AWS secret keySMTP_1_PASSWORD
- SMTP password for configuration 1 for regular emailSMTP_1_PASSWORD_TEST
- SMTP password for configuration 1 for test emailSMTP_2_PASSWORD
- SMTP password for configuration 2 for regular emailSMTP_2_PASSWORD_TEST
- SMTP password for configuration 2 for test email
For manual deployment:
- Configure AWS credentials locally
- Build the project with
dotnet publish
- Deploy using AWS SAM or AWS CDK commands
Send an email via the API:
POST /api/v1/email/1
Content-Type: application/json
{
"Email": "[email protected]", // SENDER EMAIL ADDRESS (REQUIRED)
"Username": "John Doe", // SENDER NAME (OPTIONAL)
"Message": "Hello, this is a test message", // MESSAGE CONTENT (REQUIRED)
"IsHtml": false, // SET TO TRUE FOR HTML-FORMATTED EMAILS
"Priority": "Normal" // EMAIL PRIORITY (LOW, NORMAL, HIGH, URGENT)
}
This project is licensed under the MIT License - see the LICENSE file for details.