UNPKG

@brandazm/dynamic-permissions

Version:

A flexible and powerful permissions management system for NestJS applications with built-in security features

188 lines 6.74 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const path = __importStar(require("path")); const fs = __importStar(require("fs")); const util_1 = require("util"); const execAsync = (0, util_1.promisify)(child_process_1.exec); const cliPath = path.resolve(__dirname, '../../dist/bin/nestjs-permissions-cli.js'); const testDir = path.resolve(__dirname, '../../test-cli'); const originalCwd = process.cwd(); describe('nestjs-permissions CLI', () => { beforeAll(async () => { await execAsync('npm run build'); if (!fs.existsSync(testDir)) { fs.mkdirSync(testDir, { recursive: true }); } const configDir = path.join(testDir, 'config'); if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } const migrationsDir = path.join(testDir, 'src', 'migrations'); if (!fs.existsSync(migrationsDir)) { fs.mkdirSync(migrationsDir, { recursive: true }); } const configContent = `export default { database: { type: 'sqlite', entities: { permissions: { tableName: 'permissions', fields: { id: 'id', name: 'name' } }, routerPermissions: { tableName: 'router_permissions', fields: { id: 'id', route: 'route', method: 'method', permissionId: 'permission_id' } }, userPermissions: { tableName: 'user_permissions', fields: { id: 'id', userId: 'user_id', permissionId: 'permission_id', grantedAt: 'granted_at' } } } }, permissions: { defaultRole: 'user', adminRole: 'admin', permissionStrategy: 'whitelist', publicRoutes: [] }, security: { rateLimit: { enabled: true, windowMs: '900000', max: '100' }, cors: { enabled: true, allowedOrigins: ['http://localhost:3000'], allowedMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], allowedHeaders: ['Content-Type', 'Authorization'], exposedHeaders: ['X-Total-Count'], credentials: true }, helmet: { enabled: true, contentSecurityPolicy: true, crossOriginEmbedderPolicy: true, crossOriginOpenerPolicy: true, crossOriginResourcePolicy: true, dnsPrefetchControl: true, frameguard: true, hidePoweredBy: true, hsts: true, ieNoOpen: true, noSniff: true, referrerPolicy: true, xssFilter: true }, requestValidation: { maxBodySize: '10485760', requireJsonContent: true, validateContentType: true }, enableCaching: true, cacheTimeout: '3600', enableAuditLog: true } };`; fs.writeFileSync(path.join(configDir, 'permissions.config.ts'), configContent); }); beforeEach(() => { process.chdir(testDir); const files = fs.readdirSync(testDir); for (const file of files) { if (file !== 'config' && file !== 'src') { fs.rmSync(path.join(testDir, file), { recursive: true, force: true }); } } const migrationsDir = path.join(testDir, 'src', 'migrations'); if (fs.existsSync(migrationsDir)) { const migrationFiles = fs.readdirSync(migrationsDir); for (const file of migrationFiles) { fs.rmSync(path.join(migrationsDir, file), { force: true }); } } }); afterEach(() => { process.chdir(originalCwd); }); afterAll(() => { if (fs.existsSync(testDir)) { fs.rmSync(testDir, { recursive: true, force: true }); } process.chdir(originalCwd); }); it('should show version and help information', async () => { const { stdout: versionOutput } = await execAsync(`node ${cliPath} --version`); expect(versionOutput.trim()).toMatch(/\d+\.\d+\.\d+/); const { stdout: helpOutput } = await execAsync(`node ${cliPath} --help`); expect(helpOutput).toContain('NestJS Permissions CLI'); expect(helpOutput).toContain('Commands:'); }); it('should validate configuration', async () => { process.chdir(testDir); const { stdout } = await execAsync(`node ${cliPath} validate-config`); expect(stdout).toContain('Configuration is valid'); }); it('should list security templates', async () => { const { stdout } = await execAsync(`node ${cliPath} list-security-templates`); expect(stdout).toContain('Available security templates'); expect(stdout).toContain('Basic Security'); }); it('should generate migration with custom name', async () => { process.chdir(testDir); const migrationsDir = path.join(testDir, 'src', 'migrations'); const migrationName = 'TestMigration'; await execAsync(`node ${cliPath} generate-migration -n ${migrationName} -d ${migrationsDir}`); expect(fs.existsSync(migrationsDir)).toBeTruthy(); const migrationFiles = fs.readdirSync(migrationsDir); expect(migrationFiles.some(file => file.toLowerCase().includes(migrationName.toLowerCase()))).toBeTruthy(); }); }); //# sourceMappingURL=nestjs-permissions-cli.test.js.map