@microsoft/omnichannel-chat-widget 1.8.4-main.cbab5fc → 1.8.4-main.cd79f08

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 (81) hide show
  1. package/README.md +12 -3
  2. package/lib/cjs/common/Constants.js +2 -0
  3. package/lib/cjs/common/facades/FacadeChatSDK.js +235 -9
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +13 -0
  5. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +7 -7
  6. package/lib/cjs/common/utils/xssUtils.js +23 -51
  7. package/lib/cjs/common/utils.js +15 -2
  8. package/lib/cjs/components/errorboundary/ErrorBoundary.js +2 -1
  9. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +9 -1
  10. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +23 -6
  11. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  12. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +9 -0
  13. package/lib/cjs/components/livechatwidget/common/authHelper.js +44 -4
  14. package/lib/cjs/components/livechatwidget/common/createAdapter.js +3 -2
  15. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +36 -4
  16. package/lib/cjs/components/livechatwidget/common/startChat.js +31 -14
  17. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +62 -2
  18. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
  19. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +0 -1
  20. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +42 -27
  21. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +117 -16
  22. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  23. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +13 -2
  24. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +160 -167
  25. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +1 -1
  26. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  27. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  28. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +6 -1
  29. package/lib/cjs/contexts/createReducer.js +15 -0
  30. package/lib/cjs/controller/componentController.js +13 -1
  31. package/lib/cjs/plugins/newMessageEventHandler.js +20 -3
  32. package/lib/esm/common/Constants.js +2 -0
  33. package/lib/esm/common/facades/FacadeChatSDK.js +236 -10
  34. package/lib/esm/common/telemetry/TelemetryConstants.js +13 -0
  35. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +7 -7
  36. package/lib/esm/common/utils/xssUtils.js +23 -51
  37. package/lib/esm/common/utils.js +12 -1
  38. package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -2
  39. package/lib/esm/components/livechatwidget/LiveChatWidget.js +9 -1
  40. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +23 -6
  41. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  42. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +9 -0
  43. package/lib/esm/components/livechatwidget/common/authHelper.js +44 -4
  44. package/lib/esm/components/livechatwidget/common/createAdapter.js +3 -2
  45. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +33 -2
  46. package/lib/esm/components/livechatwidget/common/startChat.js +31 -14
  47. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +62 -2
  48. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
  49. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +1 -2
  50. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +43 -28
  51. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +117 -16
  52. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  53. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +13 -2
  54. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +160 -171
  55. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +1 -1
  56. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  57. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +1 -0
  58. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  59. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +6 -1
  60. package/lib/esm/contexts/createReducer.js +15 -0
  61. package/lib/esm/controller/componentController.js +13 -1
  62. package/lib/esm/plugins/newMessageEventHandler.js +20 -3
  63. package/lib/types/common/Constants.d.ts +2 -0
  64. package/lib/types/common/facades/FacadeChatSDK.d.ts +29 -0
  65. package/lib/types/common/facades/types/IFacadeChatSDKInput.d.ts +3 -1
  66. package/lib/types/common/telemetry/TelemetryConstants.d.ts +13 -2
  67. package/lib/types/common/utils/xssUtils.d.ts +5 -21
  68. package/lib/types/common/utils.d.ts +9 -1
  69. package/lib/types/components/errorboundary/ErrorBoundary.d.ts +1 -1
  70. package/lib/types/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.d.ts +1 -0
  71. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +2 -1
  72. package/lib/types/components/livechatwidget/common/authHelper.d.ts +9 -2
  73. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +11 -0
  74. package/lib/types/components/livechatwidget/interfaces/IBotAuthActivitySubscriberOptionalParams.d.ts +1 -0
  75. package/lib/types/components/webchatcontainerstateful/interfaces/IAdaptiveCardStyles.d.ts +2 -0
  76. package/lib/types/components/webchatcontainerstateful/interfaces/IBotAuthConfig.d.ts +7 -0
  77. package/lib/types/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.d.ts +1 -1
  78. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +14 -38
  79. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  80. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  81. package/package.json +15 -6
@@ -5,7 +5,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
5
5
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
6
6
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
7
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../telemetry/TelemetryConstants";
8
- import { getAuthClientFunction, handleAuthentication } from "../../components/livechatwidget/common/authHelper";
8
+ import { getAuthClientFunction, handleAuthentication, isMidAuthEnabled } from "../../components/livechatwidget/common/authHelper";
9
9
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
10
10
  import { TelemetryHelper } from "../telemetry/TelemetryHelper";
11
11
  import { isNullOrEmptyString } from "../utils";
@@ -20,6 +20,8 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
20
20
  _defineProperty(this, "getAuthToken", void 0);
21
21
  _defineProperty(this, "sdkMocked", void 0);
22
22
  _defineProperty(this, "disableReauthentication", void 0);
23
+ // Stays true so CASE 1 re-triggers on every startChat to set deferInitialAuth
24
+ _defineProperty(this, "pendingMidAuthUnauthenticatedState", false);
23
25
  this.chatSDK = input.chatSDK;
24
26
  this.chatConfig = input.chatConfig;
25
27
  this.getAuthToken = input.getAuthToken;
@@ -44,6 +46,12 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
44
46
  value: function destroy() {
45
47
  this.token = null;
46
48
  this.expiration = 0;
49
+ if (isMidAuthEnabled(this.chatConfig)) {
50
+ this.pendingMidAuthUnauthenticatedState = false;
51
+ this.isAuthenticated = true;
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ this.chatSDK.deferInitialAuth = false;
54
+ }
47
55
  }
48
56
  }, {
49
57
  key: "isTokenSet",
@@ -208,6 +216,10 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
208
216
  message: "Token is valid"
209
217
  };
210
218
  }
219
+
220
+ // Token missing or expired - need to get a new one via getAuthToken
221
+ // For mid-auth: getAuthToken receives { isMidAuthEnabled: true } so customer implementations
222
+ // can check portal state and return null for logged-out users
211
223
  TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
212
224
  Event: TelemetryEvent.NewTokenValidationStarted,
213
225
  Description: "Token validation started."
@@ -228,6 +240,7 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
228
240
  this.token = "";
229
241
  this.expiration = 0;
230
242
  try {
243
+ var _ring$error, _ring$error2;
231
244
  const ring = await handleAuthentication(this.chatSDK, this.chatConfig, this.getAuthToken);
232
245
  if ((ring === null || ring === void 0 ? void 0 : ring.result) === true && ring !== null && ring !== void 0 && ring.token) {
233
246
  await this.setToken(ring.token);
@@ -242,18 +255,35 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
242
255
  result: true,
243
256
  message: "New Token obtained"
244
257
  };
245
- } else {
246
- var _ring$error, _ring$error2;
247
- TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.ERROR, {
248
- Event: TelemetryEvent.NewTokenValidationFailed,
249
- Description: (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
250
- ExceptionDetails: ring === null || ring === void 0 ? void 0 : ring.error
258
+ }
259
+
260
+ // Mid-auth: no token available - set pending flag for startChat to handle
261
+ const isEmptyTokenWithoutError = isNullOrEmptyString(ring === null || ring === void 0 ? void 0 : ring.token) && ((ring === null || ring === void 0 ? void 0 : ring.result) === true || (ring === null || ring === void 0 ? void 0 : ring.result) === false && !(ring !== null && ring !== void 0 && ring.error));
262
+ if (isMidAuthEnabled(this.chatConfig) && isEmptyTokenWithoutError) {
263
+ // Clear Facade and SDK token state so API calls use unauthenticated endpoints
264
+ this.token = "";
265
+ this.expiration = 0;
266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
267
+ this.chatSDK.authenticatedUserToken = null;
268
+ this.pendingMidAuthUnauthenticatedState = true;
269
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
270
+ Event: TelemetryEvent.NewTokenValidationCompleted,
271
+ Description: "Mid-auth enabled: no token returned; proceeding as unauthenticated"
251
272
  });
252
273
  return {
253
- result: false,
254
- message: (ring === null || ring === void 0 ? void 0 : (_ring$error2 = ring.error) === null || _ring$error2 === void 0 ? void 0 : _ring$error2.message) || "Failed to get token"
274
+ result: true,
275
+ message: "Mid-auth: proceeding as unauthenticated"
255
276
  };
256
277
  }
278
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.ERROR, {
279
+ Event: TelemetryEvent.NewTokenValidationFailed,
280
+ Description: (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
281
+ ExceptionDetails: ring === null || ring === void 0 ? void 0 : ring.error
282
+ });
283
+ return {
284
+ result: false,
285
+ message: (ring === null || ring === void 0 ? void 0 : (_ring$error2 = ring.error) === null || _ring$error2 === void 0 ? void 0 : _ring$error2.message) || "Failed to get token"
286
+ };
257
287
  } catch (e) {
258
288
  console.error("Unexpected error while getting token", e);
259
289
  TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.ERROR, {
@@ -267,6 +297,155 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
267
297
  };
268
298
  }
269
299
  }
300
+
301
+ /**
302
+ * Sets unauthenticated state for mid-auth flow.
303
+ * Clears SDK internal state to prevent reconnection to previous authenticated session.
304
+ */
305
+ }, {
306
+ key: "setMidAuthUnauthenticatedState",
307
+ value: function setMidAuthUnauthenticatedState() {
308
+ var _sdk$chatToken, _sdk$chatToken2;
309
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
310
+ const sdk = this.chatSDK;
311
+ const hadExistingChat = !!((_sdk$chatToken = sdk.chatToken) !== null && _sdk$chatToken !== void 0 && _sdk$chatToken.chatId);
312
+ const previousChatId = (_sdk$chatToken2 = sdk.chatToken) === null || _sdk$chatToken2 === void 0 ? void 0 : _sdk$chatToken2.chatId;
313
+ this.clearAuthState();
314
+
315
+ // Clear SDK internal state for fresh unauthenticated chat
316
+ sdk.chatToken = {};
317
+ sdk.reconnectId = null;
318
+ sdk.requestId = null;
319
+ sdk.sessionId = null;
320
+ sdk.conversation = null;
321
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
322
+ Event: TelemetryEvent.MidConversationAuthReset,
323
+ Description: hadExistingChat ? "Mid-auth without token: local state cleared" : "Mid-auth: initialized as unauthenticated (no prior chat)",
324
+ Data: hadExistingChat ? {
325
+ previousChatId
326
+ } : undefined
327
+ });
328
+ }
329
+
330
+ /** Clears authentication state in both FacadeChatSDK and underlying SDK */
331
+ }, {
332
+ key: "clearAuthState",
333
+ value: function clearAuthState() {
334
+ this.token = "";
335
+ this.expiration = 0;
336
+ this.isAuthenticated = false;
337
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
338
+ this.chatSDK.authenticatedUserToken = null;
339
+ }
340
+
341
+ /**
342
+ * Migrates conversation from unauthenticated to authenticated via authenticateChat.
343
+ * Called after startChat() when user has a valid token but the backend conversation
344
+ * was started as unauthenticated.
345
+ */
346
+ }, {
347
+ key: "migrateConversationToAuthenticated",
348
+ value: async function migrateConversationToAuthenticated() {
349
+ try {
350
+ await this.chatSDK.authenticateChat(this.token, {
351
+ refreshChatToken: true
352
+ });
353
+ this.isAuthenticated = true;
354
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
355
+ Event: TelemetryEvent.MidConversationAuthSucceeded,
356
+ Description: "Mid-auth: authenticateChat completed, conversation migrated to authenticated"
357
+ });
358
+ } catch (e) {
359
+ // Non-fatal: Chat is already active via startChat, will retry on next reconnect
360
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.WARN, {
361
+ Event: TelemetryEvent.MidConversationAuthFailed,
362
+ Description: "Mid-auth: authenticateChat returned error after startChat, chat still active",
363
+ ExceptionDetails: {
364
+ message: e === null || e === void 0 ? void 0 : e.message
365
+ }
366
+ });
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Configures SDK auth state before startChat.
372
+ * CASE 1: Pending unauthenticated (no token) - sets deferInitialAuth=true
373
+ * CASE 2: Authenticated with valid token - sets SDK token and deferInitialAuth based on scenario
374
+ */
375
+ }, {
376
+ key: "configureMidAuthState",
377
+ value: function configureMidAuthState(isReconnect, wasPreviousSessionAuthenticated) {
378
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
379
+ const sdk = this.chatSDK;
380
+
381
+ // CASE 1: No token available (user not logged in)
382
+ // pendingMidAuthUnauthenticatedState stays true until user logs in (cleared in tokenRing)
383
+ if (this.pendingMidAuthUnauthenticatedState) {
384
+ const shouldClear = this.handlePendingUnauthenticatedState(wasPreviousSessionAuthenticated);
385
+ sdk.deferInitialAuth = true;
386
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
387
+ Event: TelemetryEvent.MidConversationAuthReset,
388
+ Description: "Mid-auth configureMidAuthState: CASE 1 - unauthenticated, deferInitialAuth=true",
389
+ Data: {
390
+ isReconnect: String(isReconnect),
391
+ wasPreviousSessionAuthenticated: String(wasPreviousSessionAuthenticated),
392
+ shouldClearReconnectParams: String(shouldClear)
393
+ }
394
+ });
395
+ return {
396
+ shouldClearReconnectParams: shouldClear
397
+ };
398
+ }
399
+
400
+ // CASE 2: Authenticated with valid token
401
+ if (this.isTokenSet() && !this.isTokenExpired()) {
402
+ this.handleAuthenticatedState(isReconnect, wasPreviousSessionAuthenticated);
403
+ }
404
+ return {
405
+ shouldClearReconnectParams: false
406
+ };
407
+ }
408
+
409
+ /**
410
+ * CASE 1 handler: Returns true if reconnect params should be cleared (Auth -> Unauth transition)
411
+ */
412
+ }, {
413
+ key: "handlePendingUnauthenticatedState",
414
+ value: function handlePendingUnauthenticatedState(wasPreviousSessionAuthenticated) {
415
+ if (wasPreviousSessionAuthenticated) {
416
+ // Auth -> Unauth: user logged out, clear state for fresh chat
417
+ this.setMidAuthUnauthenticatedState();
418
+ return true;
419
+ }
420
+
421
+ // Unauth -> Unauth: keep liveChatContext for reconnection
422
+ this.isAuthenticated = false;
423
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
424
+ this.chatSDK.authenticatedUserToken = null;
425
+ return false;
426
+ }
427
+
428
+ /**
429
+ * CASE 2 handler: Sets deferInitialAuth only for reconnects to unauthenticated sessions (need migration).
430
+ * For new chats or reconnects to authenticated sessions, SDK handles auth internally.
431
+ */
432
+ }, {
433
+ key: "handleAuthenticatedState",
434
+ value: function handleAuthenticatedState(isReconnect, wasPreviousSessionAuthenticated) {
435
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
436
+ const sdk = this.chatSDK;
437
+ sdk.authenticatedUserToken = this.token;
438
+ if (isReconnect && !wasPreviousSessionAuthenticated) {
439
+ sdk.deferInitialAuth = true;
440
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
441
+ Event: TelemetryEvent.MidConversationAuthSucceeded,
442
+ Description: "Mid-auth handleAuthenticatedState: CASE 2 - reconnect to unauth session, deferInitialAuth=true (migration needed)"
443
+ });
444
+ } else {
445
+ // Reset to prevent inheriting deferInitialAuth=true from a previous unauthenticated chat
446
+ sdk.deferInitialAuth = false;
447
+ }
448
+ }
270
449
  }, {
271
450
  key: "validateAndExecuteCall",
272
451
  value: async function validateAndExecuteCall(functionName, fn) {
@@ -301,7 +480,53 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
301
480
  key: "startChat",
302
481
  value: async function startChat() {
303
482
  let optionalParams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
304
- return this.validateAndExecuteCall("startChat", () => this.chatSDK.startChat(optionalParams));
483
+ const midAuthEnabled = isMidAuthEnabled(this.chatConfig);
484
+ const isReconnect = !!optionalParams.liveChatContext || !!optionalParams.reconnectId;
485
+ const wasPreviousSessionAuthenticated = optionalParams.wasAuthenticated === true;
486
+ return this.validateAndExecuteCall("startChat", async () => {
487
+ if (midAuthEnabled) {
488
+ const {
489
+ shouldClearReconnectParams
490
+ } = this.configureMidAuthState(isReconnect, wasPreviousSessionAuthenticated);
491
+ if (shouldClearReconnectParams) {
492
+ delete optionalParams.liveChatContext;
493
+ delete optionalParams.reconnectId;
494
+ }
495
+ }
496
+ await this.chatSDK.startChat(optionalParams);
497
+
498
+ // Migrate to authenticated if needed (reconnects to unauthenticated sessions only)
499
+ if (midAuthEnabled) {
500
+ const shouldMigrateToAuth = isReconnect && this.isTokenSet() && !this.isTokenExpired() && !wasPreviousSessionAuthenticated;
501
+ if (shouldMigrateToAuth) {
502
+ TelemetryHelper.logFacadeChatSDKEventToAllTelemetry(LogLevel.INFO, {
503
+ Event: TelemetryEvent.MidConversationAuthSucceeded,
504
+ Description: "Mid-auth startChat: initiating migration to authenticated",
505
+ Data: {
506
+ isReconnect: String(isReconnect),
507
+ wasPreviousSessionAuthenticated: String(wasPreviousSessionAuthenticated)
508
+ }
509
+ });
510
+ await this.migrateConversationToAuthenticated();
511
+ }
512
+ }
513
+
514
+ // Broadcast final auth state after startChat completes (only on state change)
515
+ if (midAuthEnabled) {
516
+ const isAuthenticatedAfterStart = this.isTokenSet() && !this.isTokenExpired();
517
+ const authStateChanged = !isReconnect || isAuthenticatedAfterStart !== wasPreviousSessionAuthenticated;
518
+ if (authStateChanged) {
519
+ BroadcastService.postMessage({
520
+ eventName: isAuthenticatedAfterStart ? BroadcastEvent.MidConversationAuthSucceeded : BroadcastEvent.MidConversationAuthReset,
521
+ payload: {
522
+ isAuthenticated: isAuthenticatedAfterStart,
523
+ isStartChatComplete: true,
524
+ isReconnect
525
+ }
526
+ });
527
+ }
528
+ }
529
+ });
305
530
  }
306
531
  }, {
307
532
  key: "endChat",
@@ -439,6 +664,7 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
439
664
  let optionalParams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
440
665
  return this.validateAndExecuteCall("getAgentAvailability", () => this.chatSDK.getAgentAvailability(optionalParams));
441
666
  }
667
+
442
668
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
443
669
  }, {
444
670
  key: "getReconnectableChats",
@@ -69,6 +69,8 @@ export let BroadcastEvent;
69
69
  BroadcastEvent["FMLTrackingCompletedAck"] = "FMLTrackingCompletedAck";
70
70
  BroadcastEvent["FMLTrackingCompleted"] = "FMLTrackingCompleted";
71
71
  BroadcastEvent["PersistentConversationReset"] = "PersistentConversationReset";
72
+ BroadcastEvent["MidConversationAuthSucceeded"] = "MidConversationAuthSucceeded";
73
+ BroadcastEvent["MidConversationAuthReset"] = "MidConversationAuthReset";
72
74
  })(BroadcastEvent || (BroadcastEvent = {}));
73
75
  export let TelemetryEvent;
74
76
  (function (TelemetryEvent) {
@@ -102,6 +104,9 @@ export let TelemetryEvent;
102
104
  TelemetryEvent["CallingSDKInitFailed"] = "CallingSDKInitFailed";
103
105
  TelemetryEvent["CallingSDKLoadSuccess"] = "CallingSDKLoadSuccess";
104
106
  TelemetryEvent["CallingSDKLoadFailed"] = "CallingSDKLoadFailed";
107
+ TelemetryEvent["MidConversationAuthSucceeded"] = "MidConversationAuthSucceeded";
108
+ TelemetryEvent["MidConversationAuthFailed"] = "MidConversationAuthFailed";
109
+ TelemetryEvent["MidConversationAuthReset"] = "MidConversationAuthReset";
105
110
  TelemetryEvent["GetConversationDetailsCallStarted"] = "GetConversationDetailsCallStarted";
106
111
  TelemetryEvent["GetConversationDetailsCallFailed"] = "GetConversationDetailsCallFailed";
107
112
  TelemetryEvent["EndChatSDKCallFailed"] = "EndChatSDKCallFailed";
@@ -312,10 +317,16 @@ export let TelemetryEvent;
312
317
  TelemetryEvent["LCWLazyLoadNoMoreHistory"] = "LCWLazyLoadNoMoreHistory";
313
318
  TelemetryEvent["LCWLazyLoadHistoryError"] = "LCWLazyLoadHistoryError";
314
319
  TelemetryEvent["LCWLazyLoadDestroyed"] = "LCWLazyLoadDestroyed";
320
+ TelemetryEvent["LCWLazyLoadTriggerFired"] = "LCWLazyLoadTriggerFired";
321
+ TelemetryEvent["LCWLazyLoadBatchReceived"] = "LCWLazyLoadBatchReceived";
322
+ TelemetryEvent["LCWLazyLoadInitialLoadComplete"] = "LCWLazyLoadInitialLoadComplete";
323
+ TelemetryEvent["LCWLazyLoadScrollAnchorApplied"] = "LCWLazyLoadScrollAnchorApplied";
315
324
  TelemetryEvent["SecureEventBusUnauthorizedDispatch"] = "SecureEventBusUnauthorizedDispatch";
316
325
  TelemetryEvent["SecureEventBusListenerError"] = "SecureEventBusListenerError";
317
326
  TelemetryEvent["SecureEventBusDispatchError"] = "SecureEventBusDispatchError";
318
327
  TelemetryEvent["StartChatComplete"] = "StartChatComplete";
328
+ TelemetryEvent["AgentJoinedConversation"] = "AgentJoinedConversation";
329
+ TelemetryEvent["BrowserTabHidden"] = "BrowserTabHidden";
319
330
  })(TelemetryEvent || (TelemetryEvent = {}));
320
331
  export let TelemetryConstants = /*#__PURE__*/function () {
321
332
  function TelemetryConstants() {
@@ -386,6 +397,8 @@ export let TelemetryConstants = /*#__PURE__*/function () {
386
397
  case TelemetryEvent.SecureEventBusUnauthorizedDispatch:
387
398
  case TelemetryEvent.SecureEventBusListenerError:
388
399
  case TelemetryEvent.SecureEventBusDispatchError:
400
+ case TelemetryEvent.AgentJoinedConversation:
401
+ case TelemetryEvent.BrowserTabHidden:
389
402
  return ScenarioType.ACTIONS;
390
403
  case TelemetryEvent.StartChatSDKCall:
391
404
  case TelemetryEvent.StartChatEventReceived:
@@ -5,11 +5,11 @@ import { AppInsightsTelemetryMessage } from "../../Constants";
5
5
  import { AppInsightsEventMapping } from "../AppInsightsEvents";
6
6
  var AllowedKeys;
7
7
  (function (AllowedKeys) {
8
- AllowedKeys["OrganizationId"] = "OrganizationId";
9
- AllowedKeys["ConversationId"] = "LiveWorkItemId";
8
+ AllowedKeys["OrganizationId"] = "powerplatform.analytics.resource.organization.id";
9
+ AllowedKeys["ConversationId"] = "powerplatform.analytics.resource.id";
10
10
  AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
11
- AllowedKeys["Description"] = "Description";
12
- AllowedKeys["ChannelId"] = "ChannelType";
11
+ AllowedKeys["Description"] = "omnichannel.description";
12
+ AllowedKeys["ChannelId"] = "omnichannel.channel.type";
13
13
  AllowedKeys["LCWRuntimeId"] = "ClientSessionId";
14
14
  })(AllowedKeys || (AllowedKeys = {}));
15
15
  let initializationPromise = null;
@@ -86,8 +86,8 @@ export const appInsightsLogger = appInsightsKey => {
86
86
  if (eventName) {
87
87
  const trackingEventName = getTrackingEventName(logLevel, eventName);
88
88
  const eventProperties = setEventProperties(trackingEventName, telemetryInfo);
89
- _logger.trackEvent({
90
- name: trackingEventName,
89
+ _logger.trackTrace({
90
+ message: trackingEventName,
91
91
  properties: eventProperties
92
92
  });
93
93
  }
@@ -133,7 +133,7 @@ export const appInsightsLogger = appInsightsKey => {
133
133
  // Additional properties
134
134
  eventProperties["ConversationStage"] = customProperties.ConversationStage ?? ConversationStage.CSREngagement;
135
135
  eventProperties["Scenario"] = "Conversation Diagnostics";
136
- eventProperties["OperationName"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
136
+ eventProperties["powerplatform.analytics.subscenario"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
137
137
  return eventProperties;
138
138
  }
139
139
  function getTrackingEventName(logLevel, eventName) {
@@ -1,70 +1,42 @@
1
1
  import DOMPurify from "dompurify";
2
2
 
3
3
  /**
4
- * Detects potential Cross-Site Scripting (XSS) attacks in text input and sanitizes the content.
4
+ * Sanitizes text input and detects XSS attack patterns.
5
5
  *
6
- * This function performs comprehensive XSS detection using pattern matching for common attack vectors
7
- * and then sanitizes the input using DOMPurify with strict configuration. It's designed to protect
8
- * against various XSS techniques including script injection, event handler injection, style-based
9
- * attacks, and encoded payloads.
6
+ * Sanitizes first with DOMPurify, then checks for malicious patterns in both
7
+ * the original and sanitized text to catch mutation XSS attacks.
10
8
  *
11
- * Security patterns detected:
12
- * - JavaScript protocol URLs (javascript:)
13
- * - HTML event handlers (onmouseover, onclick, etc.)
14
- * - Script tags (<script>)
15
- * - CSS expression() functions
16
- * - CSS url() functions
17
- * - Position-based CSS attacks (position: fixed/absolute)
18
- * - VBScript protocol URLs
19
- * - Data URLs with HTML content
20
- * - Fragment identifiers with escaped quotes
21
- * - HTML entity-encoded angle brackets
22
- *
23
- * @param text - The input text to be analyzed and sanitized
24
- * @returns An object containing:
25
- * - cleanText: The sanitized version of the input text with all HTML tags and attributes removed
26
- * - isXSSDetected: Boolean flag indicating whether potential XSS patterns were found in the original text
9
+ * @param text - Input text to sanitize
10
+ * @returns Object with cleanText (sanitized) and isXSSDetected flag
27
11
  */
28
12
  export const detectAndCleanXSS = text => {
29
- // Comprehensive array of regular expressions to detect common XSS attack patterns
30
- const xssPatterns = [/javascript\s*:/gi,
31
- // JavaScript protocol URLs (with optional spaces)
32
- /vbscript\s*:/gi,
33
- // VBScript protocol URLs (with optional spaces)
34
- /on\w+\s*=/gi,
35
- // HTML event handlers (onmouseover, onclick, onload, etc.)
36
- /<\s*script/gi,
37
- // Script tag opening (with optional spaces)
38
- /expression\s*\(/gi,
39
- // CSS expression() function (IE-specific)
40
- /url\s*\(/gi,
41
- // CSS url() function
42
- /style\s*=.*position\s*:\s*fixed/gi,
43
- // CSS position fixed attacks
44
- /style\s*=.*position\s*:\s*absolute/gi,
45
- // CSS position absolute attacks
46
- /data\s*:\s*text\s*\/\s*html/gi,
47
- // Data URLs containing HTML
48
- /#.*\\"/gi,
49
- // Fragment identifiers with escaped quotes
50
- /&gt;.*&lt;/gi // HTML entity-encoded angle brackets indicating tag structure
51
- ];
52
-
53
- // Check if any XSS patterns are detected in the input text
54
- const isXSSDetected = xssPatterns.some(pattern => pattern.test(text));
55
-
56
- // Clean the text using DOMPurify with strict config
13
+ // Sanitize first to prevent mutation XSS (e.g., "s<iframe></iframe>tyle" "style")
57
14
  const cleanText = DOMPurify.sanitize(text, {
58
15
  ALLOWED_TAGS: [],
59
- // No HTML tags allowed in title
60
16
  ALLOWED_ATTR: [],
61
17
  KEEP_CONTENT: true,
62
- // Keep text content
63
18
  ALLOW_DATA_ATTR: false,
64
19
  ALLOW_UNKNOWN_PROTOCOLS: false,
65
20
  SANITIZE_DOM: true,
66
21
  FORCE_BODY: false
67
22
  });
23
+ const contentChanged = text !== cleanText;
24
+
25
+ // Non-global regex patterns to avoid stateful .test() issues
26
+ const xssPatterns = [/javascript\s*:/i, /vbscript\s*:/i, /on\w+\s*=/i,
27
+ // Event handlers
28
+ /<\s*script/i, /<\s*iframe/i, /<\s*object/i, /<\s*embed/i, /<\s*svg/i, /expression\s*\(/i,
29
+ // IE CSS expressions
30
+ /style\s*=.*position\s*:\s*(fixed|absolute)/i, /data\s*:\s*text\s*\/\s*html/i, /#.*\\"/i, /&(lt|gt|#x3c|#60|#x3e|#62);/i,
31
+ // HTML entities
32
+ /&#x?[0-9a-f]+;.*</i, /\u003c.*\u003e/i,
33
+ // Unicode escapes
34
+ /src\s*=\s*["']?\s*javascript:/i, /href\s*=\s*["']?\s*javascript:/i];
35
+ const hasXSSPattern = xssPatterns.some(pattern => {
36
+ return pattern.test(text) || pattern.test(cleanText);
37
+ });
38
+ const hasHTMLStructure = /<[^>]+>/.test(text) && !/<[^>]+>/.test(cleanText);
39
+ const isXSSDetected = contentChanged || hasXSSPattern || hasHTMLStructure;
68
40
  return {
69
41
  cleanText,
70
42
  isXSSDetected
@@ -436,7 +436,7 @@ export const setOcUserAgent = chatSDK => {
436
436
  // eslint-disable-line @typescript-eslint/no-explicit-any
437
437
  if ((_chatSDK$OCClient = chatSDK.OCClient) !== null && _chatSDK$OCClient !== void 0 && _chatSDK$OCClient.ocUserAgent && !((_chatSDK$OCClient2 = chatSDK.OCClient) !== null && _chatSDK$OCClient2 !== void 0 && _chatSDK$OCClient2.ocUserAgent.join(" ").includes("omnichannel-chat-widget/"))) {
438
438
  try {
439
- const version = require("../../../package.json").version; // eslint-disable-line @typescript-eslint/no-var-requires
439
+ const version = require("../../package.json").version; // eslint-disable-line @typescript-eslint/no-var-requires
440
440
  const userAgent = `omnichannel-chat-widget/${version}`;
441
441
  chatSDK.OCClient.ocUserAgent = [userAgent, ...chatSDK.OCClient.ocUserAgent];
442
442
  } catch (error) {
@@ -474,4 +474,15 @@ export const getCustomEventValue = customEventPayload => {
474
474
  export function isEndConversationDueToOverflowActivity(activity) {
475
475
  var _activity$channelData, _activity$channelData2;
476
476
  return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(Constants.EndConversationDueToOverflow);
477
+ }
478
+
479
+ /**
480
+ * Parses a value that can be boolean or string ("true"/"false") into a boolean.
481
+ * Handles null/undefined by returning false.
482
+ *
483
+ * @param value - The value to parse (can be boolean, string, null, or undefined)
484
+ * @returns true if value is true or "true" (case-insensitive), false otherwise
485
+ */
486
+ export function parseBooleanFromConfig(value) {
487
+ return value === true || (value === null || value === void 0 ? void 0 : value.toString().toLowerCase()) === "true";
477
488
  }
@@ -10,12 +10,14 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
10
10
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
11
11
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
12
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
13
- import React, { Component } from 'react';
13
+ import React, { Component } from "react";
14
+
15
+ // eslint-disable-next-line @typescript-eslint/ban-types
14
16
  const RenderChildrenFunction = _ref => {
15
17
  let {
16
18
  children
17
19
  } = _ref;
18
- return typeof children === 'function' ? children() : children;
20
+ return typeof children === "function" ? children() : children;
19
21
  };
20
22
  let ErrorBoundary = /*#__PURE__*/function (_Component) {
21
23
  _inherits(ErrorBoundary, _Component);
@@ -26,8 +26,16 @@ export const LiveChatWidget = props => {
26
26
  throw new Error("chatConfig is required");
27
27
  }
28
28
 
29
+ // Check configuration flags
29
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
- const isAuthenticatedChat = !!((_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction) || isPersistentChatEnabled((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Li = _props$chatConfig2.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig2$Li === void 0 ? void 0 : _props$chatConfig2$Li.msdyn_conversationmode);
31
+ const hasAuthClientFn = !!((_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction);
32
+ const persistentChatEnabled = isPersistentChatEnabled((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Li = _props$chatConfig2.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig2$Li === void 0 ? void 0 : _props$chatConfig2$Li.msdyn_conversationmode);
33
+
34
+ // isAuthenticatedChat determines if FacadeChatSDK should require authentication:
35
+ // REGULAR AUTH FLOW (config-based):
36
+ // - Persistent chat enabled ? always authenticated
37
+ // - Auth settings exist ? authenticated from start
38
+ const isAuthenticatedChat = persistentChatEnabled || hasAuthClientFn;
31
39
  if (!facadeChatSDK) {
32
40
  var _props$mock;
33
41
  setFacadeChatSDK(new FacadeChatSDK({
@@ -40,7 +40,7 @@ const extractSasUrl = async attachment => {
40
40
  }
41
41
  return sasUrl;
42
42
  };
43
- const fetchBotAuthConfig = async (retries, interval) => {
43
+ const fetchBotAuthConfig = async (retries, interval, fallback) => {
44
44
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
45
45
  Event: TelemetryEvent.SetBotAuthProviderFetchConfig
46
46
  });
@@ -56,13 +56,23 @@ const fetchBotAuthConfig = async (retries, interval) => {
56
56
  });
57
57
  if (retries === 1) {
58
58
  // Base Case
59
- throw new Error();
59
+ if (response !== undefined) {
60
+ return response;
61
+ }
62
+ if (fallback !== undefined) {
63
+ TelemetryHelper.logLoadingEvent(LogLevel.WARN, {
64
+ Event: TelemetryEvent.SetBotAuthProviderNotFound,
65
+ Description: `Failed to fetch bot auth config after maximum retries. Using fallback value: ${fallback}`
66
+ });
67
+ return fallback;
68
+ }
69
+ throw new Error("Failed to fetch bot auth config after maximum retries");
60
70
  }
61
71
  await delay(interval);
62
72
  if (response !== undefined) {
63
73
  return response;
64
74
  }
65
- return await fetchBotAuthConfig(--retries, interval);
75
+ return await fetchBotAuthConfig(--retries, interval, fallback);
66
76
  };
67
77
  export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
68
78
  function BotAuthActivitySubscriber() {
@@ -72,6 +82,7 @@ export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
72
82
  _defineProperty(this, "signInCardSeen", void 0);
73
83
  _defineProperty(this, "fetchBotAuthConfigRetries", void 0);
74
84
  _defineProperty(this, "fetchBotAuthConfigRetryInterval", void 0);
85
+ _defineProperty(this, "fallbackShowSignInCard", void 0);
75
86
  this.signInCardSeen = new Set();
76
87
  this.fetchBotAuthConfigRetries = 3;
77
88
  this.fetchBotAuthConfigRetryInterval = 1000;
@@ -81,6 +92,11 @@ export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
81
92
  if (optionalParams.fetchBotAuthConfigRetryInterval) {
82
93
  this.fetchBotAuthConfigRetryInterval = optionalParams.fetchBotAuthConfigRetryInterval;
83
94
  }
95
+ this.fallbackShowSignInCard = optionalParams.fallbackShowSignInCard;
96
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
97
+ Event: TelemetryEvent.SetBotAuthProviderFetchConfig,
98
+ Description: `BotAuthActivitySubscriber initialized with fallbackShowSignInCard: ${optionalParams.fallbackShowSignInCard}`
99
+ });
84
100
  }
85
101
  _createClass(BotAuthActivitySubscriber, [{
86
102
  key: "applicable",
@@ -125,7 +141,7 @@ export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
125
141
  BroadcastService.postMessage(event);
126
142
  }
127
143
  try {
128
- const response = await fetchBotAuthConfig(this.fetchBotAuthConfigRetries, this.fetchBotAuthConfigRetryInterval);
144
+ const response = await fetchBotAuthConfig(this.fetchBotAuthConfigRetries, this.fetchBotAuthConfigRetryInterval, this.fallbackShowSignInCard);
129
145
  if (response === false) {
130
146
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
131
147
  Event: TelemetryEvent.SetBotAuthProviderHideCard
@@ -136,9 +152,10 @@ export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
136
152
  });
137
153
  return activity;
138
154
  }
139
- } catch {
155
+ } catch (e) {
140
156
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
141
- Event: TelemetryEvent.SetBotAuthProviderNotFound
157
+ Event: TelemetryEvent.SetBotAuthProviderNotFound,
158
+ ExceptionDetails: e instanceof Error ? e.message : JSON.stringify(e)
142
159
  });
143
160
  //this is to ensure listener continues waiting for response
144
161
  if (this.signInCardSeen.has(signInId)) {
@@ -4,5 +4,6 @@ var ChatWidgetEvents;
4
4
  ChatWidgetEvents["FETCH_PERSISTENT_CHAT_HISTORY"] = "CHAT_WIDGET/FETCH_PERSISTENT_CHAT_HISTORY";
5
5
  ChatWidgetEvents["NO_MORE_HISTORY_AVAILABLE"] = "CHAT_WIDGET/NO_MORE_HISTORY_AVAILABLE";
6
6
  ChatWidgetEvents["HISTORY_LOAD_ERROR"] = "CHAT_WIDGET/HISTORY_LOAD_ERROR";
7
+ ChatWidgetEvents["HISTORY_BATCH_LOADED"] = "CHAT_WIDGET/HISTORY_BATCH_LOADED";
7
8
  })(ChatWidgetEvents || (ChatWidgetEvents = {}));
8
9
  export default ChatWidgetEvents;
@@ -127,6 +127,12 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
127
127
  }
128
128
  const messagesDescOrder = (_ref = [...messages]) === null || _ref === void 0 ? void 0 : _ref.reverse();
129
129
  this.processHistoryMessages(messagesDescOrder);
130
+
131
+ // Signal that a batch of history messages has been added to the store.
132
+ // LazyLoadActivity subscribes to this to apply scroll anchoring after render.
133
+ dispatchCustomEvent(ChatWidgetEvents.HISTORY_BATCH_LOADED, {
134
+ messageCount: messages.length
135
+ });
130
136
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
131
137
  Event: TelemetryEvent.LCWPersistentHistoryPullCompleted,
132
138
  Description: "History pull completed successfully",
@@ -235,6 +241,9 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
235
241
  value: function processMessageToActivity(message) {
236
242
  try {
237
243
  const activity = convertPersistentChatHistoryMessageToActivity(message);
244
+ if (!activity) {
245
+ return null;
246
+ }
238
247
  activity.id = activity.id || `activity-${this.count}`;
239
248
  activity.channelData = {
240
249
  ...activity.channelData,