UNPKG

@mamoorali295/rbac

Version:

Complete RBAC (Role-Based Access Control) system for Node.js with Express middleware, NestJS integration, GraphQL support, MongoDB & PostgreSQL support, modern admin dashboard, TypeScript support, and dynamic permission management

292 lines (291 loc) 12 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoAdapter = void 0; const DatabaseAdapter_1 = require("./DatabaseAdapter"); const User_1 = require("../mongo/models/User"); const UserRole_1 = require("../mongo/models/UserRole"); const Feature_1 = require("../mongo/models/Feature"); const Permission_1 = require("../mongo/models/Permission"); class MongoAdapter extends DatabaseAdapter_1.DatabaseAdapter { constructor(connection) { super(); this.connection = connection; } init() { return __awaiter(this, void 0, void 0, function* () { yield this.createStandardPermissions(); }); } createStandardPermissions() { return __awaiter(this, void 0, void 0, function* () { const standardPermissions = [ { name: 'read', description: 'View and access resources' }, { name: 'create', description: 'Add new resources' }, { name: 'update', description: 'Modify existing resources' }, { name: 'delete', description: 'Remove resources' }, { name: 'sudo', description: 'Full administrative access' } ]; for (const permissionData of standardPermissions) { const existingPermission = yield Permission_1.Permission.findOne({ name: permissionData.name }); if (!existingPermission) { const permission = new Permission_1.Permission(permissionData); yield permission.save(); } } }); } // User operations createUser(userData) { return __awaiter(this, void 0, void 0, function* () { const user = new User_1.User(userData); yield user.save(); return user.toObject(); }); } findUserByUserId(user_id) { return __awaiter(this, void 0, void 0, function* () { const user = yield User_1.User.findOne({ user_id }); return user ? user.toObject() : null; }); } findUserByUserIdWithRole(user_id) { return __awaiter(this, void 0, void 0, function* () { const user = yield User_1.User.findOne({ user_id }) .populate({ path: "role", populate: { path: "features.feature features.permissions", }, }) .exec(); return user ? user.toObject() : null; }); } updateUser(user_id, updates) { return __awaiter(this, void 0, void 0, function* () { // Handle role_id to role field mapping for MongoDB const mongoUpdates = Object.assign({}, updates); if (updates.role_id !== undefined) { mongoUpdates.role = updates.role_id; delete mongoUpdates.role_id; } yield User_1.User.updateOne({ user_id }, mongoUpdates); }); } deleteUser(user_id) { return __awaiter(this, void 0, void 0, function* () { yield User_1.User.deleteOne({ user_id }); }); } getAllUsers(limit, offset, search) { return __awaiter(this, void 0, void 0, function* () { let query = {}; if (search) { query = { $or: [ { user_id: { $regex: search, $options: 'i' } }, { name: { $regex: search, $options: 'i' } }, { email: { $regex: search, $options: 'i' } } ] }; } const total = yield User_1.User.countDocuments(query); let userQuery = User_1.User.find(query).populate('role', 'name').sort({ createdAt: -1 }); if (limit) userQuery = userQuery.limit(limit); if (offset) userQuery = userQuery.skip(offset); const users = yield userQuery.exec(); return { items: users.map(u => u.toObject()), total }; }); } // Role operations createRole(roleData) { return __awaiter(this, void 0, void 0, function* () { const role = new UserRole_1.UserRole(roleData); yield role.save(); return role.toObject(); }); } findRoleByName(name) { return __awaiter(this, void 0, void 0, function* () { const role = yield UserRole_1.UserRole.findOne({ name }); return role ? role.toObject() : null; }); } findRoleById(id) { return __awaiter(this, void 0, void 0, function* () { const role = yield UserRole_1.UserRole.findById(id); return role ? role.toObject() : null; }); } findRoleByIdWithFeatures(id) { return __awaiter(this, void 0, void 0, function* () { const role = yield UserRole_1.UserRole.findById(id) .populate({ path: "features.feature features.permissions", }) .exec(); return role ? role.toObject() : null; }); } updateRole(id, updates) { return __awaiter(this, void 0, void 0, function* () { yield UserRole_1.UserRole.updateOne({ _id: id }, updates); }); } deleteRole(id) { return __awaiter(this, void 0, void 0, function* () { yield User_1.User.updateMany({ role: id }, { $unset: { role: 1 } }); yield UserRole_1.UserRole.deleteOne({ _id: id }); }); } assignRoleFeaturePermissions(roleId, featurePermissions) { return __awaiter(this, void 0, void 0, function* () { const features = featurePermissions.map(fp => ({ feature: fp.feature_id, permissions: fp.permission_ids })); yield UserRole_1.UserRole.updateOne({ _id: roleId }, { features }); }); } getAllRoles(limit, offset) { return __awaiter(this, void 0, void 0, function* () { const total = yield UserRole_1.UserRole.countDocuments(); let roleQuery = UserRole_1.UserRole.find().sort({ createdAt: -1 }); if (limit) roleQuery = roleQuery.limit(limit); if (offset) roleQuery = roleQuery.skip(offset); const roles = yield roleQuery.exec(); return { items: roles.map(r => r.toObject()), total }; }); } // Feature operations createFeature(featureData) { return __awaiter(this, void 0, void 0, function* () { const feature = new Feature_1.Feature(featureData); yield feature.save(); return feature.toObject(); }); } findFeatureByName(name) { return __awaiter(this, void 0, void 0, function* () { const feature = yield Feature_1.Feature.findOne({ name }); return feature ? feature.toObject() : null; }); } findFeatureById(id) { return __awaiter(this, void 0, void 0, function* () { const feature = yield Feature_1.Feature.findById(id); return feature ? feature.toObject() : null; }); } updateFeature(id, updates) { return __awaiter(this, void 0, void 0, function* () { yield Feature_1.Feature.updateOne({ _id: id }, updates); }); } deleteFeature(id) { return __awaiter(this, void 0, void 0, function* () { yield UserRole_1.UserRole.updateMany({}, { $pull: { features: { feature: id } } }); yield Feature_1.Feature.deleteOne({ _id: id }); }); } getAllFeatures(limit, offset) { return __awaiter(this, void 0, void 0, function* () { const total = yield Feature_1.Feature.countDocuments(); let featureQuery = Feature_1.Feature.find().sort({ createdAt: -1 }); if (limit) featureQuery = featureQuery.limit(limit); if (offset) featureQuery = featureQuery.skip(offset); const features = yield featureQuery.exec(); return { items: features.map(f => f.toObject()), total }; }); } // Permission operations createPermission(permissionData) { return __awaiter(this, void 0, void 0, function* () { const permission = new Permission_1.Permission(permissionData); yield permission.save(); return permission.toObject(); }); } findPermissionByName(name) { return __awaiter(this, void 0, void 0, function* () { const permission = yield Permission_1.Permission.findOne({ name }); return permission ? permission.toObject() : null; }); } findPermissionById(id) { return __awaiter(this, void 0, void 0, function* () { const permission = yield Permission_1.Permission.findById(id); return permission ? permission.toObject() : null; }); } updatePermission(id, updates) { return __awaiter(this, void 0, void 0, function* () { yield Permission_1.Permission.updateOne({ _id: id }, updates); }); } deletePermission(id) { return __awaiter(this, void 0, void 0, function* () { yield UserRole_1.UserRole.updateMany({}, { $pull: { "features.$[].permissions": id } }); yield Permission_1.Permission.deleteOne({ _id: id }); }); } getAllPermissions(limit, offset) { return __awaiter(this, void 0, void 0, function* () { const total = yield Permission_1.Permission.countDocuments(); let permissionQuery = Permission_1.Permission.find().sort({ createdAt: -1 }); if (limit) permissionQuery = permissionQuery.limit(limit); if (offset) permissionQuery = permissionQuery.skip(offset); const permissions = yield permissionQuery.exec(); return { items: permissions.map(p => p.toObject()), total }; }); } getUserFeaturePermissions(user_id, featureName) { return __awaiter(this, void 0, void 0, function* () { var _a; const user = yield User_1.User.findOne({ user_id }).populate({ path: "role", populate: { path: "features.feature features.permissions", }, }); if (!user || !user.role) { return []; } const role = user.role; const feature = (_a = role.features) === null || _a === void 0 ? void 0 : _a.find((f) => f.feature.name === featureName); if (!feature) { return []; } return feature.permissions.map((p) => p.name); }); } getDashboardStats() { return __awaiter(this, void 0, void 0, function* () { const [users, roles, features, permissions] = yield Promise.all([ User_1.User.countDocuments(), UserRole_1.UserRole.countDocuments(), Feature_1.Feature.countDocuments(), Permission_1.Permission.countDocuments() ]); return { users, roles, features, permissions }; }); } } exports.MongoAdapter = MongoAdapter;