Skip to content

HiSecure unifies authentication, validation, sanitization, rate-limiting, headers and parsing into a single, consistent security layer for Express applications.

Notifications You must be signed in to change notification settings

100NikhilBro/hi-secure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

51 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”’ HiSecure

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.


Overview

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

Feature Matrix

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.


What’s New in latest version

  • 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)

Developer Experience

  • 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

Quick Start

npm install hi-secure
import express from "express";
import { HiSecure } from "hi-secure";

const app = express();

app.use(HiSecure.middleware("api"));

app.listen(3000);

Core Helpers

Password Hashing

const hash = await HiSecure.hash(password);
const isValid = await HiSecure.verify(password, hash);

Input Validation

router.post(
  "/register",
  HiSecure.validate([...]),
  controller
);

Rate Limiting

HiSecure.rateLimit({ max: 5, windowMs: 15 * 60 * 1000 });

Global CORS Configuration

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.


Basic Global CORS

Enable CORS globally using default configuration.

app.use(
  HiSecure.middleware({
    cors: true
  })
);

Custom Global CORS

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
    }
  })
);

Multiple Client Applications

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
    }
  })
);

Public API (Open Read Access)

Use open CORS rules for public or read-only APIs.

app.use(
  HiSecure.middleware({
    cors: {
      origin: "*",
      methods: ["GET"]
    }
  })
);

Route-Level Security (Advanced & Real-World Usage)

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.


Custom CORS (Deep Control)

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
);

Validation (Schema vs Rules β€” When to Use What)

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

express-validator (Rule-Based, Inline)

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
);

Zod (Schema-Based, Reusable)

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 (Trust Boundaries)

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
);

Full Route-Level Security Composition

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 Mode

JWT support is optional. Enable it only if you want authentication features.

HiSecure.resetInstance();

HiSecure.getInstance({
  auth: {
    enabled: true,
    jwtSecret: process.env.JWT_SECRET,
    jwtExpiresIn: "1d"
  }
});

πŸ” Final Authentication Setup

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.

Features Covered

  • 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

Application Bootstrap (server.js / app.js)

import express from "express";
import dotenv from "dotenv";
import { HiSecure } from "hi-secure";
import authRoutes from "./routes/auth.routes.js";

dotenv.config();

const app = express();

HiSecure.resetInstance();

HiSecure.getInstance({
  auth: {
    enabled: true,
    jwtSecret: process.env.JWT_SECRET || "supersecret_32_chars_minimum",
    jwtExpiresIn: "1d",
    googleClientId: process.env.GOOGLE_CLIENT_ID   // this only added if need googleLogin as well
  }
});

app.use(HiSecure.middleware("api"));

app.use("/auth", authRoutes);

app.listen(3000);

Note: resetInstance() is recommended only for tests or starter templates. It should not be used repeatedly in production runtime.


Authentication Routes

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;

Authentication Controllers

Signup (Email and Password)


import { HiSecure } from "hi-secure";
import { HttpError } from "../core/errors/HttpError.js";
import User from "../models/User.js";


const JWT_OPTIONS = {
    issuer: 'hi-secure-backend',
    audience: ['web-app', 'mobile-app'],
    expiresIn: '7d',
    subject: 'user-authentication'
};


exports.registerUser = async(req, res) => {
    try {
        const { name, email, password } = req.body;

        const existingUser = await User.findOne({ email });
        if (existingUser) {
            return res.status(400).json({
                error: 'User already exists'
            });
        }

        const hashedPassword = await HiSecure.hash(password);

        const user = await User.create({
            name,
            email,
            password: hashedPassword
        });

        const token = HiSecure.jwt.sign({
                userId: user._id.toString(),
                email: user.email,
                name: user.name,
                role: 'user'
            },
            JWT_OPTIONS
        );

        res.status(201).json({
            message: 'User registered successfully',
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email
            }
        });

    } catch (error) {
        console.error('Registration error:', error);
        res.status(500).json({
            error: 'Registration failed',
            details: error.message
        });
    }
};


Login (Email and Password)



exports.loginUser = async(req, res) => {
    try {
        const { email, password } = req.body;

        const user = await User.findOne({ email });
        if (!user) {
            return res.status(401).json({
                error: 'Invalid credentials'
            });
        }

        const isValid = await HiSecure.verify(password, user.password);
        if (!isValid) {
            return res.status(401).json({
                error: 'Invalid credentials'
            });
        }

        const token = HiSecure.jwt.sign({
                userId: user._id.toString(),
                email: user.email,
                name: user.name,
                role: 'user'
            },
            JWT_OPTIONS
        );

        res.json({
            message: 'Login successful',
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email
            }
        });

    } catch (error) {
        console.error('Login error:', error);
        res.status(500).json({
            error: 'Login failed',
            details: error.message
        });
    }
};


Role-Based Protected Routes

app.get(
  "/admin",
  HiSecure.auth({ roles: ["admin"] }),
  (req, res) => {
    res.json({ message: "Welcome Admin" });
  }
);

const router = express.Router();
    router.post(
        '/register',

        HiSecure.validate([
            body("name")
            .notEmpty().withMessage("Name is required")
            .isLength({ min: 3 }).withMessage("Name must be at least 3 characters"),

            body("email")
            .notEmpty().withMessage("Email is required")
            .isEmail().withMessage("Invalid email format"),

            body("password")
            .notEmpty().withMessage("Password is required")
            .isLength({ min: 6 }).withMessage("Password must be at least 6 characters"),
        ]),

        registerUser
    );

    router.post(
        '/login',

        HiSecure.validate([
            body("email")
            .notEmpty().withMessage("Email is required")
            .isEmail().withMessage("Invalid email format"),

            body("password")
            .notEmpty().withMessage("Password is required")
        ]),

        HiSecure.rateLimit({ max: 5, windowMs: 15 * 60 * 1000 }),

        loginUser
    );

    router.get(
        '/profile',
        HiSecure.auth({ required: true }),
        getProfile
    );

    
    router.post('/create', HiSecure.auth({ required: true }), createTask)
    router.get('/get', HiSecure.auth({ required: true }), getTask)
    router.put('/:id', HiSecure.auth({ required: true }), updateTask)
    router.psot('/health',heatlh);


JWT Options (Optional)

HiSecure does not require JWT options for most use cases. Default configuration provided during initialization is sufficient.

HiSecure.getInstance({
  auth: {
    enabled: true,
    jwtSecret: process.env.JWT_SECRET,
    jwtExpiresIn: "1d"
  }
});

Advanced JWT options can be provided only when needed:

HiSecure.jwt.sign(
  {
    userId: user.id,
    roles: user.roles
  },
  {
    issuer: "my-app",
    audience: ["web", "mobile"],
    subject: "user-auth",
    expiresIn: "7d"
  }
);

JWT options are optional and intended for advanced authentication scenarios.


Rules to Remember

  • Initialize HiSecure once during application startup
  • Use resetInstance only for tests or starter templates
  • Do not initialize HiSecure inside controllers
  • Google login is used for identity verification only
  • Authorization is enforced using JWT payload and roles

Summary

HiSecure provides a complete, opinionated security layer for Express. It focuses on correctness, safety and developer productivity.

One dependency. One middleware. Complete security.


Additional Documentation

Advanced patterns, RBAC strategies, adapter extensions and deployment guides will be added over time.

About

HiSecure unifies authentication, validation, sanitization, rate-limiting, headers and parsing into a single, consistent security layer for Express applications.

Topics

Resources

Stars

Watchers

Forks