feat(#709): add configured Discord interaction binding #730

Merged
jason.woltje merged 10 commits from feat/tess-discord into main 2026-07-13 09:02:46 +00:00
2 changed files with 30 additions and 1 deletions
Showing only changes of commit 533e970259 - Show all commits

View File

@@ -668,7 +668,18 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
);
const actorId = binding && resolveDiscordInteractionActorId(binding, ingress.userId);
const agentName = process.env['MOSAIC_AGENT_NAME']?.trim();
if (!actorId || !agentName || binding.instanceId !== agentName) return;
if (!actorId || !agentName || binding.instanceId !== agentName) {
this.logger.warn(
`Rejected Discord approval without a matching runtime agent from ${client.id}`,
);
client.emit('discord:approval', {
correlationId: ingress.correlationId,
success: false,
approvalId: undefined,
expiresAt: undefined,
});
return;
}
const providerId = actionParts[1]!;
const sessionId = actionParts[2]!;
const approval = await this.commandAuthorization.createRuntimeTerminationApproval({

View File

@@ -271,6 +271,24 @@ describe('Discord ingress security', () => {
]);
});
it('rejects approval when the binding targets a different runtime agent', async () => {
configureDiscordEnv();
process.env['MOSAIC_AGENT_NAME'] = 'Other';
const { gateway, client } = discordGateway('admin');
await gateway.handleDiscordApproval(
client as never,
ingressEnvelope('/approve fleet runtime-1', 'mismatched-agent-approve'),
);
expect(client.emit).toHaveBeenCalledWith('discord:approval', {
correlationId: 'correlation-001',
success: false,
approvalId: undefined,
expiresAt: undefined,
});
});
it('rejects unpaired and non-admin Discord users for approval and stop', async () => {
configureDiscordEnv();
const { gateway, client } = discordGateway('member');