@ianacaburian/generate-key-file 0.0.4 → 0.1.1

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 CHANGED
@@ -1,3 +1,115 @@
1
1
  # generate-key-file
2
2
 
3
- Provides juce_KeyGeneration::generateKeyFile() for javascript.
3
+ Ports juce_KeyGeneration::generateKeyFile() to node.
4
+
5
+ ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ianacaburian/generate-key-file/build.yml)
6
+ [![npm version](https://badge.fury.io/js/@ianacaburian%2Fgenerate-key-file.svg)](https://badge.fury.io/js/@ianacaburian%2Fgenerate-key-file)
7
+ ![GitHub License](https://img.shields.io/github/license/ianacaburian/generate-key-file)
8
+ ![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/ianacaburian)
9
+
10
+ ## Installation
11
+
12
+ ```
13
+ npm i @ianacaburian/generate-key-file
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ - `generateKeyFile(params: GenerateKeyFileParams, date: Date = new Date()) => string`
19
+
20
+ ```
21
+ import { generateKeyFile } from '@ianacaburian/generate-key-file'
22
+
23
+ const keyFileContent = generateKeyFile({
24
+ userName: 'Ian',
25
+ userEmail: 'ian@email.com',
26
+ machineNumbers: '123',
27
+ appName: 'app-name-or-product-id',
28
+ privateKey: 'comma-sep-private-key'
29
+ })
30
+ ```
31
+
32
+ - Returns the <key> string value to be used in the XML response for decryption
33
+ by the client.
34
+ - Throws ZodError for invalid params -- see
35
+ [zod](https://github.com/colinhacks/zod).
36
+ - From juce_KeyFileGeneration.h:
37
+
38
+ ```
39
+ /**
40
+ Generates the content of a key-file which can be sent to a user's machine to
41
+ unlock a product.
42
+
43
+ The returned value is a block of text containing an RSA-encoded block, followed
44
+ by some human-readable details. If you pass this block of text to
45
+ OnlineUnlockStatus::applyKeyFile(), it will decrypt it, and if the
46
+ key matches and the machine numbers match, it will unlock that machine.
47
+
48
+ Typically the way you'd use this on a server would be to build a small executable
49
+ that simply calls this method and prints the result, so that the webserver can
50
+ use this as a reply to the product's auto-registration mechanism. The
51
+ keyGenerationAppMain() function is an example of how to build such a function.
52
+
53
+ @see OnlineUnlockStatus
54
+ */
55
+ ```
56
+
57
+ - `generateExpiringKeyFile(params: GenerateExpiringKeyFileParams, date: Date = new Date()) => string`
58
+
59
+ ```
60
+ import { generateExpiringKeyFile } from '@ianacaburian/generate-key-file'
61
+
62
+ const oneDayFromNow = new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
63
+ const expiringKeyFileContent = generateExpiringKeyFile({
64
+ userName: 'Ian',
65
+ userEmail: 'ian@email.com',
66
+ machineNumbers: '123',
67
+ appName: 'app-name-or-product-id',
68
+ privateKey: 'comma-sep-private-key'
69
+ expiryTime: oneDayFromNow
70
+ })
71
+ ```
72
+
73
+ - Returns the <key> string value to be used in the XML response for decryption
74
+ by the client.
75
+ - Throws ZodError for invalid params -- see
76
+ [zod](https://github.com/colinhacks/zod).
77
+ - From juce_KeyFileGeneration.h:
78
+
79
+ ```
80
+ /** Similar to the above key file generation method but with an expiry time.
81
+ You must supply a Time after which this key file should no longer be considered as active.
82
+
83
+ N.B. when an app is unlocked with an expiring key file, OnlineUnlockStatus::isUnlocked will
84
+ still return false. You must then check OnlineUnlockStatus::getExpiryTime to see if this
85
+ expiring key file is still in date and act accordingly.
86
+
87
+ @see OnlineUnlockStatus
88
+ */
89
+ ```
90
+
91
+ ## Development
92
+
93
+ ```
94
+ npm run clean # Clean dist and test builds (inc test bins).
95
+ npm run lint # Lint the src dir.
96
+ npm run build # Lint, install tests, and build package.
97
+ ```
98
+
99
+ ### Testing
100
+
101
+ ```
102
+ npm run test # Start vitest to run all tests.
103
+ npm run test -- -t "divideBy" # Start vitest to run one test.
104
+ npm run clean:test # Clean test build.
105
+ npm run open:test/console # Open test/console project in Xcode.
106
+ npm run install:test/console # Build and install the test/console bins.
107
+ ```
108
+
109
+ Optional: Set "FC_NUM_RUMS" (default=1) to specify how many times to run each
110
+ (randomly generated) propery-based test -- see
111
+ [fast-check](https://github.com/dubzzz/fast-check).
112
+
113
+ ```
114
+ FC_NUM_RUNS=1000 npm run test # Run each fc test 1000 times.
115
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ JuceKeyGeneration: () => JuceKeyGeneration
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+
27
+ // src/juce/JuceKeyFileUtils.ts
28
+ var import_fast_xml_parser = require("fast-xml-parser");
29
+
30
+ // src/juce/JuceBigInteger.ts
31
+ var import_jsbn = require("jsbn");
32
+ var JuceBigInteger = class _JuceBigInteger {
33
+ constructor(value = 0n) {
34
+ this.value = value;
35
+ }
36
+ static fromJSBN(b) {
37
+ return _JuceBigInteger.fromHex(b.toString(16));
38
+ }
39
+ toJSBN() {
40
+ return new import_jsbn.BigInteger(this.toHex(), 16);
41
+ }
42
+ static fromHex(hex) {
43
+ const h = hex.trim();
44
+ return new _JuceBigInteger(h ? BigInt(`0x${h}`) : 0n);
45
+ }
46
+ toHex() {
47
+ return this.value.toString(16);
48
+ }
49
+ static fromUTF8MemoryBlock(input) {
50
+ const u = Buffer.from(input, "utf8");
51
+ const b = new _JuceBigInteger();
52
+ for (let i = u.length - 1; i >= 0; i--) {
53
+ b.value = b.value << 8n | BigInt(u[i]);
54
+ }
55
+ return b;
56
+ }
57
+ isZero() {
58
+ return this.value === 0n;
59
+ }
60
+ divideBy(divisor, remainder) {
61
+ if (divisor.isZero()) {
62
+ this.value = 0n;
63
+ return;
64
+ }
65
+ const b = this.toJSBN();
66
+ const d = divisor.toJSBN();
67
+ const [q, r] = b.divideAndRemainder(d);
68
+ this.value = _JuceBigInteger.fromJSBN(q).value;
69
+ remainder.value = _JuceBigInteger.fromJSBN(r).value;
70
+ }
71
+ exponentModulo(exponent, modulus) {
72
+ const b = this.toJSBN();
73
+ const e = exponent.toJSBN();
74
+ const m = modulus.toJSBN();
75
+ const em = b.modPow(e, m);
76
+ this.value = _JuceBigInteger.fromJSBN(em).value;
77
+ }
78
+ };
79
+
80
+ // src/juce/JuceKeyFileUtils.ts
81
+ var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>';
82
+ var legalXmlCharRegex = (
83
+ // Ports juce::XmlOutputFunctions::LegalCharLookupTable
84
+ /^[a-zA-Z0-9 .,;:\-()_+=?!$#@[\]/|*%~{}'\\]$/
85
+ );
86
+ var xmlAttributeCharProcessor = (char) => (
87
+ // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
88
+ char.length !== 1 ? "" : legalXmlCharRegex.test(char) ? char : char === "&" ? "&amp;" : char === '"' ? "&quot;" : char === ">" ? "&gt;" : char === "<" ? "&lt;" : `&#${char.charCodeAt(0)};`
89
+ );
90
+ var xmlAttributeValueProcessor = (value) => (
91
+ // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
92
+ typeof value !== "string" ? "" : value.split("").map(xmlAttributeCharProcessor).join("")
93
+ );
94
+ var xmlBuilder = new import_fast_xml_parser.XMLBuilder({
95
+ ignoreAttributes: false,
96
+ suppressEmptyNode: true,
97
+ processEntities: false,
98
+ // Disabled since it doesn't port to juce as is
99
+ attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)
100
+ });
101
+ var JuceKeyFileUtils = class {
102
+ static createKeyFileContentLine({
103
+ appName,
104
+ userEmail,
105
+ userName,
106
+ machineNumbers,
107
+ machineNumbersAttributeName
108
+ }, date, expiryTime) {
109
+ const xml = {
110
+ key: {
111
+ "@_user": userName,
112
+ "@_email": userEmail,
113
+ [`@_${machineNumbersAttributeName}`]: machineNumbers,
114
+ "@_app": appName,
115
+ "@_date": date,
116
+ // Does not affect key file decryption
117
+ ...expiryTime ? { "@_expiryTime": expiryTime } : {}
118
+ }
119
+ };
120
+ return [XML_DECLARATION, xmlBuilder.build(xml).trim()].join(" ");
121
+ }
122
+ static createKeyFileComment({
123
+ appName,
124
+ userEmail,
125
+ userName,
126
+ machineNumbers
127
+ }, created, expiryTime) {
128
+ return `Keyfile for ${appName}\r
129
+ ${userName ? `User: ${userName}\r
130
+ ` : ""}Email: ${userEmail}\r
131
+ Machine numbers: ${machineNumbers}\r
132
+ Created: ${created}` + (expiryTime ? `\r
133
+ Expires: ${expiryTime}` : "");
134
+ }
135
+ static encryptXMLLine(xmlLine, privateKey) {
136
+ const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine);
137
+ privateKey.applyToValue(val);
138
+ return val.toHex();
139
+ }
140
+ static createKeyFile(comment, xmlLine, rsaPrivateKey) {
141
+ let asHex = "#" + this.encryptXMLLine(xmlLine, rsaPrivateKey);
142
+ const lines = [];
143
+ lines.push(comment);
144
+ lines.push("");
145
+ const charsPerLine = 70;
146
+ while (asHex.length > 0) {
147
+ lines.push(asHex.substring(0, charsPerLine));
148
+ asHex = asHex.substring(charsPerLine);
149
+ }
150
+ lines.push("");
151
+ return lines.join("\r\n");
152
+ }
153
+ };
154
+
155
+ // src/juce/JuceDateString.ts
156
+ var JuceDateString = class {
157
+ static inHexMs(date) {
158
+ return date.getTime().toString(16);
159
+ }
160
+ static inFormattedComment(date) {
161
+ const months = [
162
+ "Jan",
163
+ "Feb",
164
+ "Mar",
165
+ "Apr",
166
+ "May",
167
+ "Jun",
168
+ "Jul",
169
+ "Aug",
170
+ "Sep",
171
+ "Oct",
172
+ "Nov",
173
+ "Dec"
174
+ ];
175
+ const day = date.getDate().toString();
176
+ const month = months[date.getMonth()];
177
+ const year = date.getFullYear();
178
+ let hours = date.getHours();
179
+ const minutes = date.getMinutes().toString().padStart(2, "0");
180
+ const seconds = date.getSeconds().toString().padStart(2, "0");
181
+ const ampm = hours >= 12 ? "pm" : "am";
182
+ hours = hours % 12;
183
+ hours = hours ? hours : 12;
184
+ return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
185
+ }
186
+ };
187
+
188
+ // src/juce/JuceRSAKey.ts
189
+ var JuceRSAKey = class {
190
+ constructor(s) {
191
+ this.s = s;
192
+ if (s.includes(",")) {
193
+ const [p1, p2] = s.split(",").map((p) => JuceBigInteger.fromHex(p));
194
+ this.part1 = p1;
195
+ this.part2 = p2;
196
+ } else {
197
+ this.part1 = new JuceBigInteger();
198
+ this.part2 = new JuceBigInteger();
199
+ }
200
+ }
201
+ applyToValue(val) {
202
+ if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {
203
+ return;
204
+ }
205
+ const result = new JuceBigInteger();
206
+ while (!val.isZero()) {
207
+ result.value *= this.part2.value;
208
+ const remainder = new JuceBigInteger();
209
+ val.divideBy(this.part2, remainder);
210
+ remainder.exponentModulo(this.part1, this.part2);
211
+ result.value += remainder.value;
212
+ }
213
+ val.value = result.value;
214
+ }
215
+ };
216
+
217
+ // src/juce/JuceKeyGeneration.ts
218
+ var JuceKeyGeneration = class {
219
+ static generateKeyFile(params, date = /* @__PURE__ */ new Date()) {
220
+ const xml = JuceKeyFileUtils.createKeyFileContentLine(
221
+ {
222
+ appName: params.appName,
223
+ userEmail: params.userEmail,
224
+ userName: params.userName,
225
+ machineNumbers: params.machineNumbers,
226
+ machineNumbersAttributeName: "mach"
227
+ },
228
+ JuceDateString.inHexMs(date)
229
+ );
230
+ const comment = JuceKeyFileUtils.createKeyFileComment(
231
+ {
232
+ appName: params.appName,
233
+ userEmail: params.userEmail,
234
+ userName: params.userName,
235
+ machineNumbers: params.machineNumbers
236
+ },
237
+ JuceDateString.inFormattedComment(date)
238
+ );
239
+ return JuceKeyFileUtils.createKeyFile(
240
+ comment,
241
+ xml,
242
+ new JuceRSAKey(params.privateKey)
243
+ );
244
+ }
245
+ static generateExpiringKeyFile(params, date = /* @__PURE__ */ new Date()) {
246
+ const xml = JuceKeyFileUtils.createKeyFileContentLine(
247
+ {
248
+ appName: params.appName,
249
+ userEmail: params.userEmail,
250
+ userName: params.userName,
251
+ machineNumbers: params.machineNumbers,
252
+ machineNumbersAttributeName: "expiring_mach"
253
+ },
254
+ JuceDateString.inHexMs(date),
255
+ JuceDateString.inHexMs(params.expiryTime)
256
+ );
257
+ const comment = JuceKeyFileUtils.createKeyFileComment(
258
+ {
259
+ appName: params.appName,
260
+ userEmail: params.userEmail,
261
+ userName: params.userName,
262
+ machineNumbers: params.machineNumbers
263
+ },
264
+ JuceDateString.inFormattedComment(date),
265
+ JuceDateString.inFormattedComment(params.expiryTime)
266
+ );
267
+ return JuceKeyFileUtils.createKeyFile(
268
+ comment,
269
+ xml,
270
+ new JuceRSAKey(params.privateKey)
271
+ );
272
+ }
273
+ };
274
+ // Annotate the CommonJS export names for ESM import in node:
275
+ 0 && (module.exports = {
276
+ JuceKeyGeneration
277
+ });
278
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceBigInteger.ts","../src/juce/JuceDateString.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts"],"sourcesContent":["export * from './juce/JuceKeyGeneration'\nexport {\n type GenerateKeyFileParams,\n type GenerateExpiringKeyFileParams\n} from './types'\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 ? '&amp;'\n : char === '\"'\n ? '&quot;'\n : char === '>'\n ? '&gt;'\n : char === '<'\n ? '&lt;'\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: false, // Disabled since it doesn't port to juce as is\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, // Does not affect key file decryption\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","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 { BigInteger as JSBN } from 'jsbn'\n\nimport { 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 { JuceKeyFileUtils } from 'src/juce/JuceKeyFileUtils'\nimport { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from 'src/types'\n\nimport { JuceDateString } from './JuceDateString'\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"],"mappings":"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","names":["JSBN"]}
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const generateKeyFileParamsValidator: z.ZodObject<z.objectUtil.extendShape<{
4
+ appName: z.ZodString;
5
+ userEmail: z.ZodString;
6
+ userName: z.ZodString;
7
+ machineNumbers: z.ZodString;
8
+ }, {
9
+ privateKey: z.ZodEffects<z.ZodString, string, string>;
10
+ }>, "strip", z.ZodTypeAny, {
11
+ appName: string;
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<{
25
+ appName: z.ZodString;
26
+ userEmail: z.ZodString;
27
+ userName: z.ZodString;
28
+ machineNumbers: z.ZodString;
29
+ }, {
30
+ privateKey: z.ZodEffects<z.ZodString, string, string>;
31
+ }>, {
32
+ expiryTime: z.ZodDate;
33
+ }>, "strip", z.ZodTypeAny, {
34
+ appName: string;
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>;
49
+
50
+ declare class JuceKeyGeneration {
51
+ static generateKeyFile(params: GenerateKeyFileParams, date?: Date): string;
52
+ static generateExpiringKeyFile(params: GenerateExpiringKeyFileParams, date?: Date): string;
53
+ }
54
+
55
+ export { type GenerateExpiringKeyFileParams, type GenerateKeyFileParams, JuceKeyGeneration };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,55 @@
1
- type GenerateKeyFileParams = {
1
+ import { z } from 'zod';
2
+
3
+ declare const generateKeyFileParamsValidator: z.ZodObject<z.objectUtil.extendShape<{
4
+ appName: z.ZodString;
5
+ userEmail: z.ZodString;
6
+ userName: z.ZodString;
7
+ machineNumbers: z.ZodString;
8
+ }, {
9
+ privateKey: z.ZodEffects<z.ZodString, string, string>;
10
+ }>, "strip", z.ZodTypeAny, {
11
+ appName: string;
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<{
25
+ appName: z.ZodString;
26
+ userEmail: z.ZodString;
27
+ userName: z.ZodString;
28
+ machineNumbers: z.ZodString;
29
+ }, {
30
+ privateKey: z.ZodEffects<z.ZodString, string, string>;
31
+ }>, {
32
+ expiryTime: z.ZodDate;
33
+ }>, "strip", z.ZodTypeAny, {
34
+ appName: string;
35
+ userEmail: string;
36
+ userName: string;
37
+ machineNumbers: string;
38
+ privateKey: string;
39
+ expiryTime: Date;
40
+ }, {
2
41
  appName: string;
3
42
  userEmail: string;
4
43
  userName: string;
5
44
  machineNumbers: string;
6
45
  privateKey: string;
7
- };
46
+ expiryTime: Date;
47
+ }>;
48
+ type GenerateExpiringKeyFileParams = z.infer<typeof generateExpiringKeyFileParamsValidator>;
8
49
 
9
- declare const generateKeyFile: (params: GenerateKeyFileParams) => string;
50
+ declare class JuceKeyGeneration {
51
+ static generateKeyFile(params: GenerateKeyFileParams, date?: Date): string;
52
+ static generateExpiringKeyFile(params: GenerateExpiringKeyFileParams, date?: Date): string;
53
+ }
10
54
 
11
- export { type GenerateKeyFileParams, generateKeyFile };
55
+ export { type GenerateExpiringKeyFileParams, type GenerateKeyFileParams, JuceKeyGeneration };
package/dist/index.js CHANGED
@@ -1,35 +1,251 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ // src/juce/JuceKeyFileUtils.ts
2
+ import { XMLBuilder } from "fast-xml-parser";
3
+
4
+ // src/juce/JuceBigInteger.ts
5
+ import { BigInteger as JSBN } from "jsbn";
6
+ var JuceBigInteger = class _JuceBigInteger {
7
+ constructor(value = 0n) {
8
+ this.value = value;
9
+ }
10
+ static fromJSBN(b) {
11
+ return _JuceBigInteger.fromHex(b.toString(16));
12
+ }
13
+ toJSBN() {
14
+ return new JSBN(this.toHex(), 16);
15
+ }
16
+ static fromHex(hex) {
17
+ const h = hex.trim();
18
+ return new _JuceBigInteger(h ? BigInt(`0x${h}`) : 0n);
19
+ }
20
+ toHex() {
21
+ return this.value.toString(16);
22
+ }
23
+ static fromUTF8MemoryBlock(input) {
24
+ const u = Buffer.from(input, "utf8");
25
+ const b = new _JuceBigInteger();
26
+ for (let i = u.length - 1; i >= 0; i--) {
27
+ b.value = b.value << 8n | BigInt(u[i]);
28
+ }
29
+ return b;
30
+ }
31
+ isZero() {
32
+ return this.value === 0n;
33
+ }
34
+ divideBy(divisor, remainder) {
35
+ if (divisor.isZero()) {
36
+ this.value = 0n;
37
+ return;
38
+ }
39
+ const b = this.toJSBN();
40
+ const d = divisor.toJSBN();
41
+ const [q, r] = b.divideAndRemainder(d);
42
+ this.value = _JuceBigInteger.fromJSBN(q).value;
43
+ remainder.value = _JuceBigInteger.fromJSBN(r).value;
44
+ }
45
+ exponentModulo(exponent, modulus) {
46
+ const b = this.toJSBN();
47
+ const e = exponent.toJSBN();
48
+ const m = modulus.toJSBN();
49
+ const em = b.modPow(e, m);
50
+ this.value = _JuceBigInteger.fromJSBN(em).value;
15
51
  }
16
- return to;
17
52
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
53
 
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- generateKeyFile: () => generateKeyFile
54
+ // src/juce/JuceKeyFileUtils.ts
55
+ var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>';
56
+ var legalXmlCharRegex = (
57
+ // Ports juce::XmlOutputFunctions::LegalCharLookupTable
58
+ /^[a-zA-Z0-9 .,;:\-()_+=?!$#@[\]/|*%~{}'\\]$/
59
+ );
60
+ var xmlAttributeCharProcessor = (char) => (
61
+ // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
62
+ char.length !== 1 ? "" : legalXmlCharRegex.test(char) ? char : char === "&" ? "&amp;" : char === '"' ? "&quot;" : char === ">" ? "&gt;" : char === "<" ? "&lt;" : `&#${char.charCodeAt(0)};`
63
+ );
64
+ var xmlAttributeValueProcessor = (value) => (
65
+ // Ports juce::XmlOutputFunctions::escapeIllegalXMLChars()
66
+ typeof value !== "string" ? "" : value.split("").map(xmlAttributeCharProcessor).join("")
67
+ );
68
+ var xmlBuilder = new XMLBuilder({
69
+ ignoreAttributes: false,
70
+ suppressEmptyNode: true,
71
+ processEntities: false,
72
+ // Disabled since it doesn't port to juce as is
73
+ attributeValueProcessor: (_, value) => xmlAttributeValueProcessor(value)
24
74
  });
25
- module.exports = __toCommonJS(src_exports);
75
+ var JuceKeyFileUtils = class {
76
+ static createKeyFileContentLine({
77
+ appName,
78
+ userEmail,
79
+ userName,
80
+ machineNumbers,
81
+ machineNumbersAttributeName
82
+ }, date, expiryTime) {
83
+ const xml = {
84
+ key: {
85
+ "@_user": userName,
86
+ "@_email": userEmail,
87
+ [`@_${machineNumbersAttributeName}`]: machineNumbers,
88
+ "@_app": appName,
89
+ "@_date": date,
90
+ // Does not affect key file decryption
91
+ ...expiryTime ? { "@_expiryTime": expiryTime } : {}
92
+ }
93
+ };
94
+ return [XML_DECLARATION, xmlBuilder.build(xml).trim()].join(" ");
95
+ }
96
+ static createKeyFileComment({
97
+ appName,
98
+ userEmail,
99
+ userName,
100
+ machineNumbers
101
+ }, created, expiryTime) {
102
+ return `Keyfile for ${appName}\r
103
+ ${userName ? `User: ${userName}\r
104
+ ` : ""}Email: ${userEmail}\r
105
+ Machine numbers: ${machineNumbers}\r
106
+ Created: ${created}` + (expiryTime ? `\r
107
+ Expires: ${expiryTime}` : "");
108
+ }
109
+ static encryptXMLLine(xmlLine, privateKey) {
110
+ const val = JuceBigInteger.fromUTF8MemoryBlock(xmlLine);
111
+ privateKey.applyToValue(val);
112
+ return val.toHex();
113
+ }
114
+ static createKeyFile(comment, xmlLine, rsaPrivateKey) {
115
+ let asHex = "#" + this.encryptXMLLine(xmlLine, rsaPrivateKey);
116
+ const lines = [];
117
+ lines.push(comment);
118
+ lines.push("");
119
+ const charsPerLine = 70;
120
+ while (asHex.length > 0) {
121
+ lines.push(asHex.substring(0, charsPerLine));
122
+ asHex = asHex.substring(charsPerLine);
123
+ }
124
+ lines.push("");
125
+ return lines.join("\r\n");
126
+ }
127
+ };
26
128
 
27
- // src/generate.ts
28
- var generateKeyFile = (params) => {
29
- return "Hello Key File World";
129
+ // src/juce/JuceDateString.ts
130
+ var JuceDateString = class {
131
+ static inHexMs(date) {
132
+ return date.getTime().toString(16);
133
+ }
134
+ static inFormattedComment(date) {
135
+ const months = [
136
+ "Jan",
137
+ "Feb",
138
+ "Mar",
139
+ "Apr",
140
+ "May",
141
+ "Jun",
142
+ "Jul",
143
+ "Aug",
144
+ "Sep",
145
+ "Oct",
146
+ "Nov",
147
+ "Dec"
148
+ ];
149
+ const day = date.getDate().toString();
150
+ const month = months[date.getMonth()];
151
+ const year = date.getFullYear();
152
+ let hours = date.getHours();
153
+ const minutes = date.getMinutes().toString().padStart(2, "0");
154
+ const seconds = date.getSeconds().toString().padStart(2, "0");
155
+ const ampm = hours >= 12 ? "pm" : "am";
156
+ hours = hours % 12;
157
+ hours = hours ? hours : 12;
158
+ return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}${ampm}`;
159
+ }
160
+ };
161
+
162
+ // src/juce/JuceRSAKey.ts
163
+ var JuceRSAKey = class {
164
+ constructor(s) {
165
+ this.s = s;
166
+ if (s.includes(",")) {
167
+ const [p1, p2] = s.split(",").map((p) => JuceBigInteger.fromHex(p));
168
+ this.part1 = p1;
169
+ this.part2 = p2;
170
+ } else {
171
+ this.part1 = new JuceBigInteger();
172
+ this.part2 = new JuceBigInteger();
173
+ }
174
+ }
175
+ applyToValue(val) {
176
+ if (this.part1.isZero() || this.part2.isZero() || val.value <= 0n) {
177
+ return;
178
+ }
179
+ const result = new JuceBigInteger();
180
+ while (!val.isZero()) {
181
+ result.value *= this.part2.value;
182
+ const remainder = new JuceBigInteger();
183
+ val.divideBy(this.part2, remainder);
184
+ remainder.exponentModulo(this.part1, this.part2);
185
+ result.value += remainder.value;
186
+ }
187
+ val.value = result.value;
188
+ }
189
+ };
190
+
191
+ // src/juce/JuceKeyGeneration.ts
192
+ var JuceKeyGeneration = class {
193
+ static generateKeyFile(params, date = /* @__PURE__ */ new Date()) {
194
+ const xml = JuceKeyFileUtils.createKeyFileContentLine(
195
+ {
196
+ appName: params.appName,
197
+ userEmail: params.userEmail,
198
+ userName: params.userName,
199
+ machineNumbers: params.machineNumbers,
200
+ machineNumbersAttributeName: "mach"
201
+ },
202
+ JuceDateString.inHexMs(date)
203
+ );
204
+ const comment = JuceKeyFileUtils.createKeyFileComment(
205
+ {
206
+ appName: params.appName,
207
+ userEmail: params.userEmail,
208
+ userName: params.userName,
209
+ machineNumbers: params.machineNumbers
210
+ },
211
+ JuceDateString.inFormattedComment(date)
212
+ );
213
+ return JuceKeyFileUtils.createKeyFile(
214
+ comment,
215
+ xml,
216
+ new JuceRSAKey(params.privateKey)
217
+ );
218
+ }
219
+ static generateExpiringKeyFile(params, date = /* @__PURE__ */ new Date()) {
220
+ const xml = JuceKeyFileUtils.createKeyFileContentLine(
221
+ {
222
+ appName: params.appName,
223
+ userEmail: params.userEmail,
224
+ userName: params.userName,
225
+ machineNumbers: params.machineNumbers,
226
+ machineNumbersAttributeName: "expiring_mach"
227
+ },
228
+ JuceDateString.inHexMs(date),
229
+ JuceDateString.inHexMs(params.expiryTime)
230
+ );
231
+ const comment = JuceKeyFileUtils.createKeyFileComment(
232
+ {
233
+ appName: params.appName,
234
+ userEmail: params.userEmail,
235
+ userName: params.userName,
236
+ machineNumbers: params.machineNumbers
237
+ },
238
+ JuceDateString.inFormattedComment(date),
239
+ JuceDateString.inFormattedComment(params.expiryTime)
240
+ );
241
+ return JuceKeyFileUtils.createKeyFile(
242
+ comment,
243
+ xml,
244
+ new JuceRSAKey(params.privateKey)
245
+ );
246
+ }
247
+ };
248
+ export {
249
+ JuceKeyGeneration
30
250
  };
31
- // Annotate the CommonJS export names for ESM import in node:
32
- 0 && (module.exports = {
33
- generateKeyFile
34
- });
35
251
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/generate.ts"],"sourcesContent":["export * from './generate'\nexport * from './types'\n","import { GenerateKeyFileParams } from './types'\n\nexport const generateKeyFile = (params: GenerateKeyFileParams) => {\n return 'Hello Key File World'\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,kBAAkB,CAAC,WAAkC;AAC9D,SAAO;AACX;","names":[]}
1
+ {"version":3,"sources":["../src/juce/JuceKeyFileUtils.ts","../src/juce/JuceBigInteger.ts","../src/juce/JuceDateString.ts","../src/juce/JuceRSAKey.ts","../src/juce/JuceKeyGeneration.ts"],"sourcesContent":["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 ? '&amp;'\n : char === '\"'\n ? '&quot;'\n : char === '>'\n ? '&gt;'\n : char === '<'\n ? '&lt;'\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: false, // Disabled since it doesn't port to juce as is\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, // Does not affect key file decryption\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","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 { BigInteger as JSBN } from 'jsbn'\n\nimport { 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 { JuceKeyFileUtils } from 'src/juce/JuceKeyFileUtils'\nimport { GenerateExpiringKeyFileParams, GenerateKeyFileParams } from 'src/types'\n\nimport { JuceDateString } from './JuceDateString'\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"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@ianacaburian/generate-key-file",
3
- "version": "0.0.4",
4
- "description": "Provides juce_KeyGeneration::generateKeyFile() for javascript.",
3
+ "version": "0.1.1",
4
+ "description": "Ports juce_KeyGeneration::generateKeyFile() to node.",
5
+ "type": "module",
5
6
  "main": "./dist/index.js",
6
7
  "module": "./dist/index.mjs",
7
8
  "types": "./dist/index.d.ts",
@@ -9,16 +10,23 @@
9
10
  "dist"
10
11
  ],
11
12
  "scripts": {
12
- "build": "tsup",
13
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "clean": "rm -rf dist && npm run clean:test",
14
+ "lint": "eslint src",
15
+ "clean:test": "rm -rf test/bin/* && cd test/console && ./script/clean-build.sh",
16
+ "open:test/console": "cd test/console && ./script/open-xcode-macos-dev.sh",
17
+ "install:test/console": "cmake -S test/console -B test/console/build && cmake --build test/console/build && cmake --install test/console/build --prefix test/bin",
18
+ "build": "npm run lint && npm run install:test/console && tsup",
19
+ "test": "vitest"
14
20
  },
15
21
  "repository": {
16
22
  "type": "git",
17
23
  "url": "git+https://github.com/ianacaburian/generate-key-file.git"
18
24
  },
19
25
  "keywords": [
20
- "key-file",
26
+ "auth",
27
+ "cryptography",
21
28
  "juce",
29
+ "keyfile",
22
30
  "rsa"
23
31
  ],
24
32
  "author": "ianacaburian",
@@ -28,14 +36,27 @@
28
36
  },
29
37
  "homepage": "https://github.com/ianacaburian/generate-key-file#readme",
30
38
  "devDependencies": {
39
+ "@eslint/js": "^9.11.1",
40
+ "@ianvs/prettier-plugin-sort-imports": "^4.3.1",
41
+ "@types/jsbn": "^1.2.33",
31
42
  "@typescript-eslint/eslint-plugin": "^8.7.0",
32
43
  "@typescript-eslint/parser": "^8.7.0",
33
44
  "eslint": "^9.11.1",
34
45
  "eslint-config-prettier": "^9.1.0",
35
46
  "eslint-plugin-prettier": "^5.2.1",
47
+ "fast-check": "^3.22.0",
48
+ "globals": "^15.9.0",
36
49
  "prettier": "^3.3.3",
37
50
  "ts-node": "^10.9.2",
38
51
  "tsup": "^8.3.0",
39
- "typescript": "^5.6.2"
52
+ "typescript": "5.5.4",
53
+ "typescript-eslint": "^8.7.0",
54
+ "vitest": "^2.1.1",
55
+ "zod-fast-check": "^0.10.1"
56
+ },
57
+ "dependencies": {
58
+ "fast-xml-parser": "^4.5.0",
59
+ "jsbn": "^1.1.0",
60
+ "zod": "^3.23.8"
40
61
  }
41
62
  }
package/dist/index.d.mts DELETED
@@ -1,11 +0,0 @@
1
- type GenerateKeyFileParams = {
2
- appName: string;
3
- userEmail: string;
4
- userName: string;
5
- machineNumbers: string;
6
- privateKey: string;
7
- };
8
-
9
- declare const generateKeyFile: (params: GenerateKeyFileParams) => string;
10
-
11
- export { type GenerateKeyFileParams, generateKeyFile };
package/dist/index.mjs DELETED
@@ -1,8 +0,0 @@
1
- // src/generate.ts
2
- var generateKeyFile = (params) => {
3
- return "Hello Key File World";
4
- };
5
- export {
6
- generateKeyFile
7
- };
8
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/generate.ts"],"sourcesContent":["import { GenerateKeyFileParams } from './types'\n\nexport const generateKeyFile = (params: GenerateKeyFileParams) => {\n return 'Hello Key File World'\n}\n"],"mappings":";AAEO,IAAM,kBAAkB,CAAC,WAAkC;AAC9D,SAAO;AACX;","names":[]}