@ianacaburian/generate-key-file
Version:
Ports juce_KeyGeneration::generateKeyFile() to node.
315 lines (306 loc) • 10.1 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
generateExpiringKeyFile: () => generateExpiringKeyFile,
generateKeyFile: () => generateKeyFile
});
module.exports = __toCommonJS(src_exports);
// src/juce/JuceKeyFileUtils.ts
var import_fast_xml_parser = require("fast-xml-parser");
// src/juce/JuceBigInteger.ts
var import_jsbn = require("jsbn");
var JuceBigInteger = class _JuceBigInteger {
constructor(value = 0n) {
this.value = value;
}
static fromJSBN(b) {
return _JuceBigInteger.fromHex(b.toString(16));
}
toJSBN() {
return new import_jsbn.BigInteger(this.toHex(), 16);
}
static fromHex(hex) {
const h = hex.trim();
return new _JuceBigInteger(h ? BigInt(`0x${h}`) : 0n);
}
toHex() {
return this.value.toString(16);
}
static fromUTF8MemoryBlock(input) {
const u = Buffer.from(input, "utf8");
const b = new _JuceBigInteger();
for (let i = u.length - 1; i >= 0; i--) {
b.value = b.value << 8n | BigInt(u[i]);
}
return b;
}
isZero() {
return this.value === 0n;
}
divideBy(divisor, remainder) {
if (divisor.isZero()) {
this.value = 0n;
return;
}
const b = this.toJSBN();
const d = divisor.toJSBN();
const [q, r] = b.divideAndRemainder(d);
this.value = _JuceBigInteger.fromJSBN(q).value;
remainder.value = _JuceBigInteger.fromJSBN(r).value;
}
exponentModulo(exponent, modulus) {
const b = this.toJSBN();
const e = exponent.toJSBN();
const m = modulus.toJSBN();
const em = b.modPow(e, m);
this.value = _JuceBigInteger.fromJSBN(em).value;
}
};
// src/juce/JuceKeyFileUtils.ts
var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>';
var legalXmlCharRegex = (
// Ports juce::XmlOutputFunctions::LegalCharLookupTable
/^[a-zA-Z0-9 .,;:\-()_+=?!$#@[\]/|*%~{}'\\]$/
);
var xmlAttributeCharProcessor = (char) => (
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
char.length !== 1 ? "" : legalXmlCharRegex.test(char) ? char : char === "&" ? "&" : char === '"' ? """ : char === ">" ? ">" : char === "<" ? "<" : `&#${char.charCodeAt(0)};`
);
var xmlAttributeValueProcessor = (value) => (
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
typeof value !== "string" ? "" : value.split("").map(xmlAttributeCharProcessor).join("")
);
var xmlBuilder = new import_fast_xml_parser.XMLBuilder({
ignoreAttributes: false,
suppressEmptyNode: true,
// processEntities is disabled since it doesn't port to juce as is
processEntities: false,
attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)
});
var JuceKeyFileUtils = class {
static toString(date) {
const months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
const day = date.getDate().toString();
const month = months[date.getMonth()];
const year = date.getFullYear();
let hours = date.getHours();
const minutes = date.getMinutes().toString().padStart(2, "0");
const seconds = date.getSeconds().toString().padStart(2, "0");
const ampm = hours >= 12 ? "pm" : "am";
hours = hours % 12;
hours = hours ? hours : 12;
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
}
static toHexStringMilliseconds(date) {
return date.getTime().toString(16);
}
static createKeyFileContentLine({
appName,
userEmail,
userName,
machineNumbers,
machineNumbersAttributeName
}, date, expiryTime) {
const xml = {
key: {
"@_user": userName,
"@_email": userEmail,
[`@_${machineNumbersAttributeName}`]: machineNumbers,
"@_app": appName,
"@_date": date,
...expiryTime ? { "@_expiryTime": expiryTime } : {}
}
};
return [XML_DECLARATION, xmlBuilder.build(xml).trim()].join(" ");
}
static createKeyFileComment({
appName,
userEmail,
userName,
machineNumbers
}, created, expiryTime) {
return `Keyfile for ${appName}\r
${userName ? `User: ${userName}\r
` : ""}Email: ${userEmail}\r
Machine numbers: ${machineNumbers}\r
Created: ${created}` + (expiryTime ? `\r
Expires: ${expiryTime}` : "");
}
static encryptXMLLine(xmlLine, privateKey) {
const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine);
privateKey.applyToValue(val);
return val.toHex();
}
static createKeyFile(comment, xmlLine, rsaPrivateKey) {
let asHex = "#" + this.encryptXMLLine(xmlLine, rsaPrivateKey);
const lines = [];
lines.push(comment);
lines.push("");
const charsPerLine = 70;
while (asHex.length > 0) {
lines.push(asHex.substring(0, charsPerLine));
asHex = asHex.substring(charsPerLine);
}
lines.push("");
return lines.join("\r\n");
}
};
// src/juce/JuceRSAKey.ts
var JuceRSAKey = class {
constructor(s) {
this.s = s;
if (s.includes(",")) {
const [p1, p2] = s.split(",").map((p) => JuceBigInteger.fromHex(p));
this.part1 = p1;
this.part2 = p2;
} else {
this.part1 = new JuceBigInteger();
this.part2 = new JuceBigInteger();
}
}
applyToValue(val) {
if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {
return;
}
const result = new JuceBigInteger();
while (!val.isZero()) {
result.value *= this.part2.value;
const remainder = new JuceBigInteger();
val.divideBy(this.part2, remainder);
remainder.exponentModulo(this.part1, this.part2);
result.value += remainder.value;
}
val.value = result.value;
}
};
// src/juce/JuceKeyGeneration.ts
var JuceKeyGeneration = class {
static generateKeyFile(params, date = /* @__PURE__ */ new Date()) {
const xml = JuceKeyFileUtils.createKeyFileContentLine(
{
appName: params.appName,
userEmail: params.userEmail,
userName: params.userName,
machineNumbers: params.machineNumbers,
machineNumbersAttributeName: "mach"
},
JuceKeyFileUtils.toHexStringMilliseconds(date)
);
const comment = JuceKeyFileUtils.createKeyFileComment(
{
appName: params.appName,
userEmail: params.userEmail,
userName: params.userName,
machineNumbers: params.machineNumbers
},
JuceKeyFileUtils.toString(date)
);
return JuceKeyFileUtils.createKeyFile(
comment,
xml,
new JuceRSAKey(params.privateKey)
);
}
static generateExpiringKeyFile(params, date = /* @__PURE__ */ new Date()) {
const xml = JuceKeyFileUtils.createKeyFileContentLine(
{
appName: params.appName,
userEmail: params.userEmail,
userName: params.userName,
machineNumbers: params.machineNumbers,
machineNumbersAttributeName: "expiring_mach"
},
JuceKeyFileUtils.toHexStringMilliseconds(date),
JuceKeyFileUtils.toHexStringMilliseconds(params.expiryTime)
);
const comment = JuceKeyFileUtils.createKeyFileComment(
{
appName: params.appName,
userEmail: params.userEmail,
userName: params.userName,
machineNumbers: params.machineNumbers
},
JuceKeyFileUtils.toString(date),
JuceKeyFileUtils.toString(params.expiryTime)
);
return JuceKeyFileUtils.createKeyFile(
comment,
xml,
new JuceRSAKey(params.privateKey)
);
}
};
// src/types.ts
var import_zod = require("zod");
var createKeyFileCommentParamsValidator = import_zod.z.object({
appName: import_zod.z.string().min(1),
userEmail: import_zod.z.string().min(1).email(),
userName: import_zod.z.string().min(1),
machineNumbers: import_zod.z.string().min(1)
});
var machineNumbersAttributeNameValidator = import_zod.z.enum([
"mach",
"expiring_mach"
]);
var createKeyFileContentLineParamsValidator = createKeyFileCommentParamsValidator.extend({
machineNumbersAttributeName: machineNumbersAttributeNameValidator
});
var rsaKeyComponentsValidator = import_zod.z.string().refine(
// Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()
(x) => x.includes(",") && x.split(",").every((p) => !JuceBigInteger.fromHex(p).isZero())
);
var generateKeyFileParamsValidator = createKeyFileCommentParamsValidator.extend({
privateKey: rsaKeyComponentsValidator
});
var generateExpiringKeyFileParamsValidator = generateKeyFileParamsValidator.extend({
expiryTime: import_zod.z.date().min(/* @__PURE__ */ new Date("1970-01-01T00:00:00.001Z"), {
message: "Expiry time must be after 1970-01-01T00:00:00.000Z"
})
});
// src/generateKeyFile.ts
var generateKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
const paramsParse = generateKeyFileParamsValidator.parse(params);
return JuceKeyGeneration.generateKeyFile(paramsParse, date);
};
// src/generateExpiringKeyFile.ts
var generateExpiringKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
const paramsParse = generateExpiringKeyFileParamsValidator.parse(params);
return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date);
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
generateExpiringKeyFile,
generateKeyFile
});
//# sourceMappingURL=index.cjs.map