import { describe, expect, it } from 'vitest'; import type { CommandDef, SlashCommandPayload } from '@mosaicstack/types'; import { CommandAuthorizationService } from './command-authorization.service.js'; const adminCommand: CommandDef = { name: 'gc', description: 'GC', aliases: [], scope: 'admin', execution: 'socket', available: true, }; const payload: SlashCommandPayload = { command: 'gc', conversationId: 'conversation-1' }; function createService( role: string, entries: Map = new Map(), ): CommandAuthorizationService { const db = { select: () => ({ from: () => ({ where: () => ({ limit: async () => [{ role }] }) }) }), }; const redis = { get: async (key: string) => entries.get(key) ?? null, set: async (key: string, value: string) => { entries.set(key, value); }, del: async (key: string) => Number(entries.delete(key)), }; return new CommandAuthorizationService(db as never, redis); } describe('CommandAuthorizationService', () => { it('consumes one exact actor-bound approval once', async (): Promise => { const service = createService('admin'); const approval = await service.createApproval(adminCommand, payload, 'admin-1'); expect(approval).not.toBeNull(); expect( (await service.authorize(adminCommand, payload, 'admin-1', approval!.approvalId)).allowed, ).toBe(true); expect( (await service.authorize(adminCommand, payload, 'admin-1', approval!.approvalId)).allowed, ).toBe(false); }); it('rejects an approval when the structured action is mutated', async (): Promise => { const service = createService('admin'); const approval = await service.createApproval(adminCommand, payload, 'admin-1'); const mutated = { ...payload, conversationId: 'other-conversation' }; expect(approval).not.toBeNull(); expect( (await service.authorize(adminCommand, mutated, 'admin-1', approval!.approvalId)).allowed, ).toBe(false); }); it('denies an admin command to a member before approval is considered', async (): Promise => { const service = createService('member'); const approval = await service.createApproval(adminCommand, payload, 'member-1'); expect(approval).toBeNull(); expect( (await service.authorize(adminCommand, payload, 'member-1', 'forged-approval-id')).allowed, ).toBe(false); }); it('denies a malformed durable approval expiry instead of treating it as unexpired', async (): Promise => { const entries = new Map(); const action = { providerId: 'fleet', sessionId: 'nova', actorId: 'admin-1', tenantId: 'tenant-1', channelId: 'discord:operator', correlationId: 'correlation-malformed-expiry', agentName: 'Nova', }; const service = createService('admin', entries); const approval = await service.createRuntimeTerminationApproval(action); expect(approval).not.toBeNull(); const key = `agent:Nova:command-approval:${approval!.approvalId}`; const stored = entries.get(key); expect(stored).toBeDefined(); entries.set(key, JSON.stringify({ ...JSON.parse(stored!), expiresAt: 'not-a-date' })); expect(await service.consumeRuntimeTerminationApproval(approval!.approvalId, action)).toBe( false, ); }); it('persists and consumes one exact runtime termination approval across a service restart', async (): Promise => { const entries = new Map(); const action = { providerId: 'fleet', sessionId: 'nova', actorId: 'admin-1', tenantId: 'tenant-1', channelId: 'discord:operator', correlationId: 'correlation-1', agentName: 'Nova', }; const beforeRestart = createService('admin', entries); const approval = await beforeRestart.createRuntimeTerminationApproval(action); const afterRestart = createService('admin', entries); expect( await afterRestart.consumeRuntimeTerminationApproval(approval!.approvalId, { ...action, sessionId: 'forged-session', }), ).toBe(false); expect(await afterRestart.consumeRuntimeTerminationApproval(approval!.approvalId, action)).toBe( true, ); expect(await afterRestart.consumeRuntimeTerminationApproval(approval!.approvalId, action)).toBe( false, ); }); });