@thoughtspot/visual-embed-sdk 1.32.0-alpha.0 → 1.32.0-alpha.2
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 +20 -0
- package/cjs/package.json +6 -4
- package/cjs/src/auth.d.ts +14 -16
- package/cjs/src/auth.d.ts.map +1 -1
- package/cjs/src/auth.js +57 -66
- package/cjs/src/auth.js.map +1 -1
- package/cjs/src/auth.spec.d.ts +12 -0
- package/cjs/src/auth.spec.d.ts.map +1 -1
- package/cjs/src/auth.spec.js +89 -67
- package/cjs/src/auth.spec.js.map +1 -1
- package/cjs/src/authToken.d.ts +1 -1
- package/cjs/src/authToken.d.ts.map +1 -1
- package/cjs/src/authToken.js +10 -4
- package/cjs/src/authToken.js.map +1 -1
- package/cjs/src/embed/app.spec.js +4 -2
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +2 -0
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/base.spec.js +1 -0
- package/cjs/src/embed/base.spec.js.map +1 -1
- package/cjs/src/embed/embed.spec.js +3 -0
- package/cjs/src/embed/embed.spec.js.map +1 -1
- package/cjs/src/embed/events.spec.js +3 -0
- package/cjs/src/embed/events.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +24 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +30 -0
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +33 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/pinboard.spec.js +3 -0
- package/cjs/src/embed/pinboard.spec.js.map +1 -1
- package/cjs/src/embed/sage.spec.js +3 -0
- package/cjs/src/embed/sage.spec.js.map +1 -1
- package/cjs/src/embed/search.spec.js +1 -0
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed-trigger.spec.js +3 -0
- package/cjs/src/embed/ts-embed-trigger.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +7 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +13 -3
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +23 -3
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +2 -1
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +2 -1
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +1 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/mixpanel-service.spec.js +7 -0
- package/cjs/src/mixpanel-service.spec.js.map +1 -1
- package/cjs/src/react/index.d.ts +1 -1
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +2 -1
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +6 -0
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/tokenizedFetch.d.ts +8 -0
- package/cjs/src/tokenizedFetch.d.ts.map +1 -1
- package/cjs/src/tokenizedFetch.js +8 -0
- package/cjs/src/tokenizedFetch.js.map +1 -1
- package/cjs/src/types.d.ts +49 -25
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +36 -25
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/authService/authService.d.ts +1 -0
- package/cjs/src/utils/authService/authService.d.ts.map +1 -1
- package/cjs/src/utils/authService/authService.js +1 -0
- package/cjs/src/utils/authService/authService.js.map +1 -1
- package/cjs/src/utils/authService/authService.spec.js +18 -5
- package/cjs/src/utils/authService/authService.spec.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.d.ts +15 -2
- package/cjs/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.js +39 -9
- package/cjs/src/utils/authService/tokenizedAuthService.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.spec.d.ts +2 -0
- package/cjs/src/utils/authService/tokenizedAuthService.spec.d.ts.map +1 -0
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js +32 -0
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -0
- package/cjs/src/utils/global-styles.d.ts +2 -0
- package/cjs/src/utils/global-styles.d.ts.map +1 -0
- package/cjs/src/utils/global-styles.js +44 -0
- package/cjs/src/utils/global-styles.js.map +1 -0
- package/cjs/src/utils/graphql/preview-service.d.ts +3 -0
- package/cjs/src/utils/graphql/preview-service.d.ts.map +1 -0
- package/cjs/src/utils/graphql/preview-service.js +30 -0
- package/cjs/src/utils/graphql/preview-service.js.map +1 -0
- package/cjs/src/utils/processData.js +2 -2
- package/cjs/src/utils/processData.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +3 -2
- package/cjs/src/utils/processData.spec.js.map +1 -1
- package/cjs/src/utils/sessionInfoService.d.ts +66 -0
- package/cjs/src/utils/sessionInfoService.d.ts.map +1 -0
- package/cjs/src/utils/sessionInfoService.js +92 -0
- package/cjs/src/utils/sessionInfoService.js.map +1 -0
- package/dist/src/auth.d.ts +14 -16
- package/dist/src/auth.d.ts.map +1 -1
- package/dist/src/auth.spec.d.ts +12 -0
- package/dist/src/auth.spec.d.ts.map +1 -1
- package/dist/src/authToken.d.ts +1 -1
- package/dist/src/authToken.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +24 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +7 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +2 -1
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/index.d.ts +1 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/tokenizedFetch.d.ts +8 -0
- package/dist/src/tokenizedFetch.d.ts.map +1 -1
- package/dist/src/types.d.ts +49 -25
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/authService/authService.d.ts +1 -0
- package/dist/src/utils/authService/authService.d.ts.map +1 -1
- package/dist/src/utils/authService/tokenizedAuthService.d.ts +15 -2
- package/dist/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/dist/src/utils/authService/tokenizedAuthService.spec.d.ts +2 -0
- package/dist/src/utils/authService/tokenizedAuthService.spec.d.ts.map +1 -0
- package/dist/src/utils/global-styles.d.ts +2 -0
- package/dist/src/utils/global-styles.d.ts.map +1 -0
- package/dist/src/utils/graphql/preview-service.d.ts +3 -0
- package/dist/src/utils/graphql/preview-service.d.ts.map +1 -0
- package/dist/src/utils/sessionInfoService.d.ts +66 -0
- package/dist/src/utils/sessionInfoService.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +298 -93
- package/dist/tsembed-react.js +298 -92
- package/dist/tsembed.es.js +306 -103
- package/dist/tsembed.js +306 -103
- package/dist/visual-embed-sdk-react-full.d.ts +169 -44
- package/dist/visual-embed-sdk-react.d.ts +169 -44
- package/dist/visual-embed-sdk.d.ts +169 -44
- package/lib/package.json +6 -4
- package/lib/src/auth.d.ts +14 -16
- package/lib/src/auth.d.ts.map +1 -1
- package/lib/src/auth.js +56 -63
- package/lib/src/auth.js.map +1 -1
- package/lib/src/auth.spec.d.ts +12 -0
- package/lib/src/auth.spec.d.ts.map +1 -1
- package/lib/src/auth.spec.js +88 -66
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/authToken.d.ts +1 -1
- package/lib/src/authToken.d.ts.map +1 -1
- package/lib/src/authToken.js +10 -4
- package/lib/src/authToken.js.map +1 -1
- package/lib/src/embed/app.spec.js +4 -2
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +3 -1
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +1 -0
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/embed.spec.js +2 -0
- package/lib/src/embed/embed.spec.js.map +1 -1
- package/lib/src/embed/events.spec.js +2 -0
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +24 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +30 -0
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +33 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.spec.js +2 -0
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/sage.spec.js +2 -0
- package/lib/src/embed/sage.spec.js.map +1 -1
- package/lib/src/embed/search.spec.js +1 -0
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/ts-embed-trigger.spec.js +2 -0
- package/lib/src/embed/ts-embed-trigger.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +7 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +13 -3
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +23 -3
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +2 -1
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +1 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/mixpanel-service.spec.js +7 -0
- package/lib/src/mixpanel-service.spec.js.map +1 -1
- package/lib/src/react/index.d.ts +1 -1
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +1 -1
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +6 -0
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/tokenizedFetch.d.ts +8 -0
- package/lib/src/tokenizedFetch.d.ts.map +1 -1
- package/lib/src/tokenizedFetch.js +8 -0
- package/lib/src/tokenizedFetch.js.map +1 -1
- package/lib/src/types.d.ts +49 -25
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +36 -25
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/authService.d.ts +1 -0
- package/lib/src/utils/authService/authService.d.ts.map +1 -1
- package/lib/src/utils/authService/authService.js +1 -0
- package/lib/src/utils/authService/authService.js.map +1 -1
- package/lib/src/utils/authService/authService.spec.js +18 -5
- package/lib/src/utils/authService/authService.spec.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.d.ts +15 -2
- package/lib/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.js +37 -8
- package/lib/src/utils/authService/tokenizedAuthService.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.spec.d.ts +2 -0
- package/lib/src/utils/authService/tokenizedAuthService.spec.d.ts.map +1 -0
- package/lib/src/utils/authService/tokenizedAuthService.spec.js +29 -0
- package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -0
- package/lib/src/utils/global-styles.d.ts +2 -0
- package/lib/src/utils/global-styles.d.ts.map +1 -0
- package/lib/src/utils/global-styles.js +40 -0
- package/lib/src/utils/global-styles.js.map +1 -0
- package/lib/src/utils/graphql/preview-service.d.ts +3 -0
- package/lib/src/utils/graphql/preview-service.d.ts.map +1 -0
- package/lib/src/utils/graphql/preview-service.js +26 -0
- package/lib/src/utils/graphql/preview-service.js.map +1 -0
- package/lib/src/utils/processData.js +3 -3
- package/lib/src/utils/processData.js.map +1 -1
- package/lib/src/utils/processData.spec.js +3 -2
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/sessionInfoService.d.ts +66 -0
- package/lib/src/utils/sessionInfoService.d.ts.map +1 -0
- package/lib/src/utils/sessionInfoService.js +85 -0
- package/lib/src/utils/sessionInfoService.js.map +1 -0
- package/lib/src/visual-embed-sdk.d.ts +174 -45
- package/package.json +6 -4
- package/src/auth.spec.ts +92 -72
- package/src/auth.ts +57 -75
- package/src/authToken.ts +9 -4
- package/src/embed/app.spec.ts +4 -2
- package/src/embed/base.spec.ts +1 -0
- package/src/embed/base.ts +3 -0
- package/src/embed/embed.spec.ts +2 -0
- package/src/embed/events.spec.ts +2 -0
- package/src/embed/liveboard.spec.ts +36 -0
- package/src/embed/liveboard.ts +61 -1
- package/src/embed/pinboard.spec.ts +2 -0
- package/src/embed/sage.spec.ts +3 -0
- package/src/embed/search.spec.ts +1 -0
- package/src/embed/ts-embed-trigger.spec.ts +3 -0
- package/src/embed/ts-embed.spec.ts +26 -3
- package/src/embed/ts-embed.ts +15 -4
- package/src/index.ts +2 -1
- package/src/mixpanel-service.spec.ts +12 -3
- package/src/mixpanel-service.ts +3 -1
- package/src/react/index.spec.tsx +7 -0
- package/src/react/index.tsx +1 -0
- package/src/tokenizedFetch.ts +8 -0
- package/src/types.ts +55 -29
- package/src/utils/authService/authService.spec.ts +18 -5
- package/src/utils/authService/authService.ts +1 -0
- package/src/utils/authService/tokenizedAuthService.spec.ts +36 -0
- package/src/utils/authService/tokenizedAuthService.ts +38 -8
- package/src/utils/global-styles.ts +40 -0
- package/src/utils/graphql/preview-service.ts +31 -0
- package/src/utils/processData.spec.ts +3 -2
- package/src/utils/processData.ts +3 -3
- package/src/utils/sessionInfoService.ts +101 -0
package/src/auth.spec.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as authInstance from './auth';
|
|
2
|
-
import * as
|
|
3
|
-
import * as tokenAuthService from './utils/authService/tokenizedAuthService';
|
|
4
|
-
import * as checkReleaseVersionInBetaInstance from './utils';
|
|
5
|
-
import * as mixPanelService from './mixpanel-service';
|
|
2
|
+
import * as authTokenService from './authToken';
|
|
6
3
|
import * as EmbedConfig from './embed/embedConfig';
|
|
7
|
-
import
|
|
4
|
+
import * as mixPanelService from './mixpanel-service';
|
|
8
5
|
import { executeAfterWait } from './test/test-utils';
|
|
9
|
-
import {
|
|
6
|
+
import { AuthType, EmbedEvent } from './types';
|
|
7
|
+
import * as checkReleaseVersionInBetaInstance from './utils';
|
|
8
|
+
import * as authService from './utils/authService/authService';
|
|
9
|
+
import * as tokenAuthService from './utils/authService/tokenizedAuthService';
|
|
10
|
+
import { logger } from './utils/logger';
|
|
11
|
+
import * as SessionService from './utils/sessionInfoService';
|
|
10
12
|
|
|
11
13
|
const thoughtSpotHost = 'http://localhost:3000';
|
|
12
14
|
const username = 'tsuser';
|
|
@@ -18,7 +20,7 @@ export const embedConfig: any = {
|
|
|
18
20
|
thoughtSpotHost,
|
|
19
21
|
username,
|
|
20
22
|
authEndpoint: 'auth',
|
|
21
|
-
authType: AuthType.
|
|
23
|
+
authType: AuthType.TrustedAuthToken,
|
|
22
24
|
getAuthToken: jest.fn(() => Promise.resolve(token)),
|
|
23
25
|
}),
|
|
24
26
|
doTokenAuthWithCookieDetect: {
|
|
@@ -112,31 +114,47 @@ export const mockSessionInfo = {
|
|
|
112
114
|
},
|
|
113
115
|
};
|
|
114
116
|
|
|
117
|
+
export const mockSessionInfoApiResponse = {
|
|
118
|
+
userGUID: '1234',
|
|
119
|
+
releaseVersion: 'test',
|
|
120
|
+
configInfo: {
|
|
121
|
+
isPublicUser: false,
|
|
122
|
+
mixpanelConfig: {
|
|
123
|
+
production: true,
|
|
124
|
+
devSdkKey: 'devKey',
|
|
125
|
+
prodSdkKey: 'prodKey',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
115
130
|
describe('Unit test for auth', () => {
|
|
116
131
|
beforeEach(() => {
|
|
132
|
+
jest.resetAllMocks();
|
|
117
133
|
global.fetch = window.fetch;
|
|
118
134
|
});
|
|
119
135
|
afterEach(() => {
|
|
120
|
-
resetCachedAuthToken();
|
|
136
|
+
authTokenService.resetCachedAuthToken();
|
|
137
|
+
SessionService.resetCachedSessionInfo();
|
|
121
138
|
});
|
|
122
139
|
test('endpoints, SAML_LOGIN_TEMPLATE', () => {
|
|
123
140
|
const ssoTemplateUrl = authService.EndPoints.SAML_LOGIN_TEMPLATE(thoughtSpotHost);
|
|
124
141
|
expect(ssoTemplateUrl).toBe(`/callosum/v1/saml/login?targetURLPath=${thoughtSpotHost}`);
|
|
125
142
|
});
|
|
126
143
|
|
|
127
|
-
test('when session info giving response', async () => {
|
|
128
|
-
jest.spyOn(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
expect(sessionInfo).
|
|
144
|
+
test('when session info giving response, it is cached', async () => {
|
|
145
|
+
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockResolvedValueOnce(mockSessionInfoApiResponse);
|
|
146
|
+
const sessionInfo = await SessionService.getSessionInfo();
|
|
147
|
+
expect(sessionInfo.mixpanelToken).toEqual('prodKey');
|
|
148
|
+
expect(sessionInfo.isPublicUser).toEqual(false);
|
|
149
|
+
await SessionService.getSessionInfo();
|
|
150
|
+
expect(tokenAuthService.fetchSessionInfoService).toHaveBeenCalledTimes(1);
|
|
132
151
|
});
|
|
133
152
|
|
|
134
153
|
test('Disable mixpanel when disableSDKTracking flag is set', () => {
|
|
135
|
-
jest.clearAllMocks();
|
|
136
|
-
jest.resetAllMocks();
|
|
137
154
|
jest.spyOn(mixPanelService, 'initMixpanel');
|
|
155
|
+
jest.spyOn(SessionService, 'getSessionInfo').mockReturnValue(mockSessionInfo);
|
|
138
156
|
jest.spyOn(EmbedConfig, 'getEmbedConfig').mockReturnValue({ disableSDKTracking: true });
|
|
139
|
-
authInstance.
|
|
157
|
+
authInstance.postLoginService();
|
|
140
158
|
expect(mixPanelService.initMixpanel).not.toBeCalled();
|
|
141
159
|
});
|
|
142
160
|
|
|
@@ -163,28 +181,22 @@ describe('Unit test for auth', () => {
|
|
|
163
181
|
});
|
|
164
182
|
|
|
165
183
|
test('doTokenAuth: when user is loggedIn', async () => {
|
|
166
|
-
jest.spyOn(
|
|
167
|
-
|
|
168
|
-
status: 200,
|
|
169
|
-
}));
|
|
170
|
-
jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
|
|
171
|
-
jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
|
|
184
|
+
const getAuthenticationTokenMock = jest.spyOn(authTokenService, 'getAuthenticationToken');
|
|
185
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockImplementation(async () => true);
|
|
172
186
|
await authInstance.doTokenAuth(embedConfig.doTokenAuthSuccess('authToken'));
|
|
173
|
-
expect(
|
|
187
|
+
expect(authTokenService.getAuthenticationToken).not.toBeCalled();
|
|
174
188
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
189
|
+
getAuthenticationTokenMock.mockRestore();
|
|
175
190
|
});
|
|
176
191
|
|
|
177
192
|
test('doTokenAuth: when user is not loggedIn & getAuthToken have response', async () => {
|
|
178
|
-
jest.spyOn(tokenAuthService, '
|
|
179
|
-
jest.spyOn(authService, 'fetchAuthTokenService').mockImplementation(() => ({
|
|
180
|
-
text: () => Promise.resolve('abc'),
|
|
181
|
-
}));
|
|
193
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockImplementation(async () => false);
|
|
182
194
|
jest.spyOn(authService, 'fetchAuthService').mockImplementation(() => Promise.resolve({
|
|
183
195
|
status: 200,
|
|
196
|
+
ok: true,
|
|
184
197
|
}));
|
|
185
198
|
jest.spyOn(authService, 'verifyTokenService').mockResolvedValueOnce(true);
|
|
186
199
|
await authInstance.doTokenAuth(embedConfig.doTokenAuthSuccess('authToken2'));
|
|
187
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
188
200
|
expect(authService.fetchAuthService).toBeCalledWith(
|
|
189
201
|
thoughtSpotHost,
|
|
190
202
|
username,
|
|
@@ -193,26 +205,25 @@ describe('Unit test for auth', () => {
|
|
|
193
205
|
});
|
|
194
206
|
|
|
195
207
|
test('doTokenAuth: when user is not loggedIn & getAuthToken not present, isLoggedIn should called', async () => {
|
|
196
|
-
jest.spyOn(tokenAuthService, '
|
|
197
|
-
jest.spyOn(authService, 'fetchAuthTokenService').mockImplementation(() =>
|
|
208
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockImplementation(async () => false);
|
|
209
|
+
jest.spyOn(authService, 'fetchAuthTokenService').mockImplementation(() => ({
|
|
210
|
+
text: () => Promise.resolve('abc'),
|
|
211
|
+
}));
|
|
198
212
|
jest.spyOn(authService, 'fetchAuthService').mockImplementation(() => Promise.resolve({
|
|
199
213
|
status: 200,
|
|
200
214
|
ok: true,
|
|
201
215
|
}));
|
|
202
216
|
jest.spyOn(authService, 'verifyTokenService').mockResolvedValueOnce(true);
|
|
203
217
|
await authInstance.doTokenAuth(embedConfig.doTokenAuthFailureWithoutGetAuthToken);
|
|
218
|
+
expect(authService.fetchAuthTokenService).toBeCalledWith('auth');
|
|
204
219
|
await executeAfterWait(() => {
|
|
205
220
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
206
|
-
expect(
|
|
207
|
-
expect(authService.fetchAuthService).toBeCalledWith(
|
|
208
|
-
thoughtSpotHost,
|
|
209
|
-
username,
|
|
210
|
-
'authToken2',
|
|
211
|
-
);
|
|
221
|
+
expect(authService.fetchAuthService).toBeCalledWith(thoughtSpotHost, username, 'abc');
|
|
212
222
|
});
|
|
213
223
|
});
|
|
214
224
|
|
|
215
225
|
test('doTokenAuth: Should raise error when duplicate token is used', async () => {
|
|
226
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockImplementation(async () => false);
|
|
216
227
|
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockResolvedValue({
|
|
217
228
|
status: 401,
|
|
218
229
|
});
|
|
@@ -254,8 +265,10 @@ describe('Unit test for auth', () => {
|
|
|
254
265
|
ok: true,
|
|
255
266
|
}));
|
|
256
267
|
jest.spyOn(authService, 'verifyTokenService').mockResolvedValueOnce(true);
|
|
268
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockResolvedValueOnce(false);
|
|
269
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockResolvedValueOnce(false);
|
|
257
270
|
const isLoggedIn = await authInstance.doTokenAuth(embedConfig.doTokenAuthWithCookieDetect);
|
|
258
|
-
expect(tokenAuthService.
|
|
271
|
+
expect(tokenAuthService.isActiveService).toHaveBeenCalledTimes(2);
|
|
259
272
|
expect(isLoggedIn).toBe(false);
|
|
260
273
|
});
|
|
261
274
|
|
|
@@ -278,7 +291,6 @@ describe('Unit test for auth', () => {
|
|
|
278
291
|
expect(await authInstance.doTokenAuth(embedConfig.doTokenAuthSuccess('authToken2'))).toBe(
|
|
279
292
|
true,
|
|
280
293
|
);
|
|
281
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
282
294
|
expect(authService.fetchAuthPostService).toBeCalledWith(
|
|
283
295
|
thoughtSpotHost,
|
|
284
296
|
username,
|
|
@@ -297,20 +309,9 @@ describe('Unit test for auth', () => {
|
|
|
297
309
|
});
|
|
298
310
|
|
|
299
311
|
it('when user is loggedIn', async () => {
|
|
300
|
-
spyOn(
|
|
301
|
-
jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
|
|
302
|
-
jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
|
|
303
|
-
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockImplementation(
|
|
304
|
-
async () => ({
|
|
305
|
-
json: () => mockSessionInfo,
|
|
306
|
-
status: 200,
|
|
307
|
-
}),
|
|
308
|
-
);
|
|
312
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockResolvedValueOnce(true);
|
|
309
313
|
await authInstance.doBasicAuth(embedConfig.doBasicAuth);
|
|
310
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
311
314
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
312
|
-
expect(authInstance.getSessionDetails).toBeCalled();
|
|
313
|
-
expect(authInstance.initSession).toBeCalled();
|
|
314
315
|
});
|
|
315
316
|
|
|
316
317
|
it('when user is not loggedIn', async () => {
|
|
@@ -321,7 +322,7 @@ describe('Unit test for auth', () => {
|
|
|
321
322
|
}));
|
|
322
323
|
|
|
323
324
|
await authInstance.doBasicAuth(embedConfig.doBasicAuth);
|
|
324
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
325
|
+
// expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
325
326
|
expect(authService.fetchBasicAuthService).toBeCalled();
|
|
326
327
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
327
328
|
});
|
|
@@ -349,10 +350,8 @@ describe('Unit test for auth', () => {
|
|
|
349
350
|
status: 200,
|
|
350
351
|
}),
|
|
351
352
|
);
|
|
352
|
-
jest.spyOn(
|
|
353
|
-
jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
|
|
353
|
+
jest.spyOn(tokenAuthService, 'isActiveService').mockReturnValue(true);
|
|
354
354
|
await authInstance.doSamlAuth(embedConfig.doSamlAuth);
|
|
355
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
356
355
|
expect(window.location.hash).toBe('');
|
|
357
356
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
358
357
|
});
|
|
@@ -360,7 +359,6 @@ describe('Unit test for auth', () => {
|
|
|
360
359
|
it('when user is not loggedIn & isAtSSORedirectUrl is true', async () => {
|
|
361
360
|
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockImplementation(() => Promise.reject());
|
|
362
361
|
await authInstance.doSamlAuth(embedConfig.doSamlAuth);
|
|
363
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
364
362
|
expect(window.location.hash).toBe('');
|
|
365
363
|
expect(authInstance.loggedInStatus).toBe(false);
|
|
366
364
|
});
|
|
@@ -374,7 +372,6 @@ describe('Unit test for auth', () => {
|
|
|
374
372
|
});
|
|
375
373
|
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockImplementation(() => Promise.reject());
|
|
376
374
|
await authInstance.doSamlAuth(embedConfig.doSamlAuth);
|
|
377
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
378
375
|
expect(global.window.location.href).toBe(samalLoginUrl);
|
|
379
376
|
});
|
|
380
377
|
|
|
@@ -387,14 +384,9 @@ describe('Unit test for auth', () => {
|
|
|
387
384
|
});
|
|
388
385
|
spyOn(authInstance, 'samlCompletionPromise');
|
|
389
386
|
global.window.open = jest.fn();
|
|
390
|
-
jest.spyOn(tokenAuthService, '
|
|
391
|
-
.
|
|
392
|
-
.
|
|
393
|
-
json: () => mockSessionInfo,
|
|
394
|
-
status: 200,
|
|
395
|
-
}));
|
|
396
|
-
jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
|
|
397
|
-
jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
|
|
387
|
+
jest.spyOn(tokenAuthService, 'isActiveService')
|
|
388
|
+
.mockReturnValueOnce(false)
|
|
389
|
+
.mockReturnValueOnce(true);
|
|
398
390
|
expect(await authInstance.samlCompletionPromise).not.toBe(null);
|
|
399
391
|
expect(
|
|
400
392
|
await authInstance.doSamlAuth({
|
|
@@ -404,15 +396,13 @@ describe('Unit test for auth', () => {
|
|
|
404
396
|
document.getElementById('ts-auth-btn').click();
|
|
405
397
|
window.postMessage({ type: EmbedEvent.SAMLComplete }, '*');
|
|
406
398
|
await authInstance.samlCompletionPromise;
|
|
407
|
-
expect(
|
|
408
|
-
expect(authInstance.getSessionDetails).toBeCalled();
|
|
409
|
-
expect(authInstance.initSession).toBeCalled();
|
|
399
|
+
expect(authInstance.loggedInStatus).toBe(true);
|
|
410
400
|
});
|
|
411
401
|
});
|
|
412
402
|
|
|
413
403
|
describe('doOIDCAuth', () => {
|
|
414
404
|
afterEach(() => {
|
|
415
|
-
resetCachedAuthToken();
|
|
405
|
+
authTokenService.resetCachedAuthToken();
|
|
416
406
|
delete global.window;
|
|
417
407
|
global.window = Object.create(originalWindow);
|
|
418
408
|
global.window.open = jest.fn();
|
|
@@ -422,7 +412,6 @@ describe('Unit test for auth', () => {
|
|
|
422
412
|
it('when user is not loggedIn & isAtSSORedirectUrl is true', async () => {
|
|
423
413
|
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockImplementation(() => Promise.reject());
|
|
424
414
|
await authInstance.doOIDCAuth(embedConfig.doOidcAuth);
|
|
425
|
-
expect(tokenAuthService.fetchSessionInfoService).toBeCalled();
|
|
426
415
|
expect(window.location.hash).toBe('');
|
|
427
416
|
expect(authInstance.loggedInStatus).toBe(false);
|
|
428
417
|
});
|
|
@@ -465,6 +454,7 @@ describe('Unit test for auth', () => {
|
|
|
465
454
|
|
|
466
455
|
it('authenticate: when authType is Basic', async () => {
|
|
467
456
|
jest.spyOn(authInstance, 'doBasicAuth');
|
|
457
|
+
jest.spyOn(authService, 'fetchBasicAuthService').mockImplementation(() => Promise.resolve({ status: 200, ok: true }));
|
|
468
458
|
await authInstance.authenticate(embedConfig.basicAuthSuccess);
|
|
469
459
|
expect(authInstance.doBasicAuth).toBeCalled();
|
|
470
460
|
expect(authInstance.loggedInStatus).toBe(true);
|
|
@@ -481,6 +471,7 @@ describe('Unit test for auth', () => {
|
|
|
481
471
|
});
|
|
482
472
|
|
|
483
473
|
it('doCookielessTokenAuth should resolve to true if valid token is passed', async () => {
|
|
474
|
+
jest.clearAllMocks();
|
|
484
475
|
jest.spyOn(authService, 'verifyTokenService').mockResolvedValueOnce(true);
|
|
485
476
|
const isLoggedIn = await authInstance.doCookielessTokenAuth(
|
|
486
477
|
embedConfig.doCookielessAuth('testToken'),
|
|
@@ -500,11 +491,11 @@ describe('Unit test for auth', () => {
|
|
|
500
491
|
authInstance.setAuthEE(testObject as any);
|
|
501
492
|
expect(authInstance.getAuthEE()).toBe(testObject);
|
|
502
493
|
});
|
|
503
|
-
it('getSessionDetails returns the correct details given sessionInfo', () => {
|
|
494
|
+
it('getSessionDetails returns the correct details given sessionInfo', async () => {
|
|
504
495
|
jest.clearAllMocks();
|
|
505
496
|
jest.restoreAllMocks();
|
|
506
497
|
|
|
507
|
-
|
|
498
|
+
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockReturnValue({
|
|
508
499
|
userGUID: '1234',
|
|
509
500
|
releaseVersion: '1',
|
|
510
501
|
configInfo: {
|
|
@@ -515,13 +506,14 @@ describe('Unit test for auth', () => {
|
|
|
515
506
|
},
|
|
516
507
|
},
|
|
517
508
|
});
|
|
509
|
+
const details = await SessionService.getSessionInfo();
|
|
518
510
|
expect(details).toEqual(
|
|
519
511
|
expect.objectContaining({
|
|
520
512
|
mixpanelToken: 'devKey',
|
|
521
513
|
}),
|
|
522
514
|
);
|
|
523
515
|
|
|
524
|
-
|
|
516
|
+
jest.spyOn(tokenAuthService, 'fetchSessionInfoService').mockReturnValue({
|
|
525
517
|
configInfo: {
|
|
526
518
|
mixpanelConfig: {
|
|
527
519
|
devSdkKey: 'devKey',
|
|
@@ -530,10 +522,38 @@ describe('Unit test for auth', () => {
|
|
|
530
522
|
},
|
|
531
523
|
},
|
|
532
524
|
});
|
|
525
|
+
|
|
526
|
+
SessionService.resetCachedSessionInfo();
|
|
527
|
+
const details2 = await SessionService.getSessionInfo();
|
|
533
528
|
expect(details2).toEqual(
|
|
534
529
|
expect.objectContaining({
|
|
535
530
|
mixpanelToken: 'prodKey',
|
|
536
531
|
}),
|
|
537
532
|
);
|
|
538
533
|
});
|
|
534
|
+
|
|
535
|
+
test('notifyAuthSuccess if getSessionInfo returns data', async () => {
|
|
536
|
+
const dummyInfo = { test: 'dummy' };
|
|
537
|
+
jest.spyOn(SessionService, 'getSessionInfo').mockResolvedValueOnce(dummyInfo);
|
|
538
|
+
jest.spyOn(logger, 'error').mockResolvedValueOnce(true);
|
|
539
|
+
const emitSpy = jest.fn();
|
|
540
|
+
authInstance.setAuthEE({ emit: emitSpy } as any);
|
|
541
|
+
await authInstance.notifyAuthSuccess();
|
|
542
|
+
expect(logger.error).not.toBeCalled();
|
|
543
|
+
expect(emitSpy).toBeCalledWith(authInstance.AuthStatus.SUCCESS, dummyInfo);
|
|
544
|
+
authInstance.setAuthEE(null);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
test('notifyAuthSuccess if getSessionInfo fails', async () => {
|
|
548
|
+
jest.spyOn(SessionService, 'getSessionInfo').mockImplementation(() => {
|
|
549
|
+
throw new Error('error');
|
|
550
|
+
});
|
|
551
|
+
jest.spyOn(logger, 'error');
|
|
552
|
+
const emitSpy = jest.fn();
|
|
553
|
+
authInstance.setAuthEE({ emit: emitSpy } as any);
|
|
554
|
+
await authInstance.notifyAuthSuccess();
|
|
555
|
+
expect(logger.error).toBeCalled();
|
|
556
|
+
expect(emitSpy).not.toBeCalled();
|
|
557
|
+
authInstance.setAuthEE(null);
|
|
558
|
+
});
|
|
539
559
|
});
|
package/src/auth.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { getAuthenticationToken, resetCachedAuthToken } from './authToken';
|
|
3
|
+
import { getEmbedConfig } from './embed/embedConfig';
|
|
2
4
|
import { initMixpanel } from './mixpanel-service';
|
|
3
5
|
import {
|
|
4
|
-
AuthType, DOMSelector, EmbedConfig, EmbedEvent,
|
|
6
|
+
AuthType, DOMSelector, EmbedConfig, EmbedEvent,
|
|
5
7
|
} from './types';
|
|
6
8
|
import { getDOMNode, getRedirectUrl } from './utils';
|
|
7
9
|
import {
|
|
8
|
-
|
|
10
|
+
EndPoints,
|
|
11
|
+
fetchAuthPostService,
|
|
9
12
|
fetchAuthService,
|
|
10
13
|
fetchBasicAuthService,
|
|
11
14
|
fetchLogoutService,
|
|
12
|
-
fetchAuthPostService,
|
|
13
|
-
EndPoints,
|
|
14
15
|
} from './utils/authService';
|
|
15
|
-
import {
|
|
16
|
+
import { isActiveService } from './utils/authService/tokenizedAuthService';
|
|
16
17
|
import { logger } from './utils/logger';
|
|
17
|
-
import {
|
|
18
|
+
import { getSessionInfo } from './utils/sessionInfoService';
|
|
18
19
|
|
|
19
20
|
// eslint-disable-next-line import/no-mutable-exports
|
|
20
21
|
export let loggedInStatus = false;
|
|
@@ -22,22 +23,11 @@ export let loggedInStatus = false;
|
|
|
22
23
|
export let samlAuthWindow: Window = null;
|
|
23
24
|
// eslint-disable-next-line import/no-mutable-exports
|
|
24
25
|
export let samlCompletionPromise: Promise<void> = null;
|
|
25
|
-
|
|
26
|
-
let sessionInfoResolver: (value: sessionInfoInterface) => void = null;
|
|
27
|
-
const sessionInfoPromise = new Promise((resolve: (value: sessionInfoInterface) => void) => {
|
|
28
|
-
sessionInfoResolver = resolve;
|
|
29
|
-
});
|
|
26
|
+
|
|
30
27
|
let releaseVersion = '';
|
|
31
28
|
|
|
32
29
|
export const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
|
|
33
30
|
|
|
34
|
-
interface sessionInfoInterface {
|
|
35
|
-
userGUID: any;
|
|
36
|
-
isPublicUser: any;
|
|
37
|
-
mixpanelToken: any;
|
|
38
|
-
[key: string]: any;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
31
|
/**
|
|
42
32
|
* Enum for auth failure types. This is the parameter passed to the listner
|
|
43
33
|
* of {@link AuthStatus.FAILURE}.
|
|
@@ -170,12 +160,17 @@ export function notifyAuthSDKSuccess(): void {
|
|
|
170
160
|
/**
|
|
171
161
|
*
|
|
172
162
|
*/
|
|
173
|
-
export function notifyAuthSuccess(): void {
|
|
163
|
+
export async function notifyAuthSuccess(): Promise<void> {
|
|
174
164
|
if (!authEE) {
|
|
175
165
|
logger.error('SDK not initialized');
|
|
176
166
|
return;
|
|
177
167
|
}
|
|
178
|
-
|
|
168
|
+
try {
|
|
169
|
+
const sessionInfo = await getSessionInfo();
|
|
170
|
+
authEE.emit(AuthStatus.SUCCESS, sessionInfo);
|
|
171
|
+
} catch (e) {
|
|
172
|
+
logger.error('Failed to get session info');
|
|
173
|
+
}
|
|
179
174
|
}
|
|
180
175
|
|
|
181
176
|
/**
|
|
@@ -201,68 +196,49 @@ export function notifyLogout(): void {
|
|
|
201
196
|
authEE.emit(AuthStatus.LOGOUT);
|
|
202
197
|
}
|
|
203
198
|
|
|
204
|
-
export const initSession = (sessionDetails: sessionInfoInterface) => {
|
|
205
|
-
const embedConfig = getEmbedConfig();
|
|
206
|
-
if (sessionInfo == null) {
|
|
207
|
-
sessionInfo = sessionDetails;
|
|
208
|
-
if (!embedConfig.disableSDKTracking) {
|
|
209
|
-
initMixpanel(sessionInfo);
|
|
210
|
-
}
|
|
211
|
-
sessionInfoResolver(sessionInfo);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
export const getSessionDetails = (sessionInfoResp: any): sessionInfoInterface => {
|
|
216
|
-
const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
|
|
217
|
-
const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
|
|
218
|
-
const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
|
|
219
|
-
? prodMixpanelToken
|
|
220
|
-
: devMixpanelToken;
|
|
221
|
-
return {
|
|
222
|
-
userGUID: sessionInfoResp.userGUID,
|
|
223
|
-
mixpanelToken,
|
|
224
|
-
isPublicUser: sessionInfoResp.configInfo.isPublicUser,
|
|
225
|
-
releaseVersion: sessionInfoResp.releaseVersion,
|
|
226
|
-
clusterId: sessionInfoResp.configInfo.selfClusterId,
|
|
227
|
-
clusterName: sessionInfoResp.configInfo.selfClusterName,
|
|
228
|
-
...sessionInfoResp,
|
|
229
|
-
};
|
|
230
|
-
};
|
|
231
|
-
|
|
232
199
|
/**
|
|
233
200
|
* Check if we are logged into the ThoughtSpot cluster
|
|
234
201
|
* @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
|
|
235
202
|
*/
|
|
236
203
|
async function isLoggedIn(thoughtSpotHost: string): Promise<boolean> {
|
|
237
|
-
const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
|
|
238
|
-
let response = null;
|
|
239
204
|
try {
|
|
240
|
-
response = await
|
|
241
|
-
|
|
242
|
-
const sessionDetails = getSessionDetails(sessionInfoResp);
|
|
243
|
-
// Store user session details from session info
|
|
244
|
-
initSession(sessionDetails);
|
|
245
|
-
releaseVersion = sessionInfoResp.releaseVersion;
|
|
205
|
+
const response = await isActiveService(thoughtSpotHost);
|
|
206
|
+
return response;
|
|
246
207
|
} catch (e) {
|
|
247
208
|
return false;
|
|
248
209
|
}
|
|
249
|
-
return response.status === 200;
|
|
250
210
|
}
|
|
251
211
|
|
|
252
212
|
/**
|
|
253
|
-
*
|
|
213
|
+
* Services to be called after the login is successful,
|
|
214
|
+
* This should be called after the cookie is set for cookie auth or
|
|
215
|
+
* after the token is set for cookieless.
|
|
216
|
+
*
|
|
217
|
+
* @return {Promise<void>}
|
|
218
|
+
* @example
|
|
219
|
+
* ```js
|
|
220
|
+
* await postLoginService();
|
|
221
|
+
* ```
|
|
222
|
+
* @version SDK: 1.28.3 | ThoughtSpot: *
|
|
254
223
|
*/
|
|
255
|
-
export function
|
|
256
|
-
|
|
224
|
+
export async function postLoginService(): Promise<void> {
|
|
225
|
+
try {
|
|
226
|
+
const sessionInfo = await getSessionInfo();
|
|
227
|
+
releaseVersion = sessionInfo.releaseVersion;
|
|
228
|
+
const embedConfig = getEmbedConfig();
|
|
229
|
+
if (!embedConfig.disableSDKTracking) {
|
|
230
|
+
initMixpanel(sessionInfo);
|
|
231
|
+
}
|
|
232
|
+
} catch (e) {
|
|
233
|
+
logger.error('Post login services failed.', e.message);
|
|
234
|
+
}
|
|
257
235
|
}
|
|
258
236
|
|
|
259
237
|
/**
|
|
260
|
-
* Return
|
|
261
|
-
* authentication is successful. And info is available.
|
|
262
|
-
* @group Global methods
|
|
238
|
+
* Return releaseVersion if available
|
|
263
239
|
*/
|
|
264
|
-
export function
|
|
265
|
-
return
|
|
240
|
+
export function getReleaseVersion() {
|
|
241
|
+
return releaseVersion;
|
|
266
242
|
}
|
|
267
243
|
|
|
268
244
|
/**
|
|
@@ -296,8 +272,15 @@ export const doTokenAuth = async (embedConfig: EmbedConfig): Promise<boolean> =>
|
|
|
296
272
|
throw new Error('Either auth endpoint or getAuthToken function must be provided');
|
|
297
273
|
}
|
|
298
274
|
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
275
|
+
|
|
299
276
|
if (!loggedInStatus) {
|
|
300
|
-
|
|
277
|
+
let authToken: string;
|
|
278
|
+
try {
|
|
279
|
+
authToken = await getAuthenticationToken(embedConfig);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
loggedInStatus = false;
|
|
282
|
+
throw e;
|
|
283
|
+
}
|
|
301
284
|
let resp;
|
|
302
285
|
try {
|
|
303
286
|
resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
|
|
@@ -386,15 +369,14 @@ async function samlPopupFlow(ssoURL: string, triggerContainer: DOMSelector, trig
|
|
|
386
369
|
authElem.textContent = triggerText;
|
|
387
370
|
authElem.addEventListener('click', openPopup, { once: true });
|
|
388
371
|
}
|
|
389
|
-
samlCompletionPromise = samlCompletionPromise
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
});
|
|
372
|
+
samlCompletionPromise = samlCompletionPromise || new Promise<void>((resolve, reject) => {
|
|
373
|
+
window.addEventListener('message', (e) => {
|
|
374
|
+
if (e.data.type === EmbedEvent.SAMLComplete) {
|
|
375
|
+
(e.source as Window).close();
|
|
376
|
+
resolve();
|
|
377
|
+
}
|
|
397
378
|
});
|
|
379
|
+
});
|
|
398
380
|
|
|
399
381
|
authEE?.once(AuthEvent.TRIGGER_SSO_POPUP, openPopup);
|
|
400
382
|
return samlCompletionPromise;
|
|
@@ -476,7 +458,7 @@ export const logout = async (embedConfig: EmbedConfig): Promise<boolean> => {
|
|
|
476
458
|
const { thoughtSpotHost } = embedConfig;
|
|
477
459
|
await fetchLogoutService(thoughtSpotHost);
|
|
478
460
|
resetCachedAuthToken();
|
|
479
|
-
const thoughtspotIframes = document.querySelectorAll(
|
|
461
|
+
const thoughtspotIframes = document.querySelectorAll("[data-ts-iframe='true']");
|
|
480
462
|
if (thoughtspotIframes?.length) {
|
|
481
463
|
thoughtspotIframes.forEach((el) => {
|
|
482
464
|
el.parentElement.innerHTML = embedConfig.loginFailedMessage;
|
package/src/authToken.ts
CHANGED
|
@@ -10,7 +10,7 @@ const INVALID_TOKEN_ERR = 'Invalid token received form token callback or authTok
|
|
|
10
10
|
let cachedAuthToken: string | null = null;
|
|
11
11
|
|
|
12
12
|
// This method can be used to get the authToken using the embedConfig
|
|
13
|
-
export
|
|
13
|
+
export async function getAuthenticationToken(embedConfig: EmbedConfig): Promise<string> {
|
|
14
14
|
// Since we don't have token validation enabled , we cannot tell if the
|
|
15
15
|
// cached token is valid or not. So we will always fetch a new token.
|
|
16
16
|
if (cachedAuthToken && !embedConfig.disableTokenVerification) {
|
|
@@ -34,12 +34,17 @@ export const getAuthenticationToken = async (embedConfig: EmbedConfig): Promise<
|
|
|
34
34
|
authToken = await response.text();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
try {
|
|
38
|
+
// this will throw error if the token is not valid
|
|
39
|
+
await validateAuthToken(embedConfig, authToken);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
logger.error(`Received invalid token from getAuthToken callback or authToken endpoint. Error : ${e.message}`);
|
|
42
|
+
throw e;
|
|
43
|
+
}
|
|
39
44
|
|
|
40
45
|
cachedAuthToken = authToken;
|
|
41
46
|
return authToken;
|
|
42
|
-
}
|
|
47
|
+
}
|
|
43
48
|
|
|
44
49
|
const validateAuthToken = async (
|
|
45
50
|
embedConfig: EmbedConfig,
|
package/src/embed/app.spec.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { version } from '../../package.json';
|
|
|
24
24
|
import * as config from '../config';
|
|
25
25
|
import { TsEmbed, V1Embed } from './ts-embed';
|
|
26
26
|
import { logger } from '../utils/logger';
|
|
27
|
+
import * as auth from '../auth';
|
|
27
28
|
|
|
28
29
|
const defaultViewConfig = {
|
|
29
30
|
frameParams: {
|
|
@@ -40,6 +41,7 @@ beforeAll(() => {
|
|
|
40
41
|
thoughtSpotHost,
|
|
41
42
|
authType: AuthType.None,
|
|
42
43
|
});
|
|
44
|
+
jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve({}));
|
|
43
45
|
(window as any).ResizeObserver = window.ResizeObserver
|
|
44
46
|
|| jest.fn().mockImplementation(() => ({
|
|
45
47
|
disconnect: jest.fn(),
|
|
@@ -72,13 +74,13 @@ describe('App embed tests', () => {
|
|
|
72
74
|
test('should hide the primary nav bar', async () => {
|
|
73
75
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
74
76
|
...defaultViewConfig,
|
|
75
|
-
showPrimaryNavbar:
|
|
77
|
+
showPrimaryNavbar: false,
|
|
76
78
|
} as AppViewConfig);
|
|
77
79
|
appEmbed.render();
|
|
78
80
|
await executeAfterWait(() => {
|
|
79
81
|
expectUrlMatchesWithParams(
|
|
80
82
|
getIFrameSrc(),
|
|
81
|
-
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=
|
|
83
|
+
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false${defaultParams}${defaultParamsPost}#/home`,
|
|
82
84
|
);
|
|
83
85
|
});
|
|
84
86
|
});
|
package/src/embed/base.spec.ts
CHANGED
package/src/embed/base.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
notifyLogout,
|
|
29
29
|
setAuthEE,
|
|
30
30
|
AuthEventEmitter,
|
|
31
|
+
postLoginService,
|
|
31
32
|
} from '../auth';
|
|
32
33
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
33
34
|
import { getEmbedConfig, setEmbedConfig } from './embedConfig';
|
|
@@ -73,6 +74,8 @@ export const handleAuth = (): Promise<boolean> => {
|
|
|
73
74
|
if (!isLoggedIn) {
|
|
74
75
|
notifyAuthFailure(AuthFailureType.SDK);
|
|
75
76
|
} else {
|
|
77
|
+
// Post login service is called after successful login.
|
|
78
|
+
postLoginService();
|
|
76
79
|
notifyAuthSDKSuccess();
|
|
77
80
|
}
|
|
78
81
|
},
|