UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

107 lines (106 loc) 4.17 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createTempCert = void 0; const path_1 = __importDefault(require("path")); const os_1 = __importDefault(require("os")); const fs_extra_1 = require("fs-extra"); const cert_parser_1 = require("./cert-parser"); const key_chain_1 = require("./key-chain"); const mkcert_1 = require("mkcert"); const fs_extra_2 = require("fs-extra"); const logger_1 = require("../logger"); const ROOT_CA_DIR = path_1.default.join(os_1.default.homedir(), '.Meegle_Developer_Platform_CA'); const ROOT_CA_FILE_NAME = 'meegle_root_ca'; const ROOT_CA_COMMON_NAME = 'MeegleDeveloperPlatform'; const ROOT_CA_KEY_PATH = path_1.default.join(ROOT_CA_DIR, `${ROOT_CA_FILE_NAME}.key`); const ROOT_CA_CERT_PATH = path_1.default.join(ROOT_CA_DIR, `${ROOT_CA_FILE_NAME}.crt`); const ROOT_CA_OPTIONS = { organization: ROOT_CA_COMMON_NAME, countryCode: 'CN', state: 'ZJ', locality: 'HZ', validity: 365, }; async function getRemoteCA() { const caCertUrl = 'https://sf3-cn.feishucdn.com/obj/meego-static/front/isv/meegle_root_ca.crt'; const caKeyUrl = 'https://sf3-cn.feishucdn.com/obj/meego-static/front/isv/meegle_root_ca.key'; const [cert, key] = await Promise.all([ fetch(caCertUrl).then(res => res.text()), fetch(caKeyUrl).then(res => res.text()), ]); return { key, cert, }; } async function getOrCreateCA() { try { // 本机已添加并信任根证书 if ((0, key_chain_1.isTrustedCert)(ROOT_CA_COMMON_NAME)) { const keyStr = (0, fs_extra_1.readFileSync)(ROOT_CA_KEY_PATH).toString(); const certStr = (0, fs_extra_1.readFileSync)(ROOT_CA_CERT_PATH).toString(); const cert = (0, cert_parser_1.readCertFromCertStr)(certStr); // 如 CA 已过期则走重新生成证书的逻辑 if ((0, cert_parser_1.isValidCert)(cert)) { logger_1.logger.info(`Root CA ${ROOT_CA_COMMON_NAME} has been trusted.`); return { key: keyStr, cert: certStr, }; } else { logger_1.logger.warn(`Root CA ${ROOT_CA_COMMON_NAME} has expired, will regenerate it.`); } } } catch (e) { // do nothing, 钥匙串有证书,实际文件被删除,读取不存在文件异常则走重新生成证书的逻辑 } try { // 本地自签生成 const CA = await (0, mkcert_1.createCA)(ROOT_CA_OPTIONS); // 写入本地文件 if (!(0, fs_extra_2.existsSync)(ROOT_CA_DIR)) { (0, fs_extra_2.mkdirSync)(ROOT_CA_DIR); } (0, fs_extra_2.writeFileSync)(ROOT_CA_KEY_PATH, CA.key); (0, fs_extra_2.writeFileSync)(ROOT_CA_CERT_PATH, CA.cert); console.log(`Root CA generated into ${ROOT_CA_DIR}`); try { (0, key_chain_1.addToKeyChain)(ROOT_CA_CERT_PATH); } catch (e) { console.warn('Root CA add to key chain failed, please Please add and trust manually'); } return CA; } catch (e) { // 兜底从远端拉根证书 const remoteCA = await getRemoteCA(); const pkiCert = (0, cert_parser_1.readCertFromCertStr)(Buffer.from(remoteCA.cert, 'utf8').toString()); if ((0, cert_parser_1.isValidCert)(pkiCert)) { return remoteCA; } else { console.error(`Please submit an issue to ask for help: 'Update remote ${ROOT_CA_COMMON_NAME} CA immediately'`); throw new Error(`Remote ${ROOT_CA_COMMON_NAME} CA has expired`); } } } async function createTempCert(domains = ['localhost', '127.0.0.1', '0.0.0.0']) { const CA = await getOrCreateCA(); const { cert, key } = await (0, mkcert_1.createCert)({ domains, validity: 365, ca: CA, }); return { cert, key, ca: CA.cert, }; } exports.createTempCert = createTempCert;