@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
45 lines (38 loc) • 2.27 kB
text/typescript
import { IRequestOptions, IResponse, ISecureSplitHttpClient, NetworkError } from './types';
import { ISettings } from '../types';
import { IPlatform } from '../sdkFactory/types';
import { splitHttpClientFactory } from './splitHttpClient';
import { authProviderFactory } from './authProvider';
import { ITelemetryTracker } from '../trackers/types';
/**
* Factory of Secure HTTP client, which authenticates requests using a JWT token.
* On 401 responses, invalidates the cached credential and retries once with a fresh token.
*
* @param settings - SDK settings
* @param platform - object containing environment-specific dependencies
* @param fetchAuth - function to fetch auth credentials from the /v2/auth endpoint
*/
export function secureSplitHttpClientFactory(settings: ISettings, platform: Pick<IPlatform, 'getOptions' | 'getFetch'>, telemetryTracker: ITelemetryTracker): ISecureSplitHttpClient {
const splitHttpClient = splitHttpClientFactory(settings, platform);
const authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
function makeRequest(url: string, options: IRequestOptions | undefined, latencyTracker: ((error?: NetworkError) => void) | undefined, logErrorsAsInfo: boolean | undefined, token: string): Promise<IResponse> {
return splitHttpClient(url, { ...options, headers: { ...options?.headers, Authorization: `Bearer ${token}` } }, latencyTracker, logErrorsAsInfo, true);
}
const httpClient = function (url: string, options?: IRequestOptions, latencyTracker?: (error?: NetworkError) => void, logErrorsAsInfo?: boolean): Promise<IResponse> {
return authProvider.credential().then(credential => {
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, credential.token)
.catch((error: NetworkError) => {
if (error.statusCode === 401) {
// retry once for 401, in case the token has just expired
authProvider.invalidate();
return authProvider.credential().then(newCredential => {
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, newCredential.token);
});
}
throw error;
});
});
};
httpClient.stop = () => authProvider.stop();
return httpClient;
}