458 lines
13 KiB
JavaScript
458 lines
13 KiB
JavaScript
|
|
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;
|
|||
|
|
}
|