@socket-mesh/server 17.3.7 → 18.0.1
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/action.d.ts +34 -34
- package/action.js +4 -8
- package/auth-engine.d.ts +5 -5
- package/inbound-packet.d.ts +11 -11
- package/index.d.ts +12 -11
- package/index.js +5 -4
- package/middleware-stream.d.ts +2 -2
- package/outbound-packet.d.ts +8 -8
- package/package.json +56 -58
- package/request.d.ts +4 -4
- package/server-options.d.ts +2 -2
- package/server.d.ts +52 -52
- package/server.js +88 -126
- package/serversocket-procedure.d.ts +6 -6
- package/serversocket.d.ts +20 -21
- package/serversocket.js +659 -723
package/server.js
CHANGED
|
@@ -1,80 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
11
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
-
var m = o[Symbol.asyncIterator], i;
|
|
13
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
14
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
15
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
16
|
-
};
|
|
17
|
-
import { AuthEngine } from "./auth-engine";
|
|
1
|
+
import { AuthEngine } from "./auth-engine.js";
|
|
18
2
|
import formatter from "@socket-mesh/formatter";
|
|
19
3
|
import { SimpleBroker } from "@socket-mesh/simple-broker";
|
|
20
4
|
import { AsyncStreamEmitter } from "@socket-mesh/async-stream-emitter";
|
|
21
5
|
import { InvalidArgumentsError, InvalidOptionsError, InvalidActionError, ServerProtocolError, SilentMiddlewareBlockedError } from "@socket-mesh/errors";
|
|
22
|
-
import { MiddlewareType } from "./middleware-type";
|
|
23
|
-
import { MiddlewareStream } from "./middleware-stream";
|
|
24
|
-
import { ActionHandshakeWS } from "./action";
|
|
6
|
+
import { MiddlewareType } from "./middleware-type.js";
|
|
7
|
+
import { MiddlewareStream } from "./middleware-stream.js";
|
|
8
|
+
import { ActionHandshakeWS } from "./action.js";
|
|
25
9
|
import { WebSocketServer } from 'ws';
|
|
26
10
|
import base64id from 'base64id';
|
|
27
|
-
import { ServerSocket } from "./serversocket";
|
|
11
|
+
import { ServerSocket } from "./serversocket.js";
|
|
28
12
|
import url from "url";
|
|
29
13
|
import crypto from "crypto";
|
|
30
14
|
export class Server extends AsyncStreamEmitter {
|
|
31
15
|
constructor(options) {
|
|
32
16
|
super();
|
|
33
|
-
this._verifyHandshake = function (info, callback) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
else {
|
|
45
|
-
try {
|
|
46
|
-
let parts = url.parse(origin);
|
|
47
|
-
parts.port = parts.port || (parts.protocol === 'https:' ? '443' : '80');
|
|
48
|
-
ok = !!(~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
|
|
49
|
-
~this.origins.indexOf(parts.hostname + ':*') ||
|
|
50
|
-
~this.origins.indexOf('*:' + parts.port));
|
|
51
|
-
}
|
|
52
|
-
catch (e) { }
|
|
53
|
-
}
|
|
54
|
-
const middlewareHandshakeStream = new MiddlewareStream(MiddlewareType.MIDDLEWARE_HANDSHAKE);
|
|
55
|
-
req['handshakeStream'] = middlewareHandshakeStream;
|
|
56
|
-
const handshakeMiddleware = this._middleware[MiddlewareType.MIDDLEWARE_HANDSHAKE];
|
|
57
|
-
if (handshakeMiddleware) {
|
|
58
|
-
handshakeMiddleware(middlewareHandshakeStream);
|
|
59
|
-
}
|
|
60
|
-
const action = new ActionHandshakeWS(req);
|
|
17
|
+
this._verifyHandshake = async function (info, callback) {
|
|
18
|
+
let req = info.req;
|
|
19
|
+
let origin = info.origin;
|
|
20
|
+
if (typeof origin !== 'string' || origin === 'null') {
|
|
21
|
+
origin = '*';
|
|
22
|
+
}
|
|
23
|
+
let ok = false;
|
|
24
|
+
if (this._allowAllOrigins) {
|
|
25
|
+
ok = true;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
61
28
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (ok) {
|
|
70
|
-
callback(true);
|
|
71
|
-
return;
|
|
29
|
+
let parts = url.parse(origin);
|
|
30
|
+
parts.port = parts.port || (parts.protocol === 'https:' ? '443' : '80');
|
|
31
|
+
ok = !!(~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
|
|
32
|
+
~this.origins.indexOf(parts.hostname + ':*') ||
|
|
33
|
+
~this.origins.indexOf('*:' + parts.port));
|
|
72
34
|
}
|
|
73
|
-
|
|
74
|
-
|
|
35
|
+
catch (e) { }
|
|
36
|
+
}
|
|
37
|
+
const middlewareHandshakeStream = new MiddlewareStream(MiddlewareType.MIDDLEWARE_HANDSHAKE);
|
|
38
|
+
req['handshakeStream'] = middlewareHandshakeStream;
|
|
39
|
+
const handshakeMiddleware = this._middleware[MiddlewareType.MIDDLEWARE_HANDSHAKE];
|
|
40
|
+
if (handshakeMiddleware) {
|
|
41
|
+
handshakeMiddleware(middlewareHandshakeStream);
|
|
42
|
+
}
|
|
43
|
+
const action = new ActionHandshakeWS(req);
|
|
44
|
+
try {
|
|
45
|
+
await this._processMiddlewareAction(middlewareHandshakeStream, action);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
75
48
|
middlewareHandshakeStream.close();
|
|
76
|
-
callback(false,
|
|
77
|
-
|
|
49
|
+
callback(false, 401, typeof error === 'string' ? error : error.message);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (ok) {
|
|
53
|
+
callback(true);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const error = new ServerProtocolError(`Failed to authorize socket handshake - Invalid origin: ${origin}`);
|
|
57
|
+
this.emitWarning(error);
|
|
58
|
+
middlewareHandshakeStream.close();
|
|
59
|
+
callback(false, 403, error.message);
|
|
78
60
|
};
|
|
79
61
|
let opts = {
|
|
80
62
|
brokerEngine: new SimpleBroker(),
|
|
@@ -117,40 +99,22 @@ export class Server extends AsyncStreamEmitter {
|
|
|
117
99
|
this.brokerEngine = opts.brokerEngine;
|
|
118
100
|
this.middlewareEmitFailures = opts.middlewareEmitFailures;
|
|
119
101
|
this._path = opts.path;
|
|
120
|
-
(() =>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for (var _d = true, _e = __asyncValues(this.brokerEngine.listen('error')), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
|
|
124
|
-
_c = _f.value;
|
|
125
|
-
_d = false;
|
|
126
|
-
try {
|
|
127
|
-
let { error } = _c;
|
|
128
|
-
this.emitWarning(error);
|
|
129
|
-
}
|
|
130
|
-
finally {
|
|
131
|
-
_d = true;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
136
|
-
finally {
|
|
137
|
-
try {
|
|
138
|
-
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
139
|
-
}
|
|
140
|
-
finally { if (e_1) throw e_1.error; }
|
|
102
|
+
(async () => {
|
|
103
|
+
for await (let { error } of this.brokerEngine.listen('error')) {
|
|
104
|
+
this.emitWarning(error);
|
|
141
105
|
}
|
|
142
|
-
})
|
|
106
|
+
})();
|
|
143
107
|
if (this.brokerEngine.isReady) {
|
|
144
108
|
this.isReady = true;
|
|
145
109
|
this.emit('ready', {});
|
|
146
110
|
}
|
|
147
111
|
else {
|
|
148
112
|
this.isReady = false;
|
|
149
|
-
(() =>
|
|
150
|
-
|
|
113
|
+
(async () => {
|
|
114
|
+
await this.brokerEngine.listen('ready').once();
|
|
151
115
|
this.isReady = true;
|
|
152
116
|
this.emit('ready', {});
|
|
153
|
-
})
|
|
117
|
+
})();
|
|
154
118
|
}
|
|
155
119
|
// let wsEngine = typeof opts.wsEngine === 'string' ? require(opts.wsEngine) : opts.wsEngine;
|
|
156
120
|
// if (!wsEngine || !wsEngine.Server) {
|
|
@@ -308,10 +272,10 @@ export class Server extends AsyncStreamEmitter {
|
|
|
308
272
|
type !== MiddlewareType.MIDDLEWARE_INBOUND_RAW &&
|
|
309
273
|
type !== MiddlewareType.MIDDLEWARE_INBOUND &&
|
|
310
274
|
type !== MiddlewareType.MIDDLEWARE_OUTBOUND) {
|
|
311
|
-
throw new InvalidArgumentsError(`Middleware
|
|
275
|
+
throw new InvalidArgumentsError(`Middleware ${type} type is not supported`);
|
|
312
276
|
}
|
|
313
277
|
if (this._middleware[type]) {
|
|
314
|
-
throw new InvalidActionError(`Middleware
|
|
278
|
+
throw new InvalidActionError(`Middleware ${type} type has already been set`);
|
|
315
279
|
}
|
|
316
280
|
this._middleware[type] = middleware;
|
|
317
281
|
}
|
|
@@ -321,47 +285,45 @@ export class Server extends AsyncStreamEmitter {
|
|
|
321
285
|
hasMiddleware(type) {
|
|
322
286
|
return !!this._middleware[type];
|
|
323
287
|
}
|
|
324
|
-
_processMiddlewareAction(middlewareStream, action, socket) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
288
|
+
async _processMiddlewareAction(middlewareStream, action, socket) {
|
|
289
|
+
if (!this.hasMiddleware(middlewareStream.type)) {
|
|
290
|
+
return { data: 'data' in action ? action.data : undefined };
|
|
291
|
+
}
|
|
292
|
+
middlewareStream.write(action);
|
|
293
|
+
let newData;
|
|
294
|
+
let options;
|
|
295
|
+
try {
|
|
296
|
+
const result = await action.promise;
|
|
297
|
+
if (result) {
|
|
298
|
+
newData = result.data;
|
|
299
|
+
options = result.options;
|
|
328
300
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
let
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
newData = result.data;
|
|
336
|
-
options = result.options;
|
|
337
|
-
}
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
let clientError;
|
|
304
|
+
if (!error) {
|
|
305
|
+
error = new SilentMiddlewareBlockedError(`The ${action.type} Action was blocked by ${middlewareStream.type} middleware`, middlewareStream.type);
|
|
306
|
+
clientError = error;
|
|
338
307
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
308
|
+
else if (error.silent) {
|
|
309
|
+
clientError = new SilentMiddlewareBlockedError(`The ${action.type} Action was blocked by ${middlewareStream.type} middleware`, middlewareStream.type);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
clientError = error;
|
|
313
|
+
}
|
|
314
|
+
if (this.middlewareEmitFailures) {
|
|
315
|
+
if (socket) {
|
|
316
|
+
socket.emitError(error);
|
|
347
317
|
}
|
|
348
318
|
else {
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
if (this.middlewareEmitFailures) {
|
|
352
|
-
if (socket) {
|
|
353
|
-
socket.emitError(error);
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
this.emitWarning(error);
|
|
357
|
-
}
|
|
319
|
+
this.emitWarning(error);
|
|
358
320
|
}
|
|
359
|
-
throw clientError;
|
|
360
321
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
322
|
+
throw clientError;
|
|
323
|
+
}
|
|
324
|
+
if (newData === undefined && 'data' in action) {
|
|
325
|
+
newData = action.data;
|
|
326
|
+
}
|
|
327
|
+
return { data: newData, options };
|
|
366
328
|
}
|
|
367
329
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { DemuxedConsumableStream, StreamDemux, StreamDemuxWrapper } from "@socket-mesh/stream-demux";
|
|
2
|
-
import { AuthenticateRequest, HandshakeRequest, InboundRequest, InvokeRequest, PublishRequest, SubscribeRequest, UnsubscribeRequest } from "./request";
|
|
2
|
+
import { AuthenticateRequest, HandshakeRequest, InboundRequest, InvokeRequest, PublishRequest, SubscribeRequest, UnsubscribeRequest } from "./request.js";
|
|
3
3
|
import { Request } from "@socket-mesh/request";
|
|
4
|
-
export declare class ServerSocketProcedure
|
|
5
|
-
constructor(stream: StreamDemux<InboundRequest
|
|
4
|
+
export declare class ServerSocketProcedure extends StreamDemuxWrapper<InboundRequest> {
|
|
5
|
+
constructor(stream: StreamDemux<InboundRequest>);
|
|
6
6
|
listen(name: '#handshake'): DemuxedConsumableStream<HandshakeRequest>;
|
|
7
7
|
listen(name: '#authenticate'): DemuxedConsumableStream<AuthenticateRequest>;
|
|
8
8
|
listen(name: '#subscribe'): DemuxedConsumableStream<SubscribeRequest>;
|
|
9
9
|
listen(name: '#unsubscribe'): DemuxedConsumableStream<UnsubscribeRequest>;
|
|
10
|
-
listen(name: '#publish'): DemuxedConsumableStream<PublishRequest
|
|
11
|
-
listen<U
|
|
12
|
-
listen<U
|
|
10
|
+
listen(name: '#publish'): DemuxedConsumableStream<PublishRequest>;
|
|
11
|
+
listen<U>(name: string): DemuxedConsumableStream<Request<U>>;
|
|
12
|
+
listen<U, V>(name: string): DemuxedConsumableStream<InvokeRequest<U, V>>;
|
|
13
13
|
}
|
package/serversocket.d.ts
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { ChannelOptions } from "@socket-mesh/channel";
|
|
4
3
|
import { AuthState, AuthToken, SignedAuthToken } from "@socket-mesh/auth";
|
|
5
|
-
import { AuthTokenOptions } from "./auth-engine";
|
|
4
|
+
import { AuthTokenOptions } from "./auth-engine.js";
|
|
6
5
|
import { WritableConsumableStream } from "@socket-mesh/writable-consumable-stream";
|
|
7
6
|
import { AsyncStreamEmitter } from "@socket-mesh/async-stream-emitter";
|
|
8
7
|
import { DemuxedConsumableStream, StreamDemuxWrapper } from "@socket-mesh/stream-demux";
|
|
9
8
|
import { ResponsePacketError } from "@socket-mesh/request";
|
|
10
9
|
import { IncomingMessage } from 'http';
|
|
11
|
-
import { SocketState } from "./socket-state";
|
|
12
|
-
import { ActionMessage, ActionPublishOut,
|
|
13
|
-
import { AuthStateChanged, AuthTokenSigned, Authenticated, BadAuthToken, Closed, ConnectAborted, Connected, Deauthenticated, Disconnected, ErrorOccurred, RawMessage, ServerSocketEvents, Subscribed, Unsubscribed } from './events';
|
|
14
|
-
import { MiddlewareStream } from './middleware-stream';
|
|
15
|
-
import { ProtocolVersions } from './server-options';
|
|
10
|
+
import { SocketState } from "./socket-state.js";
|
|
11
|
+
import { ActionMessage, ActionPublishOut, HandshakeAction, InboundAction } from "./action.js";
|
|
12
|
+
import { AuthStateChanged, AuthTokenSigned, Authenticated, BadAuthToken, Closed, ConnectAborted, Connected, Deauthenticated, Disconnected, ErrorOccurred, RawMessage, ServerSocketEvents, Subscribed, Unsubscribed } from './events.js';
|
|
13
|
+
import { MiddlewareStream } from './middleware-stream.js';
|
|
14
|
+
import { ProtocolVersions } from './server-options.js';
|
|
16
15
|
import ws from "ws";
|
|
17
|
-
import { Server } from "./server";
|
|
18
|
-
import { OutboundPacket, OutboundPacketOptions } from './outbound-packet';
|
|
19
|
-
import { ServerSocketProcedure } from './serversocket-procedure';
|
|
16
|
+
import { Server } from "./server.js";
|
|
17
|
+
import { OutboundPacket, OutboundPacketOptions } from './outbound-packet.js';
|
|
18
|
+
import { ServerSocketProcedure } from './serversocket-procedure.js';
|
|
20
19
|
export type WebSocket = ws.WebSocket & {
|
|
21
20
|
bytesReceived: number;
|
|
22
21
|
upgradeReq: IncomingMessage;
|
|
@@ -32,7 +31,7 @@ interface EventObject {
|
|
|
32
31
|
data?: any;
|
|
33
32
|
cid?: number;
|
|
34
33
|
}
|
|
35
|
-
export declare class ServerSocket
|
|
34
|
+
export declare class ServerSocket extends AsyncStreamEmitter<ServerSocketEvents> {
|
|
36
35
|
authState: AuthState;
|
|
37
36
|
authToken: AuthToken | null;
|
|
38
37
|
batchInterval: number;
|
|
@@ -52,12 +51,12 @@ export declare class ServerSocket<T> extends AsyncStreamEmitter<ServerSocketEven
|
|
|
52
51
|
[channel: string]: boolean;
|
|
53
52
|
};
|
|
54
53
|
readonly inboundMessageStream: WritableConsumableStream<string | ArrayBuffer | Buffer[]>;
|
|
55
|
-
readonly outboundPacketStream: WritableConsumableStream<OutboundPacket
|
|
56
|
-
readonly server: Server
|
|
57
|
-
readonly middlewareHandshakeStream: MiddlewareStream<HandshakeAction
|
|
58
|
-
readonly middlewareInboundRawStream: MiddlewareStream<ActionMessage
|
|
59
|
-
readonly middlewareInboundStream: MiddlewareStream<InboundAction
|
|
60
|
-
readonly middlewareOutboundStream: MiddlewareStream<ActionPublishOut
|
|
54
|
+
readonly outboundPacketStream: WritableConsumableStream<OutboundPacket>;
|
|
55
|
+
readonly server: Server;
|
|
56
|
+
readonly middlewareHandshakeStream: MiddlewareStream<HandshakeAction>;
|
|
57
|
+
readonly middlewareInboundRawStream: MiddlewareStream<ActionMessage>;
|
|
58
|
+
readonly middlewareInboundStream: MiddlewareStream<InboundAction>;
|
|
59
|
+
readonly middlewareOutboundStream: MiddlewareStream<ActionPublishOut>;
|
|
61
60
|
readonly remoteAddress?: string;
|
|
62
61
|
readonly remoteFamily?: string;
|
|
63
62
|
readonly remotePort?: number;
|
|
@@ -65,8 +64,8 @@ export declare class ServerSocket<T> extends AsyncStreamEmitter<ServerSocketEven
|
|
|
65
64
|
outboundSentMessageCount: number;
|
|
66
65
|
signedAuthToken: SignedAuthToken | null;
|
|
67
66
|
state: SocketState;
|
|
68
|
-
readonly receiver: StreamDemuxWrapper<
|
|
69
|
-
readonly procedure: ServerSocketProcedure
|
|
67
|
+
readonly receiver: StreamDemuxWrapper<any>;
|
|
68
|
+
readonly procedure: ServerSocketProcedure;
|
|
70
69
|
private _cid;
|
|
71
70
|
private _handshakeTimeoutRef;
|
|
72
71
|
private _pingIntervalTicker;
|
|
@@ -77,9 +76,9 @@ export declare class ServerSocket<T> extends AsyncStreamEmitter<ServerSocketEven
|
|
|
77
76
|
private readonly _receiverDemux;
|
|
78
77
|
private readonly _procedureDemux;
|
|
79
78
|
private readonly _sendPing;
|
|
80
|
-
constructor(id: string, server: Server
|
|
79
|
+
constructor(id: string, server: Server, socket: WebSocket, protocolVersion: ProtocolVersions);
|
|
81
80
|
getBackpressure(): number;
|
|
82
|
-
get exchange(): import("@socket-mesh/channel").Client<import("@socket-mesh/simple-broker/packet").Packet<
|
|
81
|
+
get exchange(): import("@socket-mesh/channel").Client<import("@socket-mesh/simple-broker/packet").Packet<any>>;
|
|
83
82
|
getInboundBackpressure(): number;
|
|
84
83
|
getOutboundBackpressure(): number;
|
|
85
84
|
private _startBatchOnHandshake;
|