@thoughtspot/visual-embed-sdk 1.29.0-alpha.3 → 1.29.0-alpha.authRefactor

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 (75) hide show
  1. package/cjs/package.json +1 -2
  2. package/cjs/src/embed/liveboard.js +1 -1
  3. package/cjs/src/embed/liveboard.js.map +1 -1
  4. package/cjs/src/embed/sage.d.ts +1 -1
  5. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  6. package/cjs/src/embed/ts-embed.js +0 -9
  7. package/cjs/src/embed/ts-embed.js.map +1 -1
  8. package/cjs/src/embed/ts-embed.spec.js +0 -18
  9. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  10. package/cjs/src/types.d.ts +1 -22
  11. package/cjs/src/types.d.ts.map +1 -1
  12. package/cjs/src/types.js +0 -3
  13. package/cjs/src/types.js.map +1 -1
  14. package/cjs/src/utils/sessionInfoService.d.ts +66 -0
  15. package/cjs/src/utils/sessionInfoService.d.ts.map +1 -0
  16. package/cjs/src/utils/sessionInfoService.js +92 -0
  17. package/cjs/src/utils/sessionInfoService.js.map +1 -0
  18. package/dist/src/embed/sage.d.ts +1 -1
  19. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  20. package/dist/src/types.d.ts +1 -22
  21. package/dist/src/types.d.ts.map +1 -1
  22. package/dist/tsembed-react.es.js +2 -14
  23. package/dist/tsembed-react.js +2 -14
  24. package/dist/tsembed.es.js +2 -14
  25. package/dist/tsembed.js +2 -14
  26. package/dist/visual-embed-sdk-react-full.d.ts +2 -23
  27. package/dist/visual-embed-sdk-react.d.ts +2 -23
  28. package/dist/visual-embed-sdk.d.ts +2 -23
  29. package/lib/package.json +1 -2
  30. package/lib/src/embed/liveboard.js +1 -1
  31. package/lib/src/embed/liveboard.js.map +1 -1
  32. package/lib/src/embed/sage.d.ts +1 -1
  33. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  34. package/lib/src/embed/ts-embed.js +0 -9
  35. package/lib/src/embed/ts-embed.js.map +1 -1
  36. package/lib/src/embed/ts-embed.spec.js +0 -18
  37. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  38. package/lib/src/types.d.ts +1 -22
  39. package/lib/src/types.d.ts.map +1 -1
  40. package/lib/src/types.js +0 -3
  41. package/lib/src/types.js.map +1 -1
  42. package/lib/src/utils/sessionInfoService.d.ts +66 -0
  43. package/lib/src/utils/sessionInfoService.d.ts.map +1 -0
  44. package/lib/src/utils/sessionInfoService.js +85 -0
  45. package/lib/src/utils/sessionInfoService.js.map +1 -0
  46. package/lib/src/visual-embed-sdk.d.ts +2 -23
  47. package/package.json +1 -3
  48. package/src/auth.spec.ts +66 -72
  49. package/src/auth.ts +43 -59
  50. package/src/authToken.ts +10 -4
  51. package/src/embed/app.spec.ts +4 -2
  52. package/src/embed/base.spec.ts +1 -0
  53. package/src/embed/base.ts +3 -0
  54. package/src/embed/embed.spec.ts +2 -0
  55. package/src/embed/events.spec.ts +2 -0
  56. package/src/embed/liveboard.spec.ts +2 -0
  57. package/src/embed/pinboard.spec.ts +2 -0
  58. package/src/embed/sage.spec.ts +3 -0
  59. package/src/embed/sage.ts +1 -1
  60. package/src/embed/search.spec.ts +1 -0
  61. package/src/embed/ts-embed-trigger.spec.ts +3 -0
  62. package/src/embed/ts-embed.spec.ts +8 -22
  63. package/src/embed/ts-embed.ts +1 -9
  64. package/src/index.ts +2 -1
  65. package/src/mixpanel-service.spec.ts +4 -3
  66. package/src/mixpanel-service.ts +3 -1
  67. package/src/react/index.spec.tsx +7 -0
  68. package/src/react/index.tsx +1 -0
  69. package/src/types.ts +0 -21
  70. package/src/utils/authService/authService.spec.ts +9 -4
  71. package/src/utils/authService/authService.ts +1 -0
  72. package/src/utils/authService/tokenizedAuthService.ts +38 -8
  73. package/src/utils/processData.spec.ts +3 -2
  74. package/src/utils/processData.ts +1 -3
  75. package/src/utils/sessionInfoService.ts +101 -0
@@ -7,23 +7,33 @@ import { EndPoints } from './authService';
7
7
  * @param url
8
8
  * @param options
9
9
  */
10
- function tokenisedFailureLoggedFetch(url: string, options: RequestInit = {}): Promise<Response> {
10
+ function tokenizedFailureLoggedFetch(url: string, options: RequestInit = {}): Promise<Response> {
11
11
  return tokenizedFetch(url, options).then(async (r) => {
12
12
  if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
13
- logger.error('Failure', await r.text?.());
13
+ logger.error(`Failed to fetch ${url}`, await r.text?.());
14
14
  }
15
15
  return r;
16
16
  });
17
17
  }
18
18
 
19
19
  /**
20
+ * Fetches the session info from the ThoughtSpot server.
20
21
  *
21
- * @param authVerificationUrl
22
+ * @param thoughtspotHost
23
+ * @returns {Promise<any>}
24
+ * @example
25
+ * ```js
26
+ * const response = await sessionInfoService();
27
+ * ```
22
28
  */
23
- export function fetchSessionInfoService(authVerificationUrl: string): Promise<any> {
24
- return tokenisedFailureLoggedFetch(authVerificationUrl, {
25
- credentials: 'include',
26
- });
29
+ export async function fetchSessionInfoService(thoughtspotHost: string): Promise<any> {
30
+ const sessionInfoPath = `${thoughtspotHost}${EndPoints.SESSION_INFO}`;
31
+ const response = await tokenizedFailureLoggedFetch(sessionInfoPath);
32
+ if (!response.ok) {
33
+ throw new Error(`Failed to fetch session info: ${response.statusText}`);
34
+ }
35
+ const data = await response.json();
36
+ return data;
27
37
  }
28
38
 
29
39
  /**
@@ -31,7 +41,7 @@ export function fetchSessionInfoService(authVerificationUrl: string): Promise<an
31
41
  * @param thoughtSpotHost
32
42
  */
33
43
  export async function fetchLogoutService(thoughtSpotHost: string): Promise<any> {
34
- return tokenisedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
44
+ return tokenizedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
35
45
  credentials: 'include',
36
46
  method: 'POST',
37
47
  headers: {
@@ -39,3 +49,23 @@ export async function fetchLogoutService(thoughtSpotHost: string): Promise<any>
39
49
  },
40
50
  });
41
51
  }
52
+
53
+ /**
54
+ * Is active service to check if the user is logged in.
55
+ *
56
+ * @param thoughtSpotHost
57
+ * @version SDK: 1.28.4 | ThoughtSpot: *
58
+ */
59
+ export async function isActiveService(thoughtSpotHost: string): Promise<boolean> {
60
+ const isActiveUrl = `${thoughtSpotHost}${EndPoints.IS_ACTIVE}`;
61
+ try {
62
+ const res = await tokenizedFetch(isActiveUrl, {
63
+ credentials: 'include',
64
+ });
65
+ return res.ok;
66
+ } catch (e) {
67
+ logger.warn(`Is Logged In Service failed : ${e.message}`);
68
+ }
69
+
70
+ return false;
71
+ }
@@ -4,9 +4,11 @@ import * as auth from '../auth';
4
4
  import * as base from '../embed/base';
5
5
  import * as embedConfigInstance from '../embed/embedConfig';
6
6
  import { EmbedEvent, AuthType } from '../types';
7
+ import * as sessionInfoService from './sessionInfoService';
7
8
 
8
9
  describe('Unit test for process data', () => {
9
10
  beforeAll(() => {
11
+ jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve({}));
10
12
  base.init({
11
13
  thoughtSpotHost: 'https://tshost',
12
14
  authType: AuthType.None,
@@ -58,15 +60,14 @@ describe('Unit test for process data', () => {
58
60
  isPublicUser: false,
59
61
  };
60
62
  const e = { type: EmbedEvent.AuthInit, data: sessionInfo };
61
- jest.spyOn(auth, 'initSession').mockReturnValue(null);
62
63
  jest.spyOn(base, 'notifyAuthSuccess');
64
+ jest.spyOn(sessionInfoService, 'getSessionInfoSync').mockReturnValue(sessionInfo);
63
65
  expect(processDataInstance.processEventData(e.type, e, '', null)).toEqual({
64
66
  type: e.type,
65
67
  data: {
66
68
  userGUID: sessionInfo.userGUID,
67
69
  },
68
70
  });
69
- expect(auth.initSession).toBeCalledWith(sessionInfo);
70
71
  expect(base.notifyAuthSuccess).toBeCalled();
71
72
  });
72
73
 
@@ -5,7 +5,7 @@ import {
5
5
  notifyAuthSuccess,
6
6
  notifyLogout,
7
7
  } from '../embed/base';
8
- import { AuthFailureType, initSession } from '../auth';
8
+ import { AuthFailureType } from '../auth';
9
9
  import { AuthType, CustomActionPayload, EmbedEvent } from '../types';
10
10
  import { AnswerService } from './graphql/answerService/answerService';
11
11
  import { resetCachedAuthToken } from '../authToken';
@@ -34,8 +34,6 @@ export function processCustomAction(e: any, thoughtSpotHost: string) {
34
34
  * @param e
35
35
  */
36
36
  function processAuthInit(e: any) {
37
- // Store user session details sent by app.
38
- initSession(e.data);
39
37
  notifyAuthSuccess();
40
38
 
41
39
  // Expose only allowed details (eg: userGUID) back to SDK users.
@@ -0,0 +1,101 @@
1
+ import { getEmbedConfig } from '../embed/embedConfig';
2
+ import { fetchSessionInfoService } from './authService';
3
+
4
+ export type SessionInfo = {
5
+ releaseVersion: string;
6
+ userGUID: string;
7
+ currentOrgId: number;
8
+ privileges: string[];
9
+ mixpanelToken: string;
10
+ isPublicUser: boolean;
11
+ clusterId: string;
12
+ clusterName: string;
13
+ [key: string]: any;
14
+ };
15
+
16
+ let sessionInfo: null | SessionInfo = null;
17
+
18
+ /**
19
+ * Returns the session info object and caches it for future use.
20
+ * Once fetched the session info object is cached and returned from the cache on
21
+ * subsequent calls.
22
+ *
23
+ * @example ```js
24
+ * const sessionInfo = await getSessionInfo();
25
+ * console.log(sessionInfo);
26
+ * ```
27
+ * @version SDK: 1.28.3 | ThoughtSpot: *
28
+ * @returns {Promise<SessionInfo>} The session info object.
29
+ */
30
+ export async function getSessionInfo(): Promise<SessionInfo> {
31
+ if (!sessionInfo) {
32
+ const host = getEmbedConfig().thoughtSpotHost;
33
+ const sessionResponse = await fetchSessionInfoService(host);
34
+ const processedSessionInfo = getSessionDetails(sessionResponse);
35
+ sessionInfo = processedSessionInfo;
36
+ }
37
+ return sessionInfo;
38
+ }
39
+
40
+ /**
41
+ * Returns the cached session info object. If the client is not authenticated the
42
+ * function will return null.
43
+ *
44
+ * @example ```js
45
+ * const sessionInfo = getSessionInfoSync();
46
+ * if (sessionInfo) {
47
+ * console.log(sessionInfo);
48
+ * } else {
49
+ * console.log('Not authenticated');
50
+ * }
51
+ * ```
52
+ * @returns {SessionInfo | null} The session info object.
53
+ * @version SDK: 1.28.3 | ThoughtSpot: *
54
+ */
55
+ export function getSessionInfoSync(): SessionInfo | null {
56
+ return sessionInfo;
57
+ }
58
+
59
+ /**
60
+ * Processes the session info response and returns the session info object.
61
+ *
62
+ * @param sessionInfoResp {any} Response from the session info API.
63
+ * @returns {SessionInfo} The session info object.
64
+ * @example ```js
65
+ * const sessionInfoResp = await fetch(sessionInfoPath);
66
+ * const sessionInfo = getSessionDetails(sessionInfoResp);
67
+ * console.log(sessionInfo);
68
+ * ```
69
+ * @version SDK: 1.28.3 | ThoughtSpot: *
70
+ */
71
+ export const getSessionDetails = (sessionInfoResp: any): SessionInfo => {
72
+ const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
73
+ const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
74
+ const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
75
+ ? prodMixpanelToken
76
+ : devMixpanelToken;
77
+ return {
78
+ userGUID: sessionInfoResp.userGUID,
79
+ mixpanelToken,
80
+ isPublicUser: sessionInfoResp.configInfo.isPublicUser,
81
+ releaseVersion: sessionInfoResp.releaseVersion,
82
+ clusterId: sessionInfoResp.configInfo.selfClusterId,
83
+ clusterName: sessionInfoResp.configInfo.selfClusterName,
84
+ ...sessionInfoResp,
85
+ };
86
+ };
87
+
88
+ /**
89
+ * Resets the cached session info object and forces a new fetch on the next call.
90
+ *
91
+ * @example ```js
92
+ * resetCachedSessionInfo();
93
+ * const sessionInfo = await getSessionInfo();
94
+ * console.log(sessionInfo);
95
+ * ```
96
+ * @version SDK: 1.28.3 | ThoughtSpot ts7.april.cl, 7.2.1
97
+ * @returns {void}
98
+ */
99
+ export function resetCachedSessionInfo(): void {
100
+ sessionInfo = null;
101
+ }