Files
waggle-os/packages/server/tests/channels-routes-auth.test.ts
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

98 lines
3.5 KiB
TypeScript

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import Fastify, { type FastifyInstance } from 'fastify';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { ChannelManager } from '../src/local/channels/manager.js';
import { channelRoutes } from '../src/local/channels/routes.js';
import { securityMiddleware } from '../src/local/security-middleware.js';
describe('protected channel management routes', () => {
let server: FastifyInstance;
let dataDir: string;
let originalTrustLocalhost: string | undefined;
const secrets = new Map<string, string>();
beforeEach(async () => {
originalTrustLocalhost = process.env.WAGGLE_TRUST_LOCALHOST;
process.env.WAGGLE_TRUST_LOCALHOST = '0';
dataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'waggle-channel-routes-'));
secrets.clear();
server = Fastify();
const vault = {
get: (key: string) => secrets.has(key) ? { value: secrets.get(key)! } : null,
has: (key: string) => secrets.has(key),
set: (key: string, value: string) => { secrets.set(key, value); },
delete: (key: string) => secrets.delete(key),
};
const manager = new ChannelManager({
dataDir,
port: 3333,
sessionToken: 'channel-route-token',
vault,
log: { info: () => undefined, warn: () => undefined },
listWorkspaceIds: () => ['ws-1'],
adapterFactory: () => null,
});
server.decorate('vault', vault as never);
server.decorate('channelManager', manager);
server.decorate('workspaceManager', {
list: () => [{ id: 'ws-1', name: 'Client Alpha' }],
} as never);
await server.register(securityMiddleware, { sessionToken: 'channel-route-token' });
await server.register(channelRoutes);
await server.ready();
});
afterEach(async () => {
await server.close();
fs.rmSync(dataDir, { recursive: true, force: true });
if (originalTrustLocalhost === undefined) delete process.env.WAGGLE_TRUST_LOCALHOST;
else process.env.WAGGLE_TRUST_LOCALHOST = originalTrustLocalhost;
});
const auth = { authorization: 'Bearer channel-route-token' };
it('rejects unauthenticated local callers', async () => {
const response = await server.inject({ method: 'GET', url: '/api/channels' });
expect(response.statusCode).toBe(401);
expect(response.json()).toMatchObject({ code: 'MISSING_TOKEN' });
});
it('validates a config atomically and accepts a real workspace id', async () => {
const badSecret = await server.inject({
method: 'POST',
url: '/api/channels/slack/config',
headers: auth,
payload: {
secrets: {
slack_app_token: 'xapp-valid-first-value',
unexpected_secret: 'must-reject-the-whole-request',
},
},
});
expect(badSecret.statusCode).toBe(400);
expect(secrets.has('slack_app_token')).toBe(false);
const badWorkspace = await server.inject({
method: 'POST',
url: '/api/channels/telegram/config',
headers: auth,
payload: { defaultWorkspace: 'missing-workspace' },
});
expect(badWorkspace.statusCode).toBe(400);
const valid = await server.inject({
method: 'POST',
url: '/api/channels/telegram/config',
headers: auth,
payload: {
defaultWorkspace: 'ws-1',
secrets: { telegram_bot_token: '123456:valid-token-value' },
},
});
expect(valid.statusCode).toBe(200);
expect(secrets.get('telegram_bot_token')).toBe('123456:valid-token-value');
});
});