@thoughtspot/visual-embed-sdk 1.20.0-prerender.2 → 1.20.1

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 (182) hide show
  1. package/README.md +1 -1
  2. package/dist/src/auth.d.ts +2 -38
  3. package/dist/src/auth.d.ts.map +1 -1
  4. package/dist/src/config.d.ts +0 -1
  5. package/dist/src/config.d.ts.map +1 -1
  6. package/dist/src/embed/app.d.ts +5 -17
  7. package/dist/src/embed/app.d.ts.map +1 -1
  8. package/dist/src/embed/base.d.ts +9 -20
  9. package/dist/src/embed/base.d.ts.map +1 -1
  10. package/dist/src/embed/liveboard.d.ts +5 -17
  11. package/dist/src/embed/liveboard.d.ts.map +1 -1
  12. package/dist/src/embed/search-bar.d.ts +0 -3
  13. package/dist/src/embed/search-bar.d.ts.map +1 -1
  14. package/dist/src/embed/search.d.ts +5 -9
  15. package/dist/src/embed/search.d.ts.map +1 -1
  16. package/dist/src/embed/ts-embed.d.ts +6 -43
  17. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  18. package/dist/src/errors.d.ts.map +1 -1
  19. package/dist/src/index.d.ts.map +1 -1
  20. package/dist/src/mixpanel-service.d.ts +0 -8
  21. package/dist/src/mixpanel-service.d.ts.map +1 -1
  22. package/dist/src/react/index.d.ts.map +1 -1
  23. package/dist/src/react/util.d.ts +0 -4
  24. package/dist/src/react/util.d.ts.map +1 -1
  25. package/dist/src/test/test-utils.d.ts +2 -11
  26. package/dist/src/test/test-utils.d.ts.map +1 -1
  27. package/dist/src/types.d.ts +76 -273
  28. package/dist/src/types.d.ts.map +1 -1
  29. package/dist/src/utils/answerService.d.ts +0 -7
  30. package/dist/src/utils/answerService.d.ts.map +1 -1
  31. package/dist/src/utils/authService.d.ts +0 -30
  32. package/dist/src/utils/authService.d.ts.map +1 -1
  33. package/dist/src/utils/processData.d.ts +0 -12
  34. package/dist/src/utils/processData.d.ts.map +1 -1
  35. package/dist/src/utils/processTrigger.d.ts +0 -7
  36. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  37. package/dist/src/utils.d.ts +0 -12
  38. package/dist/src/utils.d.ts.map +1 -1
  39. package/dist/tsembed.es.js +262 -637
  40. package/dist/tsembed.js +261 -629
  41. package/lib/package.json +8 -3
  42. package/lib/src/auth.d.ts +2 -38
  43. package/lib/src/auth.d.ts.map +1 -1
  44. package/lib/src/auth.js +25 -70
  45. package/lib/src/auth.js.map +1 -1
  46. package/lib/src/auth.spec.js +5 -14
  47. package/lib/src/auth.spec.js.map +1 -1
  48. package/lib/src/config.d.ts +0 -1
  49. package/lib/src/config.d.ts.map +1 -1
  50. package/lib/src/config.js +3 -5
  51. package/lib/src/config.js.map +1 -1
  52. package/lib/src/config.spec.js.map +1 -1
  53. package/lib/src/embed/app.d.ts +5 -17
  54. package/lib/src/embed/app.d.ts.map +1 -1
  55. package/lib/src/embed/app.js +15 -25
  56. package/lib/src/embed/app.js.map +1 -1
  57. package/lib/src/embed/app.spec.js +12 -12
  58. package/lib/src/embed/app.spec.js.map +1 -1
  59. package/lib/src/embed/base.d.ts +9 -20
  60. package/lib/src/embed/base.d.ts.map +1 -1
  61. package/lib/src/embed/base.js +15 -31
  62. package/lib/src/embed/base.js.map +1 -1
  63. package/lib/src/embed/base.spec.js.map +1 -1
  64. package/lib/src/embed/embed.spec.js +1 -1
  65. package/lib/src/embed/embed.spec.js.map +1 -1
  66. package/lib/src/embed/liveboard.d.ts +5 -17
  67. package/lib/src/embed/liveboard.d.ts.map +1 -1
  68. package/lib/src/embed/liveboard.js +37 -49
  69. package/lib/src/embed/liveboard.js.map +1 -1
  70. package/lib/src/embed/liveboard.spec.js +30 -37
  71. package/lib/src/embed/liveboard.spec.js.map +1 -1
  72. package/lib/src/embed/pinboard.spec.js +26 -14
  73. package/lib/src/embed/pinboard.spec.js.map +1 -1
  74. package/lib/src/embed/search-bar.d.ts +0 -3
  75. package/lib/src/embed/search-bar.d.ts.map +1 -1
  76. package/lib/src/embed/search-bar.js +6 -5
  77. package/lib/src/embed/search-bar.js.map +1 -1
  78. package/lib/src/embed/search.d.ts +5 -9
  79. package/lib/src/embed/search.d.ts.map +1 -1
  80. package/lib/src/embed/search.js +14 -18
  81. package/lib/src/embed/search.js.map +1 -1
  82. package/lib/src/embed/search.spec.js +19 -16
  83. package/lib/src/embed/search.spec.js.map +1 -1
  84. package/lib/src/embed/searchEmbed-basic-auth.spec.js +0 -4
  85. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -1
  86. package/lib/src/embed/ts-embed.d.ts +6 -43
  87. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  88. package/lib/src/embed/ts-embed.js +72 -117
  89. package/lib/src/embed/ts-embed.js.map +1 -1
  90. package/lib/src/embed/ts-embed.spec.js +24 -23
  91. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  92. package/lib/src/errors.d.ts.map +1 -1
  93. package/lib/src/errors.js.map +1 -1
  94. package/lib/src/index.d.ts.map +1 -1
  95. package/lib/src/index.js +2 -2
  96. package/lib/src/index.js.map +1 -1
  97. package/lib/src/mixpanel-service.d.ts +0 -8
  98. package/lib/src/mixpanel-service.d.ts.map +1 -1
  99. package/lib/src/mixpanel-service.js +1 -13
  100. package/lib/src/mixpanel-service.js.map +1 -1
  101. package/lib/src/mixpanel-service.spec.js.map +1 -1
  102. package/lib/src/react/index.d.ts.map +1 -1
  103. package/lib/src/react/index.js +6 -6
  104. package/lib/src/react/index.js.map +1 -1
  105. package/lib/src/react/index.spec.js +6 -15
  106. package/lib/src/react/index.spec.js.map +1 -1
  107. package/lib/src/react/util.d.ts +0 -4
  108. package/lib/src/react/util.d.ts.map +1 -1
  109. package/lib/src/react/util.js +0 -4
  110. package/lib/src/react/util.js.map +1 -1
  111. package/lib/src/test/test-utils.d.ts +2 -11
  112. package/lib/src/test/test-utils.d.ts.map +1 -1
  113. package/lib/src/test/test-utils.js +25 -36
  114. package/lib/src/test/test-utils.js.map +1 -1
  115. package/lib/src/types.d.ts +76 -273
  116. package/lib/src/types.d.ts.map +1 -1
  117. package/lib/src/types.js +54 -200
  118. package/lib/src/types.js.map +1 -1
  119. package/lib/src/utils/answerService.d.ts +0 -7
  120. package/lib/src/utils/answerService.d.ts.map +1 -1
  121. package/lib/src/utils/answerService.js +0 -7
  122. package/lib/src/utils/answerService.js.map +1 -1
  123. package/lib/src/utils/answerService.spec.js.map +1 -1
  124. package/lib/src/utils/authService.d.ts +0 -30
  125. package/lib/src/utils/authService.d.ts.map +1 -1
  126. package/lib/src/utils/authService.js +2 -39
  127. package/lib/src/utils/authService.js.map +1 -1
  128. package/lib/src/utils/authService.spec.js.map +1 -1
  129. package/lib/src/utils/processData.d.ts +0 -12
  130. package/lib/src/utils/processData.d.ts.map +1 -1
  131. package/lib/src/utils/processData.js +5 -33
  132. package/lib/src/utils/processData.js.map +1 -1
  133. package/lib/src/utils/processData.spec.js.map +1 -1
  134. package/lib/src/utils/processTrigger.d.ts +0 -7
  135. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  136. package/lib/src/utils/processTrigger.js +3 -17
  137. package/lib/src/utils/processTrigger.js.map +1 -1
  138. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  139. package/lib/src/utils.d.ts +0 -12
  140. package/lib/src/utils.d.ts.map +1 -1
  141. package/lib/src/utils.js +19 -24
  142. package/lib/src/utils.js.map +1 -1
  143. package/lib/src/utils.spec.js.map +1 -1
  144. package/lib/src/visual-embed-sdk.d.ts +102 -406
  145. package/package.json +8 -3
  146. package/src/auth.spec.ts +150 -68
  147. package/src/auth.ts +108 -102
  148. package/src/config.spec.ts +4 -2
  149. package/src/config.ts +3 -5
  150. package/src/embed/app.spec.ts +14 -25
  151. package/src/embed/app.ts +35 -47
  152. package/src/embed/base.spec.ts +9 -3
  153. package/src/embed/base.ts +53 -51
  154. package/src/embed/embed.spec.ts +6 -5
  155. package/src/embed/liveboard.spec.ts +37 -56
  156. package/src/embed/liveboard.ts +64 -66
  157. package/src/embed/pinboard.spec.ts +29 -26
  158. package/src/embed/search-bar.tsx +8 -10
  159. package/src/embed/search.spec.ts +21 -31
  160. package/src/embed/search.ts +25 -26
  161. package/src/embed/searchEmbed-basic-auth.spec.ts +28 -22
  162. package/src/embed/ts-embed.spec.ts +148 -70
  163. package/src/embed/ts-embed.ts +157 -147
  164. package/src/errors.ts +6 -3
  165. package/src/index.ts +10 -4
  166. package/src/mixpanel-service.spec.ts +3 -1
  167. package/src/mixpanel-service.ts +1 -13
  168. package/src/react/index.spec.tsx +13 -37
  169. package/src/react/index.tsx +57 -38
  170. package/src/react/util.ts +4 -8
  171. package/src/test/test-utils.ts +39 -43
  172. package/src/types.ts +78 -270
  173. package/src/utils/answerService.spec.ts +5 -3
  174. package/src/utils/answerService.ts +17 -21
  175. package/src/utils/authService.spec.ts +41 -26
  176. package/src/utils/authService.ts +21 -47
  177. package/src/utils/processData.spec.ts +59 -26
  178. package/src/utils/processData.ts +14 -36
  179. package/src/utils/processTrigger.spec.ts +6 -1
  180. package/src/utils/processTrigger.ts +9 -18
  181. package/src/utils.spec.ts +12 -8
  182. package/src/utils.ts +26 -25
package/src/auth.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import EventEmitter from 'eventemitter3';
2
2
  import { initMixpanel } from './mixpanel-service';
3
- import {
4
- AuthType, DOMSelector, EmbedConfig, EmbedEvent, Param,
5
- } from './types';
3
+ import { AuthType, DOMSelector, EmbedConfig, EmbedEvent, Param } from './types';
6
4
  import { getDOMNode, getRedirectUrl } from './utils';
7
5
  // eslint-disable-next-line import/no-cycle
8
6
  import {
@@ -27,12 +25,15 @@ const sessionInfoPromise = new Promise((resolve) => {
27
25
  });
28
26
  let releaseVersion = '';
29
27
 
30
- export const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
28
+ export const SSO_REDIRECTION_MARKER_GUID =
29
+ '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
31
30
 
32
31
  export const EndPoints = {
33
32
  AUTH_VERIFICATION: '/callosum/v1/session/info',
34
- SAML_LOGIN_TEMPLATE: (targetUrl: string) => `/callosum/v1/saml/login?targetURLPath=${targetUrl}`,
35
- OIDC_LOGIN_TEMPLATE: (targetUrl: string) => `/callosum/v1/oidc/login?targetURLPath=${targetUrl}`,
33
+ SAML_LOGIN_TEMPLATE: (targetUrl: string) =>
34
+ `/callosum/v1/saml/login?targetURLPath=${targetUrl}`,
35
+ OIDC_LOGIN_TEMPLATE: (targetUrl: string) =>
36
+ `/callosum/v1/oidc/login?targetURLPath=${targetUrl}`,
36
37
  TOKEN_LOGIN: '/callosum/v1/session/login/token',
37
38
  BASIC_LOGIN: '/callosum/v1/session/login',
38
39
  LOGOUT: '/callosum/v1/session/logout',
@@ -41,7 +42,6 @@ export const EndPoints = {
41
42
  /**
42
43
  * Enum for auth failure types. This is the parameter passed to the listner
43
44
  * of {@link AuthStatus.FAILURE}.
44
- *
45
45
  * @group Authentication / Init
46
46
  */
47
47
  export enum AuthFailureType {
@@ -53,7 +53,6 @@ export enum AuthFailureType {
53
53
 
54
54
  /**
55
55
  * Enum for auth status emitted by the emitter returned from {@link init}.
56
- *
57
56
  * @group Authentication / Init
58
57
  */
59
58
  export enum AuthStatus {
@@ -77,7 +76,6 @@ export enum AuthStatus {
77
76
  * Emitted when inPopup: true in the SAMLRedirect flow.
78
77
  * And, we are waiting for popup to be triggered either programatically
79
78
  * or by the trigger button.
80
- *
81
79
  * @version SDK: 1.19.0
82
80
  */
83
81
  WAITING_FOR_POPUP = 'WAITING_FOR_POPUP',
@@ -85,25 +83,28 @@ export enum AuthStatus {
85
83
 
86
84
  /**
87
85
  * Event emitter returned from {@link init}.
88
- *
89
86
  * @group Authentication / Init
90
87
  */
91
88
  export interface AuthEventEmitter {
92
89
  /**
93
90
  * Registed a listener on Auth failure.
94
- *
95
91
  * @param event
96
92
  * @param listener
97
93
  */
98
- on(event: AuthStatus.FAILURE, listener: (failureType: AuthFailureType) => void): this;
99
94
  on(
100
- event: AuthStatus.SDK_SUCCESS | AuthStatus.LOGOUT | AuthStatus.WAITING_FOR_POPUP,
95
+ event: AuthStatus.FAILURE,
96
+ listener: (failureType: AuthFailureType) => void,
97
+ ): this;
98
+ on(
99
+ event:
100
+ | AuthStatus.SDK_SUCCESS
101
+ | AuthStatus.LOGOUT
102
+ | AuthStatus.WAITING_FOR_POPUP,
101
103
  listener: () => void,
102
104
  ): this;
103
105
  on(event: AuthStatus.SUCCESS, listener: (sessionInfo: any) => void): this;
104
106
  /**
105
107
  * Trigger an event on the emitter returned from init.
106
- *
107
108
  * @param {@link AuthEvent}
108
109
  */
109
110
  emit(event: AuthEvent): void;
@@ -111,7 +112,6 @@ export interface AuthEventEmitter {
111
112
 
112
113
  /**
113
114
  * Events which can be triggered on the emitter returned from {@link init}.
114
- *
115
115
  * @group Authentication / Init
116
116
  */
117
117
  export enum AuthEvent {
@@ -124,24 +124,16 @@ export enum AuthEvent {
124
124
 
125
125
  let authEE: EventEmitter<AuthStatus | AuthEvent>;
126
126
 
127
- /**
128
- *
129
- */
130
127
  export function getAuthEE(): EventEmitter<AuthStatus | AuthEvent> {
131
128
  return authEE;
132
129
  }
133
130
 
134
- /**
135
- *
136
- * @param eventEmitter
137
- */
138
- export function setAuthEE(eventEmitter: EventEmitter<AuthStatus | AuthEvent>): void {
131
+ export function setAuthEE(
132
+ eventEmitter: EventEmitter<AuthStatus | AuthEvent>,
133
+ ): void {
139
134
  authEE = eventEmitter;
140
135
  }
141
136
 
142
- /**
143
- *
144
- */
145
137
  export function notifyAuthSDKSuccess(): void {
146
138
  if (!authEE) {
147
139
  console.error('SDK not initialized');
@@ -150,9 +142,6 @@ export function notifyAuthSDKSuccess(): void {
150
142
  authEE.emit(AuthStatus.SDK_SUCCESS);
151
143
  }
152
144
 
153
- /**
154
- *
155
- */
156
145
  export function notifyAuthSuccess(): void {
157
146
  if (!authEE) {
158
147
  console.error('SDK not initialized');
@@ -161,10 +150,6 @@ export function notifyAuthSuccess(): void {
161
150
  authEE.emit(AuthStatus.SUCCESS, sessionInfo);
162
151
  }
163
152
 
164
- /**
165
- *
166
- * @param failureType
167
- */
168
153
  export function notifyAuthFailure(failureType: AuthFailureType): void {
169
154
  if (!authEE) {
170
155
  console.error('SDK not initialized');
@@ -173,9 +158,6 @@ export function notifyAuthFailure(failureType: AuthFailureType): void {
173
158
  authEE.emit(AuthStatus.FAILURE, failureType);
174
159
  }
175
160
 
176
- /**
177
- *
178
- */
179
161
  export function notifyLogout(): void {
180
162
  if (!authEE) {
181
163
  console.error('SDK not initialized');
@@ -186,7 +168,6 @@ export function notifyLogout(): void {
186
168
 
187
169
  /**
188
170
  * Check if we are logged into the ThoughtSpot cluster
189
- *
190
171
  * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
191
172
  */
192
173
  async function isLoggedIn(thoughtSpotHost: string): Promise<boolean> {
@@ -210,32 +191,24 @@ export function getReleaseVersion() {
210
191
  }
211
192
 
212
193
  /**
213
- * Return a promise that resolves with the session information when
214
- * authentication is successful. And info is available.
215
- *
194
+ * Return a promise that resolves with the session information when authentication is
195
+ * successful. And info is available.
216
196
  * @group Global methods
217
197
  */
218
198
  export function getSessionInfo(): Promise<any> {
219
199
  return sessionInfoPromise;
220
200
  }
221
201
 
222
- /**
223
- *
224
- * @param sessionDetails
225
- */
226
202
  export function initSession(sessionDetails: any) {
227
203
  sessionInfo = sessionDetails;
228
204
  initMixpanel(sessionInfo);
229
205
  sessionInfoResolver(sessionInfo);
230
206
  }
231
207
 
232
- const DUPLICATE_TOKEN_ERR = 'Duplicate token, please issue a new token every time getAuthToken callback is called.'
233
- + 'See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.';
208
+ const DUPLICATE_TOKEN_ERR =
209
+ 'Duplicate token, please issue a new token every time getAuthToken callback is called.' +
210
+ 'See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.';
234
211
  let prevAuthToken: string = null;
235
- /**
236
- *
237
- * @param authtoken
238
- */
239
212
  function alertForDuplicateToken(authtoken: string) {
240
213
  if (prevAuthToken === authtoken) {
241
214
  // eslint-disable-next-line no-alert
@@ -257,14 +230,18 @@ function isAtSSORedirectUrl(): boolean {
257
230
  */
258
231
  function removeSSORedirectUrlMarker(): void {
259
232
  // Note (sunny): This will leave a # around even if it was not in the URL
260
- // to begin with. Trying to remove the hash by changing window.location will
261
- // reload the page which we don't want. We'll live with adding an
262
- // unnecessary hash to the parent page URL until we find any use case where
263
- // that creates an issue.
264
- window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
233
+ // to begin with. Trying to remove the hash by changing window.location will reload
234
+ // the page which we don't want. We'll live with adding an unnecessary hash to the
235
+ // parent page URL until we find any use case where that creates an issue.
236
+ window.location.hash = window.location.hash.replace(
237
+ SSO_REDIRECTION_MARKER_GUID,
238
+ '',
239
+ );
265
240
  }
266
241
 
267
- export const getAuthenticaionToken = async (embedConfig: EmbedConfig): Promise<any> => {
242
+ export const getAuthenticaionToken = async (
243
+ embedConfig: EmbedConfig,
244
+ ): Promise<any> => {
268
245
  const { authEndpoint, getAuthToken } = embedConfig;
269
246
  let authToken = null;
270
247
  if (getAuthToken) {
@@ -279,30 +256,40 @@ export const getAuthenticaionToken = async (embedConfig: EmbedConfig): Promise<a
279
256
 
280
257
  /**
281
258
  * Perform token based authentication
282
- *
283
259
  * @param embedConfig The embed configuration
284
260
  */
285
- export const doTokenAuth = async (embedConfig: EmbedConfig): Promise<boolean> => {
261
+ export const doTokenAuth = async (
262
+ embedConfig: EmbedConfig,
263
+ ): Promise<boolean> => {
286
264
  const {
287
- thoughtSpotHost, username, authEndpoint, getAuthToken,
265
+ thoughtSpotHost,
266
+ username,
267
+ authEndpoint,
268
+ getAuthToken,
288
269
  } = embedConfig;
289
270
  if (!authEndpoint && !getAuthToken) {
290
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
271
+ throw new Error(
272
+ 'Either auth endpoint or getAuthToken function must be provided',
273
+ );
291
274
  }
292
275
  loggedInStatus = await isLoggedIn(thoughtSpotHost);
293
276
  if (!loggedInStatus) {
294
277
  const authToken = await getAuthenticaionToken(embedConfig);
295
278
  let resp;
296
279
  try {
297
- resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
280
+ resp = await fetchAuthPostService(
281
+ thoughtSpotHost,
282
+ username,
283
+ authToken,
284
+ );
298
285
  } catch (e) {
299
286
  resp = await fetchAuthService(thoughtSpotHost, username, authToken);
300
287
  }
301
288
  // token login issues a 302 when successful
302
289
  loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
303
290
  if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
304
- // When 3rd party cookie access is blocked, this will fail because
305
- // cookies will not be sent with the call.
291
+ // When 3rd party cookie access is blocked, this will fail because cookies will
292
+ // not be sent with the call.
306
293
  loggedInStatus = await isLoggedIn(thoughtSpotHost);
307
294
  }
308
295
  }
@@ -311,13 +298,16 @@ export const doTokenAuth = async (embedConfig: EmbedConfig): Promise<boolean> =>
311
298
 
312
299
  /**
313
300
  * Validate embedConfig parameters required for cookielessTokenAuth
314
- *
315
301
  * @param embedConfig The embed configuration
316
302
  */
317
- export const doCookielessTokenAuth = async (embedConfig: EmbedConfig): Promise<boolean> => {
303
+ export const doCookielessTokenAuth = async (
304
+ embedConfig: EmbedConfig,
305
+ ): Promise<boolean> => {
318
306
  const { authEndpoint, getAuthToken } = embedConfig;
319
307
  if (!authEndpoint && !getAuthToken) {
320
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
308
+ throw new Error(
309
+ 'Either auth endpoint or getAuthToken function must be provided',
310
+ );
321
311
  }
322
312
  return Promise.resolve(true);
323
313
  };
@@ -328,14 +318,19 @@ export const doCookielessTokenAuth = async (embedConfig: EmbedConfig): Promise<b
328
318
  *
329
319
  * Warning: This feature is primarily intended for developer testing. It is
330
320
  * strongly advised not to use this authentication method in production.
331
- *
332
321
  * @param embedConfig The embed configuration
333
322
  */
334
- export const doBasicAuth = async (embedConfig: EmbedConfig): Promise<boolean> => {
323
+ export const doBasicAuth = async (
324
+ embedConfig: EmbedConfig,
325
+ ): Promise<boolean> => {
335
326
  const { thoughtSpotHost, username, password } = embedConfig;
336
327
  const loggedIn = await isLoggedIn(thoughtSpotHost);
337
328
  if (!loggedIn) {
338
- const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
329
+ const response = await fetchBasicAuthService(
330
+ thoughtSpotHost,
331
+ username,
332
+ password,
333
+ );
339
334
  loggedInStatus = response.ok;
340
335
  if (embedConfig.detectCookieAccessSlow) {
341
336
  loggedInStatus = await isLoggedIn(thoughtSpotHost);
@@ -346,13 +341,11 @@ export const doBasicAuth = async (embedConfig: EmbedConfig): Promise<boolean> =>
346
341
  return loggedInStatus;
347
342
  };
348
343
 
349
- /**
350
- *
351
- * @param ssoURL
352
- * @param triggerContainer
353
- * @param triggerText
354
- */
355
- async function samlPopupFlow(ssoURL: string, triggerContainer: DOMSelector, triggerText: string) {
344
+ async function samlPopupFlow(
345
+ ssoURL: string,
346
+ triggerContainer: DOMSelector,
347
+ triggerText: string,
348
+ ) {
356
349
  const openPopup = () => {
357
350
  if (samlAuthWindow === null || samlAuthWindow.closed) {
358
351
  samlAuthWindow = window.open(
@@ -367,13 +360,15 @@ async function samlPopupFlow(ssoURL: string, triggerContainer: DOMSelector, trig
367
360
  authEE?.emit(AuthStatus.WAITING_FOR_POPUP);
368
361
  const containerEl = getDOMNode(triggerContainer);
369
362
  if (containerEl) {
370
- containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
363
+ containerEl.innerHTML =
364
+ '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
371
365
  const authElem = document.getElementById('ts-auth-btn');
372
366
  authElem.textContent = triggerText;
373
367
  authElem.addEventListener('click', openPopup, { once: true });
374
368
  }
375
- samlCompletionPromise = samlCompletionPromise
376
- || new Promise<void>((resolve, reject) => {
369
+ samlCompletionPromise =
370
+ samlCompletionPromise ||
371
+ new Promise<void>((resolve, reject) => {
377
372
  window.addEventListener('message', (e) => {
378
373
  if (e.data.type === EmbedEvent.SAMLComplete) {
379
374
  (e.source as Window).close();
@@ -388,11 +383,12 @@ async function samlPopupFlow(ssoURL: string, triggerContainer: DOMSelector, trig
388
383
 
389
384
  /**
390
385
  * Perform SAML authentication
391
- *
392
386
  * @param embedConfig The embed configuration
393
- * @param ssoEndPoint
394
387
  */
395
- const doSSOAuth = async (embedConfig: EmbedConfig, ssoEndPoint: string): Promise<void> => {
388
+ const doSSOAuth = async (
389
+ embedConfig: EmbedConfig,
390
+ ssoEndPoint: string,
391
+ ): Promise<void> => {
396
392
  const { thoughtSpotHost } = embedConfig;
397
393
  const loggedIn = await isLoggedIn(thoughtSpotHost);
398
394
  if (loggedIn) {
@@ -413,7 +409,11 @@ const doSSOAuth = async (embedConfig: EmbedConfig, ssoEndPoint: string): Promise
413
409
 
414
410
  const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
415
411
  if (embedConfig.inPopup) {
416
- await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
412
+ await samlPopupFlow(
413
+ ssoURL,
414
+ embedConfig.authTriggerContainer,
415
+ embedConfig.authTriggerText,
416
+ );
417
417
  loggedInStatus = true;
418
418
  return;
419
419
  }
@@ -423,18 +423,20 @@ const doSSOAuth = async (embedConfig: EmbedConfig, ssoEndPoint: string): Promise
423
423
 
424
424
  export const doSamlAuth = async (embedConfig: EmbedConfig) => {
425
425
  const { thoughtSpotHost } = embedConfig;
426
- // redirect for SSO, when the SSO authentication is done, this page will be
427
- // loaded again and the same JS will execute again.
426
+ // redirect for SSO, when the SSO authentication is done, this page will be loaded
427
+ // again and the same JS will execute again.
428
428
  const ssoRedirectUrl = embedConfig.inPopup
429
429
  ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
430
430
  : getRedirectUrl(
431
- window.location.href,
432
- SSO_REDIRECTION_MARKER_GUID,
433
- embedConfig.redirectPath,
434
- );
431
+ window.location.href,
432
+ SSO_REDIRECTION_MARKER_GUID,
433
+ embedConfig.redirectPath,
434
+ );
435
435
 
436
436
  // bring back the page to the same URL
437
- const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
437
+ const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(
438
+ encodeURIComponent(ssoRedirectUrl),
439
+ )}`;
438
440
 
439
441
  await doSSOAuth(embedConfig, ssoEndPoint);
440
442
  return loggedInStatus;
@@ -442,18 +444,21 @@ export const doSamlAuth = async (embedConfig: EmbedConfig) => {
442
444
 
443
445
  export const doOIDCAuth = async (embedConfig: EmbedConfig) => {
444
446
  const { thoughtSpotHost } = embedConfig;
445
- // redirect for SSO, when the SSO authentication is done, this page will be
446
- // loaded again and the same JS will execute again.
447
- const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
448
- ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
449
- : getRedirectUrl(
450
- window.location.href,
451
- SSO_REDIRECTION_MARKER_GUID,
452
- embedConfig.redirectPath,
453
- );
447
+ // redirect for SSO, when the SSO authentication is done, this page will be loaded
448
+ // again and the same JS will execute again.
449
+ const ssoRedirectUrl =
450
+ embedConfig.noRedirect || embedConfig.inPopup
451
+ ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
452
+ : getRedirectUrl(
453
+ window.location.href,
454
+ SSO_REDIRECTION_MARKER_GUID,
455
+ embedConfig.redirectPath,
456
+ );
454
457
 
455
458
  // bring back the page to the same URL
456
- const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
459
+ const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(
460
+ encodeURIComponent(ssoRedirectUrl),
461
+ )}`;
457
462
 
458
463
  await doSSOAuth(embedConfig, ssoEndPoint);
459
464
  return loggedInStatus;
@@ -468,10 +473,11 @@ export const logout = async (embedConfig: EmbedConfig): Promise<boolean> => {
468
473
 
469
474
  /**
470
475
  * Perform authentication on the ThoughtSpot cluster
471
- *
472
476
  * @param embedConfig The embed configuration
473
477
  */
474
- export const authenticate = async (embedConfig: EmbedConfig): Promise<boolean> => {
478
+ export const authenticate = async (
479
+ embedConfig: EmbedConfig,
480
+ ): Promise<boolean> => {
475
481
  const { authType } = embedConfig;
476
482
  switch (authType) {
477
483
  case AuthType.SSO:
@@ -59,7 +59,8 @@ describe('getThoughtSpotHost', () => {
59
59
  expect(
60
60
  getThoughtSpotHost({
61
61
  ...embedConfig,
62
- thoughtSpotHost: 'http://1.2.3.4:8088/v2/?foo=bar&baz=42#myhash',
62
+ thoughtSpotHost:
63
+ 'http://1.2.3.4:8088/v2/?foo=bar&baz=42#myhash',
63
64
  }),
64
65
  ).toBe('http://1.2.3.4:8088/v2');
65
66
  });
@@ -69,7 +70,8 @@ describe('getThoughtSpotHost', () => {
69
70
  getThoughtSpotHost({
70
71
  ...embedConfig,
71
72
  authType: AuthType.SAML,
72
- thoughtSpotHost: 'http://1.2.3.4:8088/v2/?foo=bar&baz=42#myhash',
73
+ thoughtSpotHost:
74
+ 'http://1.2.3.4:8088/v2/?foo=bar&baz=42#myhash',
73
75
  }),
74
76
  ).toBe('http://1.2.3.4:8088/v2');
75
77
  });
package/src/config.ts CHANGED
@@ -23,7 +23,6 @@ const urlRegex = new RegExp(
23
23
  /**
24
24
  * Parse and construct the ThoughtSpot hostname or IP address
25
25
  * from the embed configuration object.
26
- *
27
26
  * @param config
28
27
  */
29
28
  export const getThoughtSpotHost = (config: EmbedConfig): string => {
@@ -52,10 +51,9 @@ export const getV2BasePath = (config: EmbedConfig): string => {
52
51
 
53
52
  const tsHost = getThoughtSpotHost(config);
54
53
 
55
- // This is to handle when e2e's. Search is run on pods for
56
- // comp-blink-test-pipeline with baseUrl=https://localhost:8443.
57
- // This is to handle when the developer is developing in their local
58
- // environment.
54
+ // This is to handle when e2e's. Search is run on pods for comp-blink-test-pipeline
55
+ // with baseUrl=https://localhost:8443.
56
+ // This is to handle when the developer is developing in their local environment.
59
57
  if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
60
58
  return '';
61
59
  }
@@ -1,8 +1,6 @@
1
1
  import { AppEmbed, AppViewConfig, Page } from './app';
2
2
  import { init } from '../index';
3
- import {
4
- Action, AuthType, HostEvent, RuntimeFilterOp,
5
- } from '../types';
3
+ import { Action, AuthType, HostEvent, RuntimeFilterOp } from '../types';
6
4
  import {
7
5
  executeAfterWait,
8
6
  getDocumentBody,
@@ -13,7 +11,6 @@ import {
13
11
  defaultParams,
14
12
  defaultParamsForPinboardEmbed,
15
13
  defaultParamsWithoutHiddenActions,
16
- expectUrlMatchesWithParams,
17
14
  } from '../test/test-utils';
18
15
  import { version } from '../../package.json';
19
16
  import * as config from '../config';
@@ -47,8 +44,7 @@ describe('App embed tests', () => {
47
44
  const appEmbed = new AppEmbed(getRootEl(), defaultViewConfig);
48
45
  appEmbed.render();
49
46
  await executeAfterWait(() => {
50
- expectUrlMatchesWithParams(
51
- getIFrameSrc(),
47
+ expect(getIFrameSrc()).toBe(
52
48
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false${defaultParams}${defaultParamsPost}#/home`,
53
49
  );
54
50
  });
@@ -61,8 +57,7 @@ describe('App embed tests', () => {
61
57
  } as AppViewConfig);
62
58
  appEmbed.render();
63
59
  await executeAfterWait(() => {
64
- expectUrlMatchesWithParams(
65
- getIFrameSrc(),
60
+ expect(getIFrameSrc()).toBe(
66
61
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=false&profileAndHelpInNavBarHidden=false${defaultParams}${defaultParamsPost}#/home`,
67
62
  );
68
63
  });
@@ -75,8 +70,7 @@ describe('App embed tests', () => {
75
70
  } as AppViewConfig);
76
71
  appEmbed.render();
77
72
  await executeAfterWait(() => {
78
- expectUrlMatchesWithParams(
79
- getIFrameSrc(),
73
+ expect(getIFrameSrc()).toBe(
80
74
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=true${defaultParams}${defaultParamsPost}#/home`,
81
75
  );
82
76
  });
@@ -107,8 +101,7 @@ describe('App embed tests', () => {
107
101
  appEmbed.render();
108
102
 
109
103
  await executeAfterWait(() => {
110
- expectUrlMatchesWithParams(
111
- getIFrameSrc(),
104
+ expect(getIFrameSrc()).toBe(
112
105
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false${defaultParams}${defaultParamsPost}#/${route}`,
113
106
  );
114
107
  cleanUp();
@@ -124,8 +117,7 @@ describe('App embed tests', () => {
124
117
  } as AppViewConfig);
125
118
  appEmbed.render();
126
119
  await executeAfterWait(() => {
127
- expectUrlMatchesWithParams(
128
- getIFrameSrc(),
120
+ expect(getIFrameSrc()).toBe(
129
121
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false${defaultParams}${defaultParamsPost}#/foo/bar`,
130
122
  );
131
123
  });
@@ -146,8 +138,7 @@ describe('App embed tests', () => {
146
138
 
147
139
  appEmbed.render();
148
140
  await executeAfterWait(() => {
149
- expectUrlMatchesWithParams(
150
- getIFrameSrc(),
141
+ expect(getIFrameSrc()).toBe(
151
142
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=false&profileAndHelpInNavBarHidden=false&col1=sales&op1=EQ&val1=1000${defaultParams}${defaultParamsPost}#/home`,
152
143
  );
153
144
  });
@@ -164,8 +155,7 @@ describe('App embed tests', () => {
164
155
 
165
156
  appEmbed.render();
166
157
  await executeAfterWait(() => {
167
- expectUrlMatchesWithParams(
168
- getIFrameSrc(),
158
+ expect(getIFrameSrc()).toBe(
169
159
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=false&profileAndHelpInNavBarHidden=false&${defaultParamsWithoutHiddenActions}&disableAction=[%22save%22,%22update%22]&disableHint=Access%20denied&hideAction=[%22${Action.ReportError}%22,%22download%22]${defaultParamsPost}#/home`,
170
160
  );
171
161
  });
@@ -180,8 +170,7 @@ describe('App embed tests', () => {
180
170
 
181
171
  appEmbed.render();
182
172
  await executeAfterWait(() => {
183
- expectUrlMatchesWithParams(
184
- getIFrameSrc(),
173
+ expect(getIFrameSrc()).toBe(
185
174
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false${defaultParams}&tag=Finance${defaultParamsPost}#/home`,
186
175
  );
187
176
  });
@@ -195,8 +184,7 @@ describe('App embed tests', () => {
195
184
 
196
185
  appEmbed.render();
197
186
  await executeAfterWait(() => {
198
- expectUrlMatchesWithParams(
199
- getIFrameSrc(),
187
+ expect(getIFrameSrc()).toBe(
200
188
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&enableSearchAssist=true${defaultParams}${defaultParamsPost}#/home`,
201
189
  );
202
190
  });
@@ -205,7 +193,9 @@ describe('App embed tests', () => {
205
193
  describe('Navigate to Page API', () => {
206
194
  const path = 'pinboard/e0836cad-4fdf-42d4-bd97-567a6b2a6058';
207
195
  beforeEach(() => {
208
- jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
196
+ jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
197
+ () => 'http://tshost',
198
+ );
209
199
  });
210
200
 
211
201
  test('when app is AppEmbed after navigateToPage function call, new path should be set to iframe', async () => {
@@ -217,8 +207,7 @@ describe('App embed tests', () => {
217
207
  });
218
208
  await appEmbed.render();
219
209
  appEmbed.navigateToPage(path);
220
- expectUrlMatchesWithParams(
221
- getIFrameSrc(),
210
+ expect(getIFrameSrc()).toBe(
222
211
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&${defaultParamsForPinboardEmbed}${defaultParamsPost}#/${path}`,
223
212
  );
224
213
  });