secure-mern
Version:
**A lightweight yet powerful npm package to supercharge security in MERN stack applications.** Built with **enterprise-grade architecture** in mind, Secure-MERN integrates essential security features with **minimal configuration**.
350 lines (252 loc) โข 9.85 kB
Markdown
# ๐ Secure-MERN
**A lightweight yet powerful npm package to supercharge security in MERN stack applications.**
Built with **enterprise-grade architecture** in mind, Secure-MERN integrates essential security features with **minimal configuration**.
## โ
Features
- ๐ Preconfigured **JWT-based authentication**
- ๐ **Role-based access control** with fine-grained permissions
- ๐งฐ Centralized **security middleware** for Express apps
- ๐งผ Built-in **sanitization & validation**
- ๐ก๏ธ **Helmet** integration for HTTP header protection
- ๐ซ **Rate limiting** enabled by default *(excluded for Admin roles in v3.0.0)*
- โ ๏ธ **CSRF protection** included (commented out, easily enabled)
- ๐ Predefined **User & Role Mongoose schemas**
- ๐งช Perfect for **small projects โ enterprise-grade systems**
- ๐ฑ Simple **plug-and-play** into any MERN app
- ๐ค **User profile management** *(image upload & view โ needs extra setup)*
- ๐ **Password update via dashboard** *(planned development)*
- ๐ **Automatic user activity logs** *(requires setup โ guide below)*
## โ
Whatโs New in v4.0.0
- ๐ Built-in Upload middleware (no need for custom setup)
- ๐ Built-in Userlog model
- ๐ Built-in Userlog utility
- ๐ Fixed major bugs from v3.0.0 & v4.0.0-beta1
- โก Default role = member when registering new users
## ๐ฆ Installation
Install with npm:
```bash
npm i secure-mern
```
## โ ๏ธ Limitation (Important)
- When registering a new user, you may encounter a role _id error.
- ๐ To fix this: upload the following Role collection to your MongoDB.
Run the backend once (it will auto-create the models in MongoDB/Compass). Then import this JSON into your Role collection:
```json
[{
"_id": { "$oid": "6837b60b735077d2866f126b" },
"name": "admin",
"permissions": [
"role:manage",
"role:create",
"role:update",
"systemusers:manage",
"systemusers:create",
"systemusers:update",
"permission:manage",
"permission:create",
"permission:update",
"permission:delete",
"role:getone",
"role:delete",
"user:updatestatus",
"useractivity:manage",
"useractivity:oneget"
],
"createdAt": { "$date": "2025-05-29T01:19:07.542Z" },
"updatedAt": { "$date": "2025-08-19T14:44:25.137Z" },
"__v": 45
},
{
"_id": { "$oid": "6837b616735077d2866f126e" },
"name": "staff",
"permissions": [],
"createdAt": { "$date": "2025-05-29T01:19:18.585Z" },
"updatedAt": { "$date": "2025-08-19T14:57:41.167Z" },
"__v": 38
},
{
"_id": { "$oid": "6843973fea08c312b1a7d4cb" },
"name": "user",
"permissions": [],
"createdAt": { "$date": "2025-06-07T01:34:55.181Z" },
"updatedAt": { "$date": "2025-08-15T12:24:48.025Z" },
"__v": 4
},
{
"_id": { "$oid": "68439748ea08c312b1a7d4d6" },
"name": "member",
"permissions": [],
"createdAt": { "$date": "2025-06-07T01:35:04.435Z" },
"updatedAt": { "$date": "2025-08-15T12:25:08.129Z" },
"__v": 12
}]
```
## ๐ Default Role Behavior
- Every newly registered user is automatically assigned the member role.
- If you want to promote a user to admin, follow these steps:
- - Go to the User collection in MongoDB.
- - Export the user document as .json.
- - Update the userโs role field with the Admin role _id (6837b60b735077d2866f126b).
- - Re-import the updated JSON back into the User collection.
## ๐ Quick Start
Example Express app setup:
```js
const express = require("express");
const mongoose = require("mongoose");
const secureMern = require("secure-mern");
const path = require('path');
require("dotenv").config();
const app = express();
// Initialize Secure-MERN
secureMern(app);
// File serving for uploads
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
app.get('/', (req, res) => {
res.send(`Server running on port ${process.env.PORT}`);
});
app.listen(process.env.PORT, () => {
console.log(`Server running on port ${process.env.PORT}`);
});
```
## ๐ง Required Setup
### ๐ Uploads Directory
```js
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
```
- Create an `uploads` folder in your **backend root**
- Add `uploads/` to `.gitignore`
### ๐ผ Profile Image Management
- `ProfileImage.js` model already included in package
- Only frontend integration required
Sample React component:
```js
import React, { useState, useEffect } from 'react'
import API from '../../../services/api'
const Profile = () => {
const [pimg, setPimg] = useState(null)
const [imgSrc, setImgSrc] = useState("/default-avatar.png")
const token = localStorage.getItem('token')
useEffect(() => {
const fetchProfileImage = async () => {
try {
const res = await API.get(`/auth/get-profile-img?nocache=${Date.now()}`, {
headers: { Authorization: `Bearer ${token}` }
})
setPimg(res.data.result || null)
} catch {
setPimg(null)
}
}
fetchProfileImage()
}, [token])
useEffect(() => {
if (pimg?.profile_image) {
const normalizedPath = pimg.profile_image.replace(/\\/g, "/")
const url = `${import.meta.env.VITE_APP_API}${normalizedPath.startsWith("/") ? "" : "/"}${normalizedPath}`
fetch(url).then(res => res.blob()).then(blob => {
setImgSrc(URL.createObjectURL(blob))
}).catch(() => setImgSrc("/default-avatar.png"))
}
}, [pimg])
return (
<div className="p-6">
<img src={imgSrc} alt="profile" className="w-40 h-40 rounded-full border-4 border-violet-600 object-cover shadow-md" />
</div>
)
}
export default Profile
```
## โ๏ธ Environment Setup
๐ `.env`
```env
MONGO_URI=mongodb://127.0.0.1:27017/newMERNtestAuth
JWT_SECRET=your_jwt_secret_key
PORT=5000
EMAIL_USER=your_email_address
EMAIL_PASSWORD=your_app_password
```
## ๐งฐ Included Middleware & Features
This project comes with several built-in middlewares and utilities to simplify development and enhance security.
| Feature / Middleware | Purpose |
|-------------------------|---------|
| **cors** | Enables CORS (cross-origin requests) |
| **helmet** | Adds secure HTTP headers |
| **express.json()** | Parses incoming JSON |
| **cookie-parser** | Parses cookies (required for CSRF protection) |
| **morgan** | HTTP request logger for debugging |
| **express-rate-limit** | Protects against brute-force attacks (100 reqs / 15 min) |
| *(Admin exception)* | Admin role is exempt from rate limits |
| **csurf (optional)** | CSRF protection (disabled by default) |
| **/auth routes** | Built-in authentication routes (login, register, etc.) |
| **Upload Middleware** | Integrated Multer upload support (no setup required) |
| **Userlogs Model** | Tracks user activity (login, logout, actions) |
| **Userlogs Util** | Helper for automatically logging user actions |
| **Profile Image Support** | Upload and view user profile images |
โ
Everything is pre-configured, so you can focus on building your application logic instead of boilerplate setup.
## ๐ฅ Models
๐ `User.js`
```js
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
fullName: { type: String, required: true, trim: true },
username: { type: String, required: true, unique: true, lowercase: true },
email: { type: String, required: true, unique: true, lowercase: true },
password: { type: String, required: true },
phone: String,
avatar: String,
role: { type: mongoose.Schema.Types.ObjectId, ref: "Role", required: true },
isActive: { type: Boolean, default: true },
isEmailVerified: { type: Boolean, default: false },
lastLogin: Date,
}, { timestamps: true });
module.exports = mongoose.model("User", userSchema);
```
๐ `Role.js`
```js
const mongoose = require("mongoose");
const roleSchema = new mongoose.Schema({
name: { type: String, required: true, unique: true },
permissions: [{ type: String }],
}, { timestamps: true });
module.exports = mongoose.model("Role", roleSchema);
```
## ๐ฎ Roadmap
Planned & completed features for upcoming versions:
- โ
Built-in Upload middleware
- โ
Built-in Userlogs (model + util)
- โ
Bug fixes from v3 & beta
- ๐ Refresh tokens
- ๐ 2FA (Two-Factor Authentication) integration
- ๐ OAuth2 / SSO login support
- ๐งโ๐ป Admin panel templates (React + Tailwind)
- ๐ง Advanced audit logging & IP tracking
- ๐ Usage analytics
## ๐ Versioning
This project follows **semantic versioning**. Below is the release history:
| Version | Notes |
|--------------|-------|
| **v1.0.0** | Initial release |
| **v2.0.0** | Added email verification + password reset |
| **v3.0.0** | Bug fixes, no rate limits for Admins |
| **v4.0.0-beta1** | Beta release, known bugs present |
| **v4.0.0** | Stable release, built-in upload + user logs |
๐ Always use the **latest stable release** for production.
## ๐ค Contributing
We welcome contributions! ๐
- Fork the repo
- Run locally with `npm install`
- Submit PRs or open issues
## ๐ Acknowledgments
Built with โค๏ธ for **MERN developers** who value **security-first architecture**.