@ianacaburian/generate-key-file 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/dist/index.cjs +67 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -37
- package/dist/index.d.ts +8 -37
- package/dist/index.js +64 -73
- package/dist/index.js.map +1 -1
- package/package.json +24 -24
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@ Ports juce_KeyGeneration::generateKeyFile() to node.
|
|
|
6
6
|
[](https://www.npmjs.com/package/@ianacaburian/generate-key-file)
|
|
7
7
|
[](https://twitter.com/intent/tweet?text=Need%20to%20auth%20a%20JUCE%20app%20in%20nodejs%20%3F%20Check%20out%20generate-key-file%20by%20%40ianacaburian%20%20&url=https%3A%2F%2Fgithub.com%2Fianacaburian%2Fgenerate-key-file)
|
|
8
8
|
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
Node.js >= 24
|
|
12
|
+
|
|
9
13
|
## Installation
|
|
10
14
|
|
|
11
15
|
```
|
|
@@ -39,7 +43,7 @@ const keyFileContent = generateKeyFile({
|
|
|
39
43
|
- Returns the <key> string value to be used in the XML response for decryption
|
|
40
44
|
by the client.
|
|
41
45
|
- Throws ZodError for invalid params -- see
|
|
42
|
-
[zod](https://
|
|
46
|
+
[zod](https://zod.dev).
|
|
43
47
|
- From juce_KeyFileGeneration.h:
|
|
44
48
|
|
|
45
49
|
```
|
|
@@ -80,7 +84,7 @@ const expiringKeyFileContent = generateExpiringKeyFile({
|
|
|
80
84
|
userEmail: 'ian@email.com',
|
|
81
85
|
machineNumbers: '123',
|
|
82
86
|
appName: 'app-name-or-product-id',
|
|
83
|
-
privateKey: 'comma-sep-private-key'
|
|
87
|
+
privateKey: 'comma-sep-private-key',
|
|
84
88
|
expiryTime: oneDayFromNow
|
|
85
89
|
})
|
|
86
90
|
```
|
|
@@ -88,7 +92,7 @@ const expiringKeyFileContent = generateExpiringKeyFile({
|
|
|
88
92
|
- Returns the <key> string value to be used in the XML response for decryption
|
|
89
93
|
by the client.
|
|
90
94
|
- Throws ZodError for invalid params -- see
|
|
91
|
-
[zod](https://
|
|
95
|
+
[zod](https://zod.dev).
|
|
92
96
|
- From juce_KeyFileGeneration.h:
|
|
93
97
|
|
|
94
98
|
```
|
|
@@ -116,13 +120,13 @@ npm run build # Lint, install tests, and build package.
|
|
|
116
120
|
```
|
|
117
121
|
npm run test # Start vitest to run all tests.
|
|
118
122
|
npm run test -- -t "divideBy" # Start vitest to run one test.
|
|
119
|
-
npm run clean
|
|
120
|
-
npm run open
|
|
121
|
-
npm run install
|
|
123
|
+
npm run cm:clean # Clean test build.
|
|
124
|
+
npm run cm:open # Open test/console project in Xcode.
|
|
125
|
+
npm run cm:install # Build and install the test/console bins.
|
|
122
126
|
```
|
|
123
127
|
|
|
124
|
-
- Optional: Set "
|
|
125
|
-
each (randomly generated)
|
|
128
|
+
- Optional: Set "FC_NUM_RUNS" (default=1) to specify how many times to run
|
|
129
|
+
each (randomly generated) property-based test -- see
|
|
126
130
|
[fast-check](https://github.com/dubzzz/fast-check).
|
|
127
131
|
|
|
128
132
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -18,48 +18,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
23
|
generateExpiringKeyFile: () => generateExpiringKeyFile,
|
|
24
24
|
generateKeyFile: () => generateKeyFile
|
|
25
25
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
27
|
-
|
|
28
|
-
// src/juce/JuceDateString.ts
|
|
29
|
-
var JuceDateString = class {
|
|
30
|
-
static inHexMs(date) {
|
|
31
|
-
return date.getTime().toString(16);
|
|
32
|
-
}
|
|
33
|
-
static inFormattedComment(date) {
|
|
34
|
-
const months = [
|
|
35
|
-
"Jan",
|
|
36
|
-
"Feb",
|
|
37
|
-
"Mar",
|
|
38
|
-
"Apr",
|
|
39
|
-
"May",
|
|
40
|
-
"Jun",
|
|
41
|
-
"Jul",
|
|
42
|
-
"Aug",
|
|
43
|
-
"Sep",
|
|
44
|
-
"Oct",
|
|
45
|
-
"Nov",
|
|
46
|
-
"Dec"
|
|
47
|
-
];
|
|
48
|
-
const day = date.getDate().toString();
|
|
49
|
-
const month = months[date.getMonth()];
|
|
50
|
-
const year = date.getFullYear();
|
|
51
|
-
let hours = date.getHours();
|
|
52
|
-
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
53
|
-
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
54
|
-
const ampm = hours >= 12 ? "pm" : "am";
|
|
55
|
-
hours = hours % 12;
|
|
56
|
-
hours = hours ? hours : 12;
|
|
57
|
-
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// src/juce/JuceKeyFileUtils.ts
|
|
62
|
-
var import_fast_xml_parser = require("fast-xml-parser");
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
63
27
|
|
|
64
28
|
// src/juce/JuceBigInteger.ts
|
|
65
29
|
var import_jsbn = require("jsbn");
|
|
@@ -121,18 +85,44 @@ var xmlAttributeCharProcessor = (char) => (
|
|
|
121
85
|
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
|
|
122
86
|
char.length !== 1 ? "" : legalXmlCharRegex.test(char) ? char : char === "&" ? "&" : char === '"' ? """ : char === ">" ? ">" : char === "<" ? "<" : `&#${char.charCodeAt(0)};`
|
|
123
87
|
);
|
|
124
|
-
var
|
|
88
|
+
var escapeAttr = (value) => (
|
|
125
89
|
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
|
|
126
|
-
|
|
90
|
+
value.split("").map(xmlAttributeCharProcessor).join("")
|
|
127
91
|
);
|
|
128
|
-
var
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
processEntities: false,
|
|
133
|
-
attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)
|
|
134
|
-
});
|
|
92
|
+
var buildKeyElement = (attrs) => {
|
|
93
|
+
const attrStr = Object.entries(attrs).map(([k, v]) => `${k}="${escapeAttr(v)}"`).join(" ");
|
|
94
|
+
return `<key ${attrStr}/>`;
|
|
95
|
+
};
|
|
135
96
|
var JuceKeyFileUtils = class {
|
|
97
|
+
static toString(date) {
|
|
98
|
+
const months = [
|
|
99
|
+
"Jan",
|
|
100
|
+
"Feb",
|
|
101
|
+
"Mar",
|
|
102
|
+
"Apr",
|
|
103
|
+
"May",
|
|
104
|
+
"Jun",
|
|
105
|
+
"Jul",
|
|
106
|
+
"Aug",
|
|
107
|
+
"Sep",
|
|
108
|
+
"Oct",
|
|
109
|
+
"Nov",
|
|
110
|
+
"Dec"
|
|
111
|
+
];
|
|
112
|
+
const day = date.getDate().toString();
|
|
113
|
+
const month = months[date.getMonth()];
|
|
114
|
+
const year = date.getFullYear();
|
|
115
|
+
let hours = date.getHours();
|
|
116
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
117
|
+
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
118
|
+
const ampm = hours >= 12 ? "pm" : "am";
|
|
119
|
+
hours = hours % 12;
|
|
120
|
+
hours = hours ? hours : 12;
|
|
121
|
+
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
|
|
122
|
+
}
|
|
123
|
+
static toHexStringMilliseconds(date) {
|
|
124
|
+
return date.getTime().toString(16);
|
|
125
|
+
}
|
|
136
126
|
static createKeyFileContentLine({
|
|
137
127
|
appName,
|
|
138
128
|
userEmail,
|
|
@@ -140,17 +130,15 @@ var JuceKeyFileUtils = class {
|
|
|
140
130
|
machineNumbers,
|
|
141
131
|
machineNumbersAttributeName
|
|
142
132
|
}, date, expiryTime) {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
"@_date": date,
|
|
150
|
-
...expiryTime ? { "@_expiryTime": expiryTime } : {}
|
|
151
|
-
}
|
|
133
|
+
const attrs = {
|
|
134
|
+
user: userName,
|
|
135
|
+
email: userEmail,
|
|
136
|
+
[machineNumbersAttributeName]: machineNumbers,
|
|
137
|
+
app: appName,
|
|
138
|
+
date
|
|
152
139
|
};
|
|
153
|
-
|
|
140
|
+
if (expiryTime) attrs.expiryTime = expiryTime;
|
|
141
|
+
return [XML_DECLARATION, buildKeyElement(attrs)].join(" ");
|
|
154
142
|
}
|
|
155
143
|
static createKeyFileComment({
|
|
156
144
|
appName,
|
|
@@ -225,7 +213,7 @@ var JuceKeyGeneration = class {
|
|
|
225
213
|
machineNumbers: params.machineNumbers,
|
|
226
214
|
machineNumbersAttributeName: "mach"
|
|
227
215
|
},
|
|
228
|
-
|
|
216
|
+
JuceKeyFileUtils.toHexStringMilliseconds(date)
|
|
229
217
|
);
|
|
230
218
|
const comment = JuceKeyFileUtils.createKeyFileComment(
|
|
231
219
|
{
|
|
@@ -234,7 +222,7 @@ var JuceKeyGeneration = class {
|
|
|
234
222
|
userName: params.userName,
|
|
235
223
|
machineNumbers: params.machineNumbers
|
|
236
224
|
},
|
|
237
|
-
|
|
225
|
+
JuceKeyFileUtils.toString(date)
|
|
238
226
|
);
|
|
239
227
|
return JuceKeyFileUtils.createKeyFile(
|
|
240
228
|
comment,
|
|
@@ -251,8 +239,8 @@ var JuceKeyGeneration = class {
|
|
|
251
239
|
machineNumbers: params.machineNumbers,
|
|
252
240
|
machineNumbersAttributeName: "expiring_mach"
|
|
253
241
|
},
|
|
254
|
-
|
|
255
|
-
|
|
242
|
+
JuceKeyFileUtils.toHexStringMilliseconds(date),
|
|
243
|
+
JuceKeyFileUtils.toHexStringMilliseconds(params.expiryTime)
|
|
256
244
|
);
|
|
257
245
|
const comment = JuceKeyFileUtils.createKeyFileComment(
|
|
258
246
|
{
|
|
@@ -261,8 +249,8 @@ var JuceKeyGeneration = class {
|
|
|
261
249
|
userName: params.userName,
|
|
262
250
|
machineNumbers: params.machineNumbers
|
|
263
251
|
},
|
|
264
|
-
|
|
265
|
-
|
|
252
|
+
JuceKeyFileUtils.toString(date),
|
|
253
|
+
JuceKeyFileUtils.toString(params.expiryTime)
|
|
266
254
|
);
|
|
267
255
|
return JuceKeyFileUtils.createKeyFile(
|
|
268
256
|
comment,
|
|
@@ -274,39 +262,42 @@ var JuceKeyGeneration = class {
|
|
|
274
262
|
|
|
275
263
|
// src/types.ts
|
|
276
264
|
var import_zod = require("zod");
|
|
277
|
-
var
|
|
265
|
+
var createKeyFileCommentParamsSchema = import_zod.z.object({
|
|
278
266
|
appName: import_zod.z.string().min(1),
|
|
279
|
-
userEmail: import_zod.z.string().min(1)
|
|
267
|
+
userEmail: import_zod.z.string().min(1),
|
|
280
268
|
userName: import_zod.z.string().min(1),
|
|
281
269
|
machineNumbers: import_zod.z.string().min(1)
|
|
282
270
|
});
|
|
283
|
-
var
|
|
271
|
+
var machineNumbersAttributeNameSchema = import_zod.z.enum([
|
|
284
272
|
"mach",
|
|
285
273
|
"expiring_mach"
|
|
286
274
|
]);
|
|
287
|
-
var
|
|
288
|
-
machineNumbersAttributeName:
|
|
275
|
+
var createKeyFileContentLineParamsSchema = createKeyFileCommentParamsSchema.extend({
|
|
276
|
+
machineNumbersAttributeName: machineNumbersAttributeNameSchema
|
|
289
277
|
});
|
|
290
|
-
var
|
|
278
|
+
var rsaKeyComponentsSchema = import_zod.z.stringFormat(
|
|
291
279
|
// Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()
|
|
280
|
+
"RSAKeyComponents",
|
|
292
281
|
(x) => x.includes(",") && x.split(",").every((p) => !JuceBigInteger.fromHex(p).isZero())
|
|
293
282
|
);
|
|
294
|
-
var
|
|
295
|
-
privateKey:
|
|
283
|
+
var generateKeyFileParamsSchema = createKeyFileCommentParamsSchema.extend({
|
|
284
|
+
privateKey: rsaKeyComponentsSchema
|
|
296
285
|
});
|
|
297
|
-
var
|
|
298
|
-
expiryTime: import_zod.z.date()
|
|
286
|
+
var generateExpiringKeyFileParamsSchema = generateKeyFileParamsSchema.extend({
|
|
287
|
+
expiryTime: import_zod.z.date().min(/* @__PURE__ */ new Date("1970-01-01T00:00:00.001Z"), {
|
|
288
|
+
error: "Expiry time must be after 1970-01-01T00:00:00.000Z"
|
|
289
|
+
})
|
|
299
290
|
});
|
|
300
291
|
|
|
301
292
|
// src/generateKeyFile.ts
|
|
302
293
|
var generateKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
|
|
303
|
-
const paramsParse =
|
|
294
|
+
const paramsParse = generateKeyFileParamsSchema.parse(params);
|
|
304
295
|
return JuceKeyGeneration.generateKeyFile(paramsParse, date);
|
|
305
296
|
};
|
|
306
297
|
|
|
307
298
|
// src/generateExpiringKeyFile.ts
|
|
308
299
|
var generateExpiringKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
|
|
309
|
-
const paramsParse =
|
|
300
|
+
const paramsParse = generateExpiringKeyFileParamsSchema.parse(params);
|
|
310
301
|
return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date);
|
|
311
302
|
};
|
|
312
303
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/juce/JuceDateString.ts","../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceBigInteger.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts","../src/types.ts","../src/generateKeyFile.ts","../src/generateExpiringKeyFile.ts"],"sourcesContent":["export {\n type GenerateKeyFileParams,\n type GenerateExpiringKeyFileParams\n} from './types'\n\nexport { generateKeyFile } from './generateKeyFile'\nexport { generateExpiringKeyFile } from './generateExpiringKeyFile'\n","export class JuceDateString {\n static inHexMs(date: Date): string {\n // Ports juce::String::toHexString (juce::Time::getCurrentTime().toMilliseconds())\n return date.getTime().toString(16)\n }\n\n static inFormattedComment(date: Date): string {\n // Ports juce::Time::getCurrentTime().toString (true, true)\n // prettier-ignore\n const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]\n const day = date.getDate().toString()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n let hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n const ampm = hours >= 12 ? 'pm' : 'am'\n hours = hours % 12\n hours = hours ? hours : 12\n return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`\n }\n}\n","import { XMLBuilder } from 'fast-xml-parser'\nimport {\n CreateKeyFileCommentParams,\n CreateKeyFileContentLineParams\n} from 'src/types'\n\nimport { JuceBigInteger } from './JuceBigInteger'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n\nconst legalXmlCharRegex =\n // Ports juce::XmlOutputFunctions::LegalCharLookupTable\n /^[a-zA-Z0-9 .,;:\\-()_+=?!$#@[\\]/|*%~{}'\\\\]$/\n\nconst xmlAttributeCharProcessor = (char: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n char.length !== 1\n ? ''\n : legalXmlCharRegex.test(char)\n ? char\n : char === '&'\n ? '&'\n : char === '\"'\n ? '"'\n : char === '>'\n ? '>'\n : char === '<'\n ? '<'\n : `&#${char.charCodeAt(0)};`\n\nconst xmlAttributeValueProcessor = (value: unknown): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n typeof value !== 'string'\n ? ''\n : value.split('').map(xmlAttributeCharProcessor).join('')\n\nconst xmlBuilder = new XMLBuilder({\n ignoreAttributes: false,\n suppressEmptyNode: true,\n // processEntities is disabled since it doesn't port to juce as is\n processEntities: false,\n attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)\n})\n\nexport class JuceKeyFileUtils {\n static createKeyFileContentLine(\n {\n appName,\n userEmail,\n userName,\n machineNumbers,\n machineNumbersAttributeName\n }: CreateKeyFileContentLineParams,\n date: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileContent\n // and juce::KeyFileUtils::encryptXML\n const xml = {\n key: {\n '@_user': userName,\n '@_email': userEmail,\n [`@_${machineNumbersAttributeName}`]: machineNumbers,\n '@_app': appName,\n '@_date': date,\n ...(expiryTime ? { '@_expiryTime': expiryTime } : {})\n }\n }\n return [XML_DECLARATION, xmlBuilder.build(xml).trim()].join(' ')\n }\n\n static createKeyFileComment(\n {\n appName,\n userEmail,\n userName,\n machineNumbers\n }: CreateKeyFileCommentParams,\n created: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileComment\n return (\n `Keyfile for ${appName}\\r\\n` +\n `${userName ? `User: ${userName}\\r\\n` : ''}` +\n `Email: ${userEmail}\\r\\n` +\n `Machine numbers: ${machineNumbers}\\r\\n` +\n `Created: ${created}` +\n (expiryTime ? `\\r\\nExpires: ${expiryTime}` : '')\n )\n }\n\n static encryptXMLLine(xmlLine: string, privateKey: JuceRSAKey): string {\n // Ports juce::KeyFileUtils::encryptXML\n const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine)\n privateKey.applyToValue(val)\n return val.toHex()\n }\n\n static createKeyFile(\n comment: string,\n xmlLine: string,\n rsaPrivateKey: JuceRSAKey\n ): string {\n // Ports juce::KeyFileUtils::createKeyFile\n let asHex = '#' + this.encryptXMLLine(xmlLine, rsaPrivateKey)\n\n const lines: string[] = []\n lines.push(comment)\n lines.push('')\n\n const charsPerLine = 70\n while (asHex.length > 0) {\n lines.push(asHex.substring(0, charsPerLine))\n asHex = asHex.substring(charsPerLine)\n }\n\n lines.push('')\n\n return lines.join('\\r\\n')\n }\n}\n","import { BigInteger as JSBN } from 'jsbn'\n\nexport class JuceBigInteger {\n constructor(public value: bigint = 0n) {}\n\n static fromJSBN(b: JSBN): JuceBigInteger {\n return JuceBigInteger.fromHex(b.toString(16))\n }\n\n toJSBN(): JSBN {\n return new JSBN(this.toHex(), 16)\n }\n\n static fromHex(hex: string): JuceBigInteger {\n const h = hex.trim()\n return new JuceBigInteger(h ? BigInt(`0x${h}`) : 0n)\n }\n\n toHex(): string {\n return this.value.toString(16)\n }\n\n static fromUTF8MemoryBlock(input: string): JuceBigInteger {\n // Ports juce::BigInteger::loadFromMemoryBlock()\n const u = Buffer.from(input, 'utf8')\n const b = new JuceBigInteger()\n for (let i = u.length - 1; i >= 0; i--) {\n b.value = (b.value << 8n) | BigInt(u[i])\n }\n return b\n }\n\n isZero(): boolean {\n return this.value === 0n\n }\n\n divideBy(divisor: JuceBigInteger, remainder: JuceBigInteger): void {\n // Ports juce::BigInteger::divideBy()\n if (divisor.isZero()) {\n this.value = 0n\n return\n }\n const b = this.toJSBN()\n const d = divisor.toJSBN()\n const [q, r] = b.divideAndRemainder(d)\n this.value = JuceBigInteger.fromJSBN(q).value\n remainder.value = JuceBigInteger.fromJSBN(r).value\n }\n\n exponentModulo(exponent: JuceBigInteger, modulus: JuceBigInteger): void {\n // Ports juce::BigInteger::exponentModulo()\n const b = this.toJSBN()\n const e = exponent.toJSBN()\n const m = modulus.toJSBN()\n const em = b.modPow(e, m)\n this.value = JuceBigInteger.fromJSBN(em).value\n }\n}\n","import { JuceBigInteger } from './JuceBigInteger'\n\nexport class JuceRSAKey {\n protected part1: JuceBigInteger\n protected part2: JuceBigInteger\n constructor(public s: string) {\n // Ports juce::RSAKey::RSAKey()\n if (s.includes(',')) {\n const [p1, p2] = s.split(',').map(p => JuceBigInteger.fromHex(p))\n this.part1 = p1\n this.part2 = p2\n } else {\n this.part1 = new JuceBigInteger()\n this.part2 = new JuceBigInteger()\n }\n }\n applyToValue(val: JuceBigInteger): void {\n // Ports juce::RSAKey::applyToValue()\n if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {\n return\n }\n\n const result = new JuceBigInteger()\n\n while (!val.isZero()) {\n result.value *= this.part2.value\n\n const remainder = new JuceBigInteger()\n val.divideBy(this.part2, remainder)\n\n remainder.exponentModulo(this.part1, this.part2)\n\n result.value += remainder.value\n }\n\n val.value = result.value\n }\n}\n","import { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from 'src/types'\n\nimport { JuceDateString } from './JuceDateString'\nimport { JuceKeyFileUtils } from './JuceKeyFileUtils'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nexport class JuceKeyGeneration {\n static generateKeyFile(\n params: GenerateKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'mach'\n },\n JuceDateString.inHexMs(date)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceDateString.inFormattedComment(date)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n\n static generateExpiringKeyFile(\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'expiring_mach'\n },\n JuceDateString.inHexMs(date),\n JuceDateString.inHexMs(params.expiryTime)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceDateString.inFormattedComment(date),\n JuceDateString.inFormattedComment(params.expiryTime)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n}\n","import { z } from 'zod'\n\nimport { JuceBigInteger } from './juce/JuceBigInteger'\n\nexport const createKeyFileCommentParamsValidator = z.object({\n appName: z.string().min(1),\n userEmail: z.string().min(1).email(),\n userName: z.string().min(1),\n machineNumbers: z.string().min(1)\n})\nexport type CreateKeyFileCommentParams = z.infer<\n typeof createKeyFileCommentParamsValidator\n>\n\nexport const machineNumbersAttributeNameValidator = z.enum([\n 'mach',\n 'expiring_mach'\n])\nexport type MachineNumbersAttributeName = z.infer<\n typeof machineNumbersAttributeNameValidator\n>\n\nexport const createKeyFileContentLineParamsValidator =\n createKeyFileCommentParamsValidator.extend({\n machineNumbersAttributeName: machineNumbersAttributeNameValidator\n })\nexport type CreateKeyFileContentLineParams = z.infer<\n typeof createKeyFileContentLineParamsValidator\n>\n\nexport const rsaKeyComponentsValidator = z.string().refine(\n // Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()\n x =>\n x.includes(',') &&\n x.split(',').every(p => !JuceBigInteger.fromHex(p).isZero())\n)\nexport type RSAKeyComponents = z.infer<typeof rsaKeyComponentsValidator>\n\nexport const generateKeyFileParamsValidator =\n createKeyFileCommentParamsValidator.extend({\n privateKey: rsaKeyComponentsValidator\n })\nexport type GenerateKeyFileParams = z.infer<\n typeof generateKeyFileParamsValidator\n>\n\nexport const generateExpiringKeyFileParamsValidator =\n generateKeyFileParamsValidator.extend({\n expiryTime: z.date()\n })\nexport type GenerateExpiringKeyFileParams = z.infer<\n typeof generateExpiringKeyFileParamsValidator\n>\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport { GenerateKeyFileParams, generateKeyFileParamsValidator } from './types'\n\nexport const generateKeyFile = (\n params: GenerateKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateKeyFileParamsValidator.parse(params)\n return JuceKeyGeneration.generateKeyFile(paramsParse, date)\n}\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport {\n GenerateExpiringKeyFileParams,\n generateExpiringKeyFileParamsValidator\n} from './types'\n\nexport const generateExpiringKeyFile = (\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateExpiringKeyFileParamsValidator.parse(params)\n return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date)\n}\n"],"mappings":"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","names":["JSBN"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/juce/JuceBigInteger.ts","../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts","../src/types.ts","../src/generateKeyFile.ts","../src/generateExpiringKeyFile.ts"],"sourcesContent":["export {\n type GenerateKeyFileParams,\n type GenerateExpiringKeyFileParams\n} from './types'\n\nexport { generateKeyFile } from './generateKeyFile'\nexport { generateExpiringKeyFile } from './generateExpiringKeyFile'\n","import { BigInteger as JSBN } from 'jsbn'\n\nexport class JuceBigInteger {\n constructor(public value: bigint = 0n) {}\n\n static fromJSBN(b: JSBN): JuceBigInteger {\n return JuceBigInteger.fromHex(b.toString(16))\n }\n\n toJSBN(): JSBN {\n return new JSBN(this.toHex(), 16)\n }\n\n static fromHex(hex: string): JuceBigInteger {\n const h = hex.trim()\n return new JuceBigInteger(h ? BigInt(`0x${h}`) : 0n)\n }\n\n toHex(): string {\n return this.value.toString(16)\n }\n\n static fromUTF8MemoryBlock(input: string): JuceBigInteger {\n // Ports juce::BigInteger::loadFromMemoryBlock()\n const u = Buffer.from(input, 'utf8')\n const b = new JuceBigInteger()\n for (let i = u.length - 1; i >= 0; i--) {\n b.value = (b.value << 8n) | BigInt(u[i])\n }\n return b\n }\n\n isZero(): boolean {\n return this.value === 0n\n }\n\n divideBy(divisor: JuceBigInteger, remainder: JuceBigInteger): void {\n // Ports juce::BigInteger::divideBy()\n if (divisor.isZero()) {\n this.value = 0n\n return\n }\n const b = this.toJSBN()\n const d = divisor.toJSBN()\n const [q, r] = b.divideAndRemainder(d)\n this.value = JuceBigInteger.fromJSBN(q).value\n remainder.value = JuceBigInteger.fromJSBN(r).value\n }\n\n exponentModulo(exponent: JuceBigInteger, modulus: JuceBigInteger): void {\n // Ports juce::BigInteger::exponentModulo()\n const b = this.toJSBN()\n const e = exponent.toJSBN()\n const m = modulus.toJSBN()\n const em = b.modPow(e, m)\n this.value = JuceBigInteger.fromJSBN(em).value\n }\n}\n","import {\n CreateKeyFileCommentParams,\n CreateKeyFileContentLineParams\n} from '../types'\nimport { JuceBigInteger } from './JuceBigInteger'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n\nconst legalXmlCharRegex =\n // Ports juce::XmlOutputFunctions::LegalCharLookupTable\n /^[a-zA-Z0-9 .,;:\\-()_+=?!$#@[\\]/|*%~{}'\\\\]$/\n\nconst xmlAttributeCharProcessor = (char: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n char.length !== 1\n ? ''\n : legalXmlCharRegex.test(char)\n ? char\n : char === '&'\n ? '&'\n : char === '\"'\n ? '"'\n : char === '>'\n ? '>'\n : char === '<'\n ? '<'\n : `&#${char.charCodeAt(0)};`\n\nconst escapeAttr = (value: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n value.split('').map(xmlAttributeCharProcessor).join('')\n\nconst buildKeyElement = (attrs: Record<string, string>): string => {\n // Builds <key attr=\"val\" .../> without delegating to fast-xml-parser,\n // which unconditionally escapes single quotes in attribute values in v5\n // — breaking the JUCE port (single quote is a legal char in JUCE XML).\n const attrStr = Object.entries(attrs)\n .map(([k, v]) => `${k}=\"${escapeAttr(v)}\"`)\n .join(' ')\n return `<key ${attrStr}/>`\n}\n\nexport class JuceKeyFileUtils {\n static toString(date: Date): string {\n // Ports juce::Time::getCurrentTime().toString (true, true)\n // prettier-ignore\n const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]\n const day = date.getDate().toString()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n let hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n const ampm = hours >= 12 ? 'pm' : 'am'\n hours = hours % 12\n hours = hours ? hours : 12\n return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`\n }\n\n static toHexStringMilliseconds(date: Date): string {\n // Ports juce::String::toHexString (juce::Time::getCurrentTime().toMilliseconds())\n return date.getTime().toString(16)\n }\n\n static createKeyFileContentLine(\n {\n appName,\n userEmail,\n userName,\n machineNumbers,\n machineNumbersAttributeName\n }: CreateKeyFileContentLineParams,\n date: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileContent\n // and juce::KeyFileUtils::encryptXML\n const attrs: Record<string, string> = {\n user: userName,\n email: userEmail,\n [machineNumbersAttributeName]: machineNumbers,\n app: appName,\n date\n }\n if (expiryTime) attrs.expiryTime = expiryTime\n return [XML_DECLARATION, buildKeyElement(attrs)].join(' ')\n }\n\n static createKeyFileComment(\n {\n appName,\n userEmail,\n userName,\n machineNumbers\n }: CreateKeyFileCommentParams,\n created: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileComment\n return (\n `Keyfile for ${appName}\\r\\n` +\n `${userName ? `User: ${userName}\\r\\n` : ''}` +\n `Email: ${userEmail}\\r\\n` +\n `Machine numbers: ${machineNumbers}\\r\\n` +\n `Created: ${created}` +\n (expiryTime ? `\\r\\nExpires: ${expiryTime}` : '')\n )\n }\n\n static encryptXMLLine(xmlLine: string, privateKey: JuceRSAKey): string {\n // Ports juce::KeyFileUtils::encryptXML\n const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine)\n privateKey.applyToValue(val)\n return val.toHex()\n }\n\n static createKeyFile(\n comment: string,\n xmlLine: string,\n rsaPrivateKey: JuceRSAKey\n ): string {\n // Ports juce::KeyFileUtils::createKeyFile\n let asHex = '#' + this.encryptXMLLine(xmlLine, rsaPrivateKey)\n\n const lines: string[] = []\n lines.push(comment)\n lines.push('')\n\n const charsPerLine = 70\n while (asHex.length > 0) {\n lines.push(asHex.substring(0, charsPerLine))\n asHex = asHex.substring(charsPerLine)\n }\n\n lines.push('')\n\n return lines.join('\\r\\n')\n }\n}\n","import { JuceBigInteger } from './JuceBigInteger'\n\nexport class JuceRSAKey {\n protected part1: JuceBigInteger\n protected part2: JuceBigInteger\n constructor(public s: string) {\n // Ports juce::RSAKey::RSAKey()\n if (s.includes(',')) {\n const [p1, p2] = s.split(',').map(p => JuceBigInteger.fromHex(p))\n this.part1 = p1\n this.part2 = p2\n } else {\n this.part1 = new JuceBigInteger()\n this.part2 = new JuceBigInteger()\n }\n }\n applyToValue(val: JuceBigInteger): void {\n // Ports juce::RSAKey::applyToValue()\n if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {\n return\n }\n\n const result = new JuceBigInteger()\n\n while (!val.isZero()) {\n result.value *= this.part2.value\n\n const remainder = new JuceBigInteger()\n val.divideBy(this.part2, remainder)\n\n remainder.exponentModulo(this.part1, this.part2)\n\n result.value += remainder.value\n }\n\n val.value = result.value\n }\n}\n","import { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from '../types'\nimport { JuceKeyFileUtils } from './JuceKeyFileUtils'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nexport class JuceKeyGeneration {\n static generateKeyFile(\n params: GenerateKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'mach'\n },\n JuceKeyFileUtils.toHexStringMilliseconds(date)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceKeyFileUtils.toString(date)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n\n static generateExpiringKeyFile(\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'expiring_mach'\n },\n JuceKeyFileUtils.toHexStringMilliseconds(date),\n JuceKeyFileUtils.toHexStringMilliseconds(params.expiryTime)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceKeyFileUtils.toString(date),\n JuceKeyFileUtils.toString(params.expiryTime)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n}\n","import { z } from 'zod'\n\nimport { JuceBigInteger } from './juce/JuceBigInteger'\n\nexport const createKeyFileCommentParamsSchema = z.object({\n appName: z.string().min(1),\n userEmail: z.string().min(1),\n userName: z.string().min(1),\n machineNumbers: z.string().min(1)\n})\nexport type CreateKeyFileCommentParams = z.infer<\n typeof createKeyFileCommentParamsSchema\n>\n\nexport const machineNumbersAttributeNameSchema = z.enum([\n 'mach',\n 'expiring_mach'\n])\nexport type MachineNumbersAttributeName = z.infer<\n typeof machineNumbersAttributeNameSchema\n>\n\nexport const createKeyFileContentLineParamsSchema =\n createKeyFileCommentParamsSchema.extend({\n machineNumbersAttributeName: machineNumbersAttributeNameSchema\n })\nexport type CreateKeyFileContentLineParams = z.infer<\n typeof createKeyFileContentLineParamsSchema\n>\n\nexport const rsaKeyComponentsSchema = z.stringFormat(\n // Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()\n 'RSAKeyComponents',\n x =>\n x.includes(',') &&\n x.split(',').every(p => !JuceBigInteger.fromHex(p).isZero())\n)\nexport type RSAKeyComponents = z.infer<typeof rsaKeyComponentsSchema>\n\nexport const generateKeyFileParamsSchema =\n createKeyFileCommentParamsSchema.extend({\n privateKey: rsaKeyComponentsSchema\n })\nexport type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsSchema>\n\nexport const generateExpiringKeyFileParamsSchema =\n generateKeyFileParamsSchema.extend({\n expiryTime: z.date().min(new Date('1970-01-01T00:00:00.001Z'), {\n error: 'Expiry time must be after 1970-01-01T00:00:00.000Z'\n })\n })\nexport type GenerateExpiringKeyFileParams = z.infer<\n typeof generateExpiringKeyFileParamsSchema\n>\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport { GenerateKeyFileParams, generateKeyFileParamsSchema } from './types'\n\nexport const generateKeyFile = (\n params: GenerateKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateKeyFileParamsSchema.parse(params)\n return JuceKeyGeneration.generateKeyFile(paramsParse, date)\n}\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport {\n GenerateExpiringKeyFileParams,\n generateExpiringKeyFileParamsSchema\n} from './types'\n\nexport const generateExpiringKeyFile = (\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateExpiringKeyFileParamsSchema.parse(params)\n return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date)\n}\n"],"mappings":"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","names":["JSBN"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,51 +1,22 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
declare const
|
|
3
|
+
declare const generateKeyFileParamsSchema: z.ZodObject<{
|
|
4
4
|
appName: z.ZodString;
|
|
5
5
|
userEmail: z.ZodString;
|
|
6
6
|
userName: z.ZodString;
|
|
7
7
|
machineNumbers: z.ZodString;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
userEmail: string;
|
|
13
|
-
userName: string;
|
|
14
|
-
machineNumbers: string;
|
|
15
|
-
privateKey: string;
|
|
16
|
-
}, {
|
|
17
|
-
appName: string;
|
|
18
|
-
userEmail: string;
|
|
19
|
-
userName: string;
|
|
20
|
-
machineNumbers: string;
|
|
21
|
-
privateKey: string;
|
|
22
|
-
}>;
|
|
23
|
-
type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsValidator>;
|
|
24
|
-
declare const generateExpiringKeyFileParamsValidator: z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<{
|
|
8
|
+
privateKey: z.ZodCustomStringFormat<"RSAKeyComponents">;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsSchema>;
|
|
11
|
+
declare const generateExpiringKeyFileParamsSchema: z.ZodObject<{
|
|
25
12
|
appName: z.ZodString;
|
|
26
13
|
userEmail: z.ZodString;
|
|
27
14
|
userName: z.ZodString;
|
|
28
15
|
machineNumbers: z.ZodString;
|
|
29
|
-
|
|
30
|
-
privateKey: z.ZodEffects<z.ZodString, string, string>;
|
|
31
|
-
}>, {
|
|
16
|
+
privateKey: z.ZodCustomStringFormat<"RSAKeyComponents">;
|
|
32
17
|
expiryTime: z.ZodDate;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
userEmail: string;
|
|
36
|
-
userName: string;
|
|
37
|
-
machineNumbers: string;
|
|
38
|
-
privateKey: string;
|
|
39
|
-
expiryTime: Date;
|
|
40
|
-
}, {
|
|
41
|
-
appName: string;
|
|
42
|
-
userEmail: string;
|
|
43
|
-
userName: string;
|
|
44
|
-
machineNumbers: string;
|
|
45
|
-
privateKey: string;
|
|
46
|
-
expiryTime: Date;
|
|
47
|
-
}>;
|
|
48
|
-
type GenerateExpiringKeyFileParams = z.infer<typeof generateExpiringKeyFileParamsValidator>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
type GenerateExpiringKeyFileParams = z.infer<typeof generateExpiringKeyFileParamsSchema>;
|
|
49
20
|
|
|
50
21
|
declare const generateKeyFile: (params: GenerateKeyFileParams, date?: Date) => string;
|
|
51
22
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,51 +1,22 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
declare const
|
|
3
|
+
declare const generateKeyFileParamsSchema: z.ZodObject<{
|
|
4
4
|
appName: z.ZodString;
|
|
5
5
|
userEmail: z.ZodString;
|
|
6
6
|
userName: z.ZodString;
|
|
7
7
|
machineNumbers: z.ZodString;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
userEmail: string;
|
|
13
|
-
userName: string;
|
|
14
|
-
machineNumbers: string;
|
|
15
|
-
privateKey: string;
|
|
16
|
-
}, {
|
|
17
|
-
appName: string;
|
|
18
|
-
userEmail: string;
|
|
19
|
-
userName: string;
|
|
20
|
-
machineNumbers: string;
|
|
21
|
-
privateKey: string;
|
|
22
|
-
}>;
|
|
23
|
-
type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsValidator>;
|
|
24
|
-
declare const generateExpiringKeyFileParamsValidator: z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<{
|
|
8
|
+
privateKey: z.ZodCustomStringFormat<"RSAKeyComponents">;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsSchema>;
|
|
11
|
+
declare const generateExpiringKeyFileParamsSchema: z.ZodObject<{
|
|
25
12
|
appName: z.ZodString;
|
|
26
13
|
userEmail: z.ZodString;
|
|
27
14
|
userName: z.ZodString;
|
|
28
15
|
machineNumbers: z.ZodString;
|
|
29
|
-
|
|
30
|
-
privateKey: z.ZodEffects<z.ZodString, string, string>;
|
|
31
|
-
}>, {
|
|
16
|
+
privateKey: z.ZodCustomStringFormat<"RSAKeyComponents">;
|
|
32
17
|
expiryTime: z.ZodDate;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
userEmail: string;
|
|
36
|
-
userName: string;
|
|
37
|
-
machineNumbers: string;
|
|
38
|
-
privateKey: string;
|
|
39
|
-
expiryTime: Date;
|
|
40
|
-
}, {
|
|
41
|
-
appName: string;
|
|
42
|
-
userEmail: string;
|
|
43
|
-
userName: string;
|
|
44
|
-
machineNumbers: string;
|
|
45
|
-
privateKey: string;
|
|
46
|
-
expiryTime: Date;
|
|
47
|
-
}>;
|
|
48
|
-
type GenerateExpiringKeyFileParams = z.infer<typeof generateExpiringKeyFileParamsValidator>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
type GenerateExpiringKeyFileParams = z.infer<typeof generateExpiringKeyFileParamsSchema>;
|
|
49
20
|
|
|
50
21
|
declare const generateKeyFile: (params: GenerateKeyFileParams, date?: Date) => string;
|
|
51
22
|
|
package/dist/index.js
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
// src/juce/JuceDateString.ts
|
|
2
|
-
var JuceDateString = class {
|
|
3
|
-
static inHexMs(date) {
|
|
4
|
-
return date.getTime().toString(16);
|
|
5
|
-
}
|
|
6
|
-
static inFormattedComment(date) {
|
|
7
|
-
const months = [
|
|
8
|
-
"Jan",
|
|
9
|
-
"Feb",
|
|
10
|
-
"Mar",
|
|
11
|
-
"Apr",
|
|
12
|
-
"May",
|
|
13
|
-
"Jun",
|
|
14
|
-
"Jul",
|
|
15
|
-
"Aug",
|
|
16
|
-
"Sep",
|
|
17
|
-
"Oct",
|
|
18
|
-
"Nov",
|
|
19
|
-
"Dec"
|
|
20
|
-
];
|
|
21
|
-
const day = date.getDate().toString();
|
|
22
|
-
const month = months[date.getMonth()];
|
|
23
|
-
const year = date.getFullYear();
|
|
24
|
-
let hours = date.getHours();
|
|
25
|
-
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
26
|
-
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
27
|
-
const ampm = hours >= 12 ? "pm" : "am";
|
|
28
|
-
hours = hours % 12;
|
|
29
|
-
hours = hours ? hours : 12;
|
|
30
|
-
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// src/juce/JuceKeyFileUtils.ts
|
|
35
|
-
import { XMLBuilder } from "fast-xml-parser";
|
|
36
|
-
|
|
37
1
|
// src/juce/JuceBigInteger.ts
|
|
38
2
|
import { BigInteger as JSBN } from "jsbn";
|
|
39
3
|
var JuceBigInteger = class _JuceBigInteger {
|
|
@@ -94,18 +58,44 @@ var xmlAttributeCharProcessor = (char) => (
|
|
|
94
58
|
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
|
|
95
59
|
char.length !== 1 ? "" : legalXmlCharRegex.test(char) ? char : char === "&" ? "&" : char === '"' ? """ : char === ">" ? ">" : char === "<" ? "<" : `&#${char.charCodeAt(0)};`
|
|
96
60
|
);
|
|
97
|
-
var
|
|
61
|
+
var escapeAttr = (value) => (
|
|
98
62
|
// Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
|
|
99
|
-
|
|
63
|
+
value.split("").map(xmlAttributeCharProcessor).join("")
|
|
100
64
|
);
|
|
101
|
-
var
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
processEntities: false,
|
|
106
|
-
attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)
|
|
107
|
-
});
|
|
65
|
+
var buildKeyElement = (attrs) => {
|
|
66
|
+
const attrStr = Object.entries(attrs).map(([k, v]) => `${k}="${escapeAttr(v)}"`).join(" ");
|
|
67
|
+
return `<key ${attrStr}/>`;
|
|
68
|
+
};
|
|
108
69
|
var JuceKeyFileUtils = class {
|
|
70
|
+
static toString(date) {
|
|
71
|
+
const months = [
|
|
72
|
+
"Jan",
|
|
73
|
+
"Feb",
|
|
74
|
+
"Mar",
|
|
75
|
+
"Apr",
|
|
76
|
+
"May",
|
|
77
|
+
"Jun",
|
|
78
|
+
"Jul",
|
|
79
|
+
"Aug",
|
|
80
|
+
"Sep",
|
|
81
|
+
"Oct",
|
|
82
|
+
"Nov",
|
|
83
|
+
"Dec"
|
|
84
|
+
];
|
|
85
|
+
const day = date.getDate().toString();
|
|
86
|
+
const month = months[date.getMonth()];
|
|
87
|
+
const year = date.getFullYear();
|
|
88
|
+
let hours = date.getHours();
|
|
89
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
90
|
+
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
91
|
+
const ampm = hours >= 12 ? "pm" : "am";
|
|
92
|
+
hours = hours % 12;
|
|
93
|
+
hours = hours ? hours : 12;
|
|
94
|
+
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
|
|
95
|
+
}
|
|
96
|
+
static toHexStringMilliseconds(date) {
|
|
97
|
+
return date.getTime().toString(16);
|
|
98
|
+
}
|
|
109
99
|
static createKeyFileContentLine({
|
|
110
100
|
appName,
|
|
111
101
|
userEmail,
|
|
@@ -113,17 +103,15 @@ var JuceKeyFileUtils = class {
|
|
|
113
103
|
machineNumbers,
|
|
114
104
|
machineNumbersAttributeName
|
|
115
105
|
}, date, expiryTime) {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"@_date": date,
|
|
123
|
-
...expiryTime ? { "@_expiryTime": expiryTime } : {}
|
|
124
|
-
}
|
|
106
|
+
const attrs = {
|
|
107
|
+
user: userName,
|
|
108
|
+
email: userEmail,
|
|
109
|
+
[machineNumbersAttributeName]: machineNumbers,
|
|
110
|
+
app: appName,
|
|
111
|
+
date
|
|
125
112
|
};
|
|
126
|
-
|
|
113
|
+
if (expiryTime) attrs.expiryTime = expiryTime;
|
|
114
|
+
return [XML_DECLARATION, buildKeyElement(attrs)].join(" ");
|
|
127
115
|
}
|
|
128
116
|
static createKeyFileComment({
|
|
129
117
|
appName,
|
|
@@ -198,7 +186,7 @@ var JuceKeyGeneration = class {
|
|
|
198
186
|
machineNumbers: params.machineNumbers,
|
|
199
187
|
machineNumbersAttributeName: "mach"
|
|
200
188
|
},
|
|
201
|
-
|
|
189
|
+
JuceKeyFileUtils.toHexStringMilliseconds(date)
|
|
202
190
|
);
|
|
203
191
|
const comment = JuceKeyFileUtils.createKeyFileComment(
|
|
204
192
|
{
|
|
@@ -207,7 +195,7 @@ var JuceKeyGeneration = class {
|
|
|
207
195
|
userName: params.userName,
|
|
208
196
|
machineNumbers: params.machineNumbers
|
|
209
197
|
},
|
|
210
|
-
|
|
198
|
+
JuceKeyFileUtils.toString(date)
|
|
211
199
|
);
|
|
212
200
|
return JuceKeyFileUtils.createKeyFile(
|
|
213
201
|
comment,
|
|
@@ -224,8 +212,8 @@ var JuceKeyGeneration = class {
|
|
|
224
212
|
machineNumbers: params.machineNumbers,
|
|
225
213
|
machineNumbersAttributeName: "expiring_mach"
|
|
226
214
|
},
|
|
227
|
-
|
|
228
|
-
|
|
215
|
+
JuceKeyFileUtils.toHexStringMilliseconds(date),
|
|
216
|
+
JuceKeyFileUtils.toHexStringMilliseconds(params.expiryTime)
|
|
229
217
|
);
|
|
230
218
|
const comment = JuceKeyFileUtils.createKeyFileComment(
|
|
231
219
|
{
|
|
@@ -234,8 +222,8 @@ var JuceKeyGeneration = class {
|
|
|
234
222
|
userName: params.userName,
|
|
235
223
|
machineNumbers: params.machineNumbers
|
|
236
224
|
},
|
|
237
|
-
|
|
238
|
-
|
|
225
|
+
JuceKeyFileUtils.toString(date),
|
|
226
|
+
JuceKeyFileUtils.toString(params.expiryTime)
|
|
239
227
|
);
|
|
240
228
|
return JuceKeyFileUtils.createKeyFile(
|
|
241
229
|
comment,
|
|
@@ -247,39 +235,42 @@ var JuceKeyGeneration = class {
|
|
|
247
235
|
|
|
248
236
|
// src/types.ts
|
|
249
237
|
import { z } from "zod";
|
|
250
|
-
var
|
|
238
|
+
var createKeyFileCommentParamsSchema = z.object({
|
|
251
239
|
appName: z.string().min(1),
|
|
252
|
-
userEmail: z.string().min(1)
|
|
240
|
+
userEmail: z.string().min(1),
|
|
253
241
|
userName: z.string().min(1),
|
|
254
242
|
machineNumbers: z.string().min(1)
|
|
255
243
|
});
|
|
256
|
-
var
|
|
244
|
+
var machineNumbersAttributeNameSchema = z.enum([
|
|
257
245
|
"mach",
|
|
258
246
|
"expiring_mach"
|
|
259
247
|
]);
|
|
260
|
-
var
|
|
261
|
-
machineNumbersAttributeName:
|
|
248
|
+
var createKeyFileContentLineParamsSchema = createKeyFileCommentParamsSchema.extend({
|
|
249
|
+
machineNumbersAttributeName: machineNumbersAttributeNameSchema
|
|
262
250
|
});
|
|
263
|
-
var
|
|
251
|
+
var rsaKeyComponentsSchema = z.stringFormat(
|
|
264
252
|
// Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()
|
|
253
|
+
"RSAKeyComponents",
|
|
265
254
|
(x) => x.includes(",") && x.split(",").every((p) => !JuceBigInteger.fromHex(p).isZero())
|
|
266
255
|
);
|
|
267
|
-
var
|
|
268
|
-
privateKey:
|
|
256
|
+
var generateKeyFileParamsSchema = createKeyFileCommentParamsSchema.extend({
|
|
257
|
+
privateKey: rsaKeyComponentsSchema
|
|
269
258
|
});
|
|
270
|
-
var
|
|
271
|
-
expiryTime: z.date()
|
|
259
|
+
var generateExpiringKeyFileParamsSchema = generateKeyFileParamsSchema.extend({
|
|
260
|
+
expiryTime: z.date().min(/* @__PURE__ */ new Date("1970-01-01T00:00:00.001Z"), {
|
|
261
|
+
error: "Expiry time must be after 1970-01-01T00:00:00.000Z"
|
|
262
|
+
})
|
|
272
263
|
});
|
|
273
264
|
|
|
274
265
|
// src/generateKeyFile.ts
|
|
275
266
|
var generateKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
|
|
276
|
-
const paramsParse =
|
|
267
|
+
const paramsParse = generateKeyFileParamsSchema.parse(params);
|
|
277
268
|
return JuceKeyGeneration.generateKeyFile(paramsParse, date);
|
|
278
269
|
};
|
|
279
270
|
|
|
280
271
|
// src/generateExpiringKeyFile.ts
|
|
281
272
|
var generateExpiringKeyFile = (params, date = /* @__PURE__ */ new Date()) => {
|
|
282
|
-
const paramsParse =
|
|
273
|
+
const paramsParse = generateExpiringKeyFileParamsSchema.parse(params);
|
|
283
274
|
return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date);
|
|
284
275
|
};
|
|
285
276
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/juce/JuceDateString.ts","../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceBigInteger.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts","../src/types.ts","../src/generateKeyFile.ts","../src/generateExpiringKeyFile.ts"],"sourcesContent":["export class JuceDateString {\n static inHexMs(date: Date): string {\n // Ports juce::String::toHexString (juce::Time::getCurrentTime().toMilliseconds())\n return date.getTime().toString(16)\n }\n\n static inFormattedComment(date: Date): string {\n // Ports juce::Time::getCurrentTime().toString (true, true)\n // prettier-ignore\n const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]\n const day = date.getDate().toString()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n let hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n const ampm = hours >= 12 ? 'pm' : 'am'\n hours = hours % 12\n hours = hours ? hours : 12\n return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`\n }\n}\n","import { XMLBuilder } from 'fast-xml-parser'\nimport {\n CreateKeyFileCommentParams,\n CreateKeyFileContentLineParams\n} from 'src/types'\n\nimport { JuceBigInteger } from './JuceBigInteger'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n\nconst legalXmlCharRegex =\n // Ports juce::XmlOutputFunctions::LegalCharLookupTable\n /^[a-zA-Z0-9 .,;:\\-()_+=?!$#@[\\]/|*%~{}'\\\\]$/\n\nconst xmlAttributeCharProcessor = (char: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n char.length !== 1\n ? ''\n : legalXmlCharRegex.test(char)\n ? char\n : char === '&'\n ? '&'\n : char === '\"'\n ? '"'\n : char === '>'\n ? '>'\n : char === '<'\n ? '<'\n : `&#${char.charCodeAt(0)};`\n\nconst xmlAttributeValueProcessor = (value: unknown): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n typeof value !== 'string'\n ? ''\n : value.split('').map(xmlAttributeCharProcessor).join('')\n\nconst xmlBuilder = new XMLBuilder({\n ignoreAttributes: false,\n suppressEmptyNode: true,\n // processEntities is disabled since it doesn't port to juce as is\n processEntities: false,\n attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)\n})\n\nexport class JuceKeyFileUtils {\n static createKeyFileContentLine(\n {\n appName,\n userEmail,\n userName,\n machineNumbers,\n machineNumbersAttributeName\n }: CreateKeyFileContentLineParams,\n date: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileContent\n // and juce::KeyFileUtils::encryptXML\n const xml = {\n key: {\n '@_user': userName,\n '@_email': userEmail,\n [`@_${machineNumbersAttributeName}`]: machineNumbers,\n '@_app': appName,\n '@_date': date,\n ...(expiryTime ? { '@_expiryTime': expiryTime } : {})\n }\n }\n return [XML_DECLARATION, xmlBuilder.build(xml).trim()].join(' ')\n }\n\n static createKeyFileComment(\n {\n appName,\n userEmail,\n userName,\n machineNumbers\n }: CreateKeyFileCommentParams,\n created: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileComment\n return (\n `Keyfile for ${appName}\\r\\n` +\n `${userName ? `User: ${userName}\\r\\n` : ''}` +\n `Email: ${userEmail}\\r\\n` +\n `Machine numbers: ${machineNumbers}\\r\\n` +\n `Created: ${created}` +\n (expiryTime ? `\\r\\nExpires: ${expiryTime}` : '')\n )\n }\n\n static encryptXMLLine(xmlLine: string, privateKey: JuceRSAKey): string {\n // Ports juce::KeyFileUtils::encryptXML\n const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine)\n privateKey.applyToValue(val)\n return val.toHex()\n }\n\n static createKeyFile(\n comment: string,\n xmlLine: string,\n rsaPrivateKey: JuceRSAKey\n ): string {\n // Ports juce::KeyFileUtils::createKeyFile\n let asHex = '#' + this.encryptXMLLine(xmlLine, rsaPrivateKey)\n\n const lines: string[] = []\n lines.push(comment)\n lines.push('')\n\n const charsPerLine = 70\n while (asHex.length > 0) {\n lines.push(asHex.substring(0, charsPerLine))\n asHex = asHex.substring(charsPerLine)\n }\n\n lines.push('')\n\n return lines.join('\\r\\n')\n }\n}\n","import { BigInteger as JSBN } from 'jsbn'\n\nexport class JuceBigInteger {\n constructor(public value: bigint = 0n) {}\n\n static fromJSBN(b: JSBN): JuceBigInteger {\n return JuceBigInteger.fromHex(b.toString(16))\n }\n\n toJSBN(): JSBN {\n return new JSBN(this.toHex(), 16)\n }\n\n static fromHex(hex: string): JuceBigInteger {\n const h = hex.trim()\n return new JuceBigInteger(h ? BigInt(`0x${h}`) : 0n)\n }\n\n toHex(): string {\n return this.value.toString(16)\n }\n\n static fromUTF8MemoryBlock(input: string): JuceBigInteger {\n // Ports juce::BigInteger::loadFromMemoryBlock()\n const u = Buffer.from(input, 'utf8')\n const b = new JuceBigInteger()\n for (let i = u.length - 1; i >= 0; i--) {\n b.value = (b.value << 8n) | BigInt(u[i])\n }\n return b\n }\n\n isZero(): boolean {\n return this.value === 0n\n }\n\n divideBy(divisor: JuceBigInteger, remainder: JuceBigInteger): void {\n // Ports juce::BigInteger::divideBy()\n if (divisor.isZero()) {\n this.value = 0n\n return\n }\n const b = this.toJSBN()\n const d = divisor.toJSBN()\n const [q, r] = b.divideAndRemainder(d)\n this.value = JuceBigInteger.fromJSBN(q).value\n remainder.value = JuceBigInteger.fromJSBN(r).value\n }\n\n exponentModulo(exponent: JuceBigInteger, modulus: JuceBigInteger): void {\n // Ports juce::BigInteger::exponentModulo()\n const b = this.toJSBN()\n const e = exponent.toJSBN()\n const m = modulus.toJSBN()\n const em = b.modPow(e, m)\n this.value = JuceBigInteger.fromJSBN(em).value\n }\n}\n","import { JuceBigInteger } from './JuceBigInteger'\n\nexport class JuceRSAKey {\n protected part1: JuceBigInteger\n protected part2: JuceBigInteger\n constructor(public s: string) {\n // Ports juce::RSAKey::RSAKey()\n if (s.includes(',')) {\n const [p1, p2] = s.split(',').map(p => JuceBigInteger.fromHex(p))\n this.part1 = p1\n this.part2 = p2\n } else {\n this.part1 = new JuceBigInteger()\n this.part2 = new JuceBigInteger()\n }\n }\n applyToValue(val: JuceBigInteger): void {\n // Ports juce::RSAKey::applyToValue()\n if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {\n return\n }\n\n const result = new JuceBigInteger()\n\n while (!val.isZero()) {\n result.value *= this.part2.value\n\n const remainder = new JuceBigInteger()\n val.divideBy(this.part2, remainder)\n\n remainder.exponentModulo(this.part1, this.part2)\n\n result.value += remainder.value\n }\n\n val.value = result.value\n }\n}\n","import { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from 'src/types'\n\nimport { JuceDateString } from './JuceDateString'\nimport { JuceKeyFileUtils } from './JuceKeyFileUtils'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nexport class JuceKeyGeneration {\n static generateKeyFile(\n params: GenerateKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'mach'\n },\n JuceDateString.inHexMs(date)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceDateString.inFormattedComment(date)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n\n static generateExpiringKeyFile(\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'expiring_mach'\n },\n JuceDateString.inHexMs(date),\n JuceDateString.inHexMs(params.expiryTime)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceDateString.inFormattedComment(date),\n JuceDateString.inFormattedComment(params.expiryTime)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n}\n","import { z } from 'zod'\n\nimport { JuceBigInteger } from './juce/JuceBigInteger'\n\nexport const createKeyFileCommentParamsValidator = z.object({\n appName: z.string().min(1),\n userEmail: z.string().min(1).email(),\n userName: z.string().min(1),\n machineNumbers: z.string().min(1)\n})\nexport type CreateKeyFileCommentParams = z.infer<\n typeof createKeyFileCommentParamsValidator\n>\n\nexport const machineNumbersAttributeNameValidator = z.enum([\n 'mach',\n 'expiring_mach'\n])\nexport type MachineNumbersAttributeName = z.infer<\n typeof machineNumbersAttributeNameValidator\n>\n\nexport const createKeyFileContentLineParamsValidator =\n createKeyFileCommentParamsValidator.extend({\n machineNumbersAttributeName: machineNumbersAttributeNameValidator\n })\nexport type CreateKeyFileContentLineParams = z.infer<\n typeof createKeyFileContentLineParamsValidator\n>\n\nexport const rsaKeyComponentsValidator = z.string().refine(\n // Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()\n x =>\n x.includes(',') &&\n x.split(',').every(p => !JuceBigInteger.fromHex(p).isZero())\n)\nexport type RSAKeyComponents = z.infer<typeof rsaKeyComponentsValidator>\n\nexport const generateKeyFileParamsValidator =\n createKeyFileCommentParamsValidator.extend({\n privateKey: rsaKeyComponentsValidator\n })\nexport type GenerateKeyFileParams = z.infer<\n typeof generateKeyFileParamsValidator\n>\n\nexport const generateExpiringKeyFileParamsValidator =\n generateKeyFileParamsValidator.extend({\n expiryTime: z.date()\n })\nexport type GenerateExpiringKeyFileParams = z.infer<\n typeof generateExpiringKeyFileParamsValidator\n>\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport { GenerateKeyFileParams, generateKeyFileParamsValidator } from './types'\n\nexport const generateKeyFile = (\n params: GenerateKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateKeyFileParamsValidator.parse(params)\n return JuceKeyGeneration.generateKeyFile(paramsParse, date)\n}\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport {\n GenerateExpiringKeyFileParams,\n generateExpiringKeyFileParamsValidator\n} from './types'\n\nexport const generateExpiringKeyFile = (\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateExpiringKeyFileParamsValidator.parse(params)\n return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date)\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/juce/JuceBigInteger.ts","../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts","../src/types.ts","../src/generateKeyFile.ts","../src/generateExpiringKeyFile.ts"],"sourcesContent":["import { BigInteger as JSBN } from 'jsbn'\n\nexport class JuceBigInteger {\n constructor(public value: bigint = 0n) {}\n\n static fromJSBN(b: JSBN): JuceBigInteger {\n return JuceBigInteger.fromHex(b.toString(16))\n }\n\n toJSBN(): JSBN {\n return new JSBN(this.toHex(), 16)\n }\n\n static fromHex(hex: string): JuceBigInteger {\n const h = hex.trim()\n return new JuceBigInteger(h ? BigInt(`0x${h}`) : 0n)\n }\n\n toHex(): string {\n return this.value.toString(16)\n }\n\n static fromUTF8MemoryBlock(input: string): JuceBigInteger {\n // Ports juce::BigInteger::loadFromMemoryBlock()\n const u = Buffer.from(input, 'utf8')\n const b = new JuceBigInteger()\n for (let i = u.length - 1; i >= 0; i--) {\n b.value = (b.value << 8n) | BigInt(u[i])\n }\n return b\n }\n\n isZero(): boolean {\n return this.value === 0n\n }\n\n divideBy(divisor: JuceBigInteger, remainder: JuceBigInteger): void {\n // Ports juce::BigInteger::divideBy()\n if (divisor.isZero()) {\n this.value = 0n\n return\n }\n const b = this.toJSBN()\n const d = divisor.toJSBN()\n const [q, r] = b.divideAndRemainder(d)\n this.value = JuceBigInteger.fromJSBN(q).value\n remainder.value = JuceBigInteger.fromJSBN(r).value\n }\n\n exponentModulo(exponent: JuceBigInteger, modulus: JuceBigInteger): void {\n // Ports juce::BigInteger::exponentModulo()\n const b = this.toJSBN()\n const e = exponent.toJSBN()\n const m = modulus.toJSBN()\n const em = b.modPow(e, m)\n this.value = JuceBigInteger.fromJSBN(em).value\n }\n}\n","import {\n CreateKeyFileCommentParams,\n CreateKeyFileContentLineParams\n} from '../types'\nimport { JuceBigInteger } from './JuceBigInteger'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n\nconst legalXmlCharRegex =\n // Ports juce::XmlOutputFunctions::LegalCharLookupTable\n /^[a-zA-Z0-9 .,;:\\-()_+=?!$#@[\\]/|*%~{}'\\\\]$/\n\nconst xmlAttributeCharProcessor = (char: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n char.length !== 1\n ? ''\n : legalXmlCharRegex.test(char)\n ? char\n : char === '&'\n ? '&'\n : char === '\"'\n ? '"'\n : char === '>'\n ? '>'\n : char === '<'\n ? '<'\n : `&#${char.charCodeAt(0)};`\n\nconst escapeAttr = (value: string): string =>\n // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()\n value.split('').map(xmlAttributeCharProcessor).join('')\n\nconst buildKeyElement = (attrs: Record<string, string>): string => {\n // Builds <key attr=\"val\" .../> without delegating to fast-xml-parser,\n // which unconditionally escapes single quotes in attribute values in v5\n // — breaking the JUCE port (single quote is a legal char in JUCE XML).\n const attrStr = Object.entries(attrs)\n .map(([k, v]) => `${k}=\"${escapeAttr(v)}\"`)\n .join(' ')\n return `<key ${attrStr}/>`\n}\n\nexport class JuceKeyFileUtils {\n static toString(date: Date): string {\n // Ports juce::Time::getCurrentTime().toString (true, true)\n // prettier-ignore\n const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]\n const day = date.getDate().toString()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n let hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n const ampm = hours >= 12 ? 'pm' : 'am'\n hours = hours % 12\n hours = hours ? hours : 12\n return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`\n }\n\n static toHexStringMilliseconds(date: Date): string {\n // Ports juce::String::toHexString (juce::Time::getCurrentTime().toMilliseconds())\n return date.getTime().toString(16)\n }\n\n static createKeyFileContentLine(\n {\n appName,\n userEmail,\n userName,\n machineNumbers,\n machineNumbersAttributeName\n }: CreateKeyFileContentLineParams,\n date: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileContent\n // and juce::KeyFileUtils::encryptXML\n const attrs: Record<string, string> = {\n user: userName,\n email: userEmail,\n [machineNumbersAttributeName]: machineNumbers,\n app: appName,\n date\n }\n if (expiryTime) attrs.expiryTime = expiryTime\n return [XML_DECLARATION, buildKeyElement(attrs)].join(' ')\n }\n\n static createKeyFileComment(\n {\n appName,\n userEmail,\n userName,\n machineNumbers\n }: CreateKeyFileCommentParams,\n created: string,\n expiryTime?: string\n ): string {\n // Ports juce::KeyFileUtils::createKeyFileComment\n return (\n `Keyfile for ${appName}\\r\\n` +\n `${userName ? `User: ${userName}\\r\\n` : ''}` +\n `Email: ${userEmail}\\r\\n` +\n `Machine numbers: ${machineNumbers}\\r\\n` +\n `Created: ${created}` +\n (expiryTime ? `\\r\\nExpires: ${expiryTime}` : '')\n )\n }\n\n static encryptXMLLine(xmlLine: string, privateKey: JuceRSAKey): string {\n // Ports juce::KeyFileUtils::encryptXML\n const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine)\n privateKey.applyToValue(val)\n return val.toHex()\n }\n\n static createKeyFile(\n comment: string,\n xmlLine: string,\n rsaPrivateKey: JuceRSAKey\n ): string {\n // Ports juce::KeyFileUtils::createKeyFile\n let asHex = '#' + this.encryptXMLLine(xmlLine, rsaPrivateKey)\n\n const lines: string[] = []\n lines.push(comment)\n lines.push('')\n\n const charsPerLine = 70\n while (asHex.length > 0) {\n lines.push(asHex.substring(0, charsPerLine))\n asHex = asHex.substring(charsPerLine)\n }\n\n lines.push('')\n\n return lines.join('\\r\\n')\n }\n}\n","import { JuceBigInteger } from './JuceBigInteger'\n\nexport class JuceRSAKey {\n protected part1: JuceBigInteger\n protected part2: JuceBigInteger\n constructor(public s: string) {\n // Ports juce::RSAKey::RSAKey()\n if (s.includes(',')) {\n const [p1, p2] = s.split(',').map(p => JuceBigInteger.fromHex(p))\n this.part1 = p1\n this.part2 = p2\n } else {\n this.part1 = new JuceBigInteger()\n this.part2 = new JuceBigInteger()\n }\n }\n applyToValue(val: JuceBigInteger): void {\n // Ports juce::RSAKey::applyToValue()\n if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {\n return\n }\n\n const result = new JuceBigInteger()\n\n while (!val.isZero()) {\n result.value *= this.part2.value\n\n const remainder = new JuceBigInteger()\n val.divideBy(this.part2, remainder)\n\n remainder.exponentModulo(this.part1, this.part2)\n\n result.value += remainder.value\n }\n\n val.value = result.value\n }\n}\n","import { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from '../types'\nimport { JuceKeyFileUtils } from './JuceKeyFileUtils'\nimport { JuceRSAKey } from './JuceRSAKey'\n\nexport class JuceKeyGeneration {\n static generateKeyFile(\n params: GenerateKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'mach'\n },\n JuceKeyFileUtils.toHexStringMilliseconds(date)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceKeyFileUtils.toString(date)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n\n static generateExpiringKeyFile(\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n ) {\n const xml = JuceKeyFileUtils.createKeyFileContentLine(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers,\n machineNumbersAttributeName: 'expiring_mach'\n },\n JuceKeyFileUtils.toHexStringMilliseconds(date),\n JuceKeyFileUtils.toHexStringMilliseconds(params.expiryTime)\n )\n const comment = JuceKeyFileUtils.createKeyFileComment(\n {\n appName: params.appName,\n userEmail: params.userEmail,\n userName: params.userName,\n machineNumbers: params.machineNumbers\n },\n JuceKeyFileUtils.toString(date),\n JuceKeyFileUtils.toString(params.expiryTime)\n )\n return JuceKeyFileUtils.createKeyFile(\n comment,\n xml,\n new JuceRSAKey(params.privateKey)\n )\n }\n}\n","import { z } from 'zod'\n\nimport { JuceBigInteger } from './juce/JuceBigInteger'\n\nexport const createKeyFileCommentParamsSchema = z.object({\n appName: z.string().min(1),\n userEmail: z.string().min(1),\n userName: z.string().min(1),\n machineNumbers: z.string().min(1)\n})\nexport type CreateKeyFileCommentParams = z.infer<\n typeof createKeyFileCommentParamsSchema\n>\n\nexport const machineNumbersAttributeNameSchema = z.enum([\n 'mach',\n 'expiring_mach'\n])\nexport type MachineNumbersAttributeName = z.infer<\n typeof machineNumbersAttributeNameSchema\n>\n\nexport const createKeyFileContentLineParamsSchema =\n createKeyFileCommentParamsSchema.extend({\n machineNumbersAttributeName: machineNumbersAttributeNameSchema\n })\nexport type CreateKeyFileContentLineParams = z.infer<\n typeof createKeyFileContentLineParamsSchema\n>\n\nexport const rsaKeyComponentsSchema = z.stringFormat(\n // Ports juce::RSAKey::RSAKey() and juce::RSAKey::applyToValue()\n 'RSAKeyComponents',\n x =>\n x.includes(',') &&\n x.split(',').every(p => !JuceBigInteger.fromHex(p).isZero())\n)\nexport type RSAKeyComponents = z.infer<typeof rsaKeyComponentsSchema>\n\nexport const generateKeyFileParamsSchema =\n createKeyFileCommentParamsSchema.extend({\n privateKey: rsaKeyComponentsSchema\n })\nexport type GenerateKeyFileParams = z.infer<typeof generateKeyFileParamsSchema>\n\nexport const generateExpiringKeyFileParamsSchema =\n generateKeyFileParamsSchema.extend({\n expiryTime: z.date().min(new Date('1970-01-01T00:00:00.001Z'), {\n error: 'Expiry time must be after 1970-01-01T00:00:00.000Z'\n })\n })\nexport type GenerateExpiringKeyFileParams = z.infer<\n typeof generateExpiringKeyFileParamsSchema\n>\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport { GenerateKeyFileParams, generateKeyFileParamsSchema } from './types'\n\nexport const generateKeyFile = (\n params: GenerateKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateKeyFileParamsSchema.parse(params)\n return JuceKeyGeneration.generateKeyFile(paramsParse, date)\n}\n","import { JuceKeyGeneration } from './juce/JuceKeyGeneration'\nimport {\n GenerateExpiringKeyFileParams,\n generateExpiringKeyFileParamsSchema\n} from './types'\n\nexport const generateExpiringKeyFile = (\n params: GenerateExpiringKeyFileParams,\n date: Date = new Date()\n) => {\n const paramsParse = generateExpiringKeyFileParamsSchema.parse(params)\n return JuceKeyGeneration.generateExpiringKeyFile(paramsParse, date)\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ianacaburian/generate-key-file",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Ports juce_KeyGeneration::generateKeyFile() to node.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=24"
|
|
14
|
+
},
|
|
12
15
|
"scripts": {
|
|
13
|
-
"clean": "rm -rf dist && npm run clean
|
|
16
|
+
"clean": "rm -rf dist && npm run cm:clean",
|
|
14
17
|
"lint": "eslint src",
|
|
15
|
-
"clean
|
|
16
|
-
"open
|
|
17
|
-
"install
|
|
18
|
-
"build": "npm run lint && npm run install
|
|
18
|
+
"cm:clean": "rm -rf test/bin/* && cd test/console && ./cmake/clean-build.sh",
|
|
19
|
+
"cm:open": "cd test/console && ./cmake/open-xcode-macos-dev.sh",
|
|
20
|
+
"cm:install": "cmake -S test/console -B test/console/build && cmake --build test/console/build && cmake --install test/console/build --prefix test",
|
|
21
|
+
"build": "npm run lint && npm run cm:install && tsup",
|
|
19
22
|
"test": "vitest"
|
|
20
23
|
},
|
|
21
24
|
"repository": {
|
|
@@ -36,27 +39,24 @@
|
|
|
36
39
|
},
|
|
37
40
|
"homepage": "https://github.com/ianacaburian/generate-key-file#readme",
|
|
38
41
|
"devDependencies": {
|
|
39
|
-
"@eslint/js": "^
|
|
40
|
-
"@ianvs/prettier-plugin-sort-imports": "^4.
|
|
42
|
+
"@eslint/js": "^10.0.1",
|
|
43
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
|
41
44
|
"@types/jsbn": "^1.2.33",
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
43
|
-
"@typescript-eslint/parser": "^8.
|
|
44
|
-
"eslint": "^
|
|
45
|
-
"eslint-config-prettier": "^
|
|
46
|
-
"eslint-plugin-prettier": "^5.
|
|
47
|
-
"fast-check": "^
|
|
48
|
-
"globals": "^
|
|
49
|
-
"prettier": "^3.
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"typescript": "
|
|
53
|
-
"
|
|
54
|
-
"vitest": "^2.1.1",
|
|
55
|
-
"zod-fast-check": "^0.10.1"
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.61.1",
|
|
46
|
+
"@typescript-eslint/parser": "^8.61.1",
|
|
47
|
+
"eslint": "^10.5.0",
|
|
48
|
+
"eslint-config-prettier": "^10.1.8",
|
|
49
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
50
|
+
"fast-check": "^4.8.0",
|
|
51
|
+
"globals": "^17.6.0",
|
|
52
|
+
"prettier": "^3.8.4",
|
|
53
|
+
"tsup": "^8.5.1",
|
|
54
|
+
"typescript": "~6.0.3",
|
|
55
|
+
"typescript-eslint": "^8.61.1",
|
|
56
|
+
"vitest": "^4.1.9"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
58
|
-
"fast-xml-parser": "^4.5.0",
|
|
59
59
|
"jsbn": "^1.1.0",
|
|
60
|
-
"zod": "^
|
|
60
|
+
"zod": "^4.4.3"
|
|
61
61
|
}
|
|
62
62
|
}
|