UNPKG

@azure/cosmos

Version:
95 lines 3.78 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.ProtectedDataEncryptionKeyCache = void 0; const node_crypto_1 = require("node:crypto"); const ProtectedDataEncryptionKey_js_1 = require("../EncryptionKey/ProtectedDataEncryptionKey.js"); const index_js_1 = require("../../common/index.js"); const time_js_1 = require("../../utils/time.js"); /** * The cache used to store the protected data encryption key. * see {@link ProtectedDataEncryptionKey} * @hidden */ class ProtectedDataEncryptionKeyCache { cacheTimeToLive; // key is JSON.stringify([encryptionKeyId, keyEncryptionKey.name, keyEncryptionKey.path, encryptedValue.toString("hex")]) cache; // interval for clear cache to run cacheRefresher; constructor(cacheTimeToLive) { this.cacheTimeToLive = cacheTimeToLive; this.cache = new Map(); this.clearCacheOnTtlExpiry(); } get(key) { if (!this.cache.has(key)) { return undefined; } return this.cache.get(key)[1]; } set(key, protectedDataEncryptionKey) { if (this.cacheTimeToLive === 0) { return; } this.cache.set(key, [new Date(), protectedDataEncryptionKey]); } async clearCacheOnTtlExpiry() { this.cacheRefresher = (0, time_js_1.startBackgroundTask)(async () => { const now = new Date(); for (const key of this.cache.keys()) { if (now.getTime() - this.cache.get(key)[0].getTime() > this.cacheTimeToLive) { this.cache.delete(key); } } }, index_js_1.Constants.EncryptionCacheRefreshIntervalInMs); } async createProtectedDataEncryptionKey(name, keyEncryptionKey, encryptedValue) { let rawKey; let encryptedKey; if (encryptedValue) { rawKey = await keyEncryptionKey.unwrapEncryptionKey(encryptedValue); encryptedKey = encryptedValue; } else { rawKey = this.generateColumnEncryptionKey(); encryptedKey = await keyEncryptionKey.wrapEncryptionKey(rawKey); } const newKey = new ProtectedDataEncryptionKey_js_1.ProtectedDataEncryptionKey(name, keyEncryptionKey, rawKey, encryptedKey); if (this.cacheTimeToLive !== 0) { const key = JSON.stringify([ name, keyEncryptionKey.name, keyEncryptionKey.path, encryptedKey.toString("hex"), ]); this.set(key, newKey); } return newKey; } async getOrCreate(name, keyEncryptionKey, encryptedValue, forceRefresh) { const encryptedValueBuffer = encryptedValue ? Buffer.from(encryptedValue) : undefined; if (this.cacheTimeToLive === 0 || forceRefresh) { return this.createProtectedDataEncryptionKey(name, keyEncryptionKey, encryptedValueBuffer); } if (encryptedValueBuffer) { const key = JSON.stringify([ name, keyEncryptionKey.name, keyEncryptionKey.path, encryptedValueBuffer.toString("hex"), ]); const protectedDataEncryptionKey = this.get(key); if (protectedDataEncryptionKey) { return protectedDataEncryptionKey; } } return this.createProtectedDataEncryptionKey(name, keyEncryptionKey, encryptedValueBuffer); } generateColumnEncryptionKey() { return (0, node_crypto_1.randomBytes)(32); } } exports.ProtectedDataEncryptionKeyCache = ProtectedDataEncryptionKeyCache; //# sourceMappingURL=ProtectedDataEncryptionKeyCache.js.map