@zakyyudha/node-authzkit
v1.1.0
Published
A very simple Node.js authorization library
Maintainers
Readme
node-authzkit
node-authzkit is a TypeScript library for Node.js that provides role and permission management. It allows you to define roles and permissions, assign them to "authorizable" entities (like users), and easily check for access rights.
Features
- Role and Permission Definition: Programmatically define permissions and roles with associated permissions.
- Assignment: Assign roles and direct permissions to any entity that implements the
Authorizableinterface. - Revocation: Revoke roles and direct permissions.
- Access Checks: Convenient methods to check if an entity has a specific role or permission (either directly or via an assigned role).
- Multiple Backends: Supports In-Memory, MongoDB, and PostgreSQL storages out of the box.
- Dynamic Configuration: Customize database connection details and collection/table names via configuration.
- Express.js Middleware: Includes an Express.js middleware for easy route protection based on roles and permissions.
- Dashboard: Comes with a built-in dashboard for managing roles and permissions (source code included).
Installation
pnpm install @zakyyudha/node-authzkit
# or npm install @zakyyudha/node-authzkit
# or yarn add @zakyyudha/node-authzkitQuick Start
1. Initialize Authzkit
First, initialize the Authzkit singleton. You can provide a custom store, or it will default to InMemoryAuthzkitStore.
// src/main.ts
import { Authzkit, InMemoryAuthzkitStore } from 'node-authzkit';
const authzkit = Authzkit.getInstance(new InMemoryAuthzkitStore());
// Or, if you don't provide a store, it defaults to InMemoryAuthzkitStore
// const authzkit = Authzkit.getInstance();
export default authzkit;2. persistence with MongoDB or PostgreSQL
You use IAuthzkitConfig to configure connection details and custom table/collection names.
MongoDB Example:
import { Authzkit, MongoConnection, MongoAuthzkitStore, IAuthzkitConfig } from 'node-authzkit';
const config: IAuthzkitConfig = {
connection: {
type: 'mongodb',
uri: 'mongodb://localhost:27017',
database: 'my_app_db'
},
models: { // Optional custom collection names
users: 'users',
roles: 'app_roles',
permissions: 'app_permissions'
}
};
async function init() {
const mongoConnection = MongoConnection.getInstance(config);
await mongoConnection.connect();
const store = new MongoAuthzkitStore(mongoConnection);
const authzkit = Authzkit.getInstance(store);
}PostgreSQL Example:
import { Authzkit, PgConnection, PgAuthzkitStore, IAuthzkitConfig } from 'node-authzkit';
const config: IAuthzkitConfig = {
connection: {
type: 'postgres',
uri: 'postgresql://user:pass@localhost:5432/my_app_db'
}
};
async function init() {
const pgConnection = PgConnection.getInstance(config);
await pgConnection.connect();
await pgConnection.initSchema(); // Creates tables if they don't exist
const store = new PgAuthzkitStore(pgConnection);
const authzkit = Authzkit.getInstance(store);
}3. Usage
// Define
await authzkit.definePermission('edit_posts');
await authzkit.defineRole('editor', ['edit_posts']);
// Assign
const user = { id: 123 }; // Authorizable entity
await authzkit.assignRole(user, 'editor');
// Check
if (await authzkit.hasPermission(user, 'edit_posts')) {
console.log('User can edit posts');
}4. Express Middleware
import { authorize } from 'node-authzkit';
app.post('/posts', authorize('edit_posts'), (req, res) => {
// ...
});Example: Express + MongoDB (In-Memory) Step-by-Step
Use this for local development or tests when you want a real MongoDB-backed store without installing MongoDB.
1. Install Dependencies
pnpm add @zakyyudha/node-authzkit express mongodb
pnpm add -D mongodb-memory-server ts-node typescript2. Create an Express App
// examples/express-mongo-memory.ts
import express from 'express';
import { MongoMemoryServer } from 'mongodb-memory-server';
import { MongoClient } from 'mongodb';
import {
Authzkit,
MongoAuthzkitStore,
MongoConnection,
authorize,
IAuthzkitConfig,
} from 'node-authzkit';
async function bootstrap() {
// 1) Start an in-memory MongoDB server
const mongoServer = await MongoMemoryServer.create({
instance: { dbName: 'authzkit_demo' },
});
// 2) Build Authzkit config
const uri = mongoServer.getUri();
const config: IAuthzkitConfig = {
connection: {
type: 'mongodb',
uri,
database: 'authzkit_demo',
},
};
// 3) Connect Mongo client and initialize Authzkit store
const client = new MongoClient(uri);
await client.connect();
const mongoConnection = MongoConnection.getInstance(config, client);
await mongoConnection.connect();
const store = new MongoAuthzkitStore(mongoConnection);
const authzkit = Authzkit.getInstance(store);
// 4) Define permissions/roles
await authzkit.definePermission('edit_posts');
await authzkit.defineRole('editor', ['edit_posts']);
const user = { id: 'user_1' };
await authzkit.assignRole(user, 'editor');
// 5) Express app with authorization middleware
const app = express();
app.get('/posts', (req, res) => {
res.send('Public posts');
});
app.post('/posts', authorize('edit_posts'), (req, res) => {
res.send('Post created');
});
const server = app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
// 6) Graceful shutdown
process.on('SIGINT', async () => {
await mongoConnection.disconnect();
await client.close();
await mongoServer.stop();
server.close(() => process.exit(0));
});
}
bootstrap().catch((err) => {
console.error('Failed to start:', err);
process.exit(1);
});3. Run the App
pnpm ts-node examples/express-mongo-memory.ts4. Try It
curl http://localhost:3000/posts
curl -X POST http://localhost:3000/postsYou can replace the in-memory server with a real MongoDB URI later by changing the config and removing mongodb-memory-server.
Dashboard
This project includes a built-in dashboard to manage Roles, Permissions, and User Assignments visually.
Integration in Express
You can easily mount the dashboard into your existing Express application.
Install dependencies: The dashboard requires
expressandbasic-auth.pnpm install express basic-authMount the Router:
import express from 'express'; import { Authzkit, InMemoryAuthzkitStore, createDashboardRouter } from 'node-authzkit'; const app = express(); const authzkit = Authzkit.getInstance(new InMemoryAuthzkitStore()); // Mount the dashboard at /authzkit app.use('/authzkit', createDashboardRouter({ authzkit, // Optional, defaults to singleton secret: 'supersecret', // Password for Basic Auth (User: admin) username: 'admin', // Optional, defaults to 'admin' jwtSecret: 'supersecret', // Optional, defaults to AUTHZKIT_DASHBOARD_JWT_SECRET or `secret` jwtExpiresIn: '1h' // Optional, defaults to AUTHZKIT_DASHBOARD_JWT_EXPIRES_IN or '1h' })); app.listen(3000);Access: Go to
http://localhost:3000/authzkit/and log in with the credentials you configured.
Using Environment Variables
You can configure node-authzkit stores using environment variables.
Set Environment Variables:
# Connection (required when using loadConfigFromEnv) AUTHZKIT_CONNECTION_TYPE=mongodb|postgres AUTHZKIT_CONNECTION_URI=mongodb://localhost:27017/mydb AUTHZKIT_DB_NAME=mydb # Optional model/collection overrides AUTHZKIT_MODEL_USERS=users AUTHZKIT_MODEL_ROLES=roles AUTHZKIT_MODEL_PERMISSIONS=permissions AUTHZKIT_MODEL_USER_ROLES=user_roles AUTHZKIT_MODEL_USER_PERMISSIONS=user_permissions # Dashboard Basic Auth AUTHZKIT_DASHBOARD_USERNAME=adminuser AUTHZKIT_DASHBOARD_SECRET=mysecretpassword # Dashboard API JWT AUTHZKIT_DASHBOARD_JWT_SECRET=myjwtsecret AUTHZKIT_DASHBOARD_JWT_EXPIRES_IN=1hNotes:
- If
AUTHZKIT_CONNECTION_TYPEis omitted butAUTHZKIT_CONNECTION_URIis set, the type is inferred from the URI prefix (mongodborpostgres). - Dashboard JWT secret defaults to
AUTHZKIT_DASHBOARD_JWT_SECRETor falls back toAUTHZKIT_DASHBOARD_SECRET. - Dashboard JWT expiry defaults to
AUTHZKIT_DASHBOARD_JWT_EXPIRES_INor1h.
- If
Load Configuration:
import { loadConfigFromEnv, MongoConnection, PgConnection, Authzkit, MongoAuthzkitStore, PgAuthzkitStore } from 'node-authzkit'; const config = loadConfigFromEnv(); if (config) { if (config.connection.type === 'mongodb') { const conn = MongoConnection.getInstance(config); await conn.connect(); Authzkit.getInstance(new MongoAuthzkitStore(conn)); } else if (config.connection.type === 'postgres') { const conn = PgConnection.getInstance(config); await conn.connect(); Authzkit.getInstance(new PgAuthzkitStore(conn)); } }
Dashboard API Authentication (JWT)
The dashboard UI is protected with Basic Auth, while the API requires a short-lived JWT. The frontend requests a token from:
POST /authzkit/api/auth/tokenThen it sends:
Authorization: Bearer <token>You can also call the API directly if you first obtain a token (the token expires based on AUTHZKIT_DASHBOARD_JWT_EXPIRES_IN).
API Documentation
Authzkit Class
The main singleton class.
static getInstance(store?: IAuthzkitStore): AuthzkitdefinePermission(name: string, guard_name?: string): Promise<Permission>defineRole(name: string, permissions: string[], guard_name?: string): Promise<Role>deletePermission(name: string): Promise<void>deleteRole(name: string): Promise<void>assignRole(authorizable: Authorizable, roleName: string): Promise<void>assignPermission(authorizable: Authorizable, permissionName: string): Promise<void>revokeRole(authorizable: Authorizable, roleName: string): Promise<void>revokePermission(authorizable: Authorizable, permissionName: string): Promise<void>hasRole(authorizable: Authorizable, roleName: string): Promise<boolean>hasPermission(authorizable: Authorizable, permissionName: string): Promise<boolean>getRoles(): Promise<Role[]>getPermissions(): Promise<Permission[]>getUserRoles(authorizable: Authorizable): Promise<Set<string>>getUserPermissions(authorizable: Authorizable): Promise<Set<string>>addPermissionToRole(roleName: string, permissionName: string): Promise<Role>removePermissionFromRole(roleName: string, permissionName: string): Promise<Role>
License
ISC
