2026-07-27 11:28:33 +08:00

458 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}