backend-mcp
Version:
Generador automático de backends con Node.js, Express, Prisma y módulos configurables. Servidor MCP compatible con npx para agentes IA. Soporta PostgreSQL, MySQL, MongoDB y SQLite.
234 lines (196 loc) • 8.19 kB
JavaScript
/**
* Pruebas para el sistema de autenticación JWT
*/
const { validateJWT, hasToolPermission, extractToken, authenticateToolCall } = require('./jwt-auth');
const authConfig = require('./auth-config');
// Mock de https para las pruebas
jest.mock('https');
describe('JWT Authentication System', () => {
describe('extractToken', () => {
test('should extract token from command line arguments', () => {
const context = {
args: ['--jwt', 'test-token-123']
};
expect(extractToken(context)).toBe('test-token-123');
});
test('should extract token from environment variables', () => {
process.env.BACKEND_MCP_JWT = 'env-token-456';
const context = {};
expect(extractToken(context)).toBe('env-token-456');
delete process.env.BACKEND_MCP_JWT;
});
test('should extract token from MCP message params', () => {
const context = {
mcpMessage: {
params: {
arguments: {
jwt: 'mcp-token-789'
}
}
}
};
expect(extractToken(context)).toBe('mcp-token-789');
});
test('should return null when no token found', () => {
const context = {};
expect(extractToken(context)).toBeNull();
});
});
describe('hasToolPermission', () => {
test('should allow basic tools for basic plan', () => {
const userData = {
plan: 'basic',
permissions: ['basic']
};
expect(hasToolPermission(userData, 'configure_project')).toBe(true);
expect(hasToolPermission(userData, 'create_endpoint')).toBe(true);
});
test('should deny premium tools for basic plan', () => {
const userData = {
plan: 'basic',
permissions: ['basic']
};
expect(hasToolPermission(userData, 'setup_docker')).toBe(false);
expect(hasToolPermission(userData, 'setup_ci_cd')).toBe(false);
});
test('should allow premium tools for premium plan', () => {
const userData = {
plan: 'premium',
permissions: ['basic', 'premium']
};
expect(hasToolPermission(userData, 'configure_project')).toBe(true);
expect(hasToolPermission(userData, 'setup_docker')).toBe(true);
});
test('should allow all tools for enterprise plan', () => {
const userData = {
plan: 'enterprise',
permissions: ['basic', 'premium', 'enterprise']
};
expect(hasToolPermission(userData, 'configure_project')).toBe(true);
expect(hasToolPermission(userData, 'setup_docker')).toBe(true);
expect(hasToolPermission(userData, 'setup_microservices')).toBe(true);
});
test('should return false for invalid user data', () => {
expect(hasToolPermission(null, 'configure_project')).toBe(false);
expect(hasToolPermission({}, 'configure_project')).toBe(false);
expect(hasToolPermission({ plan: 'basic' }, 'configure_project')).toBe(false);
});
});
describe('validateJWT', () => {
test('should validate demo tokens', async () => {
const result = await validateJWT('demo_basic_token_2024');
expect(result).toBeDefined();
expect(result.plan).toBe('basic');
expect(result.permissions).toContain('basic');
});
test('should validate premium demo tokens', async () => {
const result = await validateJWT('demo_premium_token_2024');
expect(result).toBeDefined();
expect(result.plan).toBe('premium');
expect(result.permissions).toEqual(['basic', 'premium']);
});
test('should validate enterprise demo tokens', async () => {
const result = await validateJWT('demo_enterprise_token_2024');
expect(result).toBeDefined();
expect(result.plan).toBe('enterprise');
expect(result.permissions).toEqual(['basic', 'premium', 'enterprise']);
});
test('should reject invalid tokens', async () => {
await expect(validateJWT('invalid-token')).rejects.toThrow();
});
test('should handle empty token', async () => {
await expect(validateJWT('')).rejects.toThrow('Token JWT requerido');
});
test('should handle null token', async () => {
await expect(validateJWT(null)).rejects.toThrow('Token JWT requerido');
});
});
describe('authenticateToolCall', () => {
test('should authenticate with valid token', async () => {
const result = await authenticateToolCall('database_query', {}, {
jwt: 'demo_basic_token_2024'
});
expect(result.success).toBe(true);
expect(result.user).toBeDefined();
expect(result.user.plan).toBe('basic');
});
test('should reject without token', async () => {
const result = await authenticateToolCall('database_query', {}, {});
expect(result.success).toBe(false);
expect(result.error).toBeDefined();
expect(result.code).toBe('AUTH_REQUIRED');
});
test('should reject insufficient permissions', async () => {
const result = await authenticateToolCall('setup_microservices', {}, {
jwt: 'demo_basic_token_2024'
});
expect(result.success).toBe(false);
expect(result.code).toBe('INSUFFICIENT_PERMISSIONS');
expect(result.requiredPlan).toBe('enterprise');
expect(result.currentPlan).toBe('basic');
});
test('should handle development bypass', async () => {
// Enable development bypass
const originalBypass = authConfig.development.bypassAuth;
authConfig.development.bypassAuth = true;
const result = await authenticateToolCall('any_tool', {}, {});
expect(result.success).toBe(true);
expect(result.user.plan).toBe('enterprise');
// Restore original setting
authConfig.development.bypassAuth = originalBypass;
});
});
describe('Configuration', () => {
test('should have valid plan configurations', () => {
expect(authConfig.plans.basic).toBeDefined();
expect(authConfig.plans.premium).toBeDefined();
expect(authConfig.plans.enterprise).toBeDefined();
expect(authConfig.plans.basic.price).toBe(5);
expect(authConfig.plans.premium.price).toBe(15);
expect(authConfig.plans.enterprise.price).toBe(50);
});
test('should have valid tool permissions', () => {
expect(authConfig.toolPermissions.basic).toContain('configure_project');
expect(authConfig.toolPermissions.premium).toContain('setup_docker');
expect(authConfig.toolPermissions.enterprise).toContain('setup_microservices');
});
test('should have valid error messages', () => {
expect(authConfig.getMessage('noToken', 'es')).toContain('Autenticación requerida');
expect(authConfig.getMessage('invalidToken', 'en')).toContain('Invalid or expired');
});
test('should determine required plan correctly', () => {
expect(authConfig.getRequiredPlan('configure_project')).toBe('basic');
expect(authConfig.getRequiredPlan('setup_docker')).toBe('premium');
expect(authConfig.getRequiredPlan('setup_microservices')).toBe('enterprise');
expect(authConfig.getRequiredPlan('unknown_tool')).toBe('basic');
});
});
describe('Error Handling', () => {
test('should handle invalid tokens gracefully', async () => {
const result = await authenticateToolCall('configure_project', {}, {
jwt: 'invalid-malformed-token'
});
expect(result.success).toBe(false);
expect(result.code).toBe('INVALID_TOKEN');
});
});
});
// Pruebas de integración
describe('Integration Tests', () => {
test('should work with demo tokens from config', async () => {
const result = await authenticateToolCall('configure_project', {}, {
jwt: 'demo_basic_token_2024'
});
expect(result.success).toBe(true);
expect(result.user.plan).toBe('basic');
expect(result.user.permissions).toContain('basic');
});
});
// Cleanup después de las pruebas
afterEach(() => {
jest.clearAllMocks();
// Limpiar variables de entorno
delete process.env.BACKEND_MCP_JWT;
delete process.env.JWT_SECRET;
delete process.env.AUTH_API_URL;
});