Skip to content

Commit

Permalink
Fix lack of Tachyon message validation in client
Browse files Browse the repository at this point in the history
Unfortunatelly JSON.parse returns `any` not `unknown` so type
checking didn't caought this mistake.
  • Loading branch information
p2004a committed Jun 9, 2024
1 parent b545a3c commit 5af5f85
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
40 changes: 33 additions & 7 deletions src/tachyonClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { once } from 'node:events';
import { TachyonClient } from './tachyonClient.js';
import { createTachyonServer } from './tachyonServer.fake.js';
import { deepEqual } from 'node:assert';
import { TachyonMessage } from './tachyonTypes.js';
import { TachyonMessage, TachyonResponseOk } from './tachyonTypes.js';

// Let's reuse the same server for all tests to make them quicker.
const server = await createTachyonServer({ clientId: 'c', clientSecret: 's' });
Expand All @@ -14,6 +14,13 @@ const port = server.fastifyServer.addresses()[0].port;
after(() => server.close());
afterEach(() => server.removeAllListeners());

const connectionParams = {
clientId: 'c',
clientSecret: 's',
hostname: 'localhost',
port,
};

test('simple full example', async () => {
server.on('connection', (conn) => {
conn.on('message', (msg) => {
Expand All @@ -29,12 +36,7 @@ test('simple full example', async () => {
});
});

const client = new TachyonClient({
clientId: 'c',
clientSecret: 's',
hostname: 'localhost',
port,
});
const client = new TachyonClient(connectionParams);
await once(client, 'connected');
client.send({
type: 'request',
Expand All @@ -52,4 +54,28 @@ test('simple full example', async () => {
client.close();
});

test("doesn't emit bad tachyon messages", async () => {
server.on('connection', (conn) => {
conn.on('message', () => {
conn.send({
type: 'asdasdasd',
} as unknown as TachyonResponseOk);
});
});
const client = new TachyonClient(connectionParams);
await once(client, 'connected');
client.send({
type: 'request',
commandId: 'test/command',
messageId: 'test-message1',
data: { test: 'test' },
});
let gotMessages = 0;
client.on('message', () => {
++gotMessages;
});
await once(client, 'close');
equal(gotMessages, 0);
});

// TODO: Add more tests then only a simple happy path.
7 changes: 4 additions & 3 deletions src/tachyonClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* and the client can send messages to the server.
*/
import { TypedEmitter } from 'tiny-typed-emitter';
import { TachyonMessage, TACHYON_PROTOCOL_VERSION } from './tachyonTypes.js';
import { parseTachyonMessage, TachyonMessage, TACHYON_PROTOCOL_VERSION } from './tachyonTypes.js';
import { getAccessToken } from './oauth2Client.js';
import WebSocket from 'ws';

Expand Down Expand Up @@ -95,14 +95,15 @@ export class TachyonClient extends TypedEmitter<{
this.close();
return;
}
let tachyonMsg: TachyonMessage;
try {
const tachyonMsg = JSON.parse(msg.toString('utf-8'));
this.emit('message', tachyonMsg);
tachyonMsg = parseTachyonMessage(msg.toString('utf-8'));
} catch (e) {
ws.close(1008, 'Failed to parse base tachyon message');
this.close();
return;
}
this.emit('message', tachyonMsg);
});
}

Expand Down

0 comments on commit 5af5f85

Please sign in to comment.