@backstage/backend-defaults
Version:
Backend defaults used by Backstage backend apps
51 lines (47 loc) • 1.46 kB
JavaScript
;
var errors = require('@backstage/errors');
var jose = require('jose');
const CLOCK_MARGIN_S = 10;
class JwksClient {
#keyStore;
#keyStoreUpdated = 0;
getEndpoint;
constructor(getEndpoint) {
this.getEndpoint = getEndpoint;
}
get getKey() {
if (!this.#keyStore) {
throw new errors.AuthenticationError(
"refreshKeyStore must be called before jwksClient.getKey"
);
}
return this.#keyStore;
}
/**
* If the last keystore refresh is stale, update the keystore URL to the latest
*/
async refreshKeyStore(rawJwtToken) {
const payload = await jose.decodeJwt(rawJwtToken);
const header = await jose.decodeProtectedHeader(rawJwtToken);
let keyStoreHasKey;
try {
if (this.#keyStore) {
const [_, rawPayload, rawSignature] = rawJwtToken.split(".");
keyStoreHasKey = await this.#keyStore(header, {
payload: rawPayload,
signature: rawSignature
});
}
} catch (error) {
keyStoreHasKey = false;
}
const issuedAfterLastRefresh = payload?.iat && payload.iat > this.#keyStoreUpdated - CLOCK_MARGIN_S;
if (!this.#keyStore || !keyStoreHasKey && issuedAfterLastRefresh) {
const endpoint = await this.getEndpoint();
this.#keyStore = jose.createRemoteJWKSet(endpoint);
this.#keyStoreUpdated = Date.now() / 1e3;
}
}
}
exports.JwksClient = JwksClient;
//# sourceMappingURL=JwksClient.cjs.js.map