| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 | "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.loadAzureCredentials = exports.fetchAzureKMSToken = exports.prepareRequest = exports.tokenCache = exports.AzureCredentialCache = void 0;const errors_1 = require("../errors");const utils_1 = require("./utils");const MINIMUM_TOKEN_REFRESH_IN_MILLISECONDS = 6000;/** * @internal */class AzureCredentialCache {    constructor() {        this.cachedToken = null;    }    async getToken() {        if (this.cachedToken == null || this.needsRefresh(this.cachedToken)) {            this.cachedToken = await this._getToken();        }        return { accessToken: this.cachedToken.accessToken };    }    needsRefresh(token) {        const timeUntilExpirationMS = token.expiresOnTimestamp - Date.now();        return timeUntilExpirationMS <= MINIMUM_TOKEN_REFRESH_IN_MILLISECONDS;    }    /**     * exposed for testing     */    resetCache() {        this.cachedToken = null;    }    /**     * exposed for testing     */    _getToken() {        return fetchAzureKMSToken();    }}exports.AzureCredentialCache = AzureCredentialCache;/** @internal */exports.tokenCache = new AzureCredentialCache();/** @internal */async function parseResponse(response) {    const { status, body: rawBody } = response;    const body = (() => {        try {            return JSON.parse(rawBody);        }        catch {            throw new errors_1.MongoCryptAzureKMSRequestError('Malformed JSON body in GET request.');        }    })();    if (status !== 200) {        throw new errors_1.MongoCryptAzureKMSRequestError('Unable to complete request.', body);    }    if (!body.access_token) {        throw new errors_1.MongoCryptAzureKMSRequestError('Malformed response body - missing field `access_token`.');    }    if (!body.expires_in) {        throw new errors_1.MongoCryptAzureKMSRequestError('Malformed response body - missing field `expires_in`.');    }    const expiresInMS = Number(body.expires_in) * 1000;    if (Number.isNaN(expiresInMS)) {        throw new errors_1.MongoCryptAzureKMSRequestError('Malformed response body - unable to parse int from `expires_in` field.');    }    return {        accessToken: body.access_token,        expiresOnTimestamp: Date.now() + expiresInMS    };}/** * @internal * * parses any options provided by prose tests to `fetchAzureKMSToken` and merges them with * the default values for headers and the request url. */function prepareRequest(options) {    const url = new URL(options.url?.toString() ?? 'http://169.254.169.254/metadata/identity/oauth2/token');    url.searchParams.append('api-version', '2018-02-01');    url.searchParams.append('resource', 'https://vault.azure.net');    const headers = { ...options.headers, 'Content-Type': 'application/json', Metadata: true };    return { headers, url };}exports.prepareRequest = prepareRequest;/** * @internal * * `AzureKMSRequestOptions` allows prose tests to modify the http request sent to the idms * servers.  This is required to simulate different server conditions.  No options are expected to * be set outside of tests. * * exposed for CSFLE * [prose test 18](https://github.com/mongodb/specifications/tree/master/source/client-side-encryption/tests#azure-imds-credentials) */async function fetchAzureKMSToken(options = {}) {    const { headers, url } = prepareRequest(options);    const response = await (0, utils_1.get)(url, { headers }).catch(error => {        if (error instanceof errors_1.MongoCryptKMSRequestNetworkTimeoutError) {            throw new errors_1.MongoCryptAzureKMSRequestError(`[Azure KMS] ${error.message}`);        }        throw error;    });    return parseResponse(response);}exports.fetchAzureKMSToken = fetchAzureKMSToken;/** * @internal * * @throws Will reject with a `MongoCryptError` if the http request fails or the http response is malformed. */async function loadAzureCredentials(kmsProviders) {    const azure = await exports.tokenCache.getToken();    return { ...kmsProviders, azure };}exports.loadAzureCredentials = loadAzureCredentials;//# sourceMappingURL=azure.js.map
 |