Skip to content

grant-pie/nest.js-mailer

Repository files navigation

NestJS Mailer API

A production-ready contact form API built with NestJS. Accepts contact form submissions, validates them against Google reCAPTCHA Enterprise, and sends dual confirmation emails (admin notification + user confirmation) via the Resend email service.

Features

  • Contact form endpoint with full input validation and sanitization
  • Google reCAPTCHA Enterprise verification with configurable risk score threshold
  • Dual email sending — admin notification and user confirmation via Resend
  • Rate limiting — 10 requests per 60 seconds per IP
  • IP tracking and logging for security monitoring
  • PostgreSQL persistence for email audit logs
  • Static file serving with custom 404 handling

API Endpoints

POST /mail/send

Handles contact form submissions.

Request body:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "message": "I'm interested in your services.",
  "recaptchaToken": "<google-recaptcha-token>"
}

Validation rules:

  • firstName / lastName — required, max 50 characters
  • email — required, valid email format
  • message — required, max 500 characters
  • recaptchaToken — required for spam protection

Success response:

{
  "success": true,
  "message": "Your message has been sent successfully. We will get back to you soon!"
}

Error responses:

  • 400 — Missing reCAPTCHA token or invalid input
  • 401 — reCAPTCHA verification failed
  • 429 — Rate limit exceeded (includes Retry-After header)
  • 500 — Internal server error

GET /emails

Returns all stored email records from the database.

GET /emails/:id

Returns a single email record by ID.

GET /

Serves the static home page (public/index.html).


Setup

Prerequisites

  • Node.js 18+
  • PostgreSQL database
  • Resend account and API key
  • Google Cloud project with reCAPTCHA Enterprise enabled

Install dependencies

npm install

Environment variables

Create a .env file in the project root:

# Email service
RESEND_API_KEY=your-resend-api-key
ADMIN_EMAIL=admin@yourdomain.com

# CORS allowed origin
DOMAIN=https://yourdomain.com

# Google reCAPTCHA Enterprise
RECAPTCHA_PROJECT_ID=your-gcp-project-id
RECAPTCHA_API_KEY=your-google-cloud-api-key
RECAPTCHA_SITE_KEY=your-recaptcha-site-key

# Server
PORT=3005

Run the application

# Development
npm run start

# Watch mode (auto-reload)
npm run start:dev

# Production
npm run start:prod

Testing

# Unit tests
npm run test

# End-to-end tests
npm run test:e2e

# Test coverage
npm run test:cov

Project Structure

src/
├── app.module.ts          # Root module
├── app.controller.ts      # Home page route
├── main.ts                # Bootstrap (CORS, validation, static files)
├── mailer/                # Contact form feature
│   ├── mailer.controller.ts  # POST /mail/send
│   ├── mailer.service.ts     # Email sending via Resend
│   ├── mailer.dto.ts         # Input validation schema
│   └── mailer.module.ts
├── recaptcha/             # Google reCAPTCHA Enterprise
│   ├── recaptcha.service.ts  # Token verification + risk scoring
│   └── recaptcha.module.ts
├── email/                 # Email audit log (PostgreSQL)
│   ├── email.controller.ts
│   ├── email.service.ts
│   ├── email.entity.ts
│   └── email.module.ts
├── common/guards/
│   └── custom-throttler.guard.ts  # Rate limiting (10 req / 60s)
└── filters/
    └── not-found.filter.ts        # Global 404 handler
public/
├── index.html
└── 404.html

Security

  • All input is sanitized (HTML stripped) before processing or emailing
  • reCAPTCHA Enterprise risk score must meet a minimum threshold (default: 0.5)
  • Rate limiting is enforced per IP per route
  • CORS is restricted to configured origins
  • Validation pipe rejects any extra/unexpected fields (whitelist mode)

About

NestJS contact form API with Google reCAPTCHA Enterprise verification, rate limiting, and dual email delivery via Resend.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors