Files

72 lines
2.6 KiB
TypeScript
Raw Permalink Normal View History

import { ShadeSessionManager } from '../../packages/shade-core/src/index.js';
import { SubtleCryptoProvider, MemoryStorage } from '../../packages/shade-crypto-web/src/index.js';
import { ShadeWebSocket } from '../../packages/shade-transport/src/index.js';
const crypto = new SubtleCryptoProvider();
async function main() {
console.log('=== Shade WebSocket Tunnel ===\n');
// Set up Alice and Bob
const alice = new ShadeSessionManager(crypto, new MemoryStorage());
const bob = new ShadeSessionManager(crypto, new MemoryStorage());
await alice.initialize();
await bob.initialize();
// Establish session (skipping prekey server for brevity)
const otpks = await bob.generateOneTimePreKeys(5);
const bundle = await bob.createPreKeyBundle();
bundle.oneTimePreKey = { keyId: otpks[0].keyId, publicKey: otpks[0].keyPair.publicKey };
await alice.initSessionFromBundle('bob', bundle);
// Pair of WebSockets connected to each other
// Use Bun's built-in WebSocket server + client for the demo
const port = 19851;
const messages: string[] = [];
const server = Bun.serve({
port,
fetch(req, srv) {
if (srv.upgrade(req)) return;
return new Response('upgrade failed', { status: 500 });
},
websocket: {
async message(ws, message) {
// Server side decrypts (acts as Bob)
const bytes = message instanceof Uint8Array ? message : new Uint8Array(Buffer.from(message as string));
// Need to manually use ShadeWebSocket or do raw decoding
console.log(`[Bob received ${bytes.length} encrypted bytes]`);
// Forward to Bob's session
const { decodeEnvelope } = await import('../../packages/shade-proto/src/index.js');
const envelope = decodeEnvelope(bytes);
const plain = await bob.decrypt('alice', envelope);
messages.push(plain);
console.log(`[Bob decrypted]: "${plain}"`);
},
},
});
// Alice opens a WebSocket and uses ShadeWebSocket wrapper
const aliceWs = new WebSocket(`ws://localhost:${port}/`);
await new Promise((r) => aliceWs.addEventListener('open', r));
const aliceShade = new ShadeWebSocket(aliceWs, alice, 'bob');
console.log('Alice → Bob: "Hello over WebSocket"');
await aliceShade.send('Hello over WebSocket');
console.log('Alice → Bob: "Second message"');
await aliceShade.send('Second message');
// Wait for messages to arrive
await new Promise((r) => setTimeout(r, 200));
console.log('\nMessages Bob received:', messages);
console.log('\n=== Done ===');
aliceShade.close();
server.stop();
}
main().catch(console.error);