61 lines
2.2 KiB
JavaScript
61 lines
2.2 KiB
JavaScript
const assert = require("node:assert/strict");
|
|
const crypto = require("node:crypto");
|
|
const fs = require("node:fs");
|
|
const os = require("node:os");
|
|
const path = require("node:path");
|
|
const { after, before, test } = require("node:test");
|
|
|
|
const { signLicense } = require("../license-manager");
|
|
|
|
let privateKeyPath;
|
|
let publicKey;
|
|
let temporaryDirectory;
|
|
|
|
before(async () => {
|
|
temporaryDirectory = await fs.promises.mkdtemp(path.join(os.tmpdir(), "reinloop-license-"));
|
|
const pair = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
|
|
privateKeyPath = path.join(temporaryDirectory, "license_private.pem");
|
|
publicKey = pair.publicKey;
|
|
await fs.promises.writeFile(privateKeyPath, pair.privateKey.export({
|
|
type: "pkcs8",
|
|
format: "pem"
|
|
}));
|
|
});
|
|
|
|
after(async () => {
|
|
await fs.promises.rm(temporaryDirectory, { recursive: true, force: true });
|
|
});
|
|
|
|
function validPayload(overrides = {}) {
|
|
return {
|
|
customer: "示例公司",
|
|
company_id: "company-1",
|
|
production_line_id: "line-1",
|
|
device_id: "sample-co/line-1",
|
|
issued: "2026-07-25 12:00",
|
|
expiry: "2027-07-25 12:00",
|
|
features: "*",
|
|
...overrides
|
|
};
|
|
}
|
|
|
|
test("signLicense creates a Python-compatible RSA-PSS license", () => {
|
|
const signed = signLicense(validPayload(), privateKeyPath);
|
|
const [payloadBase64, signatureBase64] = signed.content.split("|");
|
|
const verified = crypto.verify("sha256", Buffer.from(payloadBase64), {
|
|
key: publicKey,
|
|
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
|
saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
|
|
}, Buffer.from(signatureBase64, "base64"));
|
|
|
|
assert.equal(verified, true);
|
|
assert.deepEqual(JSON.parse(Buffer.from(payloadBase64, "base64").toString("utf8")), signed.payload);
|
|
assert.match(signed.payload.license_id, /^[0-9a-f-]{36}$/);
|
|
});
|
|
|
|
test("signLicense rejects invalid identity and date ranges", () => {
|
|
assert.throws(() => signLicense(validPayload({ device_id: "line-only" }), privateKeyPath), /device_id/);
|
|
assert.throws(() => signLicense(validPayload({ company_id: "" }), privateKeyPath), /company_id/);
|
|
assert.throws(() => signLicense(validPayload({ expiry: "2026-07-24 12:00" }), privateKeyPath), /到期时间/);
|
|
});
|