@ianacaburian/generate-key-file
Version:
Ports juce_KeyGeneration::generateKeyFile() to node.
1 lines • 19.4 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.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","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 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 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 { 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 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().min(new Date('1970-01-01T00:00:00.001Z'), {\n message: 'Expiry time must be after 1970-01-01T00:00:00.000Z'\n })\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"]}