Enterprise-grade secure authentication API supporting MySQL and MongoDB databases. Built with security best practices for production environments.
- MySQL via Prisma ORM - Type-safe, structured database with migrations
- MongoDB via Mongoose - Flexible document storage with validation
- Switch between providers by changing
DB_PROVIDERin.env
- β Password hashing with bcryptjs (configurable salt rounds)
- β JWT authentication with access and refresh tokens
- β Account lockout after failed login attempts (prevents brute-force)
- β Rate limiting to prevent abuse
- β Helmet for secure HTTP headers
- β CORS configuration
- β XSS and SQL/NoSQL injection protection
- β Input validation with Joi
- β User registration and login
- β Password reset flow (forgot/reset)
- β Admin user management (list, view, update, delete)
- β Role-based access control (user, admin)
- β
Swagger/OpenAPI documentation at
/api-docs
- β Jest unit tests with coverage
- β Supertest for API integration tests
- Winston logging with timestamps
- Morgan HTTP request logging
- Error handling middleware
- Environment-based configuration
auth-service/
βββ prisma/
β βββ schema.prisma # MySQL database schema
βββ src/
β βββ config/
β β βββ config.js # Environment configuration
β β βββ db.js # Database connection handler
β βββ controllers/
β β βββ authController.js # Authentication logic
β β βββ adminController.js # Admin user management
β βββ middlewares/
β β βββ authMiddleware.js # JWT verification
β β βββ adminMiddleware.js # Admin role check
β β βββ errorHandler.js # Global error handling
β β βββ rateLimiter.js # Rate limiting
β β βββ validate.js # Input validation
β βββ models/
β β βββ User.js # Unified User model
β β βββ Token.js # Token storage model
β βββ routes/
β β βββ authRoutes.js # API routes + Swagger docs
β βββ utils/
β βββ jwt.js # JWT utilities
β βββ logger.js # Winston logger
βββ tests/
β βββ setup.js # Jest test setup
β βββ unit/
β βββ controllers/
β β βββ authController.test.js
β βββ middlewares/
β β βββ authMiddleware.test.js
β βββ models/
β βββ User.test.js
βββ .env # Environment variables
βββ .env.example # Template for .env
βββ package.json
βββ server.js # Application entry point
βββ My_Backend_Setup.txt # Setup documentation
npm installcp .env.example .envEdit .env with your settings:
# Database Provider: mysql | mongodb
DB_PROVIDER=mysql
# MySQL Configuration
DATABASE_URL="mysql://root:password@localhost:3306/auth_service"
# MongoDB Configuration
MONGODB_URI="mongodb://localhost:27017/auth_service"
# JWT Secret (use a strong random string)
JWT_SECRET=your-super-secret-jwt-key-min-32-characters
JWT_EXPIRES_IN=7d
JWT_REFRESH_EXPIRES_IN=30dFor MySQL:
# Generate Prisma client
npm run prisma:generate
# Create database tables
npm run prisma:migrate
# Or push schema directly
npm run prisma:pushFor MongoDB: No initialization needed - schemas are created automatically.
# Development mode (with hot reload)
npm run dev
# Production mode
npm start# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverage| Component | Status | Coverage |
|---|---|---|
| authController | β | Full endpoint testing |
| authMiddleware | β | JWT validation, auth flow |
| User Model | β | Password hashing, validation |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/auth/register |
Register new user | β |
| POST | /api/auth/login |
User login | β |
| POST | /api/auth/logout |
User logout | β |
| POST | /api/auth/refresh |
Refresh access token | β |
| POST | /api/auth/forgot-password |
Request password reset | β |
| POST | /api/auth/reset-password |
Reset password with token | β |
| GET | /api/auth/me |
Get current user | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/auth/users |
List all users (paginated) | β Admin |
| GET | /api/auth/users/:id |
Get user by ID | β Admin |
| PATCH | /api/auth/users/:id |
Update user role | β Admin |
| DELETE | /api/auth/users/:id |
Delete user | β Admin |
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Service health status |
| GET | /api-docs |
Swagger API documentation |
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "SecurePassword123"}'Response:
{
"message": "Registration successful",
"user": { "id": "1", "email": "user@example.com", "role": "user" },
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "SecurePassword123"}'curl -X POST http://localhost:3000/api/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'curl -X POST http://localhost:3000/api/auth/reset-password \
-H "Content-Type: application/json" \
-d '{"token": "<reset-token>", "password": "NewSecurePassword123"}'curl -X GET http://localhost:3000/api/auth/me \
-H "Authorization: Bearer <access_token>"curl -X GET "http://localhost:3000/api/auth/users?page=1&limit=10" \
-H "Authorization: Bearer <admin_access_token>"| Variable | Default | Description |
|---|---|---|
PORT |
3000 | Server port |
NODE_ENV |
development | Environment mode |
LOG_LEVEL |
info | Logging level |
DB_PROVIDER |
mysql | Database provider (mysql/mongodb) |
DATABASE_URL |
- | MySQL connection string |
MONGODB_URI |
- | MongoDB connection string |
JWT_SECRET |
- | JWT signing secret (min 32 chars) |
JWT_EXPIRES_IN |
7d | Access token expiration |
JWT_REFRESH_EXPIRES_IN |
30d | Refresh token expiration |
CORS_ORIGINS |
localhost:3000,localhost:5173 | Allowed CORS origins |
RATE_LIMIT_MAX |
100 | Max requests per window |
RATE_LIMIT_WINDOW_MS |
900000 | Rate limit window (15 min) |
SALT_ROUNDS |
12 | bcrypt salt rounds |
LOCKOUT_MAX_ATTEMPTS |
5 | Failed attempts before lockout |
LOCKOUT_DURATION_MS |
900000 | Lockout duration (15 min) |
- Passwords hashed with bcrypt (configurable rounds, default 12)
- Passwords never returned in API responses
- Minimum 8 characters required
- Account locks after 5 failed login attempts
- Lockout duration: 15 minutes
- Returns HTTP 423 (Locked) with retry time
- Access tokens expire in 7 days
- Refresh tokens expire in 30 days
- Refresh tokens are stored in database for revocation
- Token rotation on refresh
- Helmet sets secure HTTP headers
- CORS configured for allowed origins
- Rate limiting prevents abuse (100 req/15 min)
- XSS protection via xss-clean
- Parameter pollution protection via hpp
- MySQL: SQL injection prevented by Prisma ORM
- MongoDB: NoSQL injection protection via express-mongo-sanitize
model User {
id DateTime @id @default(now())
email String @unique
password String
role String @default("user")
isVerified Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tokens Token[]
passwordResets PasswordReset?
}
model Token {
id String @id @default(uuid())
token String @unique
userId Int
type String
expiresAt DateTime
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model PasswordReset {
id String @id @default(uuid())
email String
token String @unique
expiresAt DateTime
createdAt DateTime @default(now())
@@index([email])
}// User Schema
{
email: String (unique, lowercase),
password: String (min 8 chars),
role: Enum ['user', 'admin'] (default: 'user'),
failedLoginAttempts: Number (default: 0),
lockoutUntil: Date (null = not locked),
createdAt: Date,
updatedAt: Date
}
// Token Schema
{
token: String (unique),
userId: ObjectId (ref: User),
type: Enum ['access', 'refresh'],
expiresAt: Date (TTL index for auto-expiry),
createdAt: Date
}
// PasswordReset Schema
{
email: String (lowercase),
token: String (unique),
expiresAt: Date (TTL index for auto-expiry),
createdAt: Date
}| Command | Description |
|---|---|
npm start |
Start production server |
npm run dev |
Start development server with hot reload |
npm test |
Run all tests with coverage |
npm run test:watch |
Run tests in watch mode |
npm run test:coverage |
Run tests with coverage report |
npm run prisma:generate |
Generate Prisma client |
npm run prisma:migrate |
Create database migrations |
npm run prisma:push |
Push schema to database |
To switch from MySQL to MongoDB (or vice versa):
-
Update
DB_PROVIDERin.env:DB_PROVIDER=mongodb -
Update database connection string:
MONGODB_URI="mongodb://localhost:27017/auth_service" -
Restart the server:
npm run dev
Note: Data is not migrated automatically. Each database is independent.
express- Web frameworkjsonwebtoken- JWT authenticationbcryptjs- Password hashing
mysql2- MySQL clientprisma/@prisma/client- MySQL ORMmongoose- MongoDB ODM
helmet- Secure HTTP headerscors- Cross-origin resource sharingxss-clean- XSS protectionhpp- Parameter pollution protectionexpress-rate-limit- Rate limitingexpress-mongo-sanitize- NoSQL injection protection
joi- Input validationwinston- Loggingmorgan- HTTP request logging
swagger-jsdoc- OpenAPI specification generatorswagger-ui-express- Swagger UI
jest- Test frameworksupertest- HTTP assertions
ISC