@thoughtspot/visual-embed-sdk 1.35.14 → 1.36.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.
Files changed (172) hide show
  1. package/cjs/package.json +2 -3
  2. package/cjs/src/auth.d.ts +5 -0
  3. package/cjs/src/auth.d.ts.map +1 -1
  4. package/cjs/src/auth.js +7 -0
  5. package/cjs/src/auth.js.map +1 -1
  6. package/cjs/src/embed/ts-embed.d.ts +6 -0
  7. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  8. package/cjs/src/embed/ts-embed.js +27 -0
  9. package/cjs/src/embed/ts-embed.js.map +1 -1
  10. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  11. package/cjs/src/embed/ts-embed.spec.js +73 -1
  12. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  13. package/cjs/src/react/index.spec.js +2 -2
  14. package/cjs/src/react/index.spec.js.map +1 -1
  15. package/cjs/src/types.d.ts +13 -2
  16. package/cjs/src/types.d.ts.map +1 -1
  17. package/cjs/src/types.js +12 -2
  18. package/cjs/src/types.js.map +1 -1
  19. package/cjs/src/utils/authService/authService.d.ts +1 -0
  20. package/cjs/src/utils/authService/authService.d.ts.map +1 -1
  21. package/cjs/src/utils/authService/authService.js +1 -0
  22. package/cjs/src/utils/authService/authService.js.map +1 -1
  23. package/cjs/src/utils/authService/index.d.ts +1 -1
  24. package/cjs/src/utils/authService/index.d.ts.map +1 -1
  25. package/cjs/src/utils/authService/index.js +2 -1
  26. package/cjs/src/utils/authService/index.js.map +1 -1
  27. package/cjs/src/utils/authService/tokenizedAuthService.d.ts +10 -0
  28. package/cjs/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
  29. package/cjs/src/utils/authService/tokenizedAuthService.js +27 -1
  30. package/cjs/src/utils/authService/tokenizedAuthService.js.map +1 -1
  31. package/cjs/src/utils/authService/tokenizedAuthService.spec.js +58 -1
  32. package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  33. package/cjs/src/utils/sessionInfoService.d.ts +30 -0
  34. package/cjs/src/utils/sessionInfoService.d.ts.map +1 -1
  35. package/cjs/src/utils/sessionInfoService.js +59 -1
  36. package/cjs/src/utils/sessionInfoService.js.map +1 -1
  37. package/dist/{index-B3hd6DTM.js → index-V2oBuwy6.js} +1 -1
  38. package/dist/src/auth.d.ts +5 -0
  39. package/dist/src/auth.d.ts.map +1 -1
  40. package/dist/src/embed/ts-embed.d.ts +6 -0
  41. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  42. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  43. package/dist/src/types.d.ts +13 -2
  44. package/dist/src/types.d.ts.map +1 -1
  45. package/dist/src/utils/authService/authService.d.ts +1 -0
  46. package/dist/src/utils/authService/authService.d.ts.map +1 -1
  47. package/dist/src/utils/authService/index.d.ts +1 -1
  48. package/dist/src/utils/authService/index.d.ts.map +1 -1
  49. package/dist/src/utils/authService/tokenizedAuthService.d.ts +10 -0
  50. package/dist/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
  51. package/dist/src/utils/sessionInfoService.d.ts +30 -0
  52. package/dist/src/utils/sessionInfoService.d.ts.map +1 -1
  53. package/dist/tsembed-react.es.js +129 -5
  54. package/dist/tsembed-react.js +128 -4
  55. package/dist/tsembed.es.js +130 -5
  56. package/dist/tsembed.js +129 -4
  57. package/dist/visual-embed-sdk-react-full.d.ts +48 -2
  58. package/dist/visual-embed-sdk-react.d.ts +48 -2
  59. package/dist/visual-embed-sdk.d.ts +48 -2
  60. package/lib/package.json +2 -3
  61. package/lib/src/auth.d.ts +5 -0
  62. package/lib/src/auth.d.ts.map +1 -1
  63. package/lib/src/auth.js +8 -1
  64. package/lib/src/auth.js.map +1 -1
  65. package/lib/src/embed/ts-embed.d.ts +6 -0
  66. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  67. package/lib/src/embed/ts-embed.js +27 -0
  68. package/lib/src/embed/ts-embed.js.map +1 -1
  69. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  70. package/lib/src/embed/ts-embed.spec.js +73 -1
  71. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  72. package/lib/src/react/index.spec.js +2 -2
  73. package/lib/src/react/index.spec.js.map +1 -1
  74. package/lib/src/types.d.ts +13 -2
  75. package/lib/src/types.d.ts.map +1 -1
  76. package/lib/src/types.js +12 -2
  77. package/lib/src/types.js.map +1 -1
  78. package/lib/src/utils/authService/authService.d.ts +1 -0
  79. package/lib/src/utils/authService/authService.d.ts.map +1 -1
  80. package/lib/src/utils/authService/authService.js +1 -0
  81. package/lib/src/utils/authService/authService.js.map +1 -1
  82. package/lib/src/utils/authService/index.d.ts +1 -1
  83. package/lib/src/utils/authService/index.d.ts.map +1 -1
  84. package/lib/src/utils/authService/index.js +1 -1
  85. package/lib/src/utils/authService/index.js.map +1 -1
  86. package/lib/src/utils/authService/tokenizedAuthService.d.ts +10 -0
  87. package/lib/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
  88. package/lib/src/utils/authService/tokenizedAuthService.js +25 -0
  89. package/lib/src/utils/authService/tokenizedAuthService.js.map +1 -1
  90. package/lib/src/utils/authService/tokenizedAuthService.spec.js +59 -2
  91. package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  92. package/lib/src/utils/sessionInfoService.d.ts +30 -0
  93. package/lib/src/utils/sessionInfoService.d.ts.map +1 -1
  94. package/lib/src/utils/sessionInfoService.js +57 -1
  95. package/lib/src/utils/sessionInfoService.js.map +1 -1
  96. package/lib/src/visual-embed-sdk.d.ts +48 -2
  97. package/package.json +2 -3
  98. package/src/auth.ts +8 -1
  99. package/src/embed/ts-embed.spec.ts +95 -1
  100. package/src/embed/ts-embed.ts +31 -0
  101. package/src/react/index.spec.tsx +2 -2
  102. package/src/types.ts +14 -2
  103. package/src/utils/authService/authService.ts +1 -0
  104. package/src/utils/authService/index.ts +5 -1
  105. package/src/utils/authService/tokenizedAuthService.spec.ts +66 -2
  106. package/src/utils/authService/tokenizedAuthService.ts +26 -0
  107. package/src/utils/sessionInfoService.ts +64 -1
  108. package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts +0 -2
  109. package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts.map +0 -1
  110. package/cjs/src/embed/searchEmbed-basic-auth.spec.js +0 -104
  111. package/cjs/src/embed/searchEmbed-basic-auth.spec.js.map +0 -1
  112. package/cjs/src/hostEventsTypeMapping.d.ts +0 -2
  113. package/cjs/src/hostEventsTypeMapping.d.ts.map +0 -1
  114. package/cjs/src/hostEventsTypeMapping.js +0 -4
  115. package/cjs/src/hostEventsTypeMapping.js.map +0 -1
  116. package/cjs/src/utils/embedApi/contracts.d.ts +0 -101
  117. package/cjs/src/utils/embedApi/contracts.d.ts.map +0 -1
  118. package/cjs/src/utils/embedApi/contracts.js +0 -17
  119. package/cjs/src/utils/embedApi/contracts.js.map +0 -1
  120. package/cjs/src/utils/embedApi/embedApiClient.d.ts +0 -12
  121. package/cjs/src/utils/embedApi/embedApiClient.d.ts.map +0 -1
  122. package/cjs/src/utils/embedApi/embedApiClient.js +0 -46
  123. package/cjs/src/utils/embedApi/embedApiClient.js.map +0 -1
  124. package/cjs/src/utils/embedApi/processEmbedApi.d.ts +0 -9
  125. package/cjs/src/utils/embedApi/processEmbedApi.d.ts.map +0 -1
  126. package/cjs/src/utils/embedApi/processEmbedApi.js +0 -18
  127. package/cjs/src/utils/embedApi/processEmbedApi.js.map +0 -1
  128. package/dist/index-BBBimG1x.js +0 -7370
  129. package/dist/index-BGnxP5NY.js +0 -7370
  130. package/dist/index-CENLvayL.js +0 -7370
  131. package/dist/index-CbltIawo.js +0 -7370
  132. package/dist/index-CoQfqaHj.js +0 -7370
  133. package/dist/index-CzwzS0P4.js +0 -7370
  134. package/dist/index-D-9WUCUl.js +0 -7370
  135. package/dist/index-DFwi_pV_.js +0 -7370
  136. package/dist/index-DOIjN0N_.js +0 -7370
  137. package/dist/index-DYBx8SuE.js +0 -7370
  138. package/dist/index-DaLHJaLd.js +0 -7370
  139. package/dist/index-DnJX-gN2.js +0 -7370
  140. package/dist/index-IDmSUe93.js +0 -7370
  141. package/dist/index-nWevLycs.js +0 -7370
  142. package/dist/index-vxW97_xb.js +0 -7370
  143. package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +0 -2
  144. package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts.map +0 -1
  145. package/dist/src/hostEventsTypeMapping.d.ts +0 -2
  146. package/dist/src/hostEventsTypeMapping.d.ts.map +0 -1
  147. package/dist/src/utils/embedApi/contracts.d.ts +0 -101
  148. package/dist/src/utils/embedApi/contracts.d.ts.map +0 -1
  149. package/dist/src/utils/embedApi/embedApiClient.d.ts +0 -12
  150. package/dist/src/utils/embedApi/embedApiClient.d.ts.map +0 -1
  151. package/dist/src/utils/embedApi/processEmbedApi.d.ts +0 -9
  152. package/dist/src/utils/embedApi/processEmbedApi.d.ts.map +0 -1
  153. package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +0 -2
  154. package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts.map +0 -1
  155. package/lib/src/embed/searchEmbed-basic-auth.spec.js +0 -101
  156. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +0 -1
  157. package/lib/src/hostEventsTypeMapping.d.ts +0 -2
  158. package/lib/src/hostEventsTypeMapping.d.ts.map +0 -1
  159. package/lib/src/hostEventsTypeMapping.js +0 -2
  160. package/lib/src/hostEventsTypeMapping.js.map +0 -1
  161. package/lib/src/utils/embedApi/contracts.d.ts +0 -101
  162. package/lib/src/utils/embedApi/contracts.d.ts.map +0 -1
  163. package/lib/src/utils/embedApi/contracts.js +0 -14
  164. package/lib/src/utils/embedApi/contracts.js.map +0 -1
  165. package/lib/src/utils/embedApi/embedApiClient.d.ts +0 -12
  166. package/lib/src/utils/embedApi/embedApiClient.d.ts.map +0 -1
  167. package/lib/src/utils/embedApi/embedApiClient.js +0 -42
  168. package/lib/src/utils/embedApi/embedApiClient.js.map +0 -1
  169. package/lib/src/utils/embedApi/processEmbedApi.d.ts +0 -9
  170. package/lib/src/utils/embedApi/processEmbedApi.d.ts.map +0 -1
  171. package/lib/src/utils/embedApi/processEmbedApi.js +0 -14
  172. package/lib/src/utils/embedApi/processEmbedApi.js.map +0 -1
@@ -51,12 +51,13 @@ import * as mixpanelInstance from '../mixpanel-service';
51
51
  import * as authInstance from '../auth';
52
52
  import * as baseInstance from './base';
53
53
  import { MIXPANEL_EVENT } from '../mixpanel-service';
54
- import * as authService from '../utils/authService/authService';
54
+ import * as authService from '../utils/authService';
55
55
  import { logger } from '../utils/logger';
56
56
  import { version } from '../../package.json';
57
57
  import { HiddenActionItemByDefaultForSearchEmbed } from './search';
58
58
  import { processTrigger } from '../utils/processTrigger';
59
59
  import { UIPassthroughEvent } from './hostEventClient/contracts';
60
+ import * as sessionInfoService from '../utils/sessionInfoService';
60
61
 
61
62
  jest.mock('../utils/processTrigger');
62
63
 
@@ -1147,6 +1148,99 @@ describe('Unit test case for ts embed', () => {
1147
1148
  });
1148
1149
  });
1149
1150
 
1151
+ describe('Trigger infoSuccess event on iframe load', () => {
1152
+ beforeAll(() => {
1153
+ jest.clearAllMocks();
1154
+ init({
1155
+ thoughtSpotHost,
1156
+ authType: AuthType.None,
1157
+ loginFailedMessage: 'Failed to Login',
1158
+ });
1159
+ });
1160
+
1161
+ const setup = async (isLoggedIn = false, overrideOrgId: number | undefined = undefined) => {
1162
+ jest.spyOn(window, 'addEventListener').mockImplementationOnce(
1163
+ (event, handler, options) => {
1164
+ handler({
1165
+ data: {
1166
+ type: 'xyz',
1167
+ },
1168
+ ports: [3000],
1169
+ source: null,
1170
+ });
1171
+ },
1172
+ );
1173
+ mockProcessTrigger.mockResolvedValueOnce({ session: 'test' });
1174
+ // resetCachedPreauthInfo();
1175
+ let mockGetPreauthInfo = null;
1176
+
1177
+ if (overrideOrgId) {
1178
+ mockGetPreauthInfo = jest.spyOn(sessionInfoService, 'getPreauthInfo').mockImplementation(jest.fn());
1179
+ }
1180
+
1181
+ const mockPreauthInfoFetch = jest.spyOn(authService, 'fetchPreauthInfoService').mockResolvedValueOnce({
1182
+ ok: true,
1183
+ headers: new Headers({ 'content-type': 'application/json' }), // Mock headers correctly
1184
+ json: async () => ({
1185
+ info: {
1186
+ configInfo: {
1187
+ mixpanelConfig: {
1188
+ devSdkKey: 'devSdkKey',
1189
+ },
1190
+ },
1191
+ userGUID: 'userGUID',
1192
+ },
1193
+ }), // Mock JSON response
1194
+ });
1195
+ const iFrame: any = document.createElement('div');
1196
+ jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(isLoggedIn);
1197
+ const tsEmbed = new SearchEmbed(getRootEl(), {
1198
+ overrideOrgId,
1199
+ });
1200
+ iFrame.contentWindow = {
1201
+ postMessage: jest.fn(),
1202
+ };
1203
+ tsEmbed.on(EmbedEvent.CustomAction, jest.fn());
1204
+ jest.spyOn(iFrame, 'addEventListener').mockImplementationOnce(
1205
+ (event, handler, options) => {
1206
+ handler({});
1207
+ },
1208
+ );
1209
+ jest.spyOn(document, 'createElement').mockReturnValueOnce(iFrame);
1210
+ await tsEmbed.render();
1211
+
1212
+ return {
1213
+ mockPreauthInfoFetch,
1214
+ mockGetPreauthInfo,
1215
+ iFrame,
1216
+ };
1217
+ };
1218
+
1219
+ test('should call InfoSuccess Event on preauth call success', async () => {
1220
+ const {
1221
+ mockPreauthInfoFetch,
1222
+ iFrame,
1223
+ } = await setup(true);
1224
+ expect(mockPreauthInfoFetch).toHaveBeenCalledTimes(1);
1225
+
1226
+ await executeAfterWait(() => {
1227
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
1228
+ iFrame,
1229
+ HostEvent.InfoSuccess,
1230
+ 'http://tshost',
1231
+ expect.objectContaining({ info: expect.any(Object) }),
1232
+ );
1233
+ });
1234
+ });
1235
+
1236
+ test('should not call InfoSuccess Event if overrideOrgId is true', async () => {
1237
+ const {
1238
+ mockGetPreauthInfo,
1239
+ } = await setup(true, 123);
1240
+ expect(mockGetPreauthInfo).toHaveBeenCalledTimes(0);
1241
+ });
1242
+ });
1243
+
1150
1244
  describe('when thoughtSpotHost have value and authPromise return error', () => {
1151
1245
  beforeAll(() => {
1152
1246
  init({
@@ -70,6 +70,7 @@ import {
70
70
  import { AuthFailureType } from '../auth';
71
71
  import { getEmbedConfig } from './embedConfig';
72
72
  import { ERROR_MESSAGE } from '../errors';
73
+ import { getPreauthInfo } from '../utils/sessionInfoService';
73
74
  import { HostEventClient } from './hostEventClient/host-event-client';
74
75
 
75
76
  const { version } = pkgInfo;
@@ -244,6 +245,24 @@ export class TsEmbed {
244
245
  return null;
245
246
  }
246
247
 
248
+ /**
249
+ * Checks if preauth cache is enabled
250
+ * from the view config and embed config
251
+ * @returns boolean
252
+ */
253
+ private isPreAuthCacheEnabled() {
254
+ // Disable preauth cache when:
255
+ // 1. overrideOrgId is present since:
256
+ // - cached auth info would be for wrong org
257
+ // - info call response changes for each different overrideOrgId
258
+ // 2. disablePreauthCache is explicitly set to true
259
+ const isDisabled = (
260
+ this.viewConfig.overrideOrgId !== undefined
261
+ || this.embedConfig.disablePreauthCache === true
262
+ );
263
+ return !isDisabled;
264
+ }
265
+
247
266
  /**
248
267
  * fix for ts7.sep.cl
249
268
  * will be removed for ts7.oct.cl
@@ -586,6 +605,10 @@ export class TsEmbed {
586
605
  queryParams[Param.OverrideOrgId] = overrideOrgId;
587
606
  }
588
607
 
608
+ if (this.isPreAuthCacheEnabled()) {
609
+ queryParams[Param.preAuthCache] = true;
610
+ }
611
+
589
612
  queryParams[Param.OverrideNativeConsole] = true;
590
613
  queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
591
614
 
@@ -722,6 +745,14 @@ export class TsEmbed {
722
745
  elHeight: this.iFrame.clientHeight,
723
746
  timeTookToLoad: loadTimestamp - initTimestamp,
724
747
  });
748
+ // Send info event if preauth cache is enabled
749
+ if (this.isPreAuthCacheEnabled()) {
750
+ getPreauthInfo().then((data) => {
751
+ if (data?.info) {
752
+ this.trigger(HostEvent.InfoSuccess, data);
753
+ }
754
+ });
755
+ }
725
756
  });
726
757
  this.iFrame.addEventListener('error', () => {
727
758
  nextInQueue();
@@ -56,7 +56,7 @@ describe('React Components', () => {
56
56
  ),
57
57
  ).toBe(true);
58
58
  expect(getIFrameSrc(container)).toBe(
59
- `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
59
+ `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&preAuthCache=true&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
60
60
  );
61
61
  });
62
62
 
@@ -230,7 +230,7 @@ describe('React Components', () => {
230
230
  ),
231
231
  ).toBe(true);
232
232
  expect(getIFrameSrc(container)).toBe(
233
- `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
233
+ `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&preAuthCache=true&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
234
234
  );
235
235
  });
236
236
  });
package/src/types.ts CHANGED
@@ -629,6 +629,8 @@ export interface EmbedConfig {
629
629
  * @version SDK 1.37.0 | ThoughtSpot: 10.7.0.cl
630
630
  */
631
631
  customVariablesForThirdPartyTools?: Record< string, any >;
632
+
633
+ disablePreauthCache?: boolean;
632
634
  }
633
635
 
634
636
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -3269,8 +3271,17 @@ export enum HostEvent {
3269
3271
  */
3270
3272
  UpdatePersonalisedView = 'UpdatePersonalisedView',
3271
3273
  /**
3272
- * Triggers the action to get the current view of the Liveboard.
3273
- * @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
3274
+ * @hidden
3275
+ * Notify when info call is completed successfully
3276
+ * ```js
3277
+ * liveboardEmbed.trigger(HostEvent.InfoSuccess, data);
3278
+ *```
3279
+ * @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
3280
+ */
3281
+ InfoSuccess = 'InfoSuccess',
3282
+ /**
3283
+ * Triggers the action to get the current view of the liveboard
3284
+ * @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
3274
3285
  */
3275
3286
  SaveAnswer = 'saveAnswer',
3276
3287
  /**
@@ -3427,6 +3438,7 @@ export enum Param {
3427
3438
  OauthPollingInterval = 'oAuthPollingInterval',
3428
3439
  IsForceRedirect = 'isForceRedirect',
3429
3440
  DataSourceId = 'dataSourceId',
3441
+ preAuthCache = 'preAuthCache',
3430
3442
  ShowSpotterLimitations = 'showSpotterLimitations',
3431
3443
  }
3432
3444
 
@@ -3,6 +3,7 @@ import { logger } from '../logger';
3
3
  export const EndPoints = {
4
4
  AUTH_VERIFICATION: '/callosum/v1/session/info',
5
5
  SESSION_INFO: '/callosum/v1/session/info',
6
+ PREAUTH_INFO: '/prism/preauth/info',
6
7
  SAML_LOGIN_TEMPLATE: (targetUrl: string) => `/callosum/v1/saml/login?targetURLPath=${targetUrl}`,
7
8
  OIDC_LOGIN_TEMPLATE: (targetUrl: string) => `/callosum/v1/oidc/login?targetURLPath=${targetUrl}`,
8
9
  TOKEN_LOGIN: '/callosum/v1/session/login/token',
@@ -6,4 +6,8 @@ export {
6
6
  fetchBasicAuthService,
7
7
  verifyTokenService,
8
8
  } from './authService';
9
- export { fetchLogoutService, fetchSessionInfoService } from './tokenizedAuthService';
9
+ export {
10
+ fetchLogoutService,
11
+ fetchSessionInfoService,
12
+ fetchPreauthInfoService,
13
+ } from './tokenizedAuthService';
@@ -1,9 +1,16 @@
1
1
  import * as tokenizedFetchModule from '../../tokenizedFetch';
2
- import { isActiveService } from './tokenizedAuthService';
2
+ import { isActiveService, fetchSessionInfoService, fetchPreauthInfoService } from './tokenizedAuthService';
3
3
  import { logger } from '../logger';
4
+ import { EndPoints } from './authService';
5
+
6
+ const thoughtspotHost = 'http://thoughtspotHost';
4
7
 
5
8
  describe('tokenizedAuthService', () => {
6
- test('isActiveService is fetch returns ok', async () => {
9
+ afterEach(() => {
10
+ jest.clearAllMocks();
11
+ jest.restoreAllMocks();
12
+ });
13
+ test('isActiveService if fetch returns ok', async () => {
7
14
  jest.spyOn(tokenizedFetchModule, 'tokenizedFetch').mockResolvedValueOnce({
8
15
  ok: true,
9
16
  });
@@ -34,3 +41,60 @@ describe('tokenizedAuthService', () => {
34
41
  expect(logger.warn).toHaveBeenCalled();
35
42
  });
36
43
  });
44
+
45
+ describe('fetchPreauthInfoService', () => {
46
+ afterEach(() => {
47
+ jest.clearAllMocks();
48
+ jest.restoreAllMocks();
49
+ });
50
+
51
+ test('fetchPreauthInfoService if fetch returns ok', async () => {
52
+ const mockFetch = jest.spyOn(tokenizedFetchModule, 'tokenizedFetch');
53
+
54
+ // Mock for fetchPreauthInfoService
55
+ mockFetch
56
+ .mockResolvedValueOnce({
57
+ ok: true,
58
+ headers: new Headers({ 'content-type': 'application/json' }), // Mock headers correctly
59
+ status: 200,
60
+ statusText: 'Ok',
61
+ json: jest.fn().mockResolvedValue({
62
+ info: {
63
+ configInfo: {
64
+ mixpanelConfig: {
65
+ devSdkKey: 'devSdkKey',
66
+ },
67
+ },
68
+ userGUID: 'userGUID',
69
+ },
70
+ }),
71
+ });
72
+
73
+ const result = await fetchPreauthInfoService(thoughtspotHost);
74
+ const response = await result.json();
75
+
76
+ expect(mockFetch).toHaveBeenCalledTimes(1);
77
+ expect(mockFetch).toHaveBeenNthCalledWith(1, `${thoughtspotHost}${EndPoints.PREAUTH_INFO}`, {});
78
+ expect(response).toHaveProperty('info');
79
+ });
80
+ it('fetchPreauthInfoService if fetch fails', async () => {
81
+ const mockFetch = jest.spyOn(tokenizedFetchModule, 'tokenizedFetch');
82
+
83
+ // Mock for fetchPreauthInfoService
84
+ mockFetch.mockResolvedValueOnce({
85
+ ok: false,
86
+ status: 500,
87
+ statusText: 'Internal Server Error',
88
+ json: jest.fn().mockResolvedValue({}),
89
+ text: jest.fn().mockResolvedValue('Internal Server Error'),
90
+ });
91
+
92
+ try {
93
+ await fetchPreauthInfoService(thoughtspotHost);
94
+ } catch (e) {
95
+ expect(e.message).toContain(`Failed to fetch ${thoughtspotHost}${EndPoints.PREAUTH_INFO}`);
96
+ }
97
+ expect(mockFetch).toHaveBeenCalledTimes(1);
98
+ expect(mockFetch).toHaveBeenCalledWith(`${thoughtspotHost}${EndPoints.PREAUTH_INFO}`, {});
99
+ });
100
+ });
@@ -16,6 +16,32 @@ function tokenizedFailureLoggedFetch(url: string, options: RequestInit = {}): Pr
16
16
  });
17
17
  }
18
18
 
19
+ /**
20
+ * Fetches the session info from the ThoughtSpot server.
21
+ * @param thoughtspotHost
22
+ * @returns {Promise<any>}
23
+ * @example
24
+ * ```js
25
+ * const response = await sessionInfoService();
26
+ * ```
27
+ */
28
+ export async function fetchPreauthInfoService(thoughtspotHost: string): Promise<any> {
29
+ const sessionInfoPath = `${thoughtspotHost}${EndPoints.PREAUTH_INFO}`;
30
+ const handleError = (e: any) => {
31
+ const error: any = new Error(`Failed to fetch auth info: ${e.message || e.statusText}`);
32
+ error.status = e.status; // Attach the status code to the error object
33
+ throw error;
34
+ };
35
+
36
+ try {
37
+ const response = await tokenizedFailureLoggedFetch(sessionInfoPath);
38
+ return response;
39
+ } catch (e) {
40
+ handleError(e);
41
+ return null;
42
+ }
43
+ }
44
+
19
45
  /**
20
46
  * Fetches the session info from the ThoughtSpot server.
21
47
  * @param thoughtspotHost
@@ -1,5 +1,5 @@
1
1
  import { getEmbedConfig } from '../embed/embedConfig';
2
- import { fetchSessionInfoService } from './authService';
2
+ import { fetchSessionInfoService, fetchPreauthInfoService } from './authService';
3
3
 
4
4
  export type SessionInfo = {
5
5
  releaseVersion: string;
@@ -13,7 +13,70 @@ export type SessionInfo = {
13
13
  [key: string]: any;
14
14
  };
15
15
 
16
+ export type PreauthInfo = {
17
+ info?: SessionInfo;
18
+ headers: Record<string, string>;
19
+ status: number;
20
+ [key: string]: any;
21
+ };
22
+
16
23
  let sessionInfo: null | SessionInfo = null;
24
+ let preauthInfo: null | PreauthInfo = null;
25
+
26
+ /**
27
+ * Processes the session info response and returns the session info object.
28
+ * @param preauthInfoResp {any} Response from the session info API.
29
+ * @returns {PreauthInfo} The session info object.
30
+ * @example ```js
31
+ * const preauthInfoResp = await fetch(sessionInfoPath);
32
+ * const sessionInfo = await formatPreauthInfo(preauthInfoResp);
33
+ * console.log(sessionInfo);
34
+ * ```
35
+ * @version SDK: 1.28.3 | ThoughtSpot: *
36
+ */
37
+ export const formatPreauthInfo = async (preauthInfoResp: any): Promise<PreauthInfo> => {
38
+ try {
39
+ // Convert Headers to a plain object
40
+ const headers: Record<string, string> = {};
41
+ preauthInfoResp?.headers?.forEach((value: string, key: string) => {
42
+ headers[key] = value;
43
+ });
44
+ const data = await preauthInfoResp.json();
45
+ return {
46
+ ...data,
47
+ status: 200,
48
+ headers,
49
+ };
50
+ } catch (error) {
51
+ return null;
52
+ }
53
+ };
54
+
55
+ /**
56
+ * Returns the session info object and caches it for future use.
57
+ * Once fetched the session info object is cached and returned from the cache on
58
+ * subsequent calls.
59
+ * @example ```js
60
+ * const preauthInfo = await getPreauthInfo();
61
+ * console.log(preauthInfo);
62
+ * ```
63
+ * @version SDK: 1.28.3 | ThoughtSpot: *
64
+ * @returns {Promise<SessionInfo>} The session info object.
65
+ */
66
+ export async function getPreauthInfo(allowCache = true): Promise<PreauthInfo> {
67
+ if (!allowCache || !preauthInfo) {
68
+ try {
69
+ const host = getEmbedConfig().thoughtSpotHost;
70
+ const sessionResponse = await fetchPreauthInfoService(host);
71
+ const processedPreauthInfo = await formatPreauthInfo(sessionResponse);
72
+ preauthInfo = processedPreauthInfo;
73
+ } catch (error) {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ return preauthInfo;
79
+ }
17
80
 
18
81
  /**
19
82
  * Returns the session info object and caches it for future use.
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=searchEmbed-basic-auth.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"searchEmbed-basic-auth.spec.d.ts","sourceRoot":"","sources":["../../../src/embed/searchEmbed-basic-auth.spec.ts"],"names":[],"mappings":""}
@@ -1,104 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const search_1 = require("./search");
5
- const baseInstance = tslib_1.__importStar(require("./base"));
6
- const authService = tslib_1.__importStar(require("../utils/authService"));
7
- const authInstance = tslib_1.__importStar(require("../auth"));
8
- const config = tslib_1.__importStar(require("../config"));
9
- const embedConfigInstance = tslib_1.__importStar(require("./embedConfig"));
10
- const index_1 = require("../index");
11
- const types_1 = require("../types");
12
- const test_utils_1 = require("../test/test-utils");
13
- const auth_spec_1 = require("../auth.spec");
14
- const thoughtSpotHost = 'tshost';
15
- (0, index_1.init)({
16
- thoughtSpotHost,
17
- authType: types_1.AuthType.Basic,
18
- username: 'tsadmin',
19
- password: 'admin',
20
- });
21
- describe('Search embed tests when authType is Basic', () => {
22
- /**
23
- *
24
- * @param version
25
- */
26
- function setupVersion(version) {
27
- jest.spyOn(window, 'addEventListener').mockImplementation((event, handler, options) => {
28
- handler({
29
- data: {
30
- type: 'xyz',
31
- },
32
- ports: [3000],
33
- source: null,
34
- });
35
- });
36
- jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(async () => ({
37
- json: () => ({
38
- ...auth_spec_1.mockSessionInfo,
39
- releaseVersion: version,
40
- }),
41
- status: 200,
42
- }));
43
- jest.spyOn(authInstance, 'getReleaseVersion').mockReturnValue(version);
44
- }
45
- beforeEach(() => {
46
- document.body.innerHTML = (0, test_utils_1.getDocumentBody)();
47
- jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValue(true);
48
- });
49
- afterEach(() => {
50
- jest.clearAllMocks();
51
- });
52
- test('when releaseVersion is empty', async () => {
53
- setupVersion('');
54
- const mockAlert = spyOn(window, 'alert');
55
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
56
- await searchEmbed.render();
57
- expect(mockAlert).not.toBeCalled();
58
- });
59
- test("when releaseVersion is '7.0.1.cl' ", async () => {
60
- setupVersion('7.0.1.cl');
61
- const mockAlert = jest.spyOn(window, 'alert');
62
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
63
- await searchEmbed.render();
64
- expect(mockAlert).not.toBeCalled();
65
- });
66
- test('when releaseVersion is above 8.4.0.sw', async () => {
67
- setupVersion('8.4.0.sw');
68
- const mockAlert = jest.spyOn(window, 'alert');
69
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
70
- await searchEmbed.render();
71
- expect(mockAlert).not.toBeCalled();
72
- });
73
- test('releaseVersion is above 8.4.0.sw', async () => {
74
- setupVersion('8.8.0.sw');
75
- jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
76
- const mockAlert = jest.spyOn(window, 'alert');
77
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
78
- await searchEmbed.render();
79
- expect(mockAlert).not.toBeCalled();
80
- });
81
- test('Alert should not appear when suppressSearchEmbedBetaWarning is true and releaseVersion is ts7.dec.cl', async () => {
82
- setupVersion('ts7.dec.cl');
83
- jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
84
- jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
85
- suppressSearchEmbedBetaWarning: true,
86
- });
87
- const mockAlert = jest.spyOn(window, 'alert');
88
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
89
- await searchEmbed.render();
90
- expect(mockAlert).not.toBeCalled();
91
- });
92
- test('Alert should not appear when suppressSearchEmbedBetaWarning is true and releaseVersion is 8.4.0.sw', async () => {
93
- setupVersion('8.4.0.sw');
94
- jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
95
- jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
96
- suppressSearchEmbedBetaWarning: true,
97
- });
98
- const mockAlert = jest.spyOn(window, 'alert');
99
- const searchEmbed = new search_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
100
- await searchEmbed.render();
101
- expect(mockAlert).not.toBeCalled();
102
- });
103
- });
104
- //# sourceMappingURL=searchEmbed-basic-auth.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"searchEmbed-basic-auth.spec.js","sourceRoot":"","sources":["../../../src/embed/searchEmbed-basic-auth.spec.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=hostEventsTypeMapping.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hostEventsTypeMapping.d.ts","sourceRoot":"","sources":["../../src/hostEventsTypeMapping.ts"],"names":[],"mappings":""}
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const types_1 = require("./types");
4
- //# sourceMappingURL=hostEventsTypeMapping.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hostEventsTypeMapping.js","sourceRoot":"","sources":["../../src/hostEventsTypeMapping.ts"],"names":[],"mappings":";;AAAA,mCAAoC"}