- Added SignRequestManager.js to manage sign requests, including UI states for keyspace lock, mismatch, and approval. - Implemented methods for loading state, rendering UI, and handling user interactions (approve/reject requests). - Integrated background message listeners for keyspace unlock events and request updates.
233 lines
7.2 KiB
JavaScript
233 lines
7.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Mock SigSocket Server for Testing Browser Extension
|
|
*
|
|
* This is a simple WebSocket server that simulates the SigSocket protocol
|
|
* for testing the browser extension functionality.
|
|
*
|
|
* Usage:
|
|
* node mock_sigsocket_server.js
|
|
*
|
|
* The server will listen on ws://localhost:8080/ws
|
|
*/
|
|
|
|
const WebSocket = require('ws');
|
|
const http = require('http');
|
|
|
|
class MockSigSocketServer {
|
|
constructor(port = 8080) {
|
|
this.port = port;
|
|
this.clients = new Map(); // clientId -> { ws, publicKey }
|
|
this.requestCounter = 0;
|
|
|
|
this.setupServer();
|
|
}
|
|
|
|
setupServer() {
|
|
// Create HTTP server
|
|
this.httpServer = http.createServer();
|
|
|
|
// Create WebSocket server
|
|
this.wss = new WebSocket.Server({
|
|
server: this.httpServer,
|
|
path: '/ws'
|
|
});
|
|
|
|
this.wss.on('connection', (ws, req) => {
|
|
console.log('New WebSocket connection from:', req.socket.remoteAddress);
|
|
this.handleConnection(ws);
|
|
});
|
|
|
|
this.httpServer.listen(this.port, () => {
|
|
console.log(`Mock SigSocket Server listening on ws://localhost:${this.port}/ws`);
|
|
console.log('Waiting for browser extension connections...');
|
|
});
|
|
}
|
|
|
|
handleConnection(ws) {
|
|
let clientId = null;
|
|
let publicKey = null;
|
|
|
|
ws.on('message', (data) => {
|
|
try {
|
|
const message = data.toString();
|
|
console.log('Received message:', message);
|
|
|
|
// Check if this is a client introduction (hex-encoded public key)
|
|
if (!clientId && this.isHexString(message)) {
|
|
publicKey = message;
|
|
clientId = this.generateClientId();
|
|
|
|
this.clients.set(clientId, { ws, publicKey });
|
|
|
|
console.log(`Client registered: ${clientId} with public key: ${publicKey.substring(0, 16)}...`);
|
|
|
|
// Send welcome message
|
|
ws.send(JSON.stringify({
|
|
type: 'welcome',
|
|
clientId: clientId,
|
|
message: 'Connected to Mock SigSocket Server'
|
|
}));
|
|
|
|
// Schedule a test sign request after 3 seconds
|
|
setTimeout(() => {
|
|
this.sendTestSignRequest(clientId);
|
|
}, 3000);
|
|
|
|
return;
|
|
}
|
|
|
|
// Try to parse as JSON (sign response)
|
|
try {
|
|
const jsonMessage = JSON.parse(message);
|
|
this.handleSignResponse(clientId, jsonMessage);
|
|
} catch (e) {
|
|
console.log('Received non-JSON message:', message);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Error handling message:', error);
|
|
}
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
if (clientId) {
|
|
this.clients.delete(clientId);
|
|
console.log(`Client disconnected: ${clientId}`);
|
|
}
|
|
});
|
|
|
|
ws.on('error', (error) => {
|
|
console.error('WebSocket error:', error);
|
|
});
|
|
}
|
|
|
|
handleSignResponse(clientId, response) {
|
|
console.log(`Received sign response from ${clientId}:`, response);
|
|
|
|
if (response.id && response.signature) {
|
|
console.log(`✅ Sign request ${response.id} completed successfully`);
|
|
console.log(` Signature: ${response.signature.substring(0, 32)}...`);
|
|
|
|
// Send another test request after 10 seconds
|
|
setTimeout(() => {
|
|
this.sendTestSignRequest(clientId);
|
|
}, 10000);
|
|
} else {
|
|
console.log('❌ Invalid sign response format');
|
|
}
|
|
}
|
|
|
|
sendTestSignRequest(clientId) {
|
|
const client = this.clients.get(clientId);
|
|
if (!client) {
|
|
console.log(`Client ${clientId} not found`);
|
|
return;
|
|
}
|
|
|
|
this.requestCounter++;
|
|
const requestId = `req_${this.requestCounter}_${Date.now()}`;
|
|
const testMessage = `Test message ${this.requestCounter} - ${new Date().toISOString()}`;
|
|
const messageBase64 = Buffer.from(testMessage).toString('base64');
|
|
|
|
const signRequest = {
|
|
id: requestId,
|
|
message: messageBase64
|
|
};
|
|
|
|
console.log(`📝 Sending sign request to ${clientId}:`, requestId);
|
|
console.log(` Message: "${testMessage}"`);
|
|
|
|
try {
|
|
client.ws.send(JSON.stringify(signRequest));
|
|
} catch (error) {
|
|
console.error(`Failed to send sign request to ${clientId}:`, error);
|
|
}
|
|
}
|
|
|
|
isHexString(str) {
|
|
return /^[0-9a-fA-F]+$/.test(str) && str.length >= 32; // At least 16 bytes
|
|
}
|
|
|
|
generateClientId() {
|
|
return `client_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
}
|
|
|
|
// Send a test request to all connected clients
|
|
broadcastTestRequest() {
|
|
console.log('\n📢 Broadcasting test sign request to all clients...');
|
|
for (const [clientId] of this.clients) {
|
|
this.sendTestSignRequest(clientId);
|
|
}
|
|
}
|
|
|
|
// Get server status
|
|
getStatus() {
|
|
return {
|
|
port: this.port,
|
|
connectedClients: this.clients.size,
|
|
clients: Array.from(this.clients.keys())
|
|
};
|
|
}
|
|
}
|
|
|
|
// Create and start the server
|
|
const server = new MockSigSocketServer();
|
|
|
|
// Handle graceful shutdown
|
|
process.on('SIGINT', () => {
|
|
console.log('\n🛑 Shutting down Mock SigSocket Server...');
|
|
server.httpServer.close(() => {
|
|
console.log('Server closed');
|
|
process.exit(0);
|
|
});
|
|
});
|
|
|
|
// Add some interactive commands
|
|
process.stdin.setEncoding('utf8');
|
|
console.log('\n📋 Available commands:');
|
|
console.log(' "test" - Send test sign request to all clients');
|
|
console.log(' "status" - Show server status');
|
|
console.log(' "quit" - Shutdown server');
|
|
console.log(' Type a command and press Enter\n');
|
|
|
|
process.stdin.on('readable', () => {
|
|
const chunk = process.stdin.read();
|
|
if (chunk !== null) {
|
|
const command = chunk.trim().toLowerCase();
|
|
|
|
switch (command) {
|
|
case 'test':
|
|
server.broadcastTestRequest();
|
|
break;
|
|
|
|
case 'status':
|
|
const status = server.getStatus();
|
|
console.log('\n📊 Server Status:');
|
|
console.log(` Port: ${status.port}`);
|
|
console.log(` Connected clients: ${status.connectedClients}`);
|
|
if (status.clients.length > 0) {
|
|
console.log(` Client IDs: ${status.clients.join(', ')}`);
|
|
}
|
|
console.log('');
|
|
break;
|
|
|
|
case 'quit':
|
|
case 'exit':
|
|
process.emit('SIGINT');
|
|
break;
|
|
|
|
case '':
|
|
break;
|
|
|
|
default:
|
|
console.log(`Unknown command: ${command}`);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Export for testing
|
|
module.exports = MockSigSocketServer;
|