@microsoft/omnichannel-chat-sdk 2.0.1 → 2.0.2-main.c0f210d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -113,10 +113,14 @@ For a detailed tracking of the releases, please refer to the [Changelog document
113
113
 
114
114
  _**Important Note:**_ Versions below 1.11.0 are no longer supported after November 1st, 2025. Please update to recent versions to ensure you have the latest features and bug fixes.
115
115
 
116
+ _**Known issue:**_ Versions earlier than 1.11.6 can start duplicate conversations when an application calls `startChat()` again before the previous call is complete. Upgrade to 1.11.8 or later. See [Concurrent `startChat()` calls in versions before 1.11.6](docs/KNOWN_ISSUE_CONCURRENT_STARTCHAT.md).
117
+
116
118
  | Version | Docs | Release Date | End of Support | Deprecated |
117
119
  | -- | -- | -- | -- | -- |
120
+ | 2.0.2 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v2.0.2) | Oct 20th 2026 | Oct 20th 2027 | |
118
121
  | 2.0.1 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v2.0.1) | Oct 1st 2026 | Oct 1st 2027 | |
119
122
  | 2.0.0 | [Migration Guide](docs/MIGRATION_2.0.md) / [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v2.0.0) | Aug 13th 2026 | Aug 13th 2027 | |
123
+ | 1.11.8 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v1.11.8) | Feb 2nd 2026 | Feb 2nd 2027 | |
120
124
  | 1.11.4 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v1.11.4) | Jul 17th 2025 | Jul 17th 2026 | |
121
125
  | 1.11.3 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v1.11.3) | Jul 14th 2025 | Jul 14th 2026 | |
122
126
  | 1.11.2 | [Release Notes](https://github.com/microsoft/omnichannel-chat-sdk/releases/tag/v1.11.2) | Jun 24th 2025 | Jun 24th 2026 | |
@@ -165,6 +165,24 @@ declare class OmnichannelChatSDK {
165
165
  getLiveChatConfig(optionalParams?: GetLiveChatConfigOptionalParams): Promise<ChatConfig>;
166
166
  getChatToken(cached?: boolean, optionalParams?: GetChatTokenOptionalParams): Promise<IChatToken>;
167
167
  setChatToken(chatToken: FetchChatTokenResponse): void;
168
+ /**
169
+ * Creates the ACS token refresher used to renew the chat token before it expires. Returns undefined, which keeps
170
+ * the existing behavior, unless renewal is enabled in the chat config, not disabled in the SDK config and
171
+ * supported by the installed OCSDK. The refresher never throws and falls back to the current token on failure.
172
+ */
173
+ private createChatTokenRefresher;
174
+ /**
175
+ * Gives the renewed chat token to the attachment client, which keeps the token it was initialized with and uses
176
+ * it for every upload and download. Runs in the background and never throws: on failure, attachments keep using
177
+ * the previous token as they did before renewal existed.
178
+ */
179
+ private refreshAttachmentClientToken;
180
+ /**
181
+ * Returns the token of the authenticated user to renew the chat token with, refreshed from the auth token
182
+ * provider when possible because the token used to start the chat may have expired. Returns undefined for
183
+ * unauthenticated chats.
184
+ */
185
+ private getAuthenticatedUserTokenForChatTokenRenewal;
168
186
  getCallingToken(): Promise<string>;
169
187
  private recordMessages;
170
188
  getMessages(): Promise<GetMessagesResponse>;
@@ -103,6 +103,7 @@ var location_1 = require("./utils/location");
103
103
  var internalUtils_1 = require("./utils/internalUtils");
104
104
  var loggerUtils_1 = require("./utils/loggerUtils");
105
105
  var parsers_1 = require("./utils/parsers");
106
+ var chatTokenRenewal_1 = require("./utils/chatTokenRenewal");
106
107
  var platform_1 = require("./utils/platform");
107
108
  var retrieveCollectorUri_1 = require("./telemetry/retrieveCollectorUri");
108
109
  var startPolling_1 = require("./commands/startPolling");
@@ -1116,6 +1117,7 @@ var OmnichannelChatSDK = /** @class */ (function () {
1116
1117
  return [4 /*yield*/, ((_c = this.ACSClient) === null || _c === void 0 ? void 0 : _c.initialize({
1117
1118
  token: chatAdapterConfig.token,
1118
1119
  environmentUrl: chatAdapterConfig.environmentUrl,
1120
+ tokenRefresher: this.createChatTokenRefresher(chatAdapterConfig.token)
1119
1121
  }))];
1120
1122
  case 2:
1121
1123
  _e.sent();
@@ -1790,6 +1792,145 @@ var OmnichannelChatSDK = /** @class */ (function () {
1790
1792
  this.sessionId = this.OCClient.sessionId;
1791
1793
  }
1792
1794
  };
1795
+ /**
1796
+ * Creates the ACS token refresher used to renew the chat token before it expires. Returns undefined, which keeps
1797
+ * the existing behavior, unless renewal is enabled in the chat config, not disabled in the SDK config and
1798
+ * supported by the installed OCSDK. The refresher never throws and falls back to the current token on failure.
1799
+ */
1800
+ OmnichannelChatSDK.prototype.createChatTokenRefresher = function (initialToken) {
1801
+ var _this = this;
1802
+ var _a, _b, _c, _d, _e, _f;
1803
+ try {
1804
+ if (this.liveChatVersion !== LiveChatVersion_1.default.V2
1805
+ || ((_b = (_a = this.chatSDKConfig) === null || _a === void 0 ? void 0 : _a.chatTokenRenewal) === null || _b === void 0 ? void 0 : _b.disable) === true
1806
+ || (0, parsers_1.parseLowerCaseString)((_d = (_c = this.liveChatConfig) === null || _c === void 0 ? void 0 : _c.LcwFcbConfiguration) === null || _d === void 0 ? void 0 : _d.lcwChatTokenRenewalEnabled) !== "true"
1807
+ || typeof ((_e = this.OCClient) === null || _e === void 0 ? void 0 : _e.renewChatToken) !== "function"
1808
+ || !initialToken
1809
+ || !((_f = this.chatToken) === null || _f === void 0 ? void 0 : _f.chatId)
1810
+ || !this.requestId) {
1811
+ return undefined;
1812
+ }
1813
+ var chatId_1 = this.chatToken.chatId;
1814
+ var requestId_1 = this.requestId;
1815
+ // A reconnected chat is found by its reconnect id, not by the new request id
1816
+ var renewalId_1 = this.reconnectId || requestId_1;
1817
+ var telemetryData_1 = {
1818
+ RequestId: requestId_1,
1819
+ ChatId: chatId_1
1820
+ };
1821
+ return (0, chatTokenRenewal_1.createChatTokenRefresher)({
1822
+ initialToken: initialToken,
1823
+ chatId: chatId_1,
1824
+ isChatActive: function () { var _a; return !_this.isEndingChat && _this.requestId === requestId_1 && ((_a = _this.chatToken) === null || _a === void 0 ? void 0 : _a.chatId) === chatId_1; },
1825
+ renewChatToken: function () { return __awaiter(_this, void 0, void 0, function () {
1826
+ var renewChatTokenOptionalParams, authenticatedUserToken;
1827
+ return __generator(this, function (_a) {
1828
+ switch (_a.label) {
1829
+ case 0:
1830
+ renewChatTokenOptionalParams = {};
1831
+ return [4 /*yield*/, this.getAuthenticatedUserTokenForChatTokenRenewal()];
1832
+ case 1:
1833
+ authenticatedUserToken = _a.sent();
1834
+ if (authenticatedUserToken) {
1835
+ renewChatTokenOptionalParams.authenticatedUserToken = authenticatedUserToken;
1836
+ }
1837
+ return [2 /*return*/, this.OCClient.renewChatToken(renewalId_1, renewChatTokenOptionalParams)];
1838
+ }
1839
+ });
1840
+ }); },
1841
+ isNonRetriableStatus: function (statusCode) { return (_this.authenticatedUserToken ? chatTokenRenewal_1.authenticatedNonRetriableStatusCodes : chatTokenRenewal_1.defaultNonRetriableStatusCodes).includes(statusCode); },
1842
+ onRenewed: function (renewed) {
1843
+ var _a;
1844
+ _this.chatToken = __assign(__assign({}, _this.chatToken), { token: renewed.Token, expiresIn: renewed.ExpiresIn !== undefined && renewed.ExpiresIn !== null ? String(renewed.ExpiresIn) : _this.chatToken.expiresIn, voiceVideoCallToken: (_a = renewed.VoiceVideoCallToken) !== null && _a !== void 0 ? _a : _this.chatToken.voiceVideoCallToken });
1845
+ _this.refreshAttachmentClientToken(chatId_1);
1846
+ },
1847
+ onStart: function () { return _this.scenarioMarker.startScenario(TelemetryEvent_1.default.RenewChatToken, telemetryData_1); },
1848
+ onSuccess: function () { return _this.scenarioMarker.completeScenario(TelemetryEvent_1.default.RenewChatToken, telemetryData_1); },
1849
+ onFailure: function (reason, error) {
1850
+ var exceptionDetails = {
1851
+ response: reason,
1852
+ errorObject: error !== undefined ? "".concat(error) : undefined
1853
+ };
1854
+ _this.scenarioMarker.failScenario(TelemetryEvent_1.default.RenewChatToken, __assign(__assign({}, telemetryData_1), { ExceptionDetails: JSON.stringify(exceptionDetails) }));
1855
+ }
1856
+ });
1857
+ }
1858
+ catch (_g) {
1859
+ return undefined;
1860
+ }
1861
+ };
1862
+ /**
1863
+ * Gives the renewed chat token to the attachment client, which keeps the token it was initialized with and uses
1864
+ * it for every upload and download. Runs in the background and never throws: on failure, attachments keep using
1865
+ * the previous token as they did before renewal existed.
1866
+ */
1867
+ OmnichannelChatSDK.prototype.refreshAttachmentClientToken = function (chatId) {
1868
+ var _this = this;
1869
+ try {
1870
+ var amsClient_1 = this.AMSClient;
1871
+ var chatToken_1 = this.chatToken;
1872
+ if (!this.isAMSClientAllowed
1873
+ || this.AMSClientLoadCurrentState !== AMSClientLoadStates_1.AMSClientLoadStates.LOADED
1874
+ || !amsClient_1
1875
+ || typeof amsClient_1.initialize !== "function"
1876
+ || (chatToken_1 === null || chatToken_1 === void 0 ? void 0 : chatToken_1.chatId) !== chatId
1877
+ || !chatToken_1.token) {
1878
+ return;
1879
+ }
1880
+ var telemetryData_2 = {
1881
+ RequestId: this.requestId,
1882
+ ChatId: chatId
1883
+ };
1884
+ this.scenarioMarker.startScenario(TelemetryEvent_1.default.RefreshAttachmentClientToken, telemetryData_2);
1885
+ Promise.resolve()
1886
+ .then(function () { return amsClient_1.initialize({ chatToken: chatToken_1 }); })
1887
+ .then(function () {
1888
+ _this.scenarioMarker.completeScenario(TelemetryEvent_1.default.RefreshAttachmentClientToken, telemetryData_2);
1889
+ }, function (error) {
1890
+ _this.scenarioMarker.failScenario(TelemetryEvent_1.default.RefreshAttachmentClientToken, __assign(__assign({}, telemetryData_2), { ExceptionDetails: JSON.stringify({ errorObject: "".concat(error) }) }));
1891
+ })
1892
+ .catch(function () {
1893
+ // Telemetry failures must not surface
1894
+ });
1895
+ }
1896
+ catch (_a) {
1897
+ // Attachments keep using the previous token
1898
+ }
1899
+ };
1900
+ /**
1901
+ * Returns the token of the authenticated user to renew the chat token with, refreshed from the auth token
1902
+ * provider when possible because the token used to start the chat may have expired. Returns undefined for
1903
+ * unauthenticated chats.
1904
+ */
1905
+ OmnichannelChatSDK.prototype.getAuthenticatedUserTokenForChatTokenRenewal = function () {
1906
+ return __awaiter(this, void 0, void 0, function () {
1907
+ var token, _a;
1908
+ var _b;
1909
+ return __generator(this, function (_c) {
1910
+ switch (_c.label) {
1911
+ case 0:
1912
+ if (!this.authenticatedUserToken) {
1913
+ return [2 /*return*/, undefined];
1914
+ }
1915
+ if (!(typeof ((_b = this.chatSDKConfig) === null || _b === void 0 ? void 0 : _b.getAuthToken) === "function")) return [3 /*break*/, 4];
1916
+ _c.label = 1;
1917
+ case 1:
1918
+ _c.trys.push([1, 3, , 4]);
1919
+ return [4 /*yield*/, this.chatSDKConfig.getAuthToken()];
1920
+ case 2:
1921
+ token = _c.sent();
1922
+ if (typeof token === "string" && token.trim().length > 0) {
1923
+ return [2 /*return*/, token];
1924
+ }
1925
+ return [3 /*break*/, 4];
1926
+ case 3:
1927
+ _a = _c.sent();
1928
+ return [3 /*break*/, 4];
1929
+ case 4: return [2 /*return*/, this.authenticatedUserToken];
1930
+ }
1931
+ });
1932
+ });
1933
+ };
1793
1934
  OmnichannelChatSDK.prototype.getCallingToken = function () {
1794
1935
  return __awaiter(this, void 0, void 0, function () {
1795
1936
  return __generator(this, function (_a) {