"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const es6_promisify_1 = require("es6-promisify");
const parse_domain_1 = __importDefault(require("parse-domain"));
const pem_1 = __importDefault(require("pem"));
const pemCreateCertificate = es6_promisify_1.promisify(pem_1.default.createCertificate);
const SELF_ROOT_KEY = '$$SELF_ROOT$$';
class CertificateService {
    /**
     *
     * @param storage 证书存储服务
     * @param cache 缓存服务
     */
    constructor(storage, cache) {
        this.storage = storage;
        this.cache = cache;
    }
    /**
     * 为域名获取证书
     * @param host
     * @returns {Promise<Certification>}
     */
    getCertificationForHost(host) {
        return __awaiter(this, void 0, void 0, function* () {
            let domain = host;
            /**
             * 解析后 www.baidu.com
             * {
             *   domain: "baidu"
             *   subdomain: "www"
             *   tld: "com"
             *  }
             * @type {*}
             */
            const parsed = parse_domain_1.default(host);
            // 寻找一级域名
            if (parsed && parsed.subdomain) {
                const subdomainList = parsed.subdomain.split('.');
                subdomainList.shift();
                if (subdomainList.length > 0) {
                    domain =
                        '*.' +
                            subdomainList.join('.') +
                            '.' +
                            parsed.domain +
                            '.' +
                            parsed.tld;
                }
            }
            // 从缓存里取数据
            if (this.cache.has(domain)) {
                return this.cache.get(domain);
            }
            const storageHas = yield this.storage.has(domain);
            if (storageHas) {
                const certInStorage = yield this.storage.get(domain);
                this.cache.set(domain, certInStorage);
                return certInStorage;
            }
            const cert = yield this.create(domain);
            this.storage.set(domain, cert);
            this.cache.set(domain, cert);
            return cert;
        });
    }
    getRoot() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.cache.has(SELF_ROOT_KEY)) {
                return this.cache.get(SELF_ROOT_KEY);
            }
            const root = yield this.storage.getRoot();
            this.cache.set(SELF_ROOT_KEY, root);
            return root;
        });
    }
    /**
     * 为指定域名创建证书 (使用自定义的根证书)
     * @param host
     * @returns {Promise<Certification>}
     */
    create(host) {
        return __awaiter(this, void 0, void 0, function* () {
            const root = yield this.getRoot();
            const res = yield pemCreateCertificate({
                altNames: [host],
                commonName: host,
                days: 365 * 10,
                serviceCertificate: root.cert,
                serviceKey: root.key,
            });
            return {
                cert: res.certificate,
                key: res.clientKey,
            };
        });
    }
}
exports.CertificateService = CertificateService;
//# sourceMappingURL=index.js.map