"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CRL_MEMORY_CACHE = void 0;
exports.getCrlFromMemory = getCrlFromMemory;
exports.setCrlInMemory = setCrlInMemory;
exports.clearExpiredCrlFromMemoryCache = clearExpiredCrlFromMemoryCache;
exports.clearExpiredCrlFromDiskCache = clearExpiredCrlFromDiskCache;
exports.getCrlFromDisk = getCrlFromDisk;
exports.writeCrlToDisk = writeCrlToDisk;
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
const asn1_js_rfc5280_1 = __importDefault(require("asn1.js-rfc5280"));
const disk_cache_1 = require("../../disk_cache");
const global_config_typed_1 = __importDefault(require("../../global_config_typed"));
const logger_1 = __importDefault(require("../../logger"));
exports.CRL_MEMORY_CACHE = new Map();
function getCrlFromMemory(url) {
    const cachedEntry = exports.CRL_MEMORY_CACHE.get(url);
    if (cachedEntry) {
        if (cachedEntry.expireAt > Date.now()) {
            return cachedEntry.crl;
        }
        else {
            exports.CRL_MEMORY_CACHE.delete(url);
            return null;
        }
    }
    else {
        return null;
    }
}
function setCrlInMemory(url, crl) {
    exports.CRL_MEMORY_CACHE.set(url, {
        expireAt: Math.min(Date.now() + global_config_typed_1.default.getValue('crlCacheValidityTime'), crl.tbsCertList.nextUpdate.value),
        crl,
    });
}
function clearExpiredCrlFromMemoryCache() {
    exports.CRL_MEMORY_CACHE.forEach((entry, key) => {
        if (entry.expireAt < Date.now()) {
            exports.CRL_MEMORY_CACHE.delete(key);
        }
    });
}
async function clearExpiredCrlFromDiskCache() {
    try {
        const cacheDir = global_config_typed_1.default.getValue('crlCacheDir');
        for (const fileName of await promises_1.default.readdir(cacheDir)) {
            const filePath = path_1.default.join(cacheDir, fileName);
            const stats = await promises_1.default.stat(filePath);
            const thirtyDaysAgo = Date.now() - 1000 * 60 * 60 * 24 * 30;
            // NOTE:
            // Keeping expired CRLs on disk for 30 days for debugging purposes
            if (stats.mtime.getTime() < thirtyDaysAgo) {
                (0, logger_1.default)().debug(`Deleting CRL file ${fileName} older than 30 days.`);
                await promises_1.default.rm(filePath);
            }
        }
    }
    catch (error) {
        if ((0, disk_cache_1.isFileNotFoundError)(error)) {
            (0, logger_1.default)().debug('CRL cache directory does not exist, skipping cleanup.');
        }
        else {
            (0, logger_1.default)().warn(`Failed to clear expired CRL entries from disk cache: ${error}.`);
        }
    }
}
async function getCrlFromDisk(url) {
    const filePath = path_1.default.join(global_config_typed_1.default.getValue('crlCacheDir'), encodeURIComponent(url));
    try {
        const stats = await promises_1.default.stat(filePath);
        if (Date.now() - stats.mtime.getTime() > global_config_typed_1.default.getValue('crlCacheValidityTime')) {
            (0, logger_1.default)().debug(`CRL ${filePath} is older than crlCacheValidityTime, ignoring.`);
            return null;
        }
        const rawCrl = await promises_1.default.readFile(filePath);
        const decodedCrl = asn1_js_rfc5280_1.default.CertificateList.decode(rawCrl, 'der');
        if (decodedCrl.tbsCertList.nextUpdate.value > Date.now()) {
            return decodedCrl;
        }
        else {
            (0, logger_1.default)().debug(`CRL ${filePath} is expired, ignoring.`);
            return null;
        }
    }
    catch (error) {
        if ((0, disk_cache_1.isFileNotFoundError)(error)) {
            (0, logger_1.default)().debug(`CRL ${url} not found on disk cache.`);
        }
        else {
            (0, logger_1.default)().warn(`Failed to read CRL ${filePath} from disk cache: ${error}.`);
        }
    }
    return null;
}
async function writeCrlToDisk(url, rawCrl) {
    const filePath = path_1.default.join(global_config_typed_1.default.getValue('crlCacheDir'), encodeURIComponent(url));
    try {
        return (0, disk_cache_1.writeCacheFile)(filePath, rawCrl);
    }
    catch (error) {
        (0, logger_1.default)().warn(`Failed to write CRL ${filePath} to disk cache: ${error}.`);
    }
}
//# sourceMappingURL=crl_cache.js.map