UNPKG

@authx/http-proxy-resource

Version:

The AuthX proxy for resources is a flexible HTTP proxy designed to sit in front of a resource.

111 lines 3.96 kB
import { EventEmitter } from "events"; export class AuthXKeyCache extends EventEmitter { _config; _fetchTimeout = null; _fetchAbortController = null; _fetchAbortTimeout = null; active = false; keys = null; constructor(config) { super(); this._config = config; } _fetch = async () => { this._fetchTimeout = null; // Don't fetch unless the cache is active. if (!this.active) { return; } this._fetchAbortController = new AbortController(); this._fetchAbortTimeout = setTimeout(() => { if (this._fetchAbortController) { this._fetchAbortController.abort(); } }, (this._config.authxPublicKeyRefreshRequestTimeout || 30) * 1000); try { // Fetch the keys from AuthX. const response = await (await fetch(this._config.authxUrl + "/graphql", { signal: this._fetchAbortController.signal, method: "POST", headers: { "Content-Type": "application/json", }, body: '{"query": "query { keys }"}', })).json(); if (typeof response !== "object" || response === null) { throw new Error("The response from AuthX is not an object."); } // Make sure we don't have any errors. if ("errors" in response && response.errors && Array.isArray(response.errors) && response.errors[0]) throw new Error(response.errors[0]); if (!("data" in response) || response.data === null || typeof response.data !== "object" || !("keys" in response.data) || !Array.isArray(response.data.keys)) { throw new Error("The response from AuthX is missing keys."); } const keys = response.data.keys; // Ensure that there is at least one valid key in the response. if (!keys || !Array.isArray(keys) || !keys.length || !keys.every((k) => typeof k === "string")) { throw new Error("An array of least one key must be returned by AuthX."); } if (!this.active) { return; } // Cache the keys. this.keys = keys; // Fire off a ready event. this.emit("ready"); // Fetch again in 1 minute. if (this.active && !this._fetchTimeout) { this._fetchTimeout = setTimeout(this._fetch, (this._config.authxPublicKeyRefreshInterval || 60) * 1000); } } catch (error) { this.emit("error", error); // Fetch again in 10 seconds. if (this.active && !this._fetchTimeout) { this._fetchTimeout = setTimeout(this._fetch, (this._config.authxPublicKeyRetryInterval || 10) * 1000); } } finally { this._fetchAbortController = null; clearTimeout(this._fetchAbortTimeout); this._fetchAbortTimeout = null; } }; start() { if (this.active) return; this.active = true; this._fetch(); } stop() { if (!this.active) return; this.active = false; // Clear any pending timeouts. const timeout = this._fetchTimeout; if (timeout) { clearTimeout(timeout); } const abortTimeout = this._fetchAbortTimeout; if (abortTimeout) { clearTimeout(abortTimeout); } // Abort any in-flight key requests. const abort = this._fetchAbortController; if (abort) { abort.abort(); } this.keys = null; } } //# sourceMappingURL=AuthXKeyCache.js.map