forked from SmartDropLabs/smartdrop-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpriceWebSocket.js
More file actions
61 lines (51 loc) · 1.6 KB
/
Copy pathpriceWebSocket.js
File metadata and controls
61 lines (51 loc) · 1.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'use strict';
const { WebSocketServer } = require('ws');
const logger = require('../logger');
const apiKeys = require('../services/apiKeys');
const subscriptionManager = require('./PriceSubscriptionManager');
function extractBearerToken(header) {
if (!header || typeof header !== 'string') return null;
const match = header.match(/^Bearer\s+(.+)$/i);
return match ? match[1].trim() : null;
}
function authenticateUpgrade(info, callback) {
const token = extractBearerToken(info.req.headers.authorization);
if (!token) {
callback(false, 401, 'Missing or invalid API key');
return;
}
apiKeys.validateApiKey(token)
.then((apiKey) => {
if (!apiKey) {
callback(false, 401, 'Missing or invalid API key');
return;
}
callback(true);
})
.catch((err) => {
logger.warn('WebSocket authentication failed', { error: err.message });
callback(false, 401, 'Missing or invalid API key');
});
}
/**
* Attach the WebSocket server to an existing HTTP server.
* Clients connect at ws://<host>/ws
*/
function attach(httpServer) {
const wss = new WebSocketServer({
server: httpServer,
path: '/ws',
verifyClient: authenticateUpgrade,
});
wss.on('connection', (ws, req) => {
logger.info('Incoming WS connection', { ip: req.socket.remoteAddress });
subscriptionManager.add(ws, req);
});
wss.on('error', (err) => {
logger.error('WebSocket server error', { error: err.message });
});
subscriptionManager.startHeartbeat();
logger.info('WebSocket price-stream server attached at /ws');
return wss;
}
module.exports = { attach };