@socket-mesh/server 17.3.6 → 18.0.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/serversocket.js CHANGED
@@ -1,33 +1,18 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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
1
  import cloneDeep from 'clone-deep';
18
2
  import { AuthState } from "@socket-mesh/auth";
19
3
  import { WritableConsumableStream } from "@socket-mesh/writable-consumable-stream";
20
4
  import { AsyncStreamEmitter } from "@socket-mesh/async-stream-emitter";
21
5
  import { StreamDemux, StreamDemuxWrapper } from "@socket-mesh/stream-demux";
22
- import { Request } from "@socket-mesh/request";
6
+ import { Request, RequestWithResponse, createErrorResponse } from "@socket-mesh/request";
23
7
  import { dehydrateError, hydrateError, socketProtocolIgnoreStatuses, socketProtocolErrorStatuses, InvalidArgumentsError, SocketProtocolError, TimeoutError, BadConnectionError, InvalidActionError, AuthError, AuthTokenExpiredError, AuthTokenInvalidError, AuthTokenNotBeforeError, AuthTokenError, BrokerError } from "@socket-mesh/errors";
24
- import { SocketState } from "./socket-state";
25
- import { MiddlewareType } from "./middleware-type";
26
- import { ActionAuthenticate, ActionHandshakeSC, ActionInvoke, ActionMessage, ActionPublishIn, ActionPublishOut, ActionSubscribe, ActionTransmit } from "./action";
27
- import { MiddlewareStream } from './middleware-stream';
28
- import { isAuthenticatePacket, isHandshakePacket, isPublishPacket, isRemoveAuthTokenPacket, isSubscribePacket, isUnsubscribePacket } from './inbound-packet';
29
- import { isPublishOutPacket } from './outbound-packet';
30
- import { AuthenticateRequest, HandshakeRequest, UnsubscribeRequest, isPublishRequest, isSubscribeRequest } from './request';
8
+ import { SocketState } from "./socket-state.js";
9
+ import { MiddlewareType } from "./middleware-type.js";
10
+ import { ActionAuthenticate, ActionHandshakeSC, ActionInvoke, ActionMessage, ActionPublishIn, ActionPublishOut, ActionSubscribe, ActionTransmit } from "./action.js";
11
+ import { MiddlewareStream } from './middleware-stream.js';
12
+ import { isAuthenticatePacket, isHandshakePacket, isPublishPacket, isRemoveAuthTokenPacket, isSubscribePacket, isUnsubscribePacket } from './inbound-packet.js';
13
+ import { isPublishOutPacket } from './outbound-packet.js';
14
+ import { AuthenticateRequest, HandshakeRequest, UnsubscribeRequest } from './request.js';
15
+ import { ServerSocketProcedure } from './serversocket-procedure.js';
31
16
  const HANDSHAKE_REJECTION_STATUS_CODE = 4008;
32
17
  export class ServerSocket extends AsyncStreamEmitter {
33
18
  constructor(id, server, socket, protocolVersion) {
@@ -41,7 +26,7 @@ export class ServerSocket extends AsyncStreamEmitter {
41
26
  this._receiverDemux = new StreamDemux();
42
27
  this.receiver = new StreamDemuxWrapper(this._receiverDemux);
43
28
  this._procedureDemux = new StreamDemux();
44
- this.procedure = new StreamDemuxWrapper(this._procedureDemux);
29
+ this.procedure = new ServerSocketProcedure(this._procedureDemux);
45
30
  this.request = this.socket.upgradeReq;
46
31
  this.inboundReceivedMessageCount = 0;
47
32
  this.inboundProcessedMessageCount = 0;
@@ -116,7 +101,7 @@ export class ServerSocket extends AsyncStreamEmitter {
116
101
  this._handleInboundMessageStream(pongMessage);
117
102
  this._handleOutboundPacketStream();
118
103
  // Receive incoming raw messages
119
- this.socket.on('message', (messageBuffer, isBinary) => __awaiter(this, void 0, void 0, function* () {
104
+ this.socket.on('message', async (messageBuffer, isBinary) => {
120
105
  let message = isBinary ? messageBuffer : messageBuffer.toString();
121
106
  this.inboundReceivedMessageCount++;
122
107
  let isPong = message === pongMessage;
@@ -126,7 +111,7 @@ export class ServerSocket extends AsyncStreamEmitter {
126
111
  if (this.server.hasMiddleware(MiddlewareType.MIDDLEWARE_INBOUND_RAW)) {
127
112
  const action = new ActionMessage(this, message);
128
113
  try {
129
- const { data } = yield this.server._processMiddlewareAction(this.middlewareInboundRawStream, action, this);
114
+ const { data } = await this.server._processMiddlewareAction(this.middlewareInboundRawStream, action, this);
130
115
  message = data;
131
116
  }
132
117
  catch (error) {
@@ -136,20 +121,20 @@ export class ServerSocket extends AsyncStreamEmitter {
136
121
  }
137
122
  this.inboundMessageStream.write(message);
138
123
  this.emit('message', { message });
139
- }));
124
+ });
140
125
  }
141
126
  getBackpressure() {
142
127
  return Math.max(this.getInboundBackpressure(), this.getOutboundBackpressure(), this.getListenerBackpressure(), this.receiver.getBackpressure(), this.procedure.getBackpressure());
143
128
  }
144
- ;
129
+ get exchange() {
130
+ return this.server.exchange;
131
+ }
145
132
  getInboundBackpressure() {
146
133
  return this.inboundReceivedMessageCount - this.inboundProcessedMessageCount;
147
134
  }
148
- ;
149
135
  getOutboundBackpressure() {
150
136
  return this.outboundPreparedMessageCount - this.outboundSentMessageCount;
151
137
  }
152
- ;
153
138
  _startBatchOnHandshake() {
154
139
  this._startBatching();
155
140
  setTimeout(() => {
@@ -158,463 +143,430 @@ export class ServerSocket extends AsyncStreamEmitter {
158
143
  }
159
144
  }, this.batchOnHandshakeDuration);
160
145
  }
161
- ;
162
- _handleInboundMessageStream(pongMessage) {
163
- var _a, e_1, _b, _c;
164
- return __awaiter(this, void 0, void 0, function* () {
165
- try {
166
- for (var _d = true, _e = __asyncValues(this.inboundMessageStream), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
167
- _c = _f.value;
168
- _d = false;
169
- try {
170
- let message = _c;
171
- this.inboundProcessedMessageCount++;
172
- let isPong = message === pongMessage;
173
- if (isPong) {
174
- if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
175
- this._destroy(4009);
176
- this.socket.close(4009);
177
- continue;
178
- }
179
- let token = this.getAuthToken();
180
- if (this.isAuthTokenExpired(token)) {
181
- this.deauthenticate();
182
- }
183
- continue;
184
- }
185
- let packet;
186
- try {
187
- packet = this.decode(message);
188
- }
189
- catch (error) {
190
- if (error.name === 'Error') {
191
- error.name = 'InvalidMessageError';
192
- }
193
- this.emitError(error);
194
- if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
195
- this._destroy(4009);
196
- this.socket.close(4009);
197
- }
198
- continue;
199
- }
200
- if (Array.isArray(packet)) {
201
- let len = packet.length;
202
- for (let i = 0; i < len; i++) {
203
- yield this._processInboundPacket(packet[i], message);
204
- }
205
- }
206
- else {
207
- yield this._processInboundPacket(packet, message);
208
- }
209
- }
210
- finally {
211
- _d = true;
212
- }
146
+ async _handleInboundMessageStream(pongMessage) {
147
+ for await (let message of this.inboundMessageStream) {
148
+ this.inboundProcessedMessageCount++;
149
+ let isPong = message === pongMessage;
150
+ if (isPong) {
151
+ if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
152
+ this._destroy(4009);
153
+ this.socket.close(4009);
154
+ continue;
213
155
  }
214
- }
215
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
216
- finally {
217
- try {
218
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
156
+ let token = this.getAuthToken();
157
+ if (this.isAuthTokenExpired(token)) {
158
+ this.deauthenticate();
219
159
  }
220
- finally { if (e_1) throw e_1.error; }
160
+ continue;
221
161
  }
222
- });
223
- }
224
- ;
225
- _handleHandshakeTimeout() {
226
- this.disconnect(4005);
227
- }
228
- ;
229
- _processHandshakeRequest(request) {
230
- return __awaiter(this, void 0, void 0, function* () {
231
- let data = request.data || { authToken: '' };
232
- let signedAuthToken = data.authToken;
233
- clearTimeout(this._handshakeTimeoutRef);
234
- const authInfo = yield this._validateAuthToken(signedAuthToken);
235
- const action = new ActionHandshakeSC(this, request, authInfo);
162
+ let packet;
236
163
  try {
237
- yield this.server._processMiddlewareAction(this.middlewareHandshakeStream, action);
164
+ packet = this.decode(message);
238
165
  }
239
166
  catch (error) {
240
- if (error.statusCode == null) {
241
- error.statusCode = HANDSHAKE_REJECTION_STATUS_CODE;
167
+ if (error.name === 'Error') {
168
+ error.name = 'InvalidMessageError';
242
169
  }
243
- request.error(error);
244
- this.disconnect(error.statusCode);
245
- return;
246
- }
247
- const oldAuthState = this.authState;
248
- let authError = undefined;
249
- try {
250
- yield this._processAuthentication(authInfo);
251
- if (this.state === SocketState.CLOSED) {
252
- return;
170
+ this.emitError(error);
171
+ if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
172
+ this._destroy(4009);
173
+ this.socket.close(4009);
253
174
  }
175
+ continue;
254
176
  }
255
- catch (error) {
256
- if (signedAuthToken != null) {
257
- // Because the token is optional as part of the handshake, we don't count
258
- // it as an error if the token wasn't provided.
259
- authError = dehydrateError(error);
260
- if (error.isBadToken) {
261
- this.deauthenticate();
262
- }
177
+ if (Array.isArray(packet)) {
178
+ let len = packet.length;
179
+ for (let i = 0; i < len; i++) {
180
+ await this._processInboundPacket(packet[i], message);
263
181
  }
264
182
  }
265
- const clientSocketStatus = {
266
- id: this.id,
267
- pingTimeout: this.server.pingTimeout,
268
- isAuthenticated: !!this.authToken,
269
- authError: authError
270
- };
271
- const serverSocketStatus = {
272
- id: this.id,
273
- pingTimeout: this.server.pingTimeout,
274
- isAuthenticated: !!this.authToken,
275
- authError: authError
276
- };
277
- if (this.server.pendingClients[this.id]) {
278
- delete this.server.pendingClients[this.id];
279
- this.server.pendingClientsCount--;
280
- }
281
- this.server.clients[this.id] = this;
282
- this.server.clientsCount++;
283
- this.state = SocketState.OPEN;
284
- if (clientSocketStatus.isAuthenticated) {
285
- // Needs to be executed after the connection event to allow
286
- // consumers to be setup from inside the connection loop.
287
- (() => __awaiter(this, void 0, void 0, function* () {
288
- yield this.listen('connect').once();
289
- this.triggerAuthenticationEvents(oldAuthState);
290
- }))();
291
- }
292
- // Treat authentication failure as a 'soft' error
293
- request.end(clientSocketStatus);
294
- if (this.batchOnHandshake) {
295
- this._startBatchOnHandshake();
183
+ else {
184
+ await this._processInboundPacket(packet, message);
296
185
  }
297
- this.emit('connect', serverSocketStatus);
298
- this.server.emit('connection', Object.assign({ socket: this }, serverSocketStatus));
299
- this.middlewareHandshakeStream.close();
300
- });
186
+ }
301
187
  }
302
- _processAuthenticateRequest(request) {
303
- return __awaiter(this, void 0, void 0, function* () {
304
- let signedAuthToken = request.data;
305
- let oldAuthState = this.authState;
306
- let authInfo = yield this._validateAuthToken(signedAuthToken);
307
- try {
308
- yield this._processAuthentication(authInfo);
188
+ _handleHandshakeTimeout() {
189
+ this.disconnect(4005);
190
+ }
191
+ async _processHandshakeRequest(request) {
192
+ let data = request.data || { authToken: '' };
193
+ let signedAuthToken = data.authToken;
194
+ clearTimeout(this._handshakeTimeoutRef);
195
+ const authInfo = await this._validateAuthToken(signedAuthToken);
196
+ const action = new ActionHandshakeSC(this, request, authInfo);
197
+ try {
198
+ await this.server._processMiddlewareAction(this.middlewareHandshakeStream, action);
199
+ }
200
+ catch (error) {
201
+ if (error.statusCode == null) {
202
+ error.statusCode = HANDSHAKE_REJECTION_STATUS_CODE;
309
203
  }
310
- catch (error) {
311
- if (error instanceof AuthTokenError) {
204
+ request.error(error);
205
+ this.disconnect(error.statusCode);
206
+ return;
207
+ }
208
+ const oldAuthState = this.authState;
209
+ let authError = undefined;
210
+ try {
211
+ await this._processAuthentication(authInfo);
212
+ if (this.state === SocketState.CLOSED) {
213
+ return;
214
+ }
215
+ }
216
+ catch (error) {
217
+ if (signedAuthToken != null) {
218
+ // Because the token is optional as part of the handshake, we don't count
219
+ // it as an error if the token wasn't provided.
220
+ authError = dehydrateError(error);
221
+ if (error.isBadToken) {
312
222
  this.deauthenticate();
313
- request.error(error);
314
- return;
315
223
  }
316
- request.end({
317
- isAuthenticated: !!this.authToken,
318
- authError: signedAuthToken == null ? null : dehydrateError(error)
319
- });
224
+ }
225
+ }
226
+ const clientSocketStatus = {
227
+ id: this.id,
228
+ pingTimeout: this.server.pingTimeout,
229
+ isAuthenticated: !!this.authToken,
230
+ authError: authError
231
+ };
232
+ const serverSocketStatus = {
233
+ id: this.id,
234
+ pingTimeout: this.server.pingTimeout,
235
+ isAuthenticated: !!this.authToken,
236
+ authError: authError
237
+ };
238
+ if (this.server.pendingClients[this.id]) {
239
+ delete this.server.pendingClients[this.id];
240
+ this.server.pendingClientsCount--;
241
+ }
242
+ this.server.clients[this.id] = this;
243
+ this.server.clientsCount++;
244
+ this.state = SocketState.OPEN;
245
+ if (clientSocketStatus.isAuthenticated) {
246
+ // Needs to be executed after the connection event to allow
247
+ // consumers to be setup from inside the connection loop.
248
+ (async () => {
249
+ await this.listen('connect').once();
250
+ this.triggerAuthenticationEvents(oldAuthState);
251
+ })();
252
+ }
253
+ // Treat authentication failure as a 'soft' error
254
+ request.end(clientSocketStatus);
255
+ if (this.batchOnHandshake) {
256
+ this._startBatchOnHandshake();
257
+ }
258
+ this.emit('connect', serverSocketStatus);
259
+ this.server.emit('connection', { socket: this, ...serverSocketStatus });
260
+ this.middlewareHandshakeStream.close();
261
+ }
262
+ async _processAuthenticateRequest(request) {
263
+ let signedAuthToken = request.data;
264
+ let oldAuthState = this.authState;
265
+ let authInfo = await this._validateAuthToken(signedAuthToken);
266
+ try {
267
+ await this._processAuthentication(authInfo);
268
+ }
269
+ catch (error) {
270
+ if (error instanceof AuthTokenError) {
271
+ this.deauthenticate();
272
+ request.error(error);
320
273
  return;
321
274
  }
322
- this.triggerAuthenticationEvents(oldAuthState);
323
275
  request.end({
324
276
  isAuthenticated: !!this.authToken,
325
- authError: null
277
+ authError: signedAuthToken == null ? null : dehydrateError(error)
326
278
  });
279
+ return;
280
+ }
281
+ this.triggerAuthenticationEvents(oldAuthState);
282
+ request.end({
283
+ isAuthenticated: !!this.authToken,
284
+ authError: null
327
285
  });
328
286
  }
329
- _subscribeSocket(channelName, subscriptionOptions) {
330
- return __awaiter(this, void 0, void 0, function* () {
331
- if (channelName === undefined || !subscriptionOptions) {
332
- throw new InvalidActionError(`Socket ${this.id} provided a malformated channel payload`);
333
- }
334
- if (this.server.socketChannelLimit && this.channelSubscriptionsCount >= this.server.socketChannelLimit) {
335
- throw new InvalidActionError(`Socket ${this.id} tried to exceed the channel subscription limit of ${this.server.socketChannelLimit}`);
336
- }
337
- if (typeof channelName !== 'string') {
338
- throw new InvalidActionError(`Socket ${this.id} provided an invalid channel name`);
339
- }
340
- if (this.channelSubscriptionsCount == null) {
341
- this.channelSubscriptionsCount = 0;
342
- }
343
- if (this.channelSubscriptions[channelName] == null) {
344
- this.channelSubscriptions[channelName] = true;
345
- this.channelSubscriptionsCount++;
346
- }
347
- try {
348
- this.server.brokerEngine.subscribeSocket(this, channelName);
349
- }
350
- catch (error) {
351
- delete this.channelSubscriptions[channelName];
352
- this.channelSubscriptionsCount--;
353
- throw error;
354
- }
355
- this.emit('subscribe', {
356
- channel: channelName,
357
- subscriptionOptions
358
- });
359
- this.server.emit('subscription', {
360
- socket: this,
361
- channel: channelName,
362
- subscriptionOptions
363
- });
287
+ async _subscribeSocket(channelName, subscriptionOptions) {
288
+ if (this.server.socketChannelLimit && this.channelSubscriptionsCount >= this.server.socketChannelLimit) {
289
+ throw new InvalidActionError(`Socket ${this.id} tried to exceed the channel subscription limit of ${this.server.socketChannelLimit}`);
290
+ }
291
+ if (this.channelSubscriptionsCount == null) {
292
+ this.channelSubscriptionsCount = 0;
293
+ }
294
+ if (this.channelSubscriptions[channelName] == null) {
295
+ this.channelSubscriptions[channelName] = true;
296
+ this.channelSubscriptionsCount++;
297
+ }
298
+ try {
299
+ this.server.brokerEngine.subscribeSocket(this, channelName);
300
+ }
301
+ catch (error) {
302
+ delete this.channelSubscriptions[channelName];
303
+ this.channelSubscriptionsCount--;
304
+ throw error;
305
+ }
306
+ this.emit('subscribe', {
307
+ channel: channelName,
308
+ subscriptionOptions
309
+ });
310
+ this.server.emit('subscription', {
311
+ socket: this,
312
+ channel: channelName,
313
+ subscriptionOptions
364
314
  });
365
315
  }
366
- ;
367
- _processSubscribeRequest(request) {
368
- return __awaiter(this, void 0, void 0, function* () {
316
+ async _processSubscribeRequest(request) {
317
+ if (this.state === SocketState.OPEN) {
369
318
  let subscriptionOptions = Object.assign({}, request.data);
370
319
  let channelName = subscriptionOptions.channel;
371
320
  delete subscriptionOptions.channel;
372
- if (this.state === SocketState.OPEN) {
373
- try {
374
- yield this._subscribeSocket(channelName, subscriptionOptions);
375
- }
376
- catch (err) {
377
- let error = new BrokerError(`Failed to subscribe socket to the ${channelName} channel - ${err}`);
378
- this.emitError(error);
379
- request.error(error);
380
- return;
381
- }
382
- request.end();
383
- return;
384
- }
385
- // This is an invalid state; it means the client tried to subscribe before
386
- // having completed the handshake.
387
- let error = new InvalidActionError('Cannot subscribe socket to a channel before it has completed the handshake');
388
- this.emitError(error);
389
- request.error(error);
390
- });
391
- }
392
- _unsubscribeFromAllChannels() {
393
- const channels = Object.keys(this.channelSubscriptions);
394
- return Promise.all(channels.map((channel) => this._unsubscribe(channel)));
395
- }
396
- ;
397
- _unsubscribe(channel) {
398
- return __awaiter(this, void 0, void 0, function* () {
399
- if (typeof channel !== 'string') {
400
- throw new InvalidActionError(`Socket ${this.id} tried to unsubscribe from an invalid channel name`);
401
- }
402
- if (!this.channelSubscriptions[channel]) {
403
- throw new InvalidActionError(`Socket ${this.id} tried to unsubscribe from a channel which it is not subscribed to`);
404
- }
405
321
  try {
406
- yield this.server.brokerEngine.unsubscribeSocket(this, channel);
407
- delete this.channelSubscriptions[channel];
408
- if (this.channelSubscriptionsCount != null) {
409
- this.channelSubscriptionsCount--;
410
- }
411
- this.emit('unsubscribe', { channel });
412
- this.server.emit('unsubscription', { socket: this, channel });
322
+ await this._subscribeSocket(channelName, subscriptionOptions);
413
323
  }
414
324
  catch (err) {
415
- const error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
416
- this.emitError(error);
417
- }
418
- });
419
- }
420
- ;
421
- _processUnsubscribePacket(packet) {
422
- return __awaiter(this, void 0, void 0, function* () {
423
- let channel = packet.data;
424
- try {
425
- yield this._unsubscribe(channel);
426
- }
427
- catch (err) {
428
- let error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
429
- this.emitError(error);
430
- }
431
- });
432
- }
433
- ;
434
- _processUnsubscribeRequest(request) {
435
- return __awaiter(this, void 0, void 0, function* () {
436
- const channel = request.data;
437
- try {
438
- yield this._unsubscribe(channel);
439
- }
440
- catch (err) {
441
- let error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
325
+ let error = new BrokerError(`Failed to subscribe socket to the ${channelName} channel - ${err}`);
442
326
  this.emitError(error);
443
327
  request.error(error);
444
328
  return;
445
329
  }
446
330
  request.end();
447
- });
331
+ return;
332
+ }
333
+ // This is an invalid state; it means the client tried to subscribe before
334
+ // having completed the handshake.
335
+ let error = new InvalidActionError('Cannot subscribe socket to a channel before it has completed the handshake');
336
+ this.emitError(error);
337
+ request.error(error);
448
338
  }
449
- _processInboundPublishPacket(packet) {
450
- return __awaiter(this, void 0, void 0, function* () {
451
- let data = packet.data || {};
452
- if (!data.channel || typeof data.channel !== 'string') {
453
- let error = new InvalidActionError(`Socket ${this.id} tried to invoke publish to an invalid "${data.channel}" channel`);
454
- this.emitError(error);
455
- return;
456
- }
457
- try {
458
- yield this.server.exchange.invokePublish(data.channel, data.data);
459
- }
460
- catch (error) {
461
- this.emitError(error);
339
+ async _unsubscribeFromAllChannels() {
340
+ const channels = Object.keys(this.channelSubscriptions);
341
+ await Promise.all(channels.map((channel) => this._unsubscribe(channel)));
342
+ }
343
+ async _unsubscribe(channel) {
344
+ if (typeof channel !== 'string') {
345
+ throw new InvalidActionError(`Socket ${this.id} tried to unsubscribe from an invalid channel name`);
346
+ }
347
+ if (!this.channelSubscriptions[channel]) {
348
+ throw new InvalidActionError(`Socket ${this.id} tried to unsubscribe from a channel which it is not subscribed to`);
349
+ }
350
+ try {
351
+ await this.server.brokerEngine.unsubscribeSocket(this, channel);
352
+ delete this.channelSubscriptions[channel];
353
+ if (this.channelSubscriptionsCount != null) {
354
+ this.channelSubscriptionsCount--;
462
355
  }
463
- });
356
+ this.emit('unsubscribe', { channel });
357
+ this.server.emit('unsubscription', { socket: this, channel });
358
+ }
359
+ catch (err) {
360
+ const error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
361
+ this.emitError(error);
362
+ }
464
363
  }
465
- _processInboundPublishRequest(request) {
466
- return __awaiter(this, void 0, void 0, function* () {
467
- let data = request.data || {};
468
- if (typeof data.channel !== 'string') {
469
- let error = new InvalidActionError(`Socket ${this.id} tried to transmit publish to an invalid "${data.channel}" channel`);
470
- this.emitError(error);
471
- request.error(error);
364
+ async _processUnsubscribePacket(packet) {
365
+ let channel = packet.data;
366
+ try {
367
+ await this._unsubscribe(channel);
368
+ }
369
+ catch (err) {
370
+ let error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
371
+ this.emitError(error);
372
+ }
373
+ }
374
+ async _processUnsubscribeRequest(request) {
375
+ const channel = request.data;
376
+ try {
377
+ await this._unsubscribe(channel);
378
+ }
379
+ catch (err) {
380
+ let error = new BrokerError(`Failed to unsubscribe socket from the ${channel} channel - ${err}`);
381
+ this.emitError(error);
382
+ request.error(error);
383
+ return;
384
+ }
385
+ request.end();
386
+ }
387
+ async _processInboundPublishPacket(packet) {
388
+ try {
389
+ await this.server.exchange.invokePublish(packet.data.channel, packet.data.data);
390
+ }
391
+ catch (error) {
392
+ this.emitError(error);
393
+ }
394
+ }
395
+ async _processInboundPublishRequest(request) {
396
+ try {
397
+ await this.server.exchange.invokePublish(request.data.channel, request.data.data);
398
+ }
399
+ catch (error) {
400
+ this.emitError(error);
401
+ request.error(error);
402
+ return;
403
+ }
404
+ request.end();
405
+ }
406
+ async _processInboundPacket(packet, message) {
407
+ if (packet && typeof packet.event === 'string') {
408
+ let isRPC = ('cid' in packet) && typeof packet.cid === 'number';
409
+ if (isHandshakePacket(packet)) {
410
+ if (!isRPC) {
411
+ let error = new InvalidActionError('Handshake request was malformatted');
412
+ this.emitError(error);
413
+ this._destroy(HANDSHAKE_REJECTION_STATUS_CODE);
414
+ this.socket.close(HANDSHAKE_REJECTION_STATUS_CODE);
415
+ return;
416
+ }
417
+ const request = new HandshakeRequest(this, packet.cid, packet.event, packet.data);
418
+ await this._processHandshakeRequest(request);
419
+ this._procedureDemux.write(request.procedure, request);
472
420
  return;
473
421
  }
474
- try {
475
- yield this.server.exchange.invokePublish(data.channel, data.data);
476
- }
477
- catch (error) {
478
- this.emitError(error);
479
- request.error(error);
422
+ if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
423
+ this._destroy(4009);
424
+ this.socket.close(4009);
480
425
  return;
481
426
  }
482
- request.end();
483
- });
484
- }
485
- _processInboundPacket(packet, message) {
486
- return __awaiter(this, void 0, void 0, function* () {
487
- if (packet && packet.event != null) {
488
- let isRPC = ('cid' in packet);
489
- if (isHandshakePacket(packet)) {
490
- const request = new HandshakeRequest(this, packet.cid, packet.event, packet.data);
491
- yield this._processHandshakeRequest(request);
492
- this._procedureDemux.write(request.procedure, request);
427
+ if (isAuthenticatePacket(packet)) {
428
+ if (!isRPC) {
429
+ let error = new InvalidActionError('Authenticate request was malformatted');
430
+ this.emitError(error);
431
+ this._destroy(HANDSHAKE_REJECTION_STATUS_CODE);
432
+ this.socket.close(HANDSHAKE_REJECTION_STATUS_CODE);
493
433
  return;
494
434
  }
495
- if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
496
- this._destroy(4009);
497
- this.socket.close(4009);
435
+ // Let AGServer handle these events.
436
+ const request = new AuthenticateRequest(this, packet.cid, packet.event, packet.data);
437
+ await this._processAuthenticateRequest(request);
438
+ this._procedureDemux.write(request.procedure, request);
439
+ return;
440
+ }
441
+ if (isRemoveAuthTokenPacket(packet)) {
442
+ this.deauthenticateSelf();
443
+ this._receiverDemux.write(packet.event, packet.data);
444
+ return;
445
+ }
446
+ if (isUnsubscribePacket(packet)) {
447
+ if (typeof packet.data !== 'string') {
448
+ const error = new InvalidActionError('Unsubscribe channel name was malformatted');
449
+ this.emitError(error);
450
+ if (isRPC) {
451
+ const request = new Request(this, packet.cid, packet.event, packet.data);
452
+ request.error(error);
453
+ }
498
454
  return;
499
455
  }
500
- if (isAuthenticatePacket(packet)) {
501
- // Let AGServer handle these events.
502
- const request = new AuthenticateRequest(this, packet.cid, packet.event, packet.data);
503
- yield this._processAuthenticateRequest(request);
456
+ if (isRPC) {
457
+ const request = new UnsubscribeRequest(this, packet.cid, packet.event, packet.data);
458
+ await this._processUnsubscribeRequest(request);
504
459
  this._procedureDemux.write(request.procedure, request);
505
460
  return;
506
461
  }
507
- if (isRemoveAuthTokenPacket(packet)) {
508
- this.deauthenticateSelf();
509
- this._receiverDemux.write(packet.event, packet.data);
510
- return;
511
- }
512
- if (isUnsubscribePacket(packet)) {
462
+ await this._processUnsubscribePacket(packet);
463
+ this._receiverDemux.write(packet.event, packet.data);
464
+ return;
465
+ }
466
+ let action;
467
+ if (isPublishPacket(packet)) {
468
+ if (!this.server.allowClientPublish) {
469
+ let error = new InvalidActionError('Client publish feature is disabled');
470
+ this.emitError(error);
513
471
  if (isRPC) {
514
- const request = new UnsubscribeRequest(this, packet.cid, packet.event, packet.data);
515
- yield this._processUnsubscribeRequest(request);
516
- this._procedureDemux.write(request.procedure, request);
517
- return;
472
+ const request = new Request(this, packet.cid, packet.event, packet.data);
473
+ request.error(error);
518
474
  }
519
- yield this._processUnsubscribePacket(packet);
520
- this._receiverDemux.write(packet.event, packet.data);
521
475
  return;
522
476
  }
523
- let action;
524
- if (isPublishPacket(packet)) {
525
- if (!this.server.allowClientPublish) {
526
- let error = new InvalidActionError('Client publish feature is disabled');
527
- this.emitError(error);
528
- if (isRPC) {
529
- const request = new Request(this, packet.cid, packet.event, packet.data);
530
- request.error(error);
531
- }
532
- return;
477
+ if (!packet.data || typeof packet.data.channel !== 'string') {
478
+ const error = new InvalidActionError('Publish channel name was malformatted');
479
+ this.emitError(error);
480
+ if (isRPC) {
481
+ const request = new Request(this, packet.cid, packet.event, packet.data);
482
+ request.error(error);
533
483
  }
534
- action = new ActionPublishIn(this, packet.data);
535
- }
536
- else if (isSubscribePacket(packet)) {
537
- action = new ActionSubscribe(this, packet.data);
538
- }
539
- else if (isRPC) {
540
- action = new ActionInvoke(this, packet.event, packet.data);
541
- }
542
- else {
543
- action = new ActionTransmit(this, packet.event, packet.data);
544
- }
545
- const tokenExpiredError = this._processAuthTokenExpiry();
546
- if (tokenExpiredError) {
547
- action.authTokenExpiredError = tokenExpiredError;
484
+ return;
548
485
  }
549
- let newData;
550
- if (isRPC) {
551
- let request = new Request(this, packet.cid, packet.event, packet.data);
552
- try {
553
- let { data } = yield this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
554
- newData = data;
555
- }
556
- catch (error) {
486
+ action = new ActionPublishIn(this, packet.data);
487
+ }
488
+ else if (isSubscribePacket(packet)) {
489
+ if (!packet.data || typeof packet.data.channel !== 'string') {
490
+ const error = new InvalidActionError('Subscribe channel name was malformatted');
491
+ this.emitError(error);
492
+ if (isRPC) {
493
+ const request = new Request(this, packet.cid, packet.event, packet.data);
557
494
  request.error(error);
558
- return;
559
- }
560
- if (isSubscribeRequest(request)) {
561
- if (!request.data) {
562
- request.data = {};
563
- }
564
- request.data.data = newData;
565
- yield this._processSubscribeRequest(request);
566
495
  }
567
- else if (isPublishRequest(request)) {
568
- if (!request.data) {
569
- request.data = {};
570
- }
571
- request.data.data = newData;
572
- yield this._processInboundPublishRequest(request);
573
- }
574
- else {
575
- request.data = newData;
576
- }
577
- this._procedureDemux.write(request.procedure, request);
578
496
  return;
579
497
  }
498
+ action = new ActionSubscribe(this, packet.data);
499
+ }
500
+ else if (isRPC) {
501
+ action = new ActionInvoke(this, packet.event, packet.data);
502
+ }
503
+ else {
504
+ action = new ActionTransmit(this, packet.event, packet.data);
505
+ }
506
+ const tokenExpiredError = this._processAuthTokenExpiry();
507
+ if (tokenExpiredError) {
508
+ action.authTokenExpiredError = tokenExpiredError;
509
+ }
510
+ let newData;
511
+ if (isRPC) {
580
512
  try {
581
- let { data } = yield this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
513
+ let { data } = await this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
582
514
  newData = data;
583
515
  }
584
516
  catch (error) {
517
+ this.sendObject(createErrorResponse(packet.cid, error));
585
518
  return;
586
519
  }
587
- if (isPublishPacket(packet)) {
588
- if (!packet.data) {
589
- packet.data = {};
520
+ let request;
521
+ if (isSubscribePacket(packet) || isPublishPacket(packet)) {
522
+ request = new Request(this, packet.cid, packet.event, packet.data);
523
+ request.data.data = newData;
524
+ if (isSubscribePacket(packet)) {
525
+ await this._processSubscribeRequest(request);
526
+ }
527
+ else {
528
+ await this._processInboundPublishRequest(request);
590
529
  }
591
- packet.data.data = newData;
592
- yield this._processInboundPublishPacket(packet);
593
530
  }
594
- this._receiverDemux.write(packet.event, newData);
531
+ else {
532
+ request = new RequestWithResponse(this, packet.cid, packet.event, newData);
533
+ }
534
+ this._procedureDemux.write(request.procedure, request);
595
535
  return;
596
536
  }
597
- if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
598
- this._destroy(4009);
599
- this.socket.close(4009);
600
- return;
537
+ try {
538
+ let { data } = await this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
539
+ newData = data;
601
540
  }
602
- if (packet && 'rid' in packet) {
603
- // If incoming message is a response to a previously sent message
604
- const ret = this._callbackMap[packet.rid];
605
- if (ret) {
606
- clearTimeout(ret.timeout);
607
- delete this._callbackMap[packet.rid];
608
- const rehydratedError = hydrateError(packet.error);
609
- ret.callback(rehydratedError, packet.data);
610
- }
541
+ catch (error) {
611
542
  return;
612
543
  }
613
- // The last remaining case is to treat the message as raw
614
- this.emit('raw', { message });
615
- });
544
+ if (isPublishPacket(packet)) {
545
+ packet.data.data = newData;
546
+ await this._processInboundPublishPacket(packet);
547
+ }
548
+ this._receiverDemux.write(packet.event, newData);
549
+ return;
550
+ }
551
+ if (this.server.strictHandshake && this.state === SocketState.CONNECTING) {
552
+ this._destroy(4009);
553
+ this.socket.close(4009);
554
+ return;
555
+ }
556
+ if (packet && 'rid' in packet && typeof packet.rid === 'number') {
557
+ // If incoming message is a response to a previously sent message
558
+ const ret = this._callbackMap[packet.rid];
559
+ if (ret) {
560
+ clearTimeout(ret.timeout);
561
+ delete this._callbackMap[packet.rid];
562
+ const rehydratedError = hydrateError(packet.error);
563
+ ret.callback(rehydratedError, packet.data);
564
+ }
565
+ return;
566
+ }
567
+ // The last remaining case is to treat the message as raw
568
+ this.emit('raw', { message });
616
569
  }
617
- ;
618
570
  _resetPongTimeout() {
619
571
  if (this.server.pingTimeoutDisabled) {
620
572
  return;
@@ -644,7 +596,7 @@ export class ServerSocket extends AsyncStreamEmitter {
644
596
  delete this._callbackMap[i];
645
597
  clearTimeout(eventObject.timeout);
646
598
  delete eventObject.timeout;
647
- const errorMessage = `Event "${eventObject.event}" was aborted due to a bad connection`;
599
+ const errorMessage = `Event ${eventObject.event} was aborted due to a bad connection`;
648
600
  const badConnectionError = new BadConnectionError(errorMessage, failureType);
649
601
  const callback = eventObject.callback;
650
602
  delete eventObject.callback;
@@ -697,71 +649,69 @@ export class ServerSocket extends AsyncStreamEmitter {
697
649
  this.procedure.kill();
698
650
  this.killListeners();
699
651
  }
700
- _destroy(code, reason) {
701
- return __awaiter(this, void 0, void 0, function* () {
702
- clearInterval(this._pingIntervalTicker);
703
- clearTimeout(this._pingTimeoutTicker);
704
- this._cancelBatching();
705
- if (this.state === SocketState.CLOSED) {
652
+ async _destroy(code, reason) {
653
+ clearInterval(this._pingIntervalTicker);
654
+ clearTimeout(this._pingTimeoutTicker);
655
+ this._cancelBatching();
656
+ if (this.state === SocketState.CLOSED) {
657
+ this._abortAllPendingEventsDueToBadConnection('connectAbort');
658
+ }
659
+ else {
660
+ if (!reason) {
661
+ reason = socketProtocolErrorStatuses[code];
662
+ }
663
+ const prevState = this.state;
664
+ this.state = SocketState.CLOSED;
665
+ if (prevState === SocketState.CONNECTING) {
706
666
  this._abortAllPendingEventsDueToBadConnection('connectAbort');
667
+ this.emit('connectAbort', { code, reason });
668
+ this.server.emit('connectionAbort', { socket: this, code, reason });
707
669
  }
708
670
  else {
709
- if (!reason) {
710
- reason = socketProtocolErrorStatuses[code];
711
- }
712
- const prevState = this.state;
713
- this.state = SocketState.CLOSED;
714
- if (prevState === SocketState.CONNECTING) {
715
- this._abortAllPendingEventsDueToBadConnection('connectAbort');
716
- this.emit('connectAbort', { code, reason });
717
- this.server.emit('connectionAbort', { socket: this, code, reason });
671
+ this._abortAllPendingEventsDueToBadConnection('disconnect');
672
+ this.emit('disconnect', { code, reason });
673
+ this.server.emit('disconnection', { socket: this, code, reason });
674
+ }
675
+ this.emit('close', { code, reason });
676
+ this.server.emit('closure', { socket: this, code, reason });
677
+ clearTimeout(this._handshakeTimeoutRef);
678
+ let isClientFullyConnected = !!this.server.clients[this.id];
679
+ if (isClientFullyConnected) {
680
+ delete this.server.clients[this.id];
681
+ this.server.clientsCount--;
682
+ }
683
+ let isClientPending = !!this.server.pendingClients[this.id];
684
+ if (isClientPending) {
685
+ delete this.server.pendingClients[this.id];
686
+ this.server.pendingClientsCount--;
687
+ }
688
+ if (!socketProtocolIgnoreStatuses[code]) {
689
+ let closeMessage;
690
+ if (typeof reason === 'string') {
691
+ closeMessage = `Socket connection closed with status code ${code} and reason: ${reason}`;
718
692
  }
719
693
  else {
720
- this._abortAllPendingEventsDueToBadConnection('disconnect');
721
- this.emit('disconnect', { code, reason });
722
- this.server.emit('disconnection', { socket: this, code, reason });
723
- }
724
- this.emit('close', { code, reason });
725
- this.server.emit('closure', { socket: this, code, reason });
726
- clearTimeout(this._handshakeTimeoutRef);
727
- let isClientFullyConnected = !!this.server.clients[this.id];
728
- if (isClientFullyConnected) {
729
- delete this.server.clients[this.id];
730
- this.server.clientsCount--;
731
- }
732
- let isClientPending = !!this.server.pendingClients[this.id];
733
- if (isClientPending) {
734
- delete this.server.pendingClients[this.id];
735
- this.server.pendingClientsCount--;
694
+ closeMessage = `Socket connection closed with status code ${code}`;
736
695
  }
737
- if (!socketProtocolIgnoreStatuses[code]) {
738
- let closeMessage;
739
- if (reason) {
740
- closeMessage = `Socket connection closed with status code ${code} and reason: ${reason}`;
741
- }
742
- else {
743
- closeMessage = `Socket connection closed with status code ${code}`;
744
- }
745
- let err = new SocketProtocolError(socketProtocolErrorStatuses[code] || closeMessage, code);
746
- this.emitError(err);
747
- }
748
- yield this._unsubscribeFromAllChannels();
749
- let cleanupMode = this.server.options.socketStreamCleanupMode;
750
- if (cleanupMode === 'kill') {
751
- (() => __awaiter(this, void 0, void 0, function* () {
752
- yield this.listen('end').once();
753
- this.killAllStreams();
754
- }))();
755
- }
756
- else if (cleanupMode === 'close') {
757
- (() => __awaiter(this, void 0, void 0, function* () {
758
- yield this.listen('end').once();
759
- this.closeAllStreams();
760
- }))();
761
- }
762
- this.emit('end');
696
+ let err = new SocketProtocolError(socketProtocolErrorStatuses[code] || closeMessage, code);
697
+ this.emitError(err);
763
698
  }
764
- });
699
+ await this._unsubscribeFromAllChannels();
700
+ let cleanupMode = this.server.options.socketStreamCleanupMode;
701
+ if (cleanupMode === 'kill') {
702
+ (async () => {
703
+ await this.listen('end').once();
704
+ this.killAllStreams();
705
+ })();
706
+ }
707
+ else if (cleanupMode === 'close') {
708
+ (async () => {
709
+ await this.listen('end').once();
710
+ this.closeAllStreams();
711
+ })();
712
+ }
713
+ this.emit('end');
714
+ }
765
715
  }
766
716
  disconnect(code, reason) {
767
717
  code = code || 1000;
@@ -850,7 +800,6 @@ export class ServerSocket extends AsyncStreamEmitter {
850
800
  this.isBatching = false;
851
801
  this._cancelBatching();
852
802
  }
853
- ;
854
803
  serializeObject(object) {
855
804
  let str;
856
805
  try {
@@ -862,7 +811,6 @@ export class ServerSocket extends AsyncStreamEmitter {
862
811
  }
863
812
  return str;
864
813
  }
865
- ;
866
814
  sendObject(object) {
867
815
  if (this.isBufferingBatch) {
868
816
  this._batchBuffer.push(object);
@@ -873,47 +821,27 @@ export class ServerSocket extends AsyncStreamEmitter {
873
821
  this.send(str);
874
822
  }
875
823
  }
876
- _handleOutboundPacketStream() {
877
- var _a, e_2, _b, _c;
878
- return __awaiter(this, void 0, void 0, function* () {
879
- try {
880
- for (var _d = true, _e = __asyncValues(this.outboundPacketStream), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
881
- _c = _f.value;
882
- _d = false;
824
+ async _handleOutboundPacketStream() {
825
+ for await (let packet of this.outboundPacketStream) {
826
+ if ('resolve' in packet) {
827
+ // Invoke has no middleware, so there is no need to await here.
828
+ (async () => {
829
+ let result;
883
830
  try {
884
- let packet = _c;
885
- if ('resolve' in packet) {
886
- // Invoke has no middleware, so there is no need to await here.
887
- (() => __awaiter(this, void 0, void 0, function* () {
888
- let result;
889
- try {
890
- result = yield this._invoke(packet);
891
- }
892
- catch (error) {
893
- packet.reject(error);
894
- return;
895
- }
896
- packet.resolve(result);
897
- }))();
898
- this.outboundSentMessageCount++;
899
- continue;
900
- }
901
- yield this._processTransmit(packet);
902
- this.outboundSentMessageCount++;
831
+ result = await this._invoke(packet);
903
832
  }
904
- finally {
905
- _d = true;
833
+ catch (error) {
834
+ packet.reject(error);
835
+ return;
906
836
  }
907
- }
837
+ packet.resolve(result);
838
+ })();
839
+ this.outboundSentMessageCount++;
840
+ continue;
908
841
  }
909
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
910
- finally {
911
- try {
912
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
913
- }
914
- finally { if (e_2) throw e_2.error; }
915
- }
916
- });
842
+ await this._processTransmit(packet);
843
+ this.outboundSentMessageCount++;
844
+ }
917
845
  }
918
846
  _transmit(event, data, options) {
919
847
  if (this.cloneData) {
@@ -928,31 +856,29 @@ export class ServerSocket extends AsyncStreamEmitter {
928
856
  }
929
857
  transmit(event, data, options) {
930
858
  if (this.state !== SocketState.OPEN) {
931
- let error = new BadConnectionError(`Socket transmit "${event}" was aborted due to a bad connection`, 'connectAbort');
859
+ let error = new BadConnectionError(`Socket transmit ${event} event was aborted due to a bad connection`, 'connectAbort');
932
860
  this.emitError(error);
933
861
  return;
934
862
  }
935
863
  this._transmit(event, data, options);
936
864
  }
937
- invoke(event, data, options) {
938
- return __awaiter(this, void 0, void 0, function* () {
939
- if (this.state !== SocketState.OPEN) {
940
- const error = new BadConnectionError(`Socket invoke "${event}" was aborted due to a bad connection`, 'connectAbort');
941
- this.emitError(error);
942
- throw error;
943
- }
944
- if (this.cloneData) {
945
- data = cloneDeep(data);
946
- }
947
- this.outboundPreparedMessageCount++;
948
- return new Promise((resolve, reject) => {
949
- this.outboundPacketStream.write({
950
- event,
951
- data,
952
- options,
953
- resolve,
954
- reject
955
- });
865
+ async invoke(event, data, options) {
866
+ if (this.state !== SocketState.OPEN) {
867
+ const error = new BadConnectionError(`Socket invoke ${event} event was aborted due to a bad connection`, 'connectAbort');
868
+ this.emitError(error);
869
+ throw error;
870
+ }
871
+ if (this.cloneData) {
872
+ data = cloneDeep(data);
873
+ }
874
+ this.outboundPreparedMessageCount++;
875
+ return new Promise((resolve, reject) => {
876
+ this.outboundPacketStream.write({
877
+ event,
878
+ data,
879
+ options,
880
+ resolve,
881
+ reject
956
882
  });
957
883
  });
958
884
  }
@@ -962,86 +888,82 @@ export class ServerSocket extends AsyncStreamEmitter {
962
888
  listen(eventName) {
963
889
  return super.listen(eventName);
964
890
  }
965
- _processTransmit(packet) {
966
- return __awaiter(this, void 0, void 0, function* () {
967
- let newData;
968
- let useCache = packet.options ? packet.options.useCache : false;
891
+ async _processTransmit(packet) {
892
+ let newData;
893
+ let useCache = packet.options ? packet.options.useCache : false;
894
+ if (isPublishOutPacket(packet)) {
895
+ const action = new ActionPublishOut(this);
896
+ if (packet.data !== undefined) {
897
+ action.channel = packet.data.channel;
898
+ action.data = packet.data.data;
899
+ }
900
+ useCache = !this.server.hasMiddleware(this.middlewareOutboundStream.type);
901
+ try {
902
+ const { data, options } = await this.server._processMiddlewareAction(this.middlewareOutboundStream, action, this);
903
+ newData = data;
904
+ useCache = options == null ? useCache : options.useCache;
905
+ }
906
+ catch (error) {
907
+ return;
908
+ }
909
+ }
910
+ else {
911
+ newData = packet.data;
912
+ }
913
+ if (packet.options && useCache && packet.options.stringifiedData != null && !this.isBufferingBatch) {
914
+ // Optimized
915
+ this.send(packet.options.stringifiedData);
916
+ }
917
+ else {
918
+ const eventObject = {
919
+ event: packet.event
920
+ };
969
921
  if (isPublishOutPacket(packet)) {
970
- const action = new ActionPublishOut(this);
971
- if (packet.data !== undefined) {
972
- action.channel = packet.data.channel;
973
- action.data = packet.data.data;
974
- }
975
- useCache = !this.server.hasMiddleware(this.middlewareOutboundStream.type);
976
- try {
977
- const { data, options } = yield this.server._processMiddlewareAction(this.middlewareOutboundStream, action, this);
978
- newData = data;
979
- useCache = options == null ? useCache : options.useCache;
980
- }
981
- catch (error) {
982
- return;
983
- }
922
+ eventObject.data = packet.data || {};
923
+ eventObject.data.data = newData;
984
924
  }
985
925
  else {
986
- newData = packet.data;
926
+ eventObject.data = newData;
987
927
  }
988
- if (packet.options && useCache && packet.options.stringifiedData != null && !this.isBufferingBatch) {
928
+ this.sendObject(eventObject);
929
+ }
930
+ }
931
+ async _invoke({ event, data, options }) {
932
+ options = options || {};
933
+ return new Promise((resolve, reject) => {
934
+ const eventObject = {
935
+ event,
936
+ cid: this._nextCallId()
937
+ };
938
+ if (data !== undefined) {
939
+ eventObject.data = data;
940
+ }
941
+ const ackTimeout = options.ackTimeout == null ? this.server.ackTimeout : options.ackTimeout;
942
+ const timeout = setTimeout(() => {
943
+ let error = new TimeoutError(`Event response for ${event} event timed out`);
944
+ delete this._callbackMap[eventObject.cid];
945
+ reject(error);
946
+ }, ackTimeout);
947
+ this._callbackMap[eventObject.cid] = {
948
+ event,
949
+ callback: (err, result) => {
950
+ if (err) {
951
+ reject(err);
952
+ return;
953
+ }
954
+ resolve(result);
955
+ },
956
+ timeout
957
+ };
958
+ if (options.useCache && options.stringifiedData != null && !this.isBufferingBatch) {
989
959
  // Optimized
990
- this.send(packet.options.stringifiedData);
960
+ this.send(options.stringifiedData);
991
961
  }
992
962
  else {
993
- const eventObject = {
994
- event: packet.event
995
- };
996
- if (isPublishOutPacket(packet)) {
997
- eventObject.data = packet.data || {};
998
- eventObject.data.data = newData;
999
- }
1000
- else {
1001
- eventObject.data = newData;
1002
- }
1003
963
  this.sendObject(eventObject);
1004
964
  }
1005
965
  });
1006
966
  }
1007
- _invoke({ event, data, options }) {
1008
- return __awaiter(this, void 0, void 0, function* () {
1009
- options = options || {};
1010
- return new Promise((resolve, reject) => {
1011
- const eventObject = {
1012
- event,
1013
- cid: this._nextCallId()
1014
- };
1015
- if (data !== undefined) {
1016
- eventObject.data = data;
1017
- }
1018
- const ackTimeout = options.ackTimeout == null ? this.server.ackTimeout : options.ackTimeout;
1019
- const timeout = setTimeout(() => {
1020
- let error = new TimeoutError(`Event response for "${event}" timed out`);
1021
- delete this._callbackMap[eventObject.cid];
1022
- reject(error);
1023
- }, ackTimeout);
1024
- this._callbackMap[eventObject.cid] = {
1025
- event,
1026
- callback: (err, result) => {
1027
- if (err) {
1028
- reject(err);
1029
- return;
1030
- }
1031
- resolve(result);
1032
- },
1033
- timeout
1034
- };
1035
- if (options.useCache && options.stringifiedData != null && !this.isBufferingBatch) {
1036
- // Optimized
1037
- this.send(options.stringifiedData);
1038
- }
1039
- else {
1040
- this.sendObject(eventObject);
1041
- }
1042
- });
1043
- });
1044
- }
1045
967
  triggerAuthenticationEvents(oldAuthState) {
1046
968
  if (oldAuthState !== AuthState.AUTHENTICATED) {
1047
969
  let stateChangeData = {
@@ -1050,7 +972,10 @@ export class ServerSocket extends AsyncStreamEmitter {
1050
972
  authToken: this.authToken
1051
973
  };
1052
974
  this.emit('authStateChange', stateChangeData);
1053
- this.server.emit('authenticationStateChange', Object.assign({ socket: this }, stateChangeData));
975
+ this.server.emit('authenticationStateChange', {
976
+ socket: this,
977
+ ...stateChangeData
978
+ });
1054
979
  }
1055
980
  this.emit('authenticate', { authToken: this.authToken });
1056
981
  this.server.emit('authentication', {
@@ -1058,87 +983,91 @@ export class ServerSocket extends AsyncStreamEmitter {
1058
983
  authToken: this.authToken
1059
984
  });
1060
985
  }
1061
- setAuthToken(data, options) {
1062
- return __awaiter(this, void 0, void 0, function* () {
1063
- if (this.state === SocketState.CONNECTING) {
1064
- const err = new InvalidActionError('Cannot call setAuthToken before completing the handshake');
986
+ async setAuthToken(data, options) {
987
+ if (this.state === SocketState.CONNECTING) {
988
+ const err = new InvalidActionError('Cannot call setAuthToken before completing the handshake');
989
+ this.emitError(err);
990
+ throw err;
991
+ }
992
+ const authToken = cloneDeep(data);
993
+ const oldAuthState = this.authState;
994
+ this.authState = AuthState.AUTHENTICATED;
995
+ if (options == null) {
996
+ options = {};
997
+ }
998
+ else {
999
+ options = { ...options };
1000
+ if (options.algorithm != null) {
1001
+ delete options.algorithm;
1002
+ let err = new InvalidArgumentsError('Cannot change auth token algorithm at runtime - It must be specified as a config option on launch');
1065
1003
  this.emitError(err);
1066
- throw err;
1067
1004
  }
1068
- const authToken = cloneDeep(data);
1069
- const oldAuthState = this.authState;
1070
- this.authState = AuthState.AUTHENTICATED;
1071
- if (options == null) {
1072
- options = {};
1005
+ }
1006
+ options.mutatePayload = true;
1007
+ const rejectOnFailedDelivery = options.rejectOnFailedDelivery;
1008
+ delete options.rejectOnFailedDelivery;
1009
+ const defaultSignatureOptions = this.server.defaultSignatureOptions;
1010
+ // We cannot have the exp claim on the token and the expiresIn option
1011
+ // set at the same time or else auth.signToken will throw an error.
1012
+ let expiresIn;
1013
+ if (options.expiresIn == null) {
1014
+ expiresIn = defaultSignatureOptions.expiresIn;
1015
+ }
1016
+ else {
1017
+ expiresIn = options.expiresIn;
1018
+ }
1019
+ if (authToken) {
1020
+ if (authToken.exp == null) {
1021
+ options.expiresIn = expiresIn;
1073
1022
  }
1074
1023
  else {
1075
- options = Object.assign({}, options);
1076
- if (options.algorithm != null) {
1077
- delete options.algorithm;
1078
- let err = new InvalidArgumentsError('Cannot change auth token algorithm at runtime - It must be specified as a config option on launch');
1079
- this.emitError(err);
1080
- }
1081
- }
1082
- options.mutatePayload = true;
1083
- const rejectOnFailedDelivery = options.rejectOnFailedDelivery;
1084
- delete options.rejectOnFailedDelivery;
1085
- const defaultSignatureOptions = this.server.defaultSignatureOptions;
1086
- // We cannot have the exp claim on the token and the expiresIn option
1087
- // set at the same time or else auth.signToken will throw an error.
1088
- let expiresIn;
1089
- if (options.expiresIn == null) {
1090
- expiresIn = defaultSignatureOptions.expiresIn;
1024
+ delete options.expiresIn;
1091
1025
  }
1092
- else {
1093
- expiresIn = options.expiresIn;
1026
+ }
1027
+ else {
1028
+ options.expiresIn = expiresIn;
1029
+ }
1030
+ // Always use the default algorithm since it cannot be changed at runtime.
1031
+ if (defaultSignatureOptions.algorithm != null) {
1032
+ options.algorithm = defaultSignatureOptions.algorithm;
1033
+ }
1034
+ this.authToken = authToken;
1035
+ let signedAuthToken;
1036
+ try {
1037
+ signedAuthToken = await this.server.auth.signToken(authToken, this.server.signatureKey, options);
1038
+ }
1039
+ catch (error) {
1040
+ this.emitError(error);
1041
+ this._destroy(4002, error.toString());
1042
+ this.socket.close(4002);
1043
+ throw error;
1044
+ }
1045
+ if (this.authToken === authToken) {
1046
+ this.signedAuthToken = signedAuthToken;
1047
+ this.emit('authTokenSigned', { signedAuthToken });
1048
+ }
1049
+ this.triggerAuthenticationEvents(oldAuthState);
1050
+ const tokenData = {
1051
+ token: signedAuthToken
1052
+ };
1053
+ if (rejectOnFailedDelivery) {
1054
+ try {
1055
+ await this.invoke('#setAuthToken', tokenData);
1094
1056
  }
1095
- if (authToken) {
1096
- if (authToken.exp == null) {
1097
- options.expiresIn = expiresIn;
1057
+ catch (err) {
1058
+ let error;
1059
+ if (err && typeof err.message === 'string') {
1060
+ error = new AuthError(`Failed to deliver auth token to client - ${err.message}`);
1098
1061
  }
1099
1062
  else {
1100
- delete options.expiresIn;
1063
+ error = new AuthError('Failed to confirm delivery of auth token to client due to malformatted error response');
1101
1064
  }
1102
- }
1103
- else {
1104
- options.expiresIn = expiresIn;
1105
- }
1106
- // Always use the default algorithm since it cannot be changed at runtime.
1107
- if (defaultSignatureOptions.algorithm != null) {
1108
- options.algorithm = defaultSignatureOptions.algorithm;
1109
- }
1110
- this.authToken = authToken;
1111
- let signedAuthToken;
1112
- try {
1113
- signedAuthToken = yield this.server.auth.signToken(authToken, this.server.signatureKey, options);
1114
- }
1115
- catch (error) {
1116
1065
  this.emitError(error);
1117
- this._destroy(4002, error.toString());
1118
- this.socket.close(4002);
1119
1066
  throw error;
1120
1067
  }
1121
- if (this.authToken === authToken) {
1122
- this.signedAuthToken = signedAuthToken;
1123
- this.emit('authTokenSigned', { signedAuthToken });
1124
- }
1125
- this.triggerAuthenticationEvents(oldAuthState);
1126
- const tokenData = {
1127
- token: signedAuthToken
1128
- };
1129
- if (rejectOnFailedDelivery) {
1130
- try {
1131
- yield this.invoke('#setAuthToken', tokenData);
1132
- }
1133
- catch (err) {
1134
- const error = new AuthError(`Failed to deliver auth token to client - ${err}`);
1135
- this.emitError(error);
1136
- throw error;
1137
- }
1138
- return;
1139
- }
1140
- this.transmit('#setAuthToken', tokenData);
1141
- });
1068
+ return;
1069
+ }
1070
+ this.transmit('#setAuthToken', tokenData);
1142
1071
  }
1143
1072
  getAuthToken() {
1144
1073
  return this.authToken;
@@ -1155,7 +1084,10 @@ export class ServerSocket extends AsyncStreamEmitter {
1155
1084
  newAuthState: this.authState
1156
1085
  };
1157
1086
  this.emit('authStateChange', stateChangeData);
1158
- this.server.emit('authenticationStateChange', Object.assign({ socket: this }, stateChangeData));
1087
+ this.server.emit('authenticationStateChange', {
1088
+ socket: this,
1089
+ ...stateChangeData
1090
+ });
1159
1091
  }
1160
1092
  this.emit('deauthenticate', { oldAuthToken });
1161
1093
  this.server.emit('deauthentication', {
@@ -1163,23 +1095,21 @@ export class ServerSocket extends AsyncStreamEmitter {
1163
1095
  oldAuthToken
1164
1096
  });
1165
1097
  }
1166
- deauthenticate(options) {
1167
- return __awaiter(this, void 0, void 0, function* () {
1168
- this.deauthenticateSelf();
1169
- if (options && options.rejectOnFailedDelivery) {
1170
- try {
1171
- yield this.invoke('#removeAuthToken');
1172
- }
1173
- catch (error) {
1174
- this.emitError(error);
1175
- if (options && options.rejectOnFailedDelivery) {
1176
- throw error;
1177
- }
1098
+ async deauthenticate(options) {
1099
+ this.deauthenticateSelf();
1100
+ if (options && options.rejectOnFailedDelivery) {
1101
+ try {
1102
+ await this.invoke('#removeAuthToken');
1103
+ }
1104
+ catch (error) {
1105
+ this.emitError(error);
1106
+ if (options && options.rejectOnFailedDelivery) {
1107
+ throw error;
1178
1108
  }
1179
- return;
1180
1109
  }
1181
- this._transmit('#removeAuthToken');
1182
- });
1110
+ return;
1111
+ }
1112
+ this._transmit('#removeAuthToken');
1183
1113
  }
1184
1114
  kickOut(channel, message) {
1185
1115
  const channels = channel ? [channel] : Object.keys(this.channelSubscriptions);
@@ -1203,7 +1133,7 @@ export class ServerSocket extends AsyncStreamEmitter {
1203
1133
  return null;
1204
1134
  }
1205
1135
  isAuthTokenExpired(token) {
1206
- if ((token === null || token === void 0 ? void 0 : token.exp) != null) {
1136
+ if (token?.exp != null) {
1207
1137
  const currentTime = Date.now();
1208
1138
  const expiryMilliseconds = token.exp * 1000;
1209
1139
  return currentTime > expiryMilliseconds;
@@ -1234,61 +1164,57 @@ export class ServerSocket extends AsyncStreamEmitter {
1234
1164
  signedAuthToken
1235
1165
  });
1236
1166
  }
1237
- _validateAuthToken(signedAuthToken) {
1238
- return __awaiter(this, void 0, void 0, function* () {
1239
- const verificationOptions = Object.assign({}, this.server.defaultVerificationOptions);
1240
- let authToken;
1241
- try {
1242
- authToken = yield this.server.auth.verifyToken(signedAuthToken, this.server.verificationKey, verificationOptions);
1243
- }
1244
- catch (error) {
1245
- const authTokenError = this._processTokenError(error);
1246
- return {
1247
- signedAuthToken,
1248
- authTokenError,
1249
- authToken: null,
1250
- authState: AuthState.UNAUTHENTICATED
1251
- };
1252
- }
1167
+ async _validateAuthToken(signedAuthToken) {
1168
+ const verificationOptions = Object.assign({ socket: this }, this.server.defaultVerificationOptions);
1169
+ let authToken;
1170
+ try {
1171
+ authToken = await this.server.auth.verifyToken(signedAuthToken, this.server.verificationKey, verificationOptions);
1172
+ }
1173
+ catch (error) {
1174
+ const authTokenError = this._processTokenError(error);
1253
1175
  return {
1254
1176
  signedAuthToken,
1255
- authTokenError: null,
1256
- authToken,
1257
- authState: AuthState.AUTHENTICATED
1177
+ authTokenError,
1178
+ authToken: null,
1179
+ authState: AuthState.UNAUTHENTICATED
1258
1180
  };
1259
- });
1181
+ }
1182
+ return {
1183
+ signedAuthToken,
1184
+ authTokenError: null,
1185
+ authToken,
1186
+ authState: AuthState.AUTHENTICATED
1187
+ };
1260
1188
  }
1261
- _processAuthentication({ signedAuthToken, authTokenError, authToken }) {
1262
- return __awaiter(this, void 0, void 0, function* () {
1263
- if (authTokenError) {
1264
- this.signedAuthToken = null;
1265
- this.authToken = null;
1266
- this.authState = AuthState.UNAUTHENTICATED;
1267
- // If the error is related to the JWT being badly formatted, then we will
1268
- // treat the error as a socket error.
1269
- if (signedAuthToken != null) {
1270
- this.emitError(authTokenError);
1271
- if (authTokenError instanceof AuthTokenError) {
1272
- this._emitBadAuthTokenError(authTokenError, signedAuthToken);
1273
- }
1189
+ async _processAuthentication({ signedAuthToken, authTokenError, authToken }) {
1190
+ if (authTokenError) {
1191
+ this.signedAuthToken = null;
1192
+ this.authToken = null;
1193
+ this.authState = AuthState.UNAUTHENTICATED;
1194
+ // If the error is related to the JWT being badly formatted, then we will
1195
+ // treat the error as a socket error.
1196
+ if (signedAuthToken != null) {
1197
+ this.emitError(authTokenError);
1198
+ if (authTokenError instanceof AuthTokenError) {
1199
+ this._emitBadAuthTokenError(authTokenError, signedAuthToken);
1274
1200
  }
1275
- throw authTokenError;
1276
- }
1277
- this.signedAuthToken = signedAuthToken;
1278
- this.authToken = authToken;
1279
- this.authState = AuthState.AUTHENTICATED;
1280
- const action = new ActionAuthenticate(this, authToken, signedAuthToken);
1281
- try {
1282
- yield this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
1283
1201
  }
1284
- catch (error) {
1285
- this.authToken = null;
1286
- this.authState = AuthState.UNAUTHENTICATED;
1287
- if (error instanceof AuthTokenError) {
1288
- this._emitBadAuthTokenError(error, signedAuthToken);
1289
- }
1290
- throw error;
1202
+ throw authTokenError;
1203
+ }
1204
+ this.signedAuthToken = signedAuthToken;
1205
+ this.authToken = authToken;
1206
+ this.authState = AuthState.AUTHENTICATED;
1207
+ const action = new ActionAuthenticate(this, authToken, signedAuthToken);
1208
+ try {
1209
+ await this.server._processMiddlewareAction(this.middlewareInboundStream, action, this);
1210
+ }
1211
+ catch (error) {
1212
+ this.authToken = null;
1213
+ this.authState = AuthState.UNAUTHENTICATED;
1214
+ if (error instanceof AuthTokenError) {
1215
+ this._emitBadAuthTokenError(error, signedAuthToken);
1291
1216
  }
1292
- });
1217
+ throw error;
1218
+ }
1293
1219
  }
1294
1220
  }