update server
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
const crypto = require("node:crypto");
|
||||
const fs = require("node:fs");
|
||||
|
||||
function requiredText(value, fieldName) {
|
||||
const text = String(value || "").trim();
|
||||
if (!text) throw new Error(`${fieldName}不能为空`);
|
||||
return text;
|
||||
}
|
||||
|
||||
function normalizeTimestamp(value, fieldName) {
|
||||
const timestamp = requiredText(value, fieldName);
|
||||
const match = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/.exec(timestamp);
|
||||
if (!match) throw new Error(`${fieldName}格式必须为 YYYY-MM-DD HH:MM`);
|
||||
const [, year, month, day, hour, minute] = match.map(Number);
|
||||
const parsed = new Date(year, month - 1, day, hour, minute);
|
||||
if (parsed.getFullYear() !== year || parsed.getMonth() !== month - 1 ||
|
||||
parsed.getDate() !== day || parsed.getHours() !== hour || parsed.getMinutes() !== minute) {
|
||||
throw new Error(`${fieldName}不是有效日期时间`);
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
function signLicense(payload, privateKeyPath) {
|
||||
const licenseId = payload.license_id || crypto.randomUUID();
|
||||
const deviceId = requiredText(payload.device_id, "device_id");
|
||||
const deviceParts = deviceId.split("/");
|
||||
if (deviceParts.length !== 2 || deviceParts.some((part) => !/^[a-z0-9][a-z0-9_-]{1,63}$/.test(part))) {
|
||||
throw new Error("device_id 必须是 company-code/line-code 格式");
|
||||
}
|
||||
const issued = normalizeTimestamp(payload.issued, "签发时间");
|
||||
const expiry = normalizeTimestamp(payload.expiry, "到期时间");
|
||||
if (expiry <= issued) throw new Error("到期时间必须晚于签发时间");
|
||||
const normalized = {
|
||||
license_id: licenseId,
|
||||
customer: requiredText(payload.customer, "customer"),
|
||||
company_id: requiredText(payload.company_id, "company_id"),
|
||||
production_line_id: requiredText(payload.production_line_id, "production_line_id"),
|
||||
device_id: deviceId,
|
||||
issued,
|
||||
expiry,
|
||||
features: requiredText(payload.features || "*", "features")
|
||||
};
|
||||
const payloadBase64 = Buffer.from(JSON.stringify(normalized)).toString("base64");
|
||||
const privateKey = fs.readFileSync(privateKeyPath);
|
||||
const signature = crypto.sign("sha256", Buffer.from(payloadBase64), {
|
||||
key: privateKey,
|
||||
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
||||
saltLength: crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN
|
||||
});
|
||||
return {
|
||||
payload: normalized,
|
||||
content: `${payloadBase64}|${signature.toString("base64")}`
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { signLicense };
|
||||
Reference in New Issue
Block a user