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
|