• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoughtspot / visual-embed-sdk / #2436

18 Sep 2025 03:49PM UTC coverage: 94.033% (-0.08%) from 94.116%
#2436

Pull #314

shivam-kumar-ts
 SCAL-249159 ensuring the token type is a string before proceeding to token validation
Pull Request #314: SCAL-249159 ensuring the token type is a string before proceeding token validation

1226 of 1387 branches covered (88.39%)

Branch coverage included in aggregate %.

1 of 4 new or added lines in 1 file covered. (25.0%)

1 existing line in 1 file now uncovered.

2966 of 3071 relevant lines covered (96.58%)

84.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.06
/src/authToken.ts
1
import { ERROR_MESSAGE } from './errors';
26✔
2
import { EmbedConfig } from './types';
3
import { getValueFromWindow, storeValueInWindow } from './utils';
26✔
4
import { fetchAuthTokenService, verifyTokenService } from './utils/authService/authService';
26✔
5
import { logger } from './utils/logger';
26✔
6

7
const cacheAuthTokenKey = 'cachedAuthToken';
26✔
8

9
const getCacheAuthToken = (): string | null => getValueFromWindow(cacheAuthTokenKey);
46✔
10
const storeAuthTokenInCache = (token: string): void => {
26✔
11
    storeValueInWindow(cacheAuthTokenKey, token);
296✔
12
};
13

14
// This method can be used to get the authToken using the embedConfig
15
/**
16
 *
17
 * @param embedConfig
18
 */
19
export async function getAuthenticationToken(embedConfig: EmbedConfig): Promise<string> {
26✔
20
    const cachedAuthToken = getCacheAuthToken();
26✔
21
    // Since we don't have token validation enabled , we cannot tell if the
22
    // cached token is valid or not. So we will always fetch a new token.
23
    if (cachedAuthToken && !embedConfig.disableTokenVerification) {
26✔
24
        let isCachedTokenStillValid;
25
        try {
3✔
26
            isCachedTokenStillValid = await validateAuthToken(embedConfig, cachedAuthToken, true);
3✔
27
        } catch {
28
            isCachedTokenStillValid = false;
1✔
29
        }
30

31
        if (isCachedTokenStillValid) return cachedAuthToken;
3✔
32
    }
33

34
    const { authEndpoint, getAuthToken } = embedConfig;
24✔
35

36
    let authToken = null;
24✔
37
    if (getAuthToken) {
24✔
38
        authToken = await getAuthToken();
22✔
39
    } else {
40
        const response = await fetchAuthTokenService(authEndpoint);
2✔
41
        authToken = await response.text();
2✔
42
    }
43

44
    try {
17✔
45
        // this will throw error if the token is not valid
46
        await validateAuthToken(embedConfig, authToken);
17✔
47
    } catch (e) {
48
        logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${e.message}`);
2✔
49
        throw e;
2✔
50
    }
51

52
    storeAuthTokenInCache(authToken);
15✔
53
    return authToken;
15✔
54
}
55

56
const validateAuthToken = async (
26✔
57
    embedConfig: EmbedConfig,
58
    authToken: string,
59
    suppressAlert?: boolean,
60
): Promise<boolean> => {
61
    const cachedAuthToken = getCacheAuthToken();
20✔
62
    // even if token verification is disabled, we will still validate 
63
    // the token type to ensure that the token is valid and not expired
64
    if(typeof authToken !== 'string') {
20!
NEW
65
        const errorMessage = 'Expected getAuthToken to return a string, but received a ' + typeof authToken + '.';
×
NEW
66
        logger.error(errorMessage);
×
NEW
67
        throw new Error(errorMessage);
×
68
    }
69

70
    if (embedConfig.disableTokenVerification) {
20✔
71
        logger.info('Token verification is disabled. Assuming token is valid.');
1✔
72
        return true;
1✔
73
    }
74
    try {
19✔
75
        const isTokenValid = await verifyTokenService(embedConfig.thoughtSpotHost, authToken);
19✔
76
        if (isTokenValid) return true;
19✔
77
    } catch {
UNCOV
78
        return false;
×
79
    }
80

81
    if (cachedAuthToken && cachedAuthToken === authToken) {
3✔
82
        if (!embedConfig.suppressErrorAlerts && !suppressAlert) {
2✔
83
            // eslint-disable-next-line no-alert
84
            alert(ERROR_MESSAGE.DUPLICATE_TOKEN_ERR);
1✔
85
        }
86
        throw new Error(ERROR_MESSAGE.DUPLICATE_TOKEN_ERR);
2✔
87
    } else {
88
        throw new Error(ERROR_MESSAGE.INVALID_TOKEN_ERROR);
1✔
89
    }
90
};
91

92
/**
93
 * Resets the auth token and a new token will be fetched on the next request.
94
 * @example
95
 * ```js
96
 * resetCachedAuthToken();
97
 * ```
98
 * @version SDK: 1.28.0 | ThoughtSpot: *
99
 * @group Authentication / Init
100
 */
101
export const resetCachedAuthToken = (): void => {
26✔
102
    storeAuthTokenInCache(null);
281✔
103
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc