A secure Node.js Express REST API built with Express, Drizzle ORM, Neon PostgreSQL, JWT Authentication, Arcjet Security, Zod Validation, bcrypt, and Winston Logging.
This project demonstrates a clean backend API structure with authentication, validation, database integration, security middleware, logging, and environment-based configuration.
Acquisitions API is a backend application designed with a scalable Express.js architecture. It includes user authentication features such as sign up, sign in, and sign out, while using JWT tokens stored in secure HTTP-only cookies.
The project follows a layered backend structure with routes, controllers, services, models, validations, middleware, utilities, and configuration files.
- Node.js Express API
- User sign-up endpoint
- User sign-in endpoint
- User sign-out endpoint
- JWT authentication
- Secure HTTP-only cookie handling
- Password hashing using bcrypt
- PostgreSQL database integration
- Neon serverless PostgreSQL support
- Drizzle ORM database models and migrations
- Zod request validation
- Arcjet security middleware
- Bot protection
- Rate limiting
- Security headers using Helmet
- CORS support
- Cookie parser support
- HTTP request logging with Morgan
- Application logging with Winston
- Modular folder structure
- Native ES module support
- ESLint and Prettier configuration
- Node.js
- Express.js
- JavaScript
- Drizzle ORM
- Neon PostgreSQL
- PostgreSQL
- JSON Web Token
- bcrypt
- Zod
- Arcjet
- Helmet
- CORS
- Cookie Parser
- Morgan
- Winston
- Dotenv
- ESLint
- Prettier
acquisitions/
├── drizzle/
├── logs/
├── src/
│ ├── config/
│ │ ├── arcjet.js
│ │ ├── database.js
│ │ └── logger.js
│ │
│ ├── controllers/
│ │ └── auth.controller.js
│ │
│ ├── middleware/
│ │ └── security.middleware.js
│ │
│ ├── models/
│ │ └── user.model.js
│ │
│ ├── routes/
│ │ └── auth.routes.js
│ │
│ ├── services/
│ │ └── auth.service.js
│ │
│ ├── utils/
│ │ ├── cookies.js
│ │ ├── format.js
│ │ └── jwt.js
│ │
│ ├── validations/
│ │ └── auth.validation.js
│ │
│ ├── app.js
│ ├── index.js
│ └── server.js
│
├── .gitignore
├── .prettierignore
├── .prettierrc
├── drizzle.config.js
├── eslint.config.js
├── package.json
└── README.mdClient
|
v
Express App
|
|-- Global Middleware
| |-- Helmet
| |-- CORS
| |-- Cookie Parser
| |-- Morgan Logger
| |-- Arcjet Security Middleware
|
v
Routes
|
v
Controllers
|
v
Services
|
v
Drizzle ORM
|
v
Neon PostgreSQLGET /healthReturns application health status, timestamp, and uptime.
GET /apiReturns a welcome message for the Acquisitions API.
POST /api/auth/sign-upCreates a new user account.
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"role": "user"
}{
"message": "User registered successfully",
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}
}POST /api/auth/sign-inAuthenticates an existing user and sets a JWT token in an HTTP-only cookie.
{
"email": "john@example.com",
"password": "password123"
}{
"message": "Signed in successfully",
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}
}POST /api/auth/sign-outClears the authentication cookie and signs the user out.
{
"message": "Signed out successfully"
}User submits credentials
|
v
Zod validates request body
|
v
Service checks user in database
|
v
bcrypt verifies password
|
v
JWT token is generated
|
v
Token is stored in HTTP-only cookieThis project includes multiple security layers:
- Helmet for secure HTTP headers
- Arcjet Shield protection
- Bot detection
- Role-based rate limiting
- HTTP-only cookies
- Strict same-site cookie policy
- bcrypt password hashing
- JWT token signing and verification
- Zod request validation
- Centralized error formatting
The Arcjet middleware applies different request limits based on user role:
| Role | Limit |
|---|---|
| Admin | 20 requests per minute |
| User | 10 requests per minute |
| Guest | 5 requests per minute |
The project uses Drizzle ORM with Neon PostgreSQL.
| Field | Description |
|---|---|
id |
Primary key |
name |
User full name |
email |
Unique user email |
password |
Hashed user password |
role |
User role, either user or admin |
createdAt |
Account creation timestamp |
updatedAt |
Account update timestamp |
Create a .env file in the root directory and add the following values:
PORT=3000
NODE_ENV=development
DATABASE_URL=your_neon_postgresql_database_url
JWT_SECRET=your_jwt_secret_key
ARCJET_KEY=your_arcjet_key
LOG_LEVEL=infoImportant: never commit your real .env file to GitHub.
git clone https://github.com/DANUCKSAN/acquisitions.gitcd acquisitionsnpm installCreate a .env file in the root directory and add your database, JWT, and Arcjet configuration.
npm run db:generatenpm run db:migratenpm run devThe server will run locally at:
http://localhost:3000npm run devRuns the app in watch mode using Node.js.
npm run lintChecks the project using ESLint.
npm run lint:fixAutomatically fixes supported ESLint issues.
npm run formatFormats the codebase using Prettier.
npm run format:checkChecks whether the code follows Prettier formatting.
npm run db:generateGenerates database migrations from the schema.
npm run db:migrateApplies pending database migrations.
npm run db:migrate:downOpens Drizzle Studio for database management.
The project uses Node.js import aliases for cleaner imports.
| Alias | Path |
|---|---|
#config/* |
./src/config/* |
#controllers/* |
./src/controllers/* |
#models/* |
./src/models/* |
#routes/* |
./src/routes/* |
#services/* |
./src/services/* |
#utils/* |
./src/utils/* |
#middleware/* |
./src/middleware/* |
#validations/* |
./src/validations/* |
The project uses Zod schemas for authentication validation.
- Name must be between 2 and 255 characters
- Email must be valid
- Password must be at least 6 characters
- Role must be either
useroradmin
- Email must be valid
- Password is required
The project uses Winston for application logging and Morgan for HTTP request logging.
Log files are stored in the logs directory:
logs/error.lg
logs/combined.logThis project uses native ES modules, so use:
import something from 'module';instead of:
const something = require('module');- Add protected user profile route
- Add authentication middleware for secured routes
- Add refresh token support
- Add password reset functionality
- Add email verification
- Add role-based authorization
- Add global error handling middleware
- Add API documentation with Swagger/OpenAPI
- Add automated tests
- Add Docker support
- Add Docker Compose setup
- Add GitHub Actions CI workflow
- Add Kubernetes deployment files
- Add production deployment documentation
A secure Node.js Express API with JWT authentication, Drizzle ORM, Neon PostgreSQL, Arcjet security, Zod validation, bcrypt password hashing, and Winston logging.
nodejs
express
expressjs
javascript
rest-api
backend
jwt-authentication
bcrypt
drizzle-orm
postgresql
neon
zod
arcjet
helmet
cors
winston
morgan
eslint
prettier
api-security
backend-developmentDanucksan Sathiyaraj
GitHub: DANUCKSAN
This project is open-source and available for learning, portfolio, and demonstration purposes.