@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
68 lines (67 loc) • 2.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.authProviderFactory = void 0;
var AuthClient_1 = require("../sync/streaming/AuthClient");
var Backoff_1 = require("../utils/Backoff");
var constants_1 = require("../logger/constants");
var constants_2 = require("../utils/constants");
var SKEW_SECONDS = 30;
function isExpired(credential) {
return Date.now() / 1000 + SKEW_SECONDS >= credential.decodedToken.exp;
}
/**
* Factory of AuthProvider, which provides JWT credentials for authenticated HTTP requests.
* Credentials are fetched lazily on demand, cached in memory, and retried with backoff on failure.
*/
function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
var urls = settings.urls, log = settings.log;
function fetchAuth() {
var url = "".concat(urls.auth, "/api/v3/auth?capabilities=config");
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_2.TOKEN), false, true);
}
var authenticate = (0, AuthClient_1.authenticateFactory)(fetchAuth);
var backoff = new Backoff_1.Backoff(fetchCredential);
var cachedCredential;
var inFlightPromise;
var stopped = false;
function fetchCredential() {
return authenticate().then(function (credential) {
log.info(constants_1.LOG_PREFIX_SYNC_AUTH + 'credential fetched successfully');
cachedCredential = credential;
inFlightPromise = undefined;
backoff.reset();
return credential;
}).catch(function (error) {
// Avoid rejected promises and unnecessary retries after stop()
if (stopped)
return cachedCredential;
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
log.error(constants_1.LOG_PREFIX_SYNC_AUTH + 'non-retryable error fetching credential (status ' + error.statusCode + '): ' + error.message);
inFlightPromise = undefined;
throw error;
}
log.warn(constants_1.LOG_PREFIX_SYNC_AUTH + 'credential fetch failed (attempt ' + (backoff.attempts + 1) + '). Error: ' + error.message);
return backoff.scheduleCallAsync();
});
}
return {
credential: function () {
if (cachedCredential && !isExpired(cachedCredential)) {
return Promise.resolve(cachedCredential);
}
if (cachedCredential)
log.debug(constants_1.LOG_PREFIX_SYNC_AUTH + 'cached credential expired');
return inFlightPromise || (inFlightPromise = fetchCredential());
},
invalidate: function () {
cachedCredential = undefined;
},
stop: function () {
stopped = true;
cachedCredential = undefined;
inFlightPromise = undefined;
backoff.reset();
}
};
}
exports.authProviderFactory = authProviderFactory;