@mhiliger/auth-be
v1.0.4
Published
Shared authentication and JWT management for Express.js
Readme
@mhiliger/auth-be
Shared authentication backend for Express.js applications. This package provides a generic, database-agnostic framework for:
- Secure JWT (JSON Web Token) issuance and verification.
- User registration workflow (Sign up -> Verify Email -> Admin Approve -> Set Password).
- Role-based access control middleware.
- Extensible adapter pattern (HTTP or Database).
Installation
npm install @mhiliger/auth-be express jsonwebtoken express-rate-limit axiosSetup
1. Configure Adapter
The library uses an adapter pattern to interact with identity data. For most applications, you should use the HttpAdapter to delegate to a central identity service.
Using the HttpAdapter (Recommended):
This allows your application to authenticate users without connecting directly to the database.
const axios = require("axios");
const { createHttpAdapter } = require("@mhiliger/auth-be");
const authAdapter = createHttpAdapter(axios, process.env.IDENTITY_SERVICE_URL);
module.exports = authAdapter;Using the built-in Postgres Adapter (Master Identity Service only):
The package includes a createPostgresAdapter for the service that owns the database. This requires a database connection object (e.g., from pg-promise).
// This should typically only be used by the central identity service
const { createPostgresAdapter } = require("@mhiliger/auth-be");
const db = require("./db"); // Your pg-promise database instance
const authAdapter = createPostgresAdapter(db);
module.exports = authAdapter;2. Configure Email Service
The registration workflow requires an email service. Implement an object with the following methods:
const emailService = {
sendVerificationEmail: async (user, token) => { ... },
sendAdminNotification: async (user, adminEmail) => { ... },
sendApprovalEmail: async (user, token) => { ... },
sendRejectionEmail: async (user, reason) => { ... },
sendPasswordResetEmail: async (user, token) => { ... }
};3. Initialize Express App
Mount the auth and registration routers in your Express application.
const express = require("express");
const cookieParser = require("cookie-parser");
const { createAuthRouter, createRegistrationRouter, createVerifyJWT } = require("@mhiliger/auth-be");
const authAdapter = require("./db");
const emailService = require("./services/email");
const app = express();
app.use(express.json());
app.use(cookieParser());
const authConfig = {
accessTokenSecret: process.env.ACCESS_TOKEN_SECRET,
refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET,
accessTokenLife: "15m",
refreshTokenLife: "1d",
};
// 1. Mount Auth Routes (Login, Refresh, Logout)
app.use("/api/auth", createAuthRouter({
db: authAdapter,
config: authConfig
}));
// 2. Configure JWT Verification Middleware
const verifyJWT = createVerifyJWT({
accessTokenSecret: authConfig.accessTokenSecret,
onVerifySuccess: (req, decoded) => {
// Map decoded token data to request object
req.user = decoded;
req.permissions = decoded.permissions;
}
});
// 3. Mount Registration Routes
app.use("/api/register", createRegistrationRouter({
db: authAdapter,
verifyJWT: verifyJWT,
config: {
verificationTokenLife: "24h",
passwordSetupTokenLife: "48h",
onRegistrationSubmit: (user, token) => emailService.sendVerificationEmail(user, token),
onEmailVerified: (user) => emailService.sendAdminNotification(user, process.env.ADMIN_EMAIL),
onApproval: (user, token) => emailService.sendApprovalEmail(user, token),
onRejection: (user, reason) => emailService.sendRejectionEmail(user, reason),
onPasswordReset: (user, token) => emailService.sendPasswordResetEmail(user, token),
}
}));
app.listen(3000, () => console.log("Server running"));API Reference
createAuthRouter({ db, config })
Creates authentication endpoints.
POST /(Login)GET /refresh(Refresh Token)POST /logout(Logout)
createRegistrationRouter({ db, verifyJWT, config })
Creates registration and password management endpoints.
POST /submit(Public: Initial registration)GET /verify/:token(Public: Email verification)POST /setup/:token(Public: Password setup)GET /admin/list(Admin: List pending requests)POST /admin/approve/:id(Admin: Approve request)POST /admin/reject/:id(Admin: Reject request)
