UNPKG

@splitsoftware/splitio-commons

Version:
68 lines (67 loc) 2.98 kB
"use strict"; 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;