const common = require("../../common"); const dayjs = require("dayjs"); const caApi = require("./ca-api"); const { getConfig } = require("../utils/config"); let db = ""; const caState = {}; module.exports = async (item, mongodb) => { db = mongodb; switch (item.type) { case "caAuth": return await caAuth(item); case "getSealImage": return await getSealImage(item); case "getCaUserInfo": return await getCaUserInfo(item); case "startAutoSign": return await startAutoSign(item); case "autoSign": return await autoSign(item); case "autoSignVerifyCA": return await autoSignVerifyCA(item); case "closeAutoSign": return await closeAutoSign(item); } }; // ca授权, 获取授权码 NORMAL-正常, LOCKED-冻结, DELETION-已删除 async function caAuth(item) { const { uniqueId } = item; // 查询用户信息 const { success, data, message } = await caApi.getUserInfo({ uniqueId }); if (!success) { return { success: false, message: message, }; } const { status, userId } = data; if (status === "NORMAL") { // 获取授权码 const { success, data, message } = await caApi.getAuthCode({ userId, }); if (!success) { return { success: false, message: message, }; } return { success: true, data: data.authCode, }; } return { success: false, message: "用户状态异常", }; } async function getCaUserInfo({ uniqueId }) { const { success, data, message } = await caApi.getUserInfo({ uniqueId }); if (!success) { return { success: false, message: message, }; } if (!success) { return { success: false, message: message, }; } const { status, userId } = data; if (status === "NORMAL") { return { success: true, data: { status, userId, }, }; } return { success: false, message: "用户状态异常", }; } // 查询印章图片 async function getSealImage({ uniqueId }) { const res = await caApi.getUserInfo({ uniqueId }); if (!res.success) { return { success: false, message: res.message, }; } const { userId } = res.data; const { success, data, message } = await caApi.queryImage({ userId }); if (!success) { return { success: false, message: message, }; } return { success: true, data: data.image, }; } // 开启时效签 async function startAutoSign({ userId, corpId }) { const { caTimeRegion } = await getConfig(corpId); const { success, data, message } = await caApi.startAutoSign({ userId, timeRegion: caTimeRegion, }); if (!success) { return { success: false, message: message, }; } return { success: true, data: data, caTimeRegion, }; } // 自动签名 async function autoSign({ userId, oriData }) { // data 为base64编码过的数据 const base64Data = Buffer.from(oriData).toString("base64"); console.log("=========>base64Data", base64Data); const { success, data, message } = await caApi.autoSign({ userId, data: base64Data, }); // 如果自动签时效, 采用手动签名 if (!success) { return { success: false, message: message, }; } console.log("签名成功饭后", data); const { signCert, signResult } = data; // 产生时间戳 const tsResult = await caApi.createAndGetTssInfo({ oriData, attachCert: true, }); if (!tsResult.success) { return { success: false, message: tsResult.message, }; } console.log("产生时间戳", tsResult); const { tsResp } = tsResult.data; // 验证签名结果 和 时间戳 const verifyResult = await verifySignAndTS({ userId, oriData, signResult, tsResp, signCert, base64Data, }); if (!verifyResult.success) { return { success: false, message: verifyResult.message, }; } console.log("验证签名结果 和 时间戳", verifyResult); // 保存签名结果到本地数据库 await saveSignResult({ oriData, tsResp, signCert, signResult, userId, }); return { success: true, data: data, }; } // 验证签名结果 和 时间戳 verifyTS 和 verifySign 使用 promse.all async function verifySignAndTS({ userId, oriData, signResult, tsResp, signCert, base64Data, }) { console.log("===========>验证签名结果 和 时间戳", { userId, oriData, signResult, tsResp, signCert, base64Data, }); const [verifyTSResult, verifySignResult] = await Promise.all([ caApi.verifyTS({ userId, oriData, tsResp }), caApi.verifySign({ plain: base64Data, signValue: signResult, cert: signCert, }), ]); if (!verifyTSResult.success) { return { success: false, message: verifyTSResult.message, }; } if (!verifySignResult.success) { return { success: false, message: verifySignResult.message, }; } return { success: true, data: { tsData: verifyTSResult.data, signData: verifySignResult.data, }, }; } /** * 保存签名结果到本地数据库 * @param {Object} param * @param {String} param.oriData 原始数据 * @param {String} param.tsResp 签名时间戳 * @param {String} param.signCert 签名证书 * @param {String} param.signResult 签名数据 * @param {String} param.userId 用户ID * @returns */ async function saveSignResult({ oriData, tsResp, signCert, signResult, userId, }) { const result = await db.collection("ca-sign").insertOne({ userId, oriData, tsResp, signCert, signResult, createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), }); console.log("保存签名结果到本地数据库", result); return result; } // 验证CA时效 通过 queryAutoSignRegion 接口 async function autoSignVerifyCA(item) { const { code } = item; const state = useCaState(code); if (state) { return { success: true, message: `时效签已开启,有效期至: ${state.endTime}`, userId: state.userId, }; } const uerInfo = await caApi.getUserInfo({ uniqueId: code }); if (!uerInfo.success) { return { success: false, message: uerInfo.message, }; } const { status, userId } = uerInfo.data; if (status != "NORMAL") { return { success: false, message: "用户状态异常", }; } const { success, data } = await caApi.queryAutoSignRegion({ userId, }); if (success && data.autoSignStatus === "STARTED") { const state = { userId, endTime: data.endTime } keepCaState(code, state); return { success: true, message: "时效签已开启", userId, }; } removeCaState(code); return { success: false, message: "时效签未开启", userId, }; } async function closeAutoSign({ uniqueId }) { const uerInfo = await caApi.getUserInfo({ uniqueId }); if (!uerInfo.success) { return { success: false, message: uerInfo.message, }; } const { status, userId } = uerInfo.data; if (status != "NORMAL") { return { success: false, message: "用户状态异常", }; } const { success, message } = await caApi.closeAutoSign({ userId, }); if (!success) { return { success: false, message: message, }; } return { success: true, message: "关闭成功", }; } function keepCaState(uniqueId, { userId, endTime }) { if (typeof userId === 'string' && userId.trim() && endTime && dayjs(endTime).isValid()) { // ca当天有效, 如果有效期超过当天, 则将有效期设置为当天 const newEndTime = dayjs(endTime).isAfter(dayjs().endOf('day')) ? dayjs().endOf('day').format('YYYY-MM-DD HH:mm') : endTime; caState[uniqueId] = { userId, endTime: newEndTime }; } } function removeCaState(uniqueId) { caState[uniqueId] = undefined; } function useCaState(uniqueId) { const info = caState[uniqueId]; if (!info) return null; const { userId, endTime } = info; if (endTime && dayjs().isBefore(dayjs(endTime))) { return { userId, endTime } } return null }