@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
135 lines (134 loc) • 5.5 kB
JavaScript
;
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.PostgresPermission = void 0;
class PostgresPermission {
constructor(pool) {
this.pool = pool;
}
create(permissionData) {
return __awaiter(this, void 0, void 0, function* () {
const query = `
INSERT INTO rbac_permissions (name, description)
VALUES ($1, $2)
RETURNING *
`;
const values = [permissionData.name, permissionData.description];
const result = yield this.pool.query(query, values);
return result.rows[0];
});
}
findByName(name) {
return __awaiter(this, void 0, void 0, function* () {
const query = 'SELECT * FROM rbac_permissions WHERE name = $1';
const result = yield this.pool.query(query, [name]);
return result.rows[0] || null;
});
}
findById(id) {
return __awaiter(this, void 0, void 0, function* () {
const query = 'SELECT * FROM rbac_permissions WHERE id = $1';
const result = yield this.pool.query(query, [id]);
return result.rows[0] || null;
});
}
update(id, updates) {
return __awaiter(this, void 0, void 0, function* () {
const setClause = [];
const values = [];
let paramCount = 1;
if (updates.name !== undefined) {
setClause.push(`name = $${paramCount++}`);
values.push(updates.name);
}
if (updates.description !== undefined) {
setClause.push(`description = $${paramCount++}`);
values.push(updates.description);
}
if (setClause.length === 0)
return;
values.push(id);
const query = `
UPDATE rbac_permissions
SET ${setClause.join(', ')}, updated_at = CURRENT_TIMESTAMP
WHERE id = $${paramCount}
`;
yield this.pool.query(query, values);
});
}
delete(id) {
return __awaiter(this, void 0, void 0, function* () {
const client = yield this.pool.connect();
try {
yield client.query('BEGIN');
// Delete role-feature-permission relationships
yield client.query('DELETE FROM rbac_role_feature_permissions WHERE permission_id = $1', [id]);
// Delete the permission
yield client.query('DELETE FROM rbac_permissions WHERE id = $1', [id]);
yield client.query('COMMIT');
}
catch (error) {
yield client.query('ROLLBACK');
throw error;
}
finally {
client.release();
}
});
}
getAll(limit, offset) {
return __awaiter(this, void 0, void 0, function* () {
// Get total count
const countQuery = 'SELECT COUNT(*) FROM rbac_permissions';
const countResult = yield this.pool.query(countQuery);
const total = parseInt(countResult.rows[0].count);
// Get permissions with pagination and usage count
let query = `
SELECT p.*,
COUNT(DISTINCT rfp.role_id) as role_count
FROM rbac_permissions p
LEFT JOIN rbac_role_feature_permissions rfp ON p.id = rfp.permission_id
GROUP BY p.id, p.name, p.description, p.created_at, p.updated_at
ORDER BY p.created_at DESC
`;
const params = [];
let paramCount = 1;
if (limit) {
query += ` LIMIT $${paramCount++}`;
params.push(limit);
}
if (offset) {
query += ` OFFSET $${paramCount}`;
params.push(offset);
}
const result = yield this.pool.query(query, params);
return { permissions: result.rows, total };
});
}
createStandard() {
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 existing = yield this.findByName(permissionData.name);
if (!existing) {
yield this.create(permissionData);
}
}
});
}
}
exports.PostgresPermission = PostgresPermission;