genesys-cloud-streaming-client 17.2.7 → 17.2.8-develop.120

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.
Files changed (37) hide show
  1. package/dist/cjs/client.d.ts +2 -0
  2. package/dist/cjs/client.js +45 -16
  3. package/dist/cjs/index.d.ts +1 -1
  4. package/dist/cjs/index.js +2 -1
  5. package/dist/cjs/types/interfaces.d.ts +4 -0
  6. package/dist/cjs/types/interfaces.js +6 -1
  7. package/dist/cjs/utils.d.ts +6 -0
  8. package/dist/cjs/utils.js +20 -1
  9. package/dist/deploy-info.json +5 -5
  10. package/dist/es/client.d.ts +2 -0
  11. package/dist/es/client.js +46 -17
  12. package/dist/es/index.bundle.js +76 -26
  13. package/dist/es/index.d.ts +1 -1
  14. package/dist/es/index.js +1 -1
  15. package/dist/es/types/interfaces.d.ts +4 -0
  16. package/dist/es/types/interfaces.js +5 -0
  17. package/dist/es/utils.d.ts +6 -0
  18. package/dist/es/utils.js +18 -0
  19. package/dist/npm/CHANGELOG.md +6 -0
  20. package/dist/npm/client.d.ts +2 -0
  21. package/dist/npm/client.js +45 -16
  22. package/dist/npm/index.d.ts +1 -1
  23. package/dist/npm/index.js +2 -1
  24. package/dist/npm/module.js +1 -1
  25. package/dist/npm/types/interfaces.d.ts +4 -0
  26. package/dist/npm/types/interfaces.js +6 -1
  27. package/dist/npm/utils.d.ts +6 -0
  28. package/dist/npm/utils.js +20 -1
  29. package/dist/streaming-client.browser.ie.js +6 -6
  30. package/dist/streaming-client.browser.js +6 -6
  31. package/dist/v17/streaming-client.browser.ie.js +6 -6
  32. package/dist/v17/streaming-client.browser.js +6 -6
  33. package/dist/v17.2.8/streaming-client.browser.ie.js +32 -0
  34. package/dist/v17.2.8/streaming-client.browser.js +32 -0
  35. package/package.json +119 -117
  36. package/dist/v17.2.7/streaming-client.browser.ie.js +0 -32
  37. package/dist/v17.2.7/streaming-client.browser.js +0 -32
package/dist/es/utils.js CHANGED
@@ -1,6 +1,24 @@
1
1
  import { __awaiter } from "tslib";
2
2
  import { v4 } from 'uuid';
3
3
  import { TimeoutError } from './types/timeout-error';
4
+ import { StreamingClientErrorTypes } from './types/interfaces';
5
+ export class StreamingClientError extends Error {
6
+ constructor(type, messageOrError, details) {
7
+ let message;
8
+ if (messageOrError instanceof Error) {
9
+ message = messageOrError.message;
10
+ }
11
+ else {
12
+ message = messageOrError;
13
+ }
14
+ super(message);
15
+ if (messageOrError instanceof Error) {
16
+ this.name = messageOrError.name;
17
+ }
18
+ this.type = type !== null && type !== void 0 ? type : StreamingClientErrorTypes.generic;
19
+ this.details = details;
20
+ }
21
+ }
4
22
  /* istanbul ignore next */
5
23
  export function timeoutPromise(fn, timeoutMs, msg, details) {
6
24
  return new Promise(function (resolve, reject) {
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  # [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v17.2.7...HEAD)
8
+ ### Breaking Changes
9
+ * The `connnect` method will now throw a StreamingClientError with a type indicated, rather than the passing through the underlying error. The error that was previously thrown will still be available via the `details` property.
10
+
11
+ ### Changed
12
+ * [STREAM-162](https://inindca.atlassian.net/browse/STREAM-162) - Streaming-client should trigger re-auth for some SASL errors (and 401s) - this will be indicated by a StreamingClientError of type `.invalid-token`.
13
+
8
14
  # [v17.2.7](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v17.2.6..v17.2.7)
9
15
  ### Fixed
10
16
  * [STREAM-218](https://inindca.atlassian.net/browse/STREAM-218) - update the conversationId on sessions with reinvites
@@ -56,6 +56,8 @@ export declare class Client extends EventEmitter {
56
56
  private getStartingDelay;
57
57
  connect(connectOpts?: StreamingClientConnectOptions): Promise<void>;
58
58
  private backoffConnectRetryHandler;
59
+ private networkErrorNeedsAuth;
60
+ private saslErrorIsRetryable;
59
61
  private makeConnectionAttempt;
60
62
  private setupConnectionMonitoring;
61
63
  private prepareForConnect;
@@ -11,6 +11,7 @@ const ping_1 = require("./ping");
11
11
  const server_monitor_1 = require("./server-monitor");
12
12
  const utils_1 = require("./utils");
13
13
  const http_client_1 = require("./http-client");
14
+ const interfaces_1 = require("./types/interfaces");
14
15
  const events_1 = tslib_1.__importDefault(require("events"));
15
16
  const connection_manager_1 = require("./connection-manager");
16
17
  const exponential_backoff_1 = require("exponential-backoff");
@@ -331,15 +332,17 @@ class Client extends events_1.default {
331
332
  });
332
333
  }
333
334
  catch (err) {
334
- let error = err;
335
+ let errorForThrowing;
336
+ let errorForLogging = err;
335
337
  if (!err) {
336
- error = new Error('Streaming client connection attempted received and undefined error');
338
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Streaming client connection attempted and received an undefined error');
339
+ errorForLogging = errorForThrowing;
337
340
  }
338
341
  else if (err.name === 'AxiosError') {
339
342
  const axiosError = err;
340
343
  const config = axiosError.config || { url: undefined, method: undefined };
341
344
  // sanitized error for logging
342
- error = {
345
+ errorForLogging = {
343
346
  config: {
344
347
  url: config.url,
345
348
  method: config.method
@@ -349,16 +352,26 @@ class Client extends events_1.default {
349
352
  name: axiosError.name,
350
353
  message: axiosError.message
351
354
  };
355
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Failed to connect streaming client due to network error', err);
356
+ if (this.networkErrorNeedsAuth(err)) {
357
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.invalid_token, 'Failed to connect streaming client due to invalid token', err);
358
+ }
352
359
  }
353
- this.logger.error('Failed to connect streaming client', { error });
354
- if (!err) {
355
- throw error;
360
+ else if (err instanceof sasl_error_1.default) {
361
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.invalid_token, 'Failed to connect streaming client due to invalid token', err);
362
+ if (this.saslErrorIsRetryable(err)) {
363
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Streaming client connection attempted and received a SASL error', err);
364
+ }
356
365
  }
357
- throw err;
366
+ else {
367
+ errorForThrowing = new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Streaming client connection attempted and received an unknown error', err);
368
+ }
369
+ this.logger.error('Failed to connect streaming client', { error: errorForLogging });
370
+ throw errorForThrowing;
358
371
  }
359
372
  }
360
373
  async backoffConnectRetryHandler(connectOpts, err, connectionAttempt) {
361
- var _a, _b, _c, _d, _e;
374
+ var _a, _b, _c, _d;
362
375
  // if we exceed the `numOfAttempts` in the backoff config it still calls this retry fn and just ignores the result
363
376
  // if that's the case, we just want to bail out and ignore all the extra logging here.
364
377
  if (connectionAttempt >= connectOpts.maxConnectionAttempts) {
@@ -382,17 +395,25 @@ class Client extends events_1.default {
382
395
  message: axiosError.message
383
396
  };
384
397
  additionalErrorDetails.error = sanitizedError;
385
- if ([401, 403].includes(((_b = err.response) === null || _b === void 0 ? void 0 : _b.status) || 0)) {
398
+ if (this.networkErrorNeedsAuth(err)) {
386
399
  this.logger.error('Streaming client received an error that it can\'t recover from and will not attempt to reconnect', additionalErrorDetails);
387
400
  return false;
388
401
  }
389
402
  }
390
- // if we get a sasl error, that means we made it all the way to the point of trying to open a websocket and
391
- // it was rejected for some reason. At this point we should do a hard reconnect then try again.
403
+ // If we get a sasl error, that means we made it all the way to the point of trying to open a websocket and
404
+ // it was rejected for some reason. Some errors might resolve if we try connecting again. Others need
405
+ // re-authentication.
392
406
  if (err instanceof sasl_error_1.default) {
393
- this.logger.info('hardReconnectRequired set to true due to sasl error');
394
- this.hardReconnectRequired = true;
395
- Object.assign(additionalErrorDetails, { channelId: err.channelId, stanzaInstanceId: err.stanzaInstanceId });
407
+ if (this.saslErrorIsRetryable(err)) {
408
+ this.logger.info('hardReconnectRequired set to true due to sasl error');
409
+ this.hardReconnectRequired = true;
410
+ Object.assign(additionalErrorDetails, { channelId: err.channelId, stanzaInstanceId: err.stanzaInstanceId });
411
+ }
412
+ else {
413
+ additionalErrorDetails.error = err.condition;
414
+ this.logger.error('Streaming-client received a SASL error that it can\'t recover from and will not attempt to reconnect', additionalErrorDetails);
415
+ return false;
416
+ }
396
417
  }
397
418
  // we don't need to log the stack for a timeout message
398
419
  if (err instanceof timeout_error_1.TimeoutError) {
@@ -405,7 +426,7 @@ class Client extends events_1.default {
405
426
  if (err === null || err === void 0 ? void 0 : err.response) {
406
427
  // This *should* be an axios error according to typings, but it appears this could be an AxiosError *or* and XmlHttpRequest
407
428
  // we'll check both to be safe
408
- const retryAfter = ((_c = err.response.headers) === null || _c === void 0 ? void 0 : _c['retry-after']) || ((_e = (_d = err.response).getResponseHeader) === null || _e === void 0 ? void 0 : _e.call(_d, 'retry-after'));
429
+ const retryAfter = ((_b = err.response.headers) === null || _b === void 0 ? void 0 : _b['retry-after']) || ((_d = (_c = err.response).getResponseHeader) === null || _d === void 0 ? void 0 : _d.call(_c, 'retry-after'));
409
430
  if (retryAfter) {
410
431
  // retry after comes in seconds, we need to return milliseconds
411
432
  let retryDelay = parseInt(retryAfter, 10) * 1000;
@@ -421,6 +442,14 @@ class Client extends events_1.default {
421
442
  this.logger.debug('debug: retry info', { expectedRetryInMs: connectionData.currentDelayMs, appName: this.config.appName, clientId: this.logger.clientId });
422
443
  return true;
423
444
  }
445
+ networkErrorNeedsAuth(error) {
446
+ var _a;
447
+ return [401, 403].includes(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || 0);
448
+ }
449
+ saslErrorIsRetryable(error) {
450
+ const retryConditions = ['encryption-required', 'incorrect-encoding', 'invalid-mechanism', 'malformed-request', 'mechanism-too-weak'];
451
+ return retryConditions.includes(error.condition);
452
+ }
424
453
  async makeConnectionAttempt() {
425
454
  var _a, _b;
426
455
  if (!navigator.onLine) {
@@ -550,7 +579,7 @@ class Client extends events_1.default {
550
579
  return Client.version;
551
580
  }
552
581
  static get version() {
553
- return '17.2.7';
582
+ return '17.2.8';
554
583
  }
555
584
  }
556
585
  exports.Client = Client;
@@ -6,5 +6,5 @@ export * from './types/media-session';
6
6
  export * from './types/interfaces';
7
7
  export * from './messenger';
8
8
  export { HttpClient } from './http-client';
9
- export { parseJwt } from './utils';
9
+ export { StreamingClientError, parseJwt } from './utils';
10
10
  export default Client;
package/dist/npm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseJwt = exports.HttpClient = void 0;
3
+ exports.parseJwt = exports.StreamingClientError = exports.HttpClient = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  /// <reference path="types/libs.ts" />
6
6
  const client_1 = require("./client");
@@ -12,5 +12,6 @@ tslib_1.__exportStar(require("./messenger"), exports);
12
12
  var http_client_1 = require("./http-client");
13
13
  Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return http_client_1.HttpClient; } });
14
14
  var utils_1 = require("./utils");
15
+ Object.defineProperty(exports, "StreamingClientError", { enumerable: true, get: function () { return utils_1.StreamingClientError; } });
15
16
  Object.defineProperty(exports, "parseJwt", { enumerable: true, get: function () { return utils_1.parseJwt; } });
16
17
  exports.default = client_1.Client;
@@ -6,5 +6,5 @@ export * from './types/media-session';
6
6
  export * from './types/interfaces';
7
7
  export * from './messenger';
8
8
  export { HttpClient } from './http-client';
9
- export { parseJwt } from './utils';
9
+ export { StreamingClientError, parseJwt } from './utils';
10
10
  export default Client;
@@ -101,6 +101,10 @@ export interface IResponseError extends IError {
101
101
  requestBody: string;
102
102
  url: string;
103
103
  }
104
+ export declare enum StreamingClientErrorTypes {
105
+ generic = "generic",
106
+ invalid_token = "invalid_token"
107
+ }
104
108
  export interface IError {
105
109
  message: string;
106
110
  name: string;
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SessionTypes = void 0;
3
+ exports.SessionTypes = exports.StreamingClientErrorTypes = void 0;
4
+ var StreamingClientErrorTypes;
5
+ (function (StreamingClientErrorTypes) {
6
+ StreamingClientErrorTypes["generic"] = "generic";
7
+ StreamingClientErrorTypes["invalid_token"] = "invalid_token";
8
+ })(StreamingClientErrorTypes = exports.StreamingClientErrorTypes || (exports.StreamingClientErrorTypes = {}));
4
9
  var SessionTypes;
5
10
  (function (SessionTypes) {
6
11
  SessionTypes["softphone"] = "softphone";
@@ -1,3 +1,9 @@
1
+ import { StreamingClientErrorTypes } from './types/interfaces';
2
+ export declare class StreamingClientError extends Error {
3
+ type: StreamingClientErrorTypes;
4
+ details?: unknown;
5
+ constructor(type: StreamingClientErrorTypes | null, messageOrError: string | Error, details?: unknown);
6
+ }
1
7
  export declare function timeoutPromise(fn: Function, timeoutMs: number, msg: string, details?: any): Promise<any>;
2
8
  export declare function delay(ms: number): Promise<void>;
3
9
  export declare function splitIntoIndividualTopics(topicString: string): string[];
package/dist/npm/utils.js CHANGED
@@ -1,8 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.iceIsDifferent = exports.getIcePwdFromSdp = exports.getUfragFromSdp = exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.delay = exports.timeoutPromise = void 0;
3
+ exports.iceIsDifferent = exports.getIcePwdFromSdp = exports.getUfragFromSdp = exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.delay = exports.timeoutPromise = exports.StreamingClientError = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const timeout_error_1 = require("./types/timeout-error");
6
+ const interfaces_1 = require("./types/interfaces");
7
+ class StreamingClientError extends Error {
8
+ constructor(type, messageOrError, details) {
9
+ let message;
10
+ if (messageOrError instanceof Error) {
11
+ message = messageOrError.message;
12
+ }
13
+ else {
14
+ message = messageOrError;
15
+ }
16
+ super(message);
17
+ if (messageOrError instanceof Error) {
18
+ this.name = messageOrError.name;
19
+ }
20
+ this.type = type !== null && type !== void 0 ? type : interfaces_1.StreamingClientErrorTypes.generic;
21
+ this.details = details;
22
+ }
23
+ }
24
+ exports.StreamingClientError = StreamingClientError;
6
25
  /* istanbul ignore next */
7
26
  function timeoutPromise(fn, timeoutMs, msg, details) {
8
27
  return new Promise(function (resolve, reject) {