One-line security for Express.js
HiSecure unifies authentication, validation, sanitization, rate-limiting, headers and parsing
into a single, consistent security layer for Express applications.
Modern Express applications require multiple security libraries to handle authentication, password hashing, validation, sanitization, rate limiting, headers, compression and parsing. Managing these separately leads to duplicated logic, configuration drift and subtle bugs.
HiSecure solves this by acting as a single orchestration layer.
- Password hashing (Argon2 with bcrypt fallback)
- JWT authentication and route protection
- Google login (ID token verification)
- Request validation and sanitization
- Rate limiting and abuse prevention
- CORS, security headers and compression
- JSON, URL and query parsing
| Capability | Status | Notes |
|---|---|---|
| JWT Authentication | Stable | Issuer, audience, expiry and subject supported |
| Password Hashing | Stable | Argon2 primary with bcrypt fallback |
| Google Login | Stable | ID token verification adapter included |
| Route Protection (RBAC) | Stable | Role-based access via JWT payload |
| Validation | Stable | Zod and express-validator supported |
| Sanitization | Stable | HTML injection and XSS protection |
| Rate Limiting | Stable | Presets and per-route configuration |
| CORS & Headers | Stable | Helmet, HPP and CORS integrated |
| Compression | Stable | gzip via a single flag |
| Logging | Improved | Structured, lifecycle-aware logs with adapter, manager and fallback visibility. Designed for production debugging without leaking sensitive data. |
- Improved structured logging across core lifecycle
- Clear visibility into adapter initialization and fallbacks
- Layer-based logs (core, managers, adapters) for easier debugging
- No public API changes (safe patch release)
- Single global middleware for security
- No manual wiring of multiple packages
- Consistent error handling and lifecycle-aware logging
- Safe defaults with escape hatches
- Beginner-friendly, production-ready
npm install hi-secureimport express from "express";
import { HiSecure } from "hi-secure";
const app = express();
app.use(HiSecure.middleware("api"));
app.listen(3000);
const hash = await HiSecure.hash(password);
const isValid = await HiSecure.verify(password, hash);
router.post(
"/register",
HiSecure.validate([...]),
controller
);
HiSecure.rateLimit({ max: 5, windowMs: 15 * 60 * 1000 });
Global CORS defines the baseline access rules for your entire application. These rules apply to all routes unless explicitly overridden at the route level.
This is ideal for standard APIs where most endpoints share the same access policy.
Enable CORS globally using default configuration.
app.use(
HiSecure.middleware({
cors: true
})
);
Define explicit CORS rules for all routes.
app.use(
HiSecure.middleware({
cors: {
origin: ["https://app.example.com"],
methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
credentials: true
}
})
);
Allow multiple frontends (web, admin, mobile) to access the same API.
app.use(
HiSecure.middleware({
cors: {
origin: [
"https://web.example.com",
"https://admin.example.com",
"https://mobile.example.com"
],
credentials: true
}
})
);
Use open CORS rules for public or read-only APIs.
app.use(
HiSecure.middleware({
cors: {
origin: "*",
methods: ["GET"]
}
})
);
HiSecure supports fine-grained security control at the route level. Each capability can be configured independently without affecting global middleware.
This allows you to apply strict security where needed (auth, payments, admin) and relaxed rules for public or internal endpoints.
Route-level CORS is useful when different consumers access different endpoints (e.g. web app, admin panel, third-party services).
Example: Webhook endpoint (single trusted origin)
router.post(
"/webhook",
HiSecure.cors({
origin: ["https://trusted-client.com"],
methods: ["POST"],
allowedHeaders: ["Content-Type", "Authorization"],
credentials: true
}),
controller
);
Example: Admin dashboard with restricted origins
router.get(
"/admin/stats",
HiSecure.cors({
origin: [
"https://admin.example.com",
"https://internal.example.com"
],
credentials: true
}),
controller
);
Example: Public API with open read access
router.get(
"/public/feed",
HiSecure.cors({ origin: "*" }),
controller
);
HiSecure automatically detects validation strategy based on input type. Choose the style based on complexity and ownership.
- express-validator — quick, form-like validation
- Zod — complex schemas, reuse, shared contracts
import { HiSecure , body } from "hi-secure";
router.post(
"/register",
HiSecure.validate([
body("email")
.notEmpty()
.isEmail(),
body("password")
.isLength({ min: 6 }),
body("role")
.optional()
.isIn(["user", "admin"])
]),
controller
);
import { HiSecure , z } from "hi-secure";
const registerSchema = z.object({
email: z.string().email(),
password: z.string().min(6),
role: z.enum(["user", "admin"]).optional()
});
router.post(
"/register",
HiSecure.validate(registerSchema),
controller
);
Both approaches produce a unified error response format.
Sanitization should reflect trust boundaries. Not all routes require the same level of strictness.
User-generated content (allow formatting)
router.post(
"/comment",
HiSecure.sanitize({
allowedTags: ["b", "i", "strong", "em", "a"],
allowedAttributes: {
a: ["href"]
}
}),
controller
);
Strict input (no HTML allowed)
router.post(
"/feedback",
HiSecure.sanitize({
allowedTags: [],
allowedAttributes: {}
}),
controller
);
Trusted internal pipeline (disable sanitization)
router.post(
"/internal/import",
HiSecure.sanitize(false),
controller
);
A real-world admin route combining multiple security layers. Execution order is deterministic and isolated to the route.
router.post(
"/admin/create-user",
HiSecure.auth({ roles: ["admin"] }),
HiSecure.rateLimit({ max: 3, windowMs: 10 * 60 * 1000 }),
HiSecure.cors({
origin: ["https://admin.example.com"]
}),
HiSecure.sanitize(),
HiSecure.validate([
body("email").isEmail(),
body("password").isLength({ min: 8 })
]),
controller
);
JWT support is optional. Enable it only if you want authentication features.
HiSecure.init({
auth: {
enabled: true,
jwtSecret:
process.env.JWT_SECRET , // "at least 32 - if not it shows warning in logs"
jwtExpiresIn: "1d",
},
});
This section demonstrates a complete, production-ready authentication setup using HiSecure. It covers signup, JWT login, Google login, role-based access control, and proper initialization.
- Signup using email and password
- Login using email and password (JWT-based)
- Login with Google (ID token verification) - Added Soon in Docs
- Role-based protected routes
- Optional authentication support
- Correct HiSecure bootstrap with reset rules
import express from "express";
import { HiSecure } from "hi-secure";
import dotenv from "dotenv";
dotenv.config();
HiSecure.init({
auth: {
enabled: true,
jwtSecret:
process.env.JWT_SECRET ,
jwtExpiresIn: "1d",
},
});
const app = express();
app.use(HiSecure.middleware("api"));
// When u use the Frontend [Because - Cors is the browser's security]
// HiSecure.cors({
// origin:"*" , // We can add our custome end points as well
// credentials:true
// })
import authRoutes from "./routes/auth.route";
import issueRoutes from "./routes/issue.route";
import notificationRoutes from "./routes/notification.route";
import communityRoutes from "./routes/community.route";
app.use("/api/auth", authRoutes);
app.use("/api/issues", issueRoutes);
app.use("/api/notifications", notificationRoutes);
app.use("/api/community", communityRoutes);
app.get("/", (_req, res) => {
res.json({ success: true, message: "Backend running" });
});
export default app;
import app from "./app";
import dotenv from "dotenv";
import { connectDB } from "./config/db";
dotenv.config();
connectDB();
const PORT = process.env.PORT;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
import { Router } from "express";
import {
signup,
loginWithJwt,
loginWithGoogle
} from "../controllers/auth.controller.js";
import { HiSecure } from "hi-secure";
const router = Router();
router.post("/signup", signup);
router.post("/login", loginWithJwt);
router.post("/google", loginWithGoogle);
router.get(
"/me",
HiSecure.auth(),
(req, res) => res.json({ user: req.user })
);
export default router;
export const register = async (req: Request, res: Response) => {
try {
const { name, email, password, role, hostel, block, room } = req.body;
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({
success: false,
message: 'User already exists'
});
}
const hashedPassword = await HiSecure.hash(password);
const user = await User.create({
name,
email,
password: hashedPassword,
role: role || 'student',
hostel,
block,
room
});
return res.status(201).json({
success: true,
message: 'User registered successfully',
user: {
id: user._id,
name: user.name,
email: user.email,
role: user.role
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
message: 'Registration failed',
error: error.message
});
}
};
export const login = async (req: Request, res: Response) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({
success: false,
message: 'Invalid credentials'
});
}
const isPasswordValid = await HiSecure.verify(password, user.password);
if (!isPasswordValid) {
return res.status(401).json({
success: false,
message: 'Invalid credentials'
});
}
const token = HiSecure.jwt.sign({
userId: user._id.toString(),
email: user.email,
role: user.role
});
return res.status(200).json({
success: true,
message: 'Login successful',
token,
user: {
id: user._id,
name: user.name,
email: user.email,
role: user.role
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
message: 'Login failed',
error: error.message
});
}
};
const router = Router();
router.post(
"/",
HiSecure.auth({ roles: ["student", "admin"] }),
HiSecure.validate([
body("title").notEmpty(),
body("description").notEmpty(),
body("category").notEmpty()
]),
createIssue
);
router.get(
"/my",
HiSecure.auth({ required: true }),
getMyIssues
);
router.post(
"/assign",
HiSecure.auth({ roles: ["admin"] }),
assignIssue
);
router.put(
"/status",
HiSecure.auth({ roles: ["staff", "admin"] }),
updateIssueStatus
);
router.put(
"/close",
HiSecure.auth({ required: true }),
closeIssue
);
export default router;
HiSecure provides a complete, opinionated security layer for Express. It focuses on correctness, safety and developer productivity.
One dependency. One middleware. Complete security.
Advanced patterns, RBAC strategies, adapter extensions and deployment guides will be added over time.