458 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2026-07-27 11:28:33 +08:00
const request = require("../../request");
const baseUrl = process.env.CONFIG_CA_BASE_URL;
const appId = process.env.CONFIG_CA_APPID;
const secret = process.env.CONFIG_CA_SECRET;
const crypto = require("crypto");
const caRequest = (url, data) => {
let params = {
appId,
signAlgo: "HmacSHA256",
version: "1.0",
...data,
};
params.signature = calculateSignature(params);
console.log(params);
console.log(`${baseUrl}${url}`);
return request.main(`${baseUrl}${url}`, params, "POST");
};
/**
* 添加用户
* @param {Object} param0 - 用户信息
* @param {string} param0.userName - 用户名
* @param {string} param0.idNumber - 身份证号码
* @param {string} param0.idType - 证件类型
* @param {string} param0.mobile - 手机号码
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.userId - 用户ID
*/
exports.addUser = async ({ userName, idNumber, idType = "SF", mobile }) => {
const { data, status, message } = await caRequest("addUser", {
userName,
idNumber,
idType,
mobile,
});
if (status == 200) {
return {
success: true,
message: "添加用户成功",
data,
};
} else {
return {
success: false,
message: message || "添加用户失败",
};
}
};
/**
* 产生激活码
* @param {string} userId - 用户ID
* @returns {Promise<Object>} 返回包含用户信息的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.authCode - 激活码二维码用于在手机端扫码发起用户 身份激活操作 整体生成二维码
* @returns {string} returns.data.code -用户激活码用于在手机端输入激活码发起 用户身份激活操作
*/
exports.getAuthCode = async ({ userId }) => {
const { data, status, message } = await caRequest("getAuthCode", {
userId,
});
if (status == 200) {
return {
success: true,
message: "生成激活码成功",
data,
};
} else {
return {
success: false,
message: message || "生成激活码失败",
};
}
};
/**
* 添加签名任务
* @param {Object} param0 - 任务信息
* @param {string} param0.userId - 用户ID
* @param {string} param0.dataType - 任务类型 DATA原文
* @param {string} param0.algo -签名算法(SM3withSM2)
* @param {string} param0.data - 待签数据必须是 base64 编码默认最大不超过 1M也可以通过配置文件重新设置
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.signDataId - 任务ID
* @returns {string} returns.data.qrCode - 二维码用于在手机端扫码发起签名操作
*/
exports.addSignJob = async ({ userId, dataType, data }) => {
const {
data: res,
status,
message,
} = await caRequest("addSignJob", {
userId,
dataType: "DATA",
algo: "SM3withSM2",
data,
});
if (status == 200) {
return {
success: true,
message: "添加签名任务成功",
res,
};
} else {
return {
success: false,
message: message || "添加签名任务失败",
};
}
};
/**
* 查询用户信息
* @param {string} idNumber - 身份证号码
* @param {string} idType - 证件类型
* @returns {Promise<Object>} 返回包含用户信息的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.userId - 用户ID
*/
exports.getUserInfo = async ({ uniqueId }) => {
const { data, status, message } = await caRequest("queryUserInfo", {
uniqueId,
});
if (status == 200) {
return {
success: true,
message: "查询用户信息成功",
data,
};
} else {
return {
success: false,
message: message || "查询用户信息失败",
};
}
};
/**
*查询印章图片
* @param {string} userId - 用户ID
* @returns {Promise<Object>} 返回包含印章图片的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.image - 印章图片
*/
exports.queryImage = async ({ userId }) => {
const { data, status, message } = await caRequest("queryImage", {
userId,
});
if (status == 200) {
return {
success: true,
message: "查询印章图片成功",
data,
};
} else {
return {
success: false,
message: message || "查询印章图片失败",
};
}
};
/**
* 获取签名结果
* @param {string} signDataId - 任务ID
* @returns {Promise<Object>} 返回包含任务信息的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.signResult - 签名结果
* @returns {string} returns.data.signCert - 签名证书
* @returns {string} returns.data.jobStatus - 任务状态
* @returns {string} returns.data.dataType - 原文类型
*/
exports.getSignResult = async (signDataId) => {
const { data, status, message } = await caRequest("getSignResult", {
signDataId,
});
if (status == 200) {
return {
success: true,
message: "获取签名结果成功",
data,
};
} else {
return {
success: false,
message: message || "获取签名结果失败",
};
}
};
/**
* 开启时效签名
* @param {string} userId - 用户ID
* @param {string} timeRegion - 有效时间区间
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.qrCode - 二维码用于在手机端扫码发起签名操作
* @returns {string} returns.data.data - 原文
*/
exports.startAutoSign = async ({ userId, timeRegion }) => {
// 通过 uniqueId 获取 userId
const { data, status, message } = await caRequest("startAutoSign", {
userId,
timeRegion,
});
if (status == 200) {
return {
success: true,
message: "开启时效签名成功",
data: data.qrCode,
};
} else {
return {
success: false,
message: message || "开启时效签名失败",
};
}
};
/**
* 查询时效签时间
* @param {string} userId - 用户ID
* @param {string} signToken - 签名令牌
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.region - 时间
* @returns {string} returns.data.autoSignStatus - 时效签状态
* @returns {string} returns.data.signToken - 签名令牌
*
*/
exports.queryAutoSignRegion = async ({ userId, signToken }) => {
const { data, status, message } = await caRequest("queryAutoSignRegion", {
userId,
signToken,
});
if (status == 200) {
return {
success: true,
message: "查询时效签时间成功",
data,
};
} else {
return {
success: false,
message: message || "查询时效签时间失败",
};
}
};
/**
* 时效签名
* @param {Object} param0 - 任务信息
* @param {string} param0.userId - 用户ID
* @param {string} param0.dataType - 任务类型 DATA原文
* @param {string} param0.algo -签名算法(SM3withSM2)
* @param {string} param0.data - 待签数据必须是 base64 编码默认最大不超过 1M也可以通过配置文件重新设置
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.signResult - 签名结果
* @returns {string} returns.data.signCert - 签名证书
*/
exports.autoSign = async ({ userId, data }) => {
const {
data: res,
status,
message,
} = await caRequest("autoSign", {
userId,
dataType: "DATA",
algo: "SM3withSM2",
data,
});
if (status == 200) {
return {
success: true,
message: "时效签名成功",
data: res,
};
} else {
return {
success: false,
message: message || "时效签名失败",
};
}
};
/**
* 验证数据签名
* @param {Object} param0 - 任务信息
* @param {string} param0.userId - 用户ID
* @param {string} param0.plain - 任务类型 DATA原文
* @param {string} param0.signAlg -签名算法(SM3withSM2)
* @param {string} param0.signValue - 签名值 时效签名时获取的 signResult
* @param {string} param0.cert - 证书时 效签名时获取的signCert
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
*/
exports.verifySign = async ({ plain, signValue, cert }) => {
const {
data: res,
status,
message,
} = await caRequest("verifySign", {
plain,
signAlg: "SM3withSM2",
signValue,
cert,
});
if (status == 200) {
return {
success: true,
message: "验证数据签名成功",
res,
};
} else {
return {
success: false,
message: message || "验证数据签名失败",
};
}
};
/**
*产生时间戳
* @param {string} userId - 用户ID
* @param {string} signDataId - 待签数据
* @param {string} oriData - 数据原文
* @param {string} attachCert - 是否返回证书
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.tsResp - 时间戳响应
*/
exports.createAndGetTssInfo = async ({ oriData, attachCert }) => {
const { data, status, message } = await caRequest("createAndGetTssInfo", {
oriData,
attachCert,
});
if (status == 200) {
return {
success: true,
message: "产生时间戳成功",
data,
};
} else {
return {
success: false,
message: message || "产生时间戳失败",
};
}
};
/**
* 验证时间戳
* @param {string} userId - 用户ID
* @param {string} signDataId - 待签数据
* @param {string} oriData - 时间戳ID
* @param {string} tsResp - 时间戳响应
* @returns {Promise<Object>} 返回包含操作结果的对象
* @returns {boolean} returns.status - 操作是否成功
* @returns {string} returns.message - 操作结果信息
* @returns {Object} returns.data - 操作结果数据
* @returns {string} returns.data.verifyRes - 时间戳响应 1 为时间戳有效 -1 为时间戳验证不通过 -2 为原文验证不通过 -3 为不是所信任的根 -4 证书未生效 -5 查询不到此证书 -6 为签发时间戳时服务器证书过期
*/
exports.verifyTS = async ({ oriData, tsResp }) => {
const { data, status, message } = await caRequest("verifyTS", {
tsResp,
oriData,
});
if (status == 200) {
return {
success: true,
message: "验证时间戳成功",
data,
};
} else {
return {
success: false,
message: message || "验证时间戳失败",
};
}
};
/**
* 取消时效签
*/
exports.closeAutoSign = async ({ userId }) => {
const { data, status, message } = await caRequest("endAutoSign", {
userId,
});
if (status == 200) {
return {
success: true,
message: "关闭时效签成功",
data,
};
} else {
return {
success: false,
message: message || "关闭时效签失败",
};
}
};
function calculateSignature(params) {
// 过滤空值参数(根据文档:值为空的参数不参与签名)
const filteredParams = {};
for (const key in params) {
const value = params[key];
if (value !== null && value !== undefined && value !== "") {
filteredParams[key] = value;
}
}
// 按 ASCII 字典序排序参数
const sortedKeys = Object.keys(filteredParams).sort();
// 拼接 URL 键值对字符串
const stringA = sortedKeys
.map((key) => `${key}=${filteredParams[key]}`)
.join("&");
// 转换算法名称HmacSHA256 -> sha256
const hmacAlgo = params.signAlgo
? params.signAlgo.replace(/^hmac/i, "").toLowerCase()
: "sha256";
// 计算 HMAC
const hmac = crypto.createHmac(hmacAlgo, secret);
hmac.update(stringA, "utf8");
const signature = hmac.digest("base64");
return signature;
}