@socket-mesh/server 18.0.5 → 18.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/broker/broker-events.d.ts +16 -0
- package/dist/broker/broker.d.ts +28 -0
- package/dist/broker/broker.js +17 -0
- package/dist/broker/exchange-client.d.ts +5 -0
- package/dist/broker/exchange.d.ts +4 -0
- package/dist/broker/exchange.js +3 -0
- package/dist/broker/simple-broker.d.ts +16 -0
- package/dist/broker/simple-broker.js +65 -0
- package/dist/broker/simple-exchange.d.ts +13 -0
- package/dist/broker/simple-exchange.js +33 -0
- package/dist/handlers/authenticate.d.ts +20 -0
- package/dist/handlers/authenticate.js +67 -0
- package/dist/handlers/handshake.d.ts +7 -0
- package/dist/handlers/handshake.js +61 -0
- package/dist/handlers/publish.d.ts +9 -0
- package/dist/handlers/publish.js +21 -0
- package/dist/handlers/remove-auth-token.d.ts +3 -0
- package/dist/handlers/remove-auth-token.js +7 -0
- package/dist/handlers/subscribe.d.ts +7 -0
- package/dist/handlers/subscribe.js +43 -0
- package/dist/handlers/unsubscribe.d.ts +6 -0
- package/dist/handlers/unsubscribe.js +9 -0
- package/dist/index.d.ts +30 -0
- package/{index.js → dist/index.js} +6 -6
- package/dist/maps/client-map.d.ts +10 -0
- package/dist/maps/client-map.js +1 -0
- package/dist/maps/server-map.d.ts +24 -0
- package/dist/maps/server-map.js +1 -0
- package/dist/maps/socket-map.d.ts +19 -0
- package/dist/maps/socket-map.js +1 -0
- package/dist/plugin/server-plugin.d.ts +33 -0
- package/dist/plugin/server-plugin.js +2 -0
- package/dist/server-event.d.ts +54 -0
- package/dist/server-event.js +1 -0
- package/dist/server-options.d.ts +25 -0
- package/dist/server-options.js +1 -0
- package/dist/server-socket-state.d.ts +6 -0
- package/dist/server-socket-state.js +1 -0
- package/dist/server-socket.d.ts +27 -0
- package/dist/server-socket.js +47 -0
- package/dist/server-transport.d.ts +39 -0
- package/dist/server-transport.js +246 -0
- package/dist/server.d.ts +125 -0
- package/dist/server.js +266 -0
- package/package.json +33 -47
- package/action.d.ts +0 -106
- package/action.js +0 -141
- package/auth-engine.d.ts +0 -13
- package/auth-engine.js +0 -32
- package/events.d.ts +0 -54
- package/inbound-packet.d.ts +0 -48
- package/inbound-packet.js +0 -18
- package/index.d.ts +0 -32
- package/middleware-stream.d.ts +0 -7
- package/middleware-stream.js +0 -8
- package/middleware-type.d.ts +0 -6
- package/middleware-type.js +0 -7
- package/outbound-packet.d.ts +0 -25
- package/outbound-packet.js +0 -3
- package/remote-procedure.d.ts +0 -13
- package/remote-procedure.js +0 -9
- package/request.d.ts +0 -24
- package/request.js +0 -16
- package/server-options.d.ts +0 -38
- package/server.d.ts +0 -113
- package/server.js +0 -361
- package/serversocket.d.ts +0 -182
- package/serversocket.js +0 -1262
- package/socket-state.d.ts +0 -5
- package/socket-state.js +0 -6
- /package/{events.js → dist/broker/broker-events.js} +0 -0
- /package/{server-options.js → dist/broker/exchange-client.js} +0 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import ws from "ws";
|
|
2
|
+
import { ServerProtocolError } from "@socket-mesh/errors";
|
|
3
|
+
import { ServerSocket } from "./server-socket.js";
|
|
4
|
+
import defaultCodec from "@socket-mesh/formatter";
|
|
5
|
+
import { removeAuthTokenHandler } from "@socket-mesh/client";
|
|
6
|
+
import { defaultAuthEngine, isAuthEngine } from "@socket-mesh/auth-engine";
|
|
7
|
+
import { handshakeHandler } from "./handlers/handshake.js";
|
|
8
|
+
import { authenticateHandler } from "./handlers/authenticate.js";
|
|
9
|
+
import { AsyncStreamEmitter } from "@socket-mesh/async-stream-emitter";
|
|
10
|
+
import { subscribeHandler } from "./handlers/subscribe.js";
|
|
11
|
+
import { unsubscribeHandler } from "./handlers/unsubscribe.js";
|
|
12
|
+
import { SimpleBroker } from "./broker/simple-broker.js";
|
|
13
|
+
import { publishHandler } from "./handlers/publish.js";
|
|
14
|
+
export class Server extends AsyncStreamEmitter {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
super();
|
|
17
|
+
let cid = 1;
|
|
18
|
+
if (!options) {
|
|
19
|
+
options = {};
|
|
20
|
+
}
|
|
21
|
+
options.clientTracking = true;
|
|
22
|
+
this.ackTimeoutMs = options.ackTimeoutMs || 10000;
|
|
23
|
+
this.allowClientPublish = options.allowClientPublish ?? true;
|
|
24
|
+
this.auth = isAuthEngine(options.authEngine) ? options.authEngine : defaultAuthEngine(options.authEngine);
|
|
25
|
+
this.brokerEngine = options.brokerEngine || new SimpleBroker();
|
|
26
|
+
this._callIdGenerator = options.callIdGenerator || (() => {
|
|
27
|
+
return cid++;
|
|
28
|
+
});
|
|
29
|
+
this.clients = {};
|
|
30
|
+
this.clientCount = 0;
|
|
31
|
+
this.codecEngine = options.codecEngine || defaultCodec;
|
|
32
|
+
this._handlers = Object.assign({
|
|
33
|
+
"#authenticate": authenticateHandler,
|
|
34
|
+
"#handshake": handshakeHandler,
|
|
35
|
+
"#publish": publishHandler,
|
|
36
|
+
"#removeAuthToken": removeAuthTokenHandler,
|
|
37
|
+
"#subscribe": subscribeHandler,
|
|
38
|
+
"#unsubscribe": unsubscribeHandler
|
|
39
|
+
}, options.handlers);
|
|
40
|
+
this.httpServer = options.server;
|
|
41
|
+
this.plugins = options.plugins || [];
|
|
42
|
+
this.origins = options.origins || '*:*';
|
|
43
|
+
this.pendingClients = {};
|
|
44
|
+
this.pendingClientCount = 0;
|
|
45
|
+
this.isPingTimeoutDisabled = (options.isPingTimeoutDisabled === true);
|
|
46
|
+
this.pingIntervalMs = options.pingIntervalMs || 8000;
|
|
47
|
+
this.pingTimeoutMs = options.pingTimeoutMs || 20000;
|
|
48
|
+
this.socketChannelLimit = options.socketChannelLimit;
|
|
49
|
+
this.socketStreamCleanupMode = options.socketStreamCleanupMode || 'kill';
|
|
50
|
+
this.strictHandshake = options.strictHandshake ?? true;
|
|
51
|
+
options.verifyClient = this.verifyClient.bind(this);
|
|
52
|
+
this._wss = new ws.WebSocketServer(options);
|
|
53
|
+
this._wss.on('close', this.onClose.bind(this));
|
|
54
|
+
this._wss.on('connection', this.onConnection.bind(this));
|
|
55
|
+
this._wss.on('error', this.onError.bind(this));
|
|
56
|
+
this._wss.on('headers', this.onHeaders.bind(this));
|
|
57
|
+
this._wss.on('listening', this.onListening.bind(this));
|
|
58
|
+
(async () => {
|
|
59
|
+
for await (let { error } of this.brokerEngine.listen('error')) {
|
|
60
|
+
this.emit('warning', { warning: error });
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
if (this.brokerEngine.isReady) {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
this._isReady = true;
|
|
66
|
+
this.emit('ready', {});
|
|
67
|
+
}, 0);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this._isReady = false;
|
|
71
|
+
(async () => {
|
|
72
|
+
await this.brokerEngine.listen('ready').once();
|
|
73
|
+
this._isReady = true;
|
|
74
|
+
this.emit('ready', {});
|
|
75
|
+
})();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
addPlugin(...plugin) {
|
|
79
|
+
this.plugins.push(...plugin);
|
|
80
|
+
}
|
|
81
|
+
bind(socket) {
|
|
82
|
+
if (socket.type === 'client') {
|
|
83
|
+
(async () => {
|
|
84
|
+
for await (let event of socket.listen()) {
|
|
85
|
+
this.emit(`socket${event.stream[0].toUpperCase()}${event.stream.substring(1)}`, Object.assign({ socket }, event.value));
|
|
86
|
+
}
|
|
87
|
+
})();
|
|
88
|
+
(async () => {
|
|
89
|
+
for await (let event of socket.channels.listen()) {
|
|
90
|
+
this.emit(`socket${event.stream[0].toUpperCase()}${event.stream.substring(1)}`, Object.assign({ socket }, event.value));
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
}
|
|
94
|
+
(async () => {
|
|
95
|
+
for await (let {} of socket.listen('connect')) {
|
|
96
|
+
if (this.pendingClients[socket.id]) {
|
|
97
|
+
delete this.pendingClients[socket.id];
|
|
98
|
+
this.pendingClientCount--;
|
|
99
|
+
}
|
|
100
|
+
this.clients[socket.id] = socket;
|
|
101
|
+
this.clientCount++;
|
|
102
|
+
this.startPinging();
|
|
103
|
+
}
|
|
104
|
+
})();
|
|
105
|
+
(async () => {
|
|
106
|
+
for await (let {} of socket.listen('connectAbort')) {
|
|
107
|
+
this.socketDisconnected(socket);
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
110
|
+
(async () => {
|
|
111
|
+
for await (let {} of socket.listen('disconnect')) {
|
|
112
|
+
this.socketDisconnected(socket);
|
|
113
|
+
}
|
|
114
|
+
})();
|
|
115
|
+
}
|
|
116
|
+
close(keepSocketsOpen) {
|
|
117
|
+
this._isListening = false;
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
this._wss.close((err) => {
|
|
120
|
+
if (err) {
|
|
121
|
+
reject(err);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
resolve();
|
|
125
|
+
});
|
|
126
|
+
if (!keepSocketsOpen) {
|
|
127
|
+
for (let socket of Object.values(this.clients)) {
|
|
128
|
+
socket.disconnect();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
get exchange() {
|
|
134
|
+
return this.brokerEngine.exchange;
|
|
135
|
+
}
|
|
136
|
+
get isListening() {
|
|
137
|
+
return this._isListening;
|
|
138
|
+
}
|
|
139
|
+
get isReady() {
|
|
140
|
+
return this._isReady;
|
|
141
|
+
}
|
|
142
|
+
onClose(code, reason) {
|
|
143
|
+
this.emit('close', {});
|
|
144
|
+
}
|
|
145
|
+
onConnection(wsSocket, upgradeReq) {
|
|
146
|
+
/*
|
|
147
|
+
if (!wsSocket.upgradeReq) {
|
|
148
|
+
// Normalize ws modules to match.
|
|
149
|
+
wsSocket.upgradeReq = upgradeReq;
|
|
150
|
+
}
|
|
151
|
+
*/
|
|
152
|
+
const socket = new ServerSocket({
|
|
153
|
+
ackTimeoutMs: this.ackTimeoutMs,
|
|
154
|
+
callIdGenerator: this._callIdGenerator,
|
|
155
|
+
codecEngine: this.codecEngine,
|
|
156
|
+
handlers: this._handlers,
|
|
157
|
+
plugins: this.plugins,
|
|
158
|
+
onUnhandledRequest: this.onUnhandledRequest.bind(this),
|
|
159
|
+
request: upgradeReq,
|
|
160
|
+
socket: wsSocket,
|
|
161
|
+
server: this,
|
|
162
|
+
state: {},
|
|
163
|
+
streamCleanupMode: this.socketStreamCleanupMode
|
|
164
|
+
});
|
|
165
|
+
this.pendingClientCount++;
|
|
166
|
+
this.bind(this.pendingClients[socket.id] = socket);
|
|
167
|
+
// ws.on('error', console.error);
|
|
168
|
+
this.emit('connection', { socket, upgradeReq });
|
|
169
|
+
// Emit event to signal that a socket handshake has been initiated.
|
|
170
|
+
this.emit('handshake', { socket });
|
|
171
|
+
}
|
|
172
|
+
onError(error) {
|
|
173
|
+
if (typeof error === 'string') {
|
|
174
|
+
error = new ServerProtocolError(error);
|
|
175
|
+
}
|
|
176
|
+
this.emit('error', { error });
|
|
177
|
+
}
|
|
178
|
+
onHeaders(headers, request) {
|
|
179
|
+
this.emit('headers', { headers, request });
|
|
180
|
+
}
|
|
181
|
+
onListening() {
|
|
182
|
+
this._isListening = true;
|
|
183
|
+
this.emit('listening', {});
|
|
184
|
+
}
|
|
185
|
+
onUnhandledRequest(socket, packet) {
|
|
186
|
+
}
|
|
187
|
+
socketDisconnected(socket) {
|
|
188
|
+
if (!!this.pendingClients[socket.id]) {
|
|
189
|
+
delete this.pendingClients[socket.id];
|
|
190
|
+
this.pendingClientCount--;
|
|
191
|
+
}
|
|
192
|
+
if (!!this.clients[socket.id]) {
|
|
193
|
+
delete this.clients[socket.id];
|
|
194
|
+
this.clientCount--;
|
|
195
|
+
}
|
|
196
|
+
if (this.clientCount <= 0) {
|
|
197
|
+
this.stopPinging();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
startPinging() {
|
|
201
|
+
if (!this._pingIntervalRef && !this.isPingTimeoutDisabled) {
|
|
202
|
+
this._pingIntervalRef = setInterval(() => {
|
|
203
|
+
for (const id in this.clients) {
|
|
204
|
+
this.clients[id]
|
|
205
|
+
.ping()
|
|
206
|
+
.catch(err => {
|
|
207
|
+
this.onError(err);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}, this.pingIntervalMs);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
stopPinging() {
|
|
214
|
+
if (this._pingIntervalRef) {
|
|
215
|
+
clearInterval(this._pingIntervalRef);
|
|
216
|
+
this._pingIntervalRef = null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async verifyClient(info, callback) {
|
|
220
|
+
try {
|
|
221
|
+
if (typeof info.origin !== 'string' || info.origin === 'null') {
|
|
222
|
+
info.origin = '*';
|
|
223
|
+
}
|
|
224
|
+
if (this.origins.indexOf('*:*') === -1) {
|
|
225
|
+
let ok = false;
|
|
226
|
+
try {
|
|
227
|
+
const url = new URL(info.origin);
|
|
228
|
+
url.port = url.port || (url.protocol === 'https:' ? '443' : '80');
|
|
229
|
+
ok = !!(~this.origins.indexOf(url.hostname + ':' + url.port) ||
|
|
230
|
+
~this.origins.indexOf(url.hostname + ':*') ||
|
|
231
|
+
~this.origins.indexOf('*:' + url.port));
|
|
232
|
+
}
|
|
233
|
+
catch (e) { }
|
|
234
|
+
if (!ok) {
|
|
235
|
+
const error = new ServerProtocolError(`Failed to authorize socket handshake - Invalid origin: ${info.origin}`);
|
|
236
|
+
this.emit('warning', { warning: error });
|
|
237
|
+
callback(false, 403, error.message);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
for (const plugin of this.plugins) {
|
|
243
|
+
if (plugin.onConnection) {
|
|
244
|
+
await plugin.onConnection(info.req);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
callback(false, 401, typeof err === 'string' ? err : err.message);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
callback(true);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
this.onError(err);
|
|
256
|
+
this.emit('warning', { warning: err });
|
|
257
|
+
callback(false, 403, typeof err === 'string' ? err : err.message);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
emit(event, data) {
|
|
261
|
+
super.emit(event, data);
|
|
262
|
+
}
|
|
263
|
+
listen(event) {
|
|
264
|
+
return super.listen(event);
|
|
265
|
+
}
|
|
266
|
+
}
|
package/package.json
CHANGED
|
@@ -1,59 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@socket-mesh/server",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
"description": "A TCP socket pair for easily transmitting full messages without worrying about request size limits.",
|
|
4
|
+
"version": "18.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": ["./dist"],
|
|
9
|
+
"author": {
|
|
10
|
+
"name": "Greg Kimmy"
|
|
10
11
|
},
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"@socket-mesh/errors": "^3.0.8",
|
|
16
|
-
"@socket-mesh/formatter": "^4.0.5",
|
|
17
|
-
"@socket-mesh/request": "^2.0.9",
|
|
18
|
-
"@socket-mesh/broker": "^1.0.5",
|
|
19
|
-
"@socket-mesh/simple-broker": "^6.0.6",
|
|
20
|
-
"@socket-mesh/stream-demux": "^10.0.4",
|
|
21
|
-
"@socket-mesh/writable-consumable-stream": "^4.2.9",
|
|
22
|
-
"@socket-mesh/channel": "6.0.29",
|
|
23
|
-
"base64id": "^2.0.0",
|
|
24
|
-
"clone-deep": "^4.0.1",
|
|
25
|
-
"jsonwebtoken": "^9.0.2",
|
|
26
|
-
"ws": "^8.14.2"
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "node ../../scripts/build.mjs && tsc --project tsconfig.build.json",
|
|
14
|
+
"deploy": "npm run build && node ../../scripts/publish.mjs",
|
|
15
|
+
"test": "cross-env node --test --import=./run-test.js test/server-test.ts"
|
|
27
16
|
},
|
|
28
17
|
"devDependencies": {
|
|
29
|
-
"@socket-mesh/client": "^18.0.7",
|
|
30
18
|
"@socket-mesh/local-storage": "^1.0.2",
|
|
31
19
|
"@types/base64id": "^2.0.2",
|
|
32
|
-
"@types/
|
|
33
|
-
"@types/
|
|
34
|
-
"@types/ws": "^8.5.10",
|
|
35
|
-
"cross-env": "^7.0.3",
|
|
36
|
-
"ts-node": "^10.9.1",
|
|
37
|
-
"typescript": "^5.3.2"
|
|
20
|
+
"@types/jsonwebtoken": "^9.0.6",
|
|
21
|
+
"@types/ws": "^8.5.10"
|
|
38
22
|
},
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@socket-mesh/async-stream-emitter": "^7.1.2",
|
|
25
|
+
"@socket-mesh/auth": "^2.2.0",
|
|
26
|
+
"@socket-mesh/auth-engine": "^1.0.0",
|
|
27
|
+
"@socket-mesh/client": "^18.1.0",
|
|
28
|
+
"@socket-mesh/errors": "^3.2.0",
|
|
29
|
+
"@socket-mesh/formatter": "^4.1.0",
|
|
30
|
+
"base64id": "^2.0.0",
|
|
31
|
+
"events": "^3.3.0",
|
|
32
|
+
"jsonwebtoken": "^9.0.2",
|
|
33
|
+
"ws": "^8.18.0"
|
|
43
34
|
},
|
|
44
35
|
"keywords": [
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
"author": "Jonathan Gros-Dubois <grosjona@yahoo.com.au>",
|
|
51
|
-
"contributors": [
|
|
52
|
-
"Greg Kimmy",
|
|
53
|
-
{
|
|
54
|
-
"name": "Jonathan Gros-Dubois",
|
|
55
|
-
"email": "grosjona@yahoo.com.au"
|
|
56
|
-
}
|
|
36
|
+
"ncom",
|
|
37
|
+
"tcp",
|
|
38
|
+
"simple",
|
|
39
|
+
"socket",
|
|
40
|
+
"messages"
|
|
57
41
|
],
|
|
58
|
-
"
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">= 0.8.0"
|
|
44
|
+
}
|
|
59
45
|
}
|
package/action.d.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import { AuthTokenError, AuthTokenExpiredError } from "@socket-mesh/errors";
|
|
4
|
-
import { AuthState, AuthToken, SignedAuthToken } from "@socket-mesh/auth";
|
|
5
|
-
import { IncomingMessage } from 'http';
|
|
6
|
-
import { DataPacket } from "@socket-mesh/broker";
|
|
7
|
-
import { ChannelOptions } from "@socket-mesh/channel";
|
|
8
|
-
import { ServerSocket } from "./serversocket.js";
|
|
9
|
-
import { HandshakeRequest } from "./request.js";
|
|
10
|
-
export declare enum ActionType {
|
|
11
|
-
HANDSHAKE_WS = "handshakeWS",
|
|
12
|
-
HANDSHAKE_SC = "handshakeSC",
|
|
13
|
-
MESSAGE = "message",
|
|
14
|
-
TRANSMIT = "transmit",
|
|
15
|
-
INVOKE = "invoke",
|
|
16
|
-
SUBSCRIBE = "subscribe",
|
|
17
|
-
PUBLISH_IN = "publishIn",
|
|
18
|
-
PUBLISH_OUT = "publishOut",
|
|
19
|
-
AUTHENTICATE = "authenticate"
|
|
20
|
-
}
|
|
21
|
-
export interface ActionResult<T> {
|
|
22
|
-
data: T;
|
|
23
|
-
options?: ActionOptions;
|
|
24
|
-
}
|
|
25
|
-
export interface ActionOptions {
|
|
26
|
-
useCache: boolean;
|
|
27
|
-
}
|
|
28
|
-
export declare abstract class Action<T, U extends ActionType = ActionType> {
|
|
29
|
-
readonly type: U;
|
|
30
|
-
readonly promise: Promise<ActionResult<T> | undefined>;
|
|
31
|
-
outcome: 'allowed' | 'blocked' | null;
|
|
32
|
-
private _resolve;
|
|
33
|
-
private _reject;
|
|
34
|
-
constructor(type: U);
|
|
35
|
-
allow: (packet?: ActionResult<T>) => void;
|
|
36
|
-
block: (error: Error) => void;
|
|
37
|
-
}
|
|
38
|
-
export type MiddlewareAction = ActionTransmit | ActionInvoke | ActionPublishIn | ActionPublishOut | ActionSubscribe | ActionHandshakeSC | ActionHandshakeWS | ActionAuthenticate | ActionMessage;
|
|
39
|
-
export type InboundAction = ActionAuthenticate | ActionTransmit | ActionInvoke | ActionPublishIn | ActionSubscribe;
|
|
40
|
-
export type HandshakeAction = ActionHandshakeSC | ActionHandshakeWS;
|
|
41
|
-
export declare class ActionHandshakeWS extends Action<undefined, ActionType.HANDSHAKE_WS> {
|
|
42
|
-
constructor(request: IncomingMessage);
|
|
43
|
-
request: IncomingMessage;
|
|
44
|
-
}
|
|
45
|
-
export type AuthInfo = {
|
|
46
|
-
signedAuthToken: SignedAuthToken;
|
|
47
|
-
authTokenError: AuthTokenError;
|
|
48
|
-
authToken: null;
|
|
49
|
-
authState: AuthState;
|
|
50
|
-
} | {
|
|
51
|
-
signedAuthToken: SignedAuthToken;
|
|
52
|
-
authTokenError: null;
|
|
53
|
-
authToken: AuthToken;
|
|
54
|
-
authState: AuthState;
|
|
55
|
-
};
|
|
56
|
-
export declare class ActionHandshakeSC extends Action<AuthInfo, ActionType.HANDSHAKE_SC> {
|
|
57
|
-
constructor(socket: ServerSocket, request: HandshakeRequest, data: AuthInfo);
|
|
58
|
-
request: HandshakeRequest;
|
|
59
|
-
socket: ServerSocket;
|
|
60
|
-
data: AuthInfo;
|
|
61
|
-
}
|
|
62
|
-
export declare class ActionMessage extends Action<string | ArrayBuffer | Buffer[], ActionType.MESSAGE> {
|
|
63
|
-
constructor(socket: ServerSocket, data: string | ArrayBuffer | Buffer[]);
|
|
64
|
-
socket: ServerSocket;
|
|
65
|
-
data: string | ArrayBuffer | Buffer[];
|
|
66
|
-
}
|
|
67
|
-
export declare class ActionTransmit extends Action<any, ActionType.TRANSMIT> {
|
|
68
|
-
constructor(socket: ServerSocket, receiver: string, packet: DataPacket<any>);
|
|
69
|
-
socket: ServerSocket;
|
|
70
|
-
authTokenExpiredError?: AuthTokenExpiredError;
|
|
71
|
-
receiver: string;
|
|
72
|
-
data?: DataPacket<any>;
|
|
73
|
-
}
|
|
74
|
-
export declare class ActionInvoke extends Action<any, ActionType.INVOKE> {
|
|
75
|
-
constructor(socket: ServerSocket, procedure: string, packet?: DataPacket<any>);
|
|
76
|
-
socket: ServerSocket;
|
|
77
|
-
authTokenExpiredError?: AuthTokenExpiredError;
|
|
78
|
-
procedure: string;
|
|
79
|
-
data?: DataPacket<any>;
|
|
80
|
-
}
|
|
81
|
-
export declare class ActionSubscribe extends Action<ChannelOptions, ActionType.SUBSCRIBE> {
|
|
82
|
-
constructor(socket: ServerSocket, packet?: DataPacket<ChannelOptions>);
|
|
83
|
-
socket: ServerSocket;
|
|
84
|
-
authTokenExpiredError?: AuthTokenExpiredError;
|
|
85
|
-
channel: string;
|
|
86
|
-
data?: ChannelOptions;
|
|
87
|
-
}
|
|
88
|
-
export declare class ActionPublishIn extends Action<any, ActionType.PUBLISH_IN> {
|
|
89
|
-
constructor(socket: ServerSocket, packet: Partial<DataPacket<any>>);
|
|
90
|
-
socket: ServerSocket;
|
|
91
|
-
authTokenExpiredError?: AuthTokenExpiredError;
|
|
92
|
-
channel: string;
|
|
93
|
-
data?: any;
|
|
94
|
-
}
|
|
95
|
-
export declare class ActionPublishOut extends Action<any, ActionType.PUBLISH_OUT> {
|
|
96
|
-
constructor(socket: ServerSocket);
|
|
97
|
-
socket: ServerSocket;
|
|
98
|
-
channel?: string;
|
|
99
|
-
data?: any;
|
|
100
|
-
}
|
|
101
|
-
export declare class ActionAuthenticate extends Action<undefined, ActionType.AUTHENTICATE> {
|
|
102
|
-
constructor(socket: ServerSocket, authToken: AuthToken, signedAuthToken: SignedAuthToken);
|
|
103
|
-
socket: ServerSocket;
|
|
104
|
-
authToken: AuthToken;
|
|
105
|
-
signedAuthToken: string;
|
|
106
|
-
}
|
package/action.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { InvalidActionError } from "@socket-mesh/errors";
|
|
2
|
-
export var ActionType;
|
|
3
|
-
(function (ActionType) {
|
|
4
|
-
ActionType["HANDSHAKE_WS"] = "handshakeWS";
|
|
5
|
-
ActionType["HANDSHAKE_SC"] = "handshakeSC";
|
|
6
|
-
ActionType["MESSAGE"] = "message";
|
|
7
|
-
ActionType["TRANSMIT"] = "transmit";
|
|
8
|
-
ActionType["INVOKE"] = "invoke";
|
|
9
|
-
ActionType["SUBSCRIBE"] = "subscribe";
|
|
10
|
-
ActionType["PUBLISH_IN"] = "publishIn";
|
|
11
|
-
ActionType["PUBLISH_OUT"] = "publishOut";
|
|
12
|
-
ActionType["AUTHENTICATE"] = "authenticate";
|
|
13
|
-
})(ActionType || (ActionType = {}));
|
|
14
|
-
export class Action {
|
|
15
|
-
type;
|
|
16
|
-
promise;
|
|
17
|
-
outcome;
|
|
18
|
-
_resolve;
|
|
19
|
-
_reject;
|
|
20
|
-
constructor(type) {
|
|
21
|
-
this.type = type;
|
|
22
|
-
this.outcome = null;
|
|
23
|
-
this.promise = new Promise((resolve, reject) => {
|
|
24
|
-
this._resolve = resolve;
|
|
25
|
-
this._reject = reject;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
allow = (packet) => {
|
|
29
|
-
if (this.outcome) {
|
|
30
|
-
throw new InvalidActionError(`Action ${this.type} has already been ${this.outcome}; cannot allow`);
|
|
31
|
-
}
|
|
32
|
-
this.outcome = 'allowed';
|
|
33
|
-
this._resolve(packet);
|
|
34
|
-
};
|
|
35
|
-
block = (error) => {
|
|
36
|
-
if (this.outcome) {
|
|
37
|
-
throw new InvalidActionError(`Action ${this.type} has already been ${this.outcome}; cannot block`);
|
|
38
|
-
}
|
|
39
|
-
this.outcome = 'blocked';
|
|
40
|
-
this._reject(error);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export class ActionHandshakeWS extends Action {
|
|
44
|
-
constructor(request) {
|
|
45
|
-
super(ActionType.HANDSHAKE_WS);
|
|
46
|
-
this.request = request;
|
|
47
|
-
}
|
|
48
|
-
request;
|
|
49
|
-
}
|
|
50
|
-
export class ActionHandshakeSC extends Action {
|
|
51
|
-
constructor(socket, request, data) {
|
|
52
|
-
super(ActionType.HANDSHAKE_SC);
|
|
53
|
-
this.socket = socket;
|
|
54
|
-
this.request = request;
|
|
55
|
-
this.data = data;
|
|
56
|
-
}
|
|
57
|
-
request;
|
|
58
|
-
socket;
|
|
59
|
-
data;
|
|
60
|
-
}
|
|
61
|
-
export class ActionMessage extends Action {
|
|
62
|
-
constructor(socket, data) {
|
|
63
|
-
super(ActionType.MESSAGE);
|
|
64
|
-
this.socket = socket;
|
|
65
|
-
this.data = data;
|
|
66
|
-
}
|
|
67
|
-
socket;
|
|
68
|
-
data;
|
|
69
|
-
}
|
|
70
|
-
export class ActionTransmit extends Action {
|
|
71
|
-
constructor(socket, receiver, packet) {
|
|
72
|
-
super(ActionType.TRANSMIT);
|
|
73
|
-
this.socket = socket;
|
|
74
|
-
this.receiver = receiver;
|
|
75
|
-
if (packet !== undefined) {
|
|
76
|
-
this.data = packet;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
socket;
|
|
80
|
-
authTokenExpiredError;
|
|
81
|
-
receiver;
|
|
82
|
-
data;
|
|
83
|
-
}
|
|
84
|
-
export class ActionInvoke extends Action {
|
|
85
|
-
constructor(socket, procedure, packet) {
|
|
86
|
-
super(ActionType.INVOKE);
|
|
87
|
-
this.socket = socket;
|
|
88
|
-
this.procedure = procedure;
|
|
89
|
-
if (packet !== undefined) {
|
|
90
|
-
this.data = packet;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
socket;
|
|
94
|
-
authTokenExpiredError;
|
|
95
|
-
procedure;
|
|
96
|
-
data;
|
|
97
|
-
}
|
|
98
|
-
export class ActionSubscribe extends Action {
|
|
99
|
-
constructor(socket, packet) {
|
|
100
|
-
super(ActionType.SUBSCRIBE);
|
|
101
|
-
this.socket = socket;
|
|
102
|
-
this.channel = packet.channel;
|
|
103
|
-
this.data = packet.data;
|
|
104
|
-
}
|
|
105
|
-
socket;
|
|
106
|
-
authTokenExpiredError;
|
|
107
|
-
channel;
|
|
108
|
-
data;
|
|
109
|
-
}
|
|
110
|
-
export class ActionPublishIn extends Action {
|
|
111
|
-
constructor(socket, packet) {
|
|
112
|
-
super(ActionType.PUBLISH_IN);
|
|
113
|
-
this.socket = socket;
|
|
114
|
-
this.channel = packet.channel;
|
|
115
|
-
this.data = packet.data;
|
|
116
|
-
}
|
|
117
|
-
socket;
|
|
118
|
-
authTokenExpiredError;
|
|
119
|
-
channel;
|
|
120
|
-
data;
|
|
121
|
-
}
|
|
122
|
-
export class ActionPublishOut extends Action {
|
|
123
|
-
constructor(socket) {
|
|
124
|
-
super(ActionType.PUBLISH_OUT);
|
|
125
|
-
this.socket = socket;
|
|
126
|
-
}
|
|
127
|
-
socket;
|
|
128
|
-
channel;
|
|
129
|
-
data;
|
|
130
|
-
}
|
|
131
|
-
export class ActionAuthenticate extends Action {
|
|
132
|
-
constructor(socket, authToken, signedAuthToken) {
|
|
133
|
-
super(ActionType.AUTHENTICATE);
|
|
134
|
-
this.socket = socket;
|
|
135
|
-
this.authToken = authToken;
|
|
136
|
-
this.signedAuthToken = signedAuthToken;
|
|
137
|
-
}
|
|
138
|
-
socket;
|
|
139
|
-
authToken;
|
|
140
|
-
signedAuthToken;
|
|
141
|
-
}
|
package/auth-engine.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import jwt from 'jsonwebtoken';
|
|
3
|
-
import { ServerSocket } from './serversocket.js';
|
|
4
|
-
export interface AuthTokenOptions extends jwt.SignOptions {
|
|
5
|
-
rejectOnFailedDelivery?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export interface VerifyOptions extends jwt.VerifyOptions {
|
|
8
|
-
socket: ServerSocket;
|
|
9
|
-
}
|
|
10
|
-
export declare class AuthEngine {
|
|
11
|
-
verifyToken(signedToken: string, key: jwt.Secret | jwt.GetPublicKeyOrSecret, options: VerifyOptions): Promise<jwt.JwtPayload>;
|
|
12
|
-
signToken(token: string | object | Buffer, key: jwt.Secret, options: jwt.SignOptions): Promise<string>;
|
|
13
|
-
}
|
package/auth-engine.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import jwt from 'jsonwebtoken';
|
|
2
|
-
import { InvalidArgumentsError } from '@socket-mesh/errors';
|
|
3
|
-
export class AuthEngine {
|
|
4
|
-
verifyToken(signedToken, key, options) {
|
|
5
|
-
const jwtOptions = Object.assign({}, options || {});
|
|
6
|
-
if (typeof signedToken === 'string' || signedToken == null) {
|
|
7
|
-
return new Promise((resolve, reject) => {
|
|
8
|
-
const cb = (err, token) => {
|
|
9
|
-
if (err) {
|
|
10
|
-
reject(err);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
resolve(token);
|
|
14
|
-
};
|
|
15
|
-
jwt.verify(signedToken || '', key, jwtOptions, cb);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
return Promise.reject(new InvalidArgumentsError('Invalid token format - Token must be a string'));
|
|
19
|
-
}
|
|
20
|
-
signToken(token, key, options) {
|
|
21
|
-
const jwtOptions = Object.assign({}, options || {});
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
jwt.sign(token, key, jwtOptions, (err, signedToken) => {
|
|
24
|
-
if (err) {
|
|
25
|
-
reject(err);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
resolve(signedToken);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|