@interopio/gateway-server 0.23.0 → 0.24.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/bin/gateway-server.cjs +289 -118
- package/changelog.md +15 -0
- package/dist/gateway-ent.cjs +1 -1
- package/dist/gateway-ent.cjs.map +3 -3
- package/dist/gateway-ent.js +2 -2
- package/dist/gateway-ent.js.map +3 -3
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +4 -4
- package/dist/tools.cjs +15 -1
- package/dist/tools.cjs.map +4 -4
- package/dist/tools.js +15 -1
- package/dist/tools.js.map +4 -4
- package/package.json +4 -4
- package/types/build.d.ts +63 -0
- package/types/tools.d.ts +1 -0
package/dist/tools.cjs
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var fe=Object.create;var $=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ye=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var A=(e,t)=>{for(var r in t)$(e,r,{get:t[r],enumerable:!0})},q=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of he(t))!be.call(e,s)&&s!==r&&$(e,s,{get:()=>t[s],enumerable:!(n=de(t,s))||n.enumerable});return e};var N=(e,t,r)=>(r=e!=null?fe(ye(e)):{},q(t||!e||!e.__esModule?$(r,"default",{value:e,enumerable:!0}):r,e)),we=e=>q($({},"__esModule",{value:!0}),e);var Oe={};A(Oe,{argon2:()=>_,build:()=>B,keygen:()=>L,manage:()=>T,mkcert:()=>H});module.exports=we(Oe);var _={};A(_,{ARGON2_VERSION:()=>X,ARGON2_VERSION_10:()=>z,ARGON2_VERSION_13:()=>Q,DEFAULT_ALGORITHM:()=>Se,DEFAULT_HASH_LENGTH:()=>Z,DEFAULT_MEMORY:()=>R,DEFAULT_PARALLELISM:()=>j,DEFAULT_PASSES:()=>U,DEFAULT_SALT_LENGTH:()=>I,createHash:()=>K,decode:()=>ee,encode:()=>te,hash:()=>xe,verify:()=>Ee});var L={};A(L,{createSalt:()=>P});var Y=require("node:crypto");function P(e){return(0,Y.getRandomValues)(Buffer.alloc(e))}var k;async function Ae(){if(k===void 0)try{let e=await import("node:crypto");if(!e.argon2)throw new Error("argon2 not available");k=e.argon2}catch{throw new Error("argon2 is not available in this Node.js version. Node.js 24.7.0 or later is required for Argon2 password encoding. Please upgrade Node.js or use a different authentication method.")}return k}var z=16,Q=19,X=Q,Se="argon2id",I=16,Z=32,j=4,R=65536,U=3;function ee(e){let t=e.split("$");if(t.length<4)throw new Error("Invalid encoded Argon2 hash");let r=1,n=t[r++];if(n!=="argon2d"&&n!=="argon2i"&&n!=="argon2id")throw new Error("Invalid Argon2 type");let s=z;t[r].startsWith("v=")&&(s=parseInt(t[r].substring(2),10),r++);let a={},g=t[r++].split(",");for(let l of g){let[m,o]=l.split("=");switch(m){case"m":a.memory=parseInt(o,10);break;case"t":a.passes=parseInt(o,10);break;case"p":a.parallelism=parseInt(o,10);break}}a.nonce=Buffer.from(t[r++],"base64url");let i=Buffer.from(t[r++],"base64url");return{algorithm:n,version:s,parameters:a,hash:i}}function te(e){let{algorithm:t,version:r,parameters:n,hash:s}=e;return`$${t}$v=${r}$m=${n.memory},t=${n.passes},p=${n.parallelism}$${n.nonce.toString("base64url")}$${s.toString("base64url")}`}async function K(e,t,r,n){let s=n?.nonce??P(I),a=n?.memory??R,g=n?.passes??U,i=n?.parallelism??j,l={message:t,tagLength:r,nonce:s,memory:a,passes:g,parallelism:i},m=await Ae();return new Promise((o,d)=>{m(e,l,(y,w)=>{y?d(y):w?o(Buffer.from(w)):d(new Error("argon2 returned no result"))})})}async function xe(e,t){let r=t?.algorithm??"argon2id",n=t?.saltLength??I,s=t?.hashLength??Z,a=t?.parallelism??j,g=t?.memory??R,i=t?.passes??U,l=P(n),m={memory:g,passes:i,parallelism:a,nonce:l},o=await K(r,e,s,m);return te({algorithm:r,version:X,parameters:m,hash:o})}async function Ee(e,t){try{let r=ee(e),n=await K(r.algorithm,t,r.hash.length,r.parameters);return r.hash.equals(n)}catch{return!1}}var T={};A(T,{sendCommand:()=>$e});var re=N(require("net"),1);function $e(e,t,r={}){let{timeout:n=5e3}=r,s=e?.path?{path:e.path}:{port:e?.port??0},a=e?.path??`port ${e?.port}`;return new Promise((g,i)=>{let l=re.default.connect(s,()=>{l.write(JSON.stringify(t))}),m=setTimeout(()=>{l.destroy(),i(new Error(`Connection timed out after ${n}`))},n);l.on("data",o=>{clearTimeout(m);try{let d=JSON.parse(o.toString());d.error?i(new Error(d.error)):g(d.result)}catch{g(o.toString())}l.end()}),l.on("error",o=>{clearTimeout(m),o.code==="ENOENT"||o.code==="ECONNREFUSED"?i(new Error(`Cannot connect to gateway at ${a}. Make sure the gateway server is running and the path is correct.`,{cause:o})):i(o)})})}var H={};A(H,{DEFAULT_CA_NAME:()=>oe,generateCert:()=>Pe,generateRootCA:()=>Ne});var u=require("jsrsasign"),C=require("node:os"),ne=require("node:crypto"),v=`${(0,C.userInfo)().username}@${(0,C.hostname)()}`;function se(){return(0,ne.randomBytes)(16).toString("hex")}var O="io.Gateway Dev CA",oe=`${O} ${v}`;function Ne(e){let t=e?.name||oe,r=e?.passphrase,n=u.KEYUTIL.generateKeypair("EC","secp384r1"),s=n.prvKeyObj,a=n.pubKeyObj,g=r?u.KEYUTIL.getPEM(s,"PKCS8PRV",r,"AES-256-CBC"):u.KEYUTIL.getPEM(s,"PKCS8PRV"),l=new u.KJUR.asn1.x509.Certificate({version:3,serial:{hex:se()},issuer:{str:`/CN=${t}/O=${O}/OU=${v}`},subject:{str:`/CN=${t}/O=${O}/OU=${v}`},notbefore:(0,u.datetozulu)(new Date(Date.now()-60*1e3),!1,!1),notafter:(0,u.datetozulu)(new Date(Date.now()+10*365*24*60*60*1e3),!1,!1),sbjpubkey:a,ext:[{extname:"basicConstraints",critical:!0,cA:!0},{extname:"keyUsage",critical:!0,names:["keyCertSign"]}],sigalg:"SHA384withECDSA",cakey:s}).getPEM();return{key:g,cert:l}}function Pe(e,t,r,n=!1,s=7){let a=u.KEYUTIL.generateKeypair("EC","secp256r1"),g=a.prvKeyObj,i=a.pubKeyObj,l=u.KEYUTIL.getPEM(g,"PKCS8PRV"),m=[],o=n?"dev-user":"localhost";for(let f of r)if(f.toLowerCase().startsWith("ip:"))m.push({ip:f.substring(3)});else if(f.toLowerCase().startsWith("email:"))m.push({rfc822:f.substring(6)});else{let x=f.toLowerCase().startsWith("dns:");if(n)o=x?f.substring(4):f;else{let E=x?f.substring(4):f;m.push({dns:E}),m.length===1&&(o=E)}}let d=[{extname:"basicConstraints",cA:!1},{extname:"keyUsage",critical:!0,names:["digitalSignature","keyEncipherment"]},{extname:"extKeyUsage",array:[n?"clientAuth":"serverAuth"]}];m.length>0&&d.push({extname:"subjectAltName",array:m});let w=new u.KJUR.asn1.x509.Certificate({version:3,serial:{hex:se()},issuer:{str:t},subject:{str:`/CN=${o}/O=${O}/OU=${v}`},notbefore:(0,u.datetozulu)(new Date(Date.now()-60*1e3),!1,!1),notafter:(0,u.datetozulu)(new Date(Date.now()+s*24*60*60*1e3),!1,!1),sbjpubkey:i,ext:d,sigalg:"SHA256withECDSA",cakey:e}).getPEM();return{key:l,cert:w}}var B={};A(B,{buildSea:()=>ve});var p=require("node:fs/promises"),ie=require("node:child_process"),ce=require("node:util"),le=require("node:crypto"),b=require("node:path"),S=(0,ce.promisify)(ie.execFile);function M(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}async function ve(e,t){let r=t?.outDir??"./build",n=t?.config?.executable??process.execPath,s=M(e),a=M(t?.version??""),g=M(r.replace(/\\/g,"/")),{stdout:i}=await S(n,["-e",`
|
|
2
|
+
const { mkdirSync } = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const appVersion = '${a}'.trim();
|
|
5
|
+
const dirName = '${s}' + (appVersion ? '-v' + appVersion : '') + '.' + process.platform + '-' + process.arch;
|
|
6
|
+
const dir = path.resolve('${g}', dirName);
|
|
7
|
+
mkdirSync(dir, { recursive: true });
|
|
8
|
+
process.stdout.write(JSON.stringify({ dirName, nodeVersion: process.version, platform: process.platform, arch: process.arch }));
|
|
9
|
+
`.trim()]),{dirName:l,nodeVersion:m,platform:o,arch:d}=JSON.parse(i),y;if(t?.esbuild){let c;try{c=await import("esbuild")}catch{throw new Error(`esbuild is required to bundle the entry point. Install it with:
|
|
10
|
+
|
|
11
|
+
npm install --save-dev esbuild
|
|
12
|
+
`)}y=`${r}/${e}.js`,await c.build({format:"cjs",target:"node20",platform:"node",bundle:!0,external:["esbuild","postject"],loader:{".md":"file",".d.ts":"file"},assetNames:`${l}/[name]`,entryNames:"[name]",outdir:r,minify:!0,logLevel:"info",...t.esbuild})}else if(t?.config?.main)y=(0,b.resolve)(t.config.main);else throw new Error("Either esbuild options (with entryPoints) or config.main must be provided.");let w=(0,b.resolve)(`${r}/${e}.sea.node-${m}-${o}-${d}.blob`),f=(0,b.resolve)(`${r}/${e}.sea-config.${l}.json`),x={disableExperimentalSEAWarning:!0,useSnapshot:!1,useCodeCache:!1,...t?.config,main:(0,b.resolve)(y),output:w};await(0,p.writeFile)(f,JSON.stringify(x,null,2));let E=(0,b.resolve)(r,l),D=o==="win32",F=o==="darwin",me=D?`${e}.exe`:e,h=`${E}/${me}`,ge=await(0,p.readFile)(y),V=`${r}/${(0,b.basename)(y)}.sha`,J=(0,le.createHash)("sha256").update(ge).digest("hex"),W=!1;try{let[c]=await Promise.all([(0,p.readFile)(V,"utf8"),(0,p.access)(h)]);W=c===J}catch{}if(W)return console.log("SEA build skipped - esbuild output unchanged and target exists"),h;if(await S(n,["--experimental-sea-config",f]),await(0,p.copyFile)(n,h),D)try{let c=await ae();c&&(console.log(`Found signtool at: ${c}`),await S(c,["remove","/s",h]),console.log(`Signature removed from ${h} executable`))}catch(c){console.warn("Failed to remove signature:",c.message)}else if(F)try{await S("codesign",["--remove-signature",h]),console.log(`Signature removed from ${h} executable`)}catch(c){console.warn("Failed to remove signature:",c.message)}let G;try{({inject:G}=await import("postject"))}catch{throw new Error(`postject is required to build a SEA. Install it with:
|
|
13
|
+
|
|
14
|
+
npm install --save-dev postject
|
|
15
|
+
`)}let ue=await(0,p.readFile)(w),pe=["NODE","SEA","FUSE","fce680ab2cc467b6e072b8b5df1996b2"].join("_");if(await G(h,"NODE_SEA_BLOB",ue,{overwrite:!0,sentinelFuse:pe,...F?{machoSegmentName:"NODE_SEA"}:{}}),D)try{let c=await ae();c&&(console.log(`Signing executable with signtool at: ${c}`),await S(c,["sign","/fd","SHA256",h]),console.log("Executable signed successfully"))}catch(c){console.warn("Failed to sign executable:",c.message)}else if(F)try{await S("codesign",["--sign","-",h]),console.log("Executable signed successfully")}catch(c){console.warn("Failed to sign executable:",c.message)}return await(0,p.writeFile)(V,J),h}async function ae(){let e="C:\\Program Files (x86)\\Windows Kits\\10\\bin";try{let r=(await(0,p.readdir)(e,{withFileTypes:!0})).filter(n=>n.isDirectory()&&/^10\.0\.\d+\.\d+$/.test(n.name)).map(n=>n.name).sort((n,s)=>{let a=n.split(".").map(Number),g=s.split(".").map(Number);for(let i=0;i<a.length;i++)if(a[i]!==g[i])return g[i]-a[i];return 0});for(let n of r){let s=`${e}\\${n}\\${process.arch}\\signtool.exe`;try{return await(0,p.access)(s),s}catch{}}return console.warn("signtool.exe not found in any Windows SDK version"),null}catch(t){return console.warn(`Windows SDK not found at ${e}: ${t.message}`),null}}0&&(module.exports={argon2,build,keygen,manage,mkcert});
|
|
2
16
|
//# sourceMappingURL=tools.cjs.map
|
package/dist/tools.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/tools/index.ts", "../src/tools/crypto/argon2.ts", "../src/tools/crypto/keygen.ts", "../src/manage/client.ts", "../src/tools/mkcert.ts"],
|
|
4
|
-
"sourcesContent": ["export * as argon2 from './crypto/argon2.ts';\nexport * as keygen from './crypto/keygen.ts';\nexport * as manage from '../manage/client.ts';\nexport * as mkcert from './mkcert.ts';\n", "import type {\n Argon2Algorithm,\n Argon2Parameters\n} from 'node:crypto';\n\nimport { createSalt } from './keygen.ts';\nimport type { Argon2Hash, Argon2HashParameters } from '../../../types/crypto/argon2';\n\n// Lazy import for argon2 (added in Node.js 24.7.0)\n// This allows the module to load on older Node.js versions\nlet argon2: typeof import('node:crypto').argon2 | undefined;\n\nasync function getArgon2() {\n if (argon2 === undefined) {\n try {\n const crypto = await import('node:crypto');\n if (!crypto.argon2) {\n throw new Error('argon2 not available');\n }\n argon2 = crypto.argon2;\n } catch (err) {\n throw new Error(\n 'argon2 is not available in this Node.js version. ' +\n 'Node.js 24.7.0 or later is required for Argon2 password encoding. ' +\n 'Please upgrade Node.js or use a different authentication method.'\n );\n }\n }\n return argon2;\n}\n\n// Argon2 version constants\nexport const ARGON2_VERSION_10 = 0x10; // 16\nexport const ARGON2_VERSION_13 = 0x13; // 19\nexport const ARGON2_VERSION = ARGON2_VERSION_13;\n\n// Default parameters for Argon2 hashing\nexport const DEFAULT_ALGORITHM: Argon2Algorithm = 'argon2id';\nexport const DEFAULT_SALT_LENGTH = 16;\nexport const DEFAULT_HASH_LENGTH = 32;\nexport const DEFAULT_PARALLELISM = 4;\nexport const DEFAULT_MEMORY = 65536; // 64 MB in KiB\nexport const DEFAULT_PASSES = 3;\n\n/**\n * Decode an encoded Argon2 hash string into its components.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param encodedHash - The encoded Argon2 hash string\n * @returns Decoded hash components\n * @see https://github.com/P-H-C/phc-winner-argon2/blob/master/src/encoding.c#L244\n */\nexport function decode(encodedHash: string): Argon2Hash {\n const parts = encodedHash.split('$'); // ['', 'argon2id', 'v=19', 'm=65536,t=3,p=4', 'base64salt', 'base64hash']\n if (parts.length < 4) {\n throw new Error('Invalid encoded Argon2 hash');\n }\n let current = 1;\n const algorithm = parts[current++];\n if (algorithm !== 'argon2d' && algorithm !== 'argon2i' && algorithm !== 'argon2id') {\n throw new Error('Invalid Argon2 type');\n }\n let version = ARGON2_VERSION_10;\n if (parts[current].startsWith('v=')) {\n version = parseInt(parts[current].substring(2), 10);\n current++;\n }\n const parameters: Partial<Argon2HashParameters> = {};\n const paramsParts = parts[current++].split(',');\n\n for (const param of paramsParts) {\n const [key, value] = param.split('=');\n switch (key) {\n case 'm':\n parameters.memory = parseInt(value, 10);\n break;\n case 't':\n parameters.passes = parseInt(value, 10);\n break;\n case 'p':\n parameters.parallelism = parseInt(value, 10);\n break;\n }\n }\n parameters.nonce = Buffer.from(parts[current++], 'base64url');\n const hash = Buffer.from(parts[current++], 'base64url');\n\n return { algorithm, version, parameters: parameters as Argon2Hash['parameters'], hash };\n}\n\n/**\n * Encode Argon2 hash components into a standard string format.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param hashData - The hash components to encode\n * @returns Encoded hash string\n */\nexport function encode(hashData: Argon2Hash): string {\n const { algorithm, version, parameters, hash } = hashData;\n return `$${algorithm}$v=${version}$m=${parameters.memory},t=${parameters.passes},p=${parameters.parallelism}$${parameters.nonce.toString('base64url')}$${hash.toString('base64url')}`;\n}\n\n\n/**\n * Create an Argon2 hash from parameters.\n * Low-level wrapper around node:crypto's argon2.\n *\n * @param algorithm - Argon2 algorithm variant ('argon2d' | 'argon2i' | 'argon2id')\n * @param password - The password to hash\n * @param hashLength - Length of the output hash in bytes\n * @param parameters - Argon2 parameters (nonce, memory, passes, parallelism). If not provided, defaults will be used.\n * @returns The hash buffer\n */\nexport async function createHash(\n algorithm: Argon2Algorithm,\n password: string,\n hashLength: number,\n parameters?: Argon2Hash['parameters']\n): Promise<Buffer> {\n const nonce = parameters?.nonce ?? createSalt(DEFAULT_SALT_LENGTH);\n const memory = parameters?.memory ?? DEFAULT_MEMORY;\n const passes = parameters?.passes ?? DEFAULT_PASSES;\n const parallelism = parameters?.parallelism ?? DEFAULT_PARALLELISM;\n\n const argon2Params: Argon2Parameters = {\n message: password,\n tagLength: hashLength,\n nonce,\n memory,\n passes,\n parallelism\n };\n const argon2Fn = await getArgon2();\n\n // Wrap callback-based argon2 in a Promise\n return new Promise((resolve, reject) => {\n argon2Fn(algorithm, argon2Params, (err: Error | null, result?: Uint8Array) => {\n if (err) {\n reject(err);\n }\n else if (result) {\n resolve(Buffer.from(result));\n }\n else {\n reject(new Error('argon2 returned no result'));\n }\n });\n });\n}\n\n\n/**\n * Hash a password using Argon2.\n *\n * @param password - The plain text password to hash\n * @param options - Optional parameters object. If not provided, defaults will be used.\n * @returns The encoded Argon2 hash string\n */\nexport async function hash(\n password: string,\n options?: {\n algorithm?: Argon2Algorithm;\n saltLength?: number;\n hashLength?: number;\n parallelism?: number;\n memory?: number;\n passes?: number;\n }\n): Promise<string> {\n const algorithm = options?.algorithm ?? 'argon2id';\n const saltLength = options?.saltLength ?? DEFAULT_SALT_LENGTH;\n const hashLength = options?.hashLength ?? DEFAULT_HASH_LENGTH;\n const parallelism = options?.parallelism ?? DEFAULT_PARALLELISM;\n const memory = options?.memory ?? DEFAULT_MEMORY;\n const passes = options?.passes ?? DEFAULT_PASSES;\n\n const nonce = createSalt(saltLength);\n const parameters = { memory, passes, parallelism, nonce };\n const hashBuffer = await createHash(algorithm, password, hashLength, parameters);\n return encode({\n algorithm,\n version: ARGON2_VERSION,\n parameters,\n hash: hashBuffer\n });\n}\n\n/**\n * Verify a password against an Argon2 hash.\n *\n * @param encodedHash - The encoded Argon2 hash to verify against\n * @param password - The plain text password to verify\n * @returns true if password matches the hash, false otherwise\n */\nexport async function verify(encodedHash: string, password: string): Promise<boolean> {\n try {\n const decoded = decode(encodedHash);\n const hashBuffer = await createHash(\n decoded.algorithm,\n password,\n decoded.hash.length,\n decoded.parameters\n );\n return decoded.hash.equals(hashBuffer);\n } catch {\n return false;\n }\n}\n\n", "import { getRandomValues } from 'node:crypto';\n\n/**\n * Create a random salt (nonce) for cryptographic operations.\n *\n * @param length - Length of the salt in bytes\n * @returns Random salt buffer\n */\nexport function createSalt(length: number): Buffer {\n return getRandomValues(Buffer.alloc(length));\n}\n\n", "import net from 'net';\nimport type { ManagementCommand, ManagementEndpoint, SendCommandOptions } from '../../types/manage.d.ts';\n\nexport function sendCommand(\n server: ManagementEndpoint,\n command: ManagementCommand,\n options: SendCommandOptions = {}\n): Promise<unknown> {\n const { timeout = 5000 } = options;\n\n // Determine connection target: named pipe/socket path or port\n const connectOptions: net.NetConnectOpts = server?.path\n ? { path: server.path }\n : { port: server?.port ?? 0 };\n\n const target = server?.path ?? `port ${server?.port}`;\n\n return new Promise((resolve, reject) => {\n const client = net.connect(connectOptions, () => {\n client.write(JSON.stringify(command));\n });\n\n const timeoutId = setTimeout(() => {\n client.destroy();\n reject(new Error(`Connection timed out after ${timeout}`));\n }, timeout);\n\n client.on('data', (data) => {\n clearTimeout(timeoutId);\n try {\n const response = JSON.parse(data.toString());\n if (response.error) {\n reject(new Error(response.error));\n }\n else {\n resolve(response.result);\n }\n }\n catch {\n // Not JSON, return as raw string\n resolve(data.toString());\n }\n client.end();\n });\n\n client.on('error', (err: NodeJS.ErrnoException) => {\n clearTimeout(timeoutId);\n if (err.code === 'ENOENT' || err.code === 'ECONNREFUSED') {\n reject(new Error(`Cannot connect to gateway at ${target}. Make sure the gateway server is running and the path is correct.`, { cause: err }));\n }\n else {\n reject(err);\n }\n });\n });\n}\n\n", "import { KEYUTIL, KJUR, RSAKey, datetozulu } from \"jsrsasign\";\nimport { userInfo, hostname } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\nconst userAndHost = `${userInfo().username}@${hostname()}`;\n\nfunction randomSerialNumber(): string {\n const bytes = randomBytes(16);\n return bytes.toString('hex');\n}\n\nconst DEFAULT_ORGANISATION = `io.Gateway Dev CA`;\nexport const DEFAULT_CA_NAME = `${DEFAULT_ORGANISATION} ${userAndHost}`;\n\nexport function generateRootCA(options?: { name?: string, passphrase?: string } ): { key: string, cert: string } {\n\n const commonName = options?.name || DEFAULT_CA_NAME;\n const passphrase = options?.passphrase;\n\n // STEP 1. generate a key pair for Root CA (secp384r1 for higher security)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp384r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = passphrase\n ? KEYUTIL.getPEM(prv, \"PKCS8PRV\", passphrase, \"AES-256-CBC\")\n : KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // STEP 2: create self-signed CA certificate\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000), false, false), // 10 years\n\n sbjpubkey: pub,\n\n ext: [\n {extname: \"basicConstraints\", critical: true, cA: true},\n {extname: \"keyUsage\", critical: true, names: [\"keyCertSign\"]}\n ],\n\n sigalg: \"SHA384withECDSA\",\n cakey: prv\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n\n\n/**\n * Generate a certificate with custom SAN entries\n * @param cakey - CA private key\n * @param issuer - Issuer DN string\n * @param sanEntries - Array of SAN entry strings (e.g., \"localhost\", \"IP:192.168.1.1\", \"EMAIL:user@example.com\")\n * @param isClient - Generate client cert (clientAuth) vs server cert (serverAuth)\n * @param validityDays - Certificate validity period\n */\nexport function generateCert(\n cakey: string | RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA,\n issuer: string,\n sanEntries: string[],\n isClient: boolean = false,\n validityDays: number = 7\n): {\n key: string,\n cert: string\n} {\n // STEP 1. generate key pair (secp256r1 for faster generation)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp256r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // Parse SAN entries\n const sanArray: Array<{dns?: string, ip?: string, rfc822?: string}> = [];\n let commonName = isClient ? 'dev-user' : 'localhost';\n\n for (const entry of sanEntries) {\n if (entry.toLowerCase().startsWith('ip:')) {\n sanArray.push({ip: entry.substring(3)});\n }\n else if (entry.toLowerCase().startsWith('email:')) {\n sanArray.push({rfc822: entry.substring(6)});\n }\n else {\n const dnsPrefixed = entry.toLowerCase().startsWith('dns:');\n if (isClient) {\n commonName = dnsPrefixed ? entry.substring(4) : entry;\n }\n else {\n const dns = dnsPrefixed ? entry.substring(4) : entry;\n sanArray.push({dns});\n if (sanArray.length === 1) {\n commonName = dns; // Use first DNS as CN\n }\n }\n }\n }\n\n // STEP 2: create certificate signed by CA\n const extensions: Array<{\n extname: string;\n cA?: boolean;\n critical?: boolean;\n names?: string[];\n array?: (string[] | Array<{dns?: string, ip?: string, rfc822?: string}>);\n }> = [\n {extname: \"basicConstraints\", cA: false},\n {\n extname: \"keyUsage\",\n critical: true,\n names: [\"digitalSignature\", \"keyEncipherment\"]\n },\n {\n extname: \"extKeyUsage\",\n array: [isClient ? \"clientAuth\" : \"serverAuth\"]\n }\n ];\n\n // Add SAN only if we have entries\n if (sanArray.length > 0) {\n extensions.push({\n extname: \"subjectAltName\",\n array: sanArray\n });\n }\n\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: issuer },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}`},\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + validityDays * 24 * 60 * 60 * 1000), false, false),\n\n sbjpubkey: pub,\n ext: extensions,\n\n sigalg: \"SHA256withECDSA\",\n cakey: cakey\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["index_exports", "__export", "argon2_exports", "keygen_exports", "client_exports", "mkcert_exports", "__toCommonJS", "argon2_exports", "__export", "ARGON2_VERSION", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "DEFAULT_ALGORITHM", "DEFAULT_HASH_LENGTH", "DEFAULT_MEMORY", "DEFAULT_PARALLELISM", "DEFAULT_PASSES", "DEFAULT_SALT_LENGTH", "createHash", "decode", "encode", "hash", "verify", "keygen_exports", "__export", "createSalt", "import_node_crypto", "length", "argon2", "getArgon2", "crypto", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "ARGON2_VERSION", "DEFAULT_ALGORITHM", "DEFAULT_SALT_LENGTH", "DEFAULT_HASH_LENGTH", "DEFAULT_PARALLELISM", "DEFAULT_MEMORY", "DEFAULT_PASSES", "decode", "encodedHash", "parts", "current", "algorithm", "version", "parameters", "paramsParts", "param", "key", "value", "hash", "encode", "hashData", "createHash", "password", "hashLength", "nonce", "createSalt", "memory", "passes", "parallelism", "argon2Params", "argon2Fn", "resolve", "reject", "err", "result", "options", "saltLength", "hashBuffer", "verify", "decoded", "client_exports", "__export", "sendCommand", "import_net", "server", "command", "options", "timeout", "connectOptions", "target", "resolve", "reject", "client", "net", "timeoutId", "data", "response", "err", "mkcert_exports", "__export", "DEFAULT_CA_NAME", "generateCert", "generateRootCA", "import_jsrsasign", "import_node_os", "import_node_crypto", "userAndHost", "randomSerialNumber", "DEFAULT_ORGANISATION", "options", "commonName", "passphrase", "kp", "prv", "pub", "prvPem", "certPem", "cakey", "issuer", "sanEntries", "isClient", "validityDays", "sanArray", "entry", "dnsPrefixed", "dns", "extensions"]
|
|
3
|
+
"sources": ["../src/tools/index.ts", "../src/tools/crypto/argon2.ts", "../src/tools/crypto/keygen.ts", "../src/manage/client.ts", "../src/tools/mkcert.ts", "../src/tools/build.ts"],
|
|
4
|
+
"sourcesContent": ["export * as argon2 from './crypto/argon2.ts';\nexport * as keygen from './crypto/keygen.ts';\nexport * as manage from '../manage/client.ts';\nexport * as mkcert from './mkcert.ts';\nexport * as build from './build.ts';\n", "import type {\n Argon2Algorithm,\n Argon2Parameters\n} from 'node:crypto';\n\nimport { createSalt } from './keygen.ts';\nimport type { Argon2Hash, Argon2HashParameters } from '../../../types/crypto/argon2';\n\n// Lazy import for argon2 (added in Node.js 24.7.0)\n// This allows the module to load on older Node.js versions\nlet argon2: typeof import('node:crypto').argon2 | undefined;\n\nasync function getArgon2() {\n if (argon2 === undefined) {\n try {\n const crypto = await import('node:crypto');\n if (!crypto.argon2) {\n throw new Error('argon2 not available');\n }\n argon2 = crypto.argon2;\n } catch (err) {\n throw new Error(\n 'argon2 is not available in this Node.js version. ' +\n 'Node.js 24.7.0 or later is required for Argon2 password encoding. ' +\n 'Please upgrade Node.js or use a different authentication method.'\n );\n }\n }\n return argon2;\n}\n\n// Argon2 version constants\nexport const ARGON2_VERSION_10 = 0x10; // 16\nexport const ARGON2_VERSION_13 = 0x13; // 19\nexport const ARGON2_VERSION = ARGON2_VERSION_13;\n\n// Default parameters for Argon2 hashing\nexport const DEFAULT_ALGORITHM: Argon2Algorithm = 'argon2id';\nexport const DEFAULT_SALT_LENGTH = 16;\nexport const DEFAULT_HASH_LENGTH = 32;\nexport const DEFAULT_PARALLELISM = 4;\nexport const DEFAULT_MEMORY = 65536; // 64 MB in KiB\nexport const DEFAULT_PASSES = 3;\n\n/**\n * Decode an encoded Argon2 hash string into its components.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param encodedHash - The encoded Argon2 hash string\n * @returns Decoded hash components\n * @see https://github.com/P-H-C/phc-winner-argon2/blob/master/src/encoding.c#L244\n */\nexport function decode(encodedHash: string): Argon2Hash {\n const parts = encodedHash.split('$'); // ['', 'argon2id', 'v=19', 'm=65536,t=3,p=4', 'base64salt', 'base64hash']\n if (parts.length < 4) {\n throw new Error('Invalid encoded Argon2 hash');\n }\n let current = 1;\n const algorithm = parts[current++];\n if (algorithm !== 'argon2d' && algorithm !== 'argon2i' && algorithm !== 'argon2id') {\n throw new Error('Invalid Argon2 type');\n }\n let version = ARGON2_VERSION_10;\n if (parts[current].startsWith('v=')) {\n version = parseInt(parts[current].substring(2), 10);\n current++;\n }\n const parameters: Partial<Argon2HashParameters> = {};\n const paramsParts = parts[current++].split(',');\n\n for (const param of paramsParts) {\n const [key, value] = param.split('=');\n switch (key) {\n case 'm':\n parameters.memory = parseInt(value, 10);\n break;\n case 't':\n parameters.passes = parseInt(value, 10);\n break;\n case 'p':\n parameters.parallelism = parseInt(value, 10);\n break;\n }\n }\n parameters.nonce = Buffer.from(parts[current++], 'base64url');\n const hash = Buffer.from(parts[current++], 'base64url');\n\n return { algorithm, version, parameters: parameters as Argon2Hash['parameters'], hash };\n}\n\n/**\n * Encode Argon2 hash components into a standard string format.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param hashData - The hash components to encode\n * @returns Encoded hash string\n */\nexport function encode(hashData: Argon2Hash): string {\n const { algorithm, version, parameters, hash } = hashData;\n return `$${algorithm}$v=${version}$m=${parameters.memory},t=${parameters.passes},p=${parameters.parallelism}$${parameters.nonce.toString('base64url')}$${hash.toString('base64url')}`;\n}\n\n\n/**\n * Create an Argon2 hash from parameters.\n * Low-level wrapper around node:crypto's argon2.\n *\n * @param algorithm - Argon2 algorithm variant ('argon2d' | 'argon2i' | 'argon2id')\n * @param password - The password to hash\n * @param hashLength - Length of the output hash in bytes\n * @param parameters - Argon2 parameters (nonce, memory, passes, parallelism). If not provided, defaults will be used.\n * @returns The hash buffer\n */\nexport async function createHash(\n algorithm: Argon2Algorithm,\n password: string,\n hashLength: number,\n parameters?: Argon2Hash['parameters']\n): Promise<Buffer> {\n const nonce = parameters?.nonce ?? createSalt(DEFAULT_SALT_LENGTH);\n const memory = parameters?.memory ?? DEFAULT_MEMORY;\n const passes = parameters?.passes ?? DEFAULT_PASSES;\n const parallelism = parameters?.parallelism ?? DEFAULT_PARALLELISM;\n\n const argon2Params: Argon2Parameters = {\n message: password,\n tagLength: hashLength,\n nonce,\n memory,\n passes,\n parallelism\n };\n const argon2Fn = await getArgon2();\n\n // Wrap callback-based argon2 in a Promise\n return new Promise((resolve, reject) => {\n argon2Fn(algorithm, argon2Params, (err: Error | null, result?: Uint8Array) => {\n if (err) {\n reject(err);\n }\n else if (result) {\n resolve(Buffer.from(result));\n }\n else {\n reject(new Error('argon2 returned no result'));\n }\n });\n });\n}\n\n\n/**\n * Hash a password using Argon2.\n *\n * @param password - The plain text password to hash\n * @param options - Optional parameters object. If not provided, defaults will be used.\n * @returns The encoded Argon2 hash string\n */\nexport async function hash(\n password: string,\n options?: {\n algorithm?: Argon2Algorithm;\n saltLength?: number;\n hashLength?: number;\n parallelism?: number;\n memory?: number;\n passes?: number;\n }\n): Promise<string> {\n const algorithm = options?.algorithm ?? 'argon2id';\n const saltLength = options?.saltLength ?? DEFAULT_SALT_LENGTH;\n const hashLength = options?.hashLength ?? DEFAULT_HASH_LENGTH;\n const parallelism = options?.parallelism ?? DEFAULT_PARALLELISM;\n const memory = options?.memory ?? DEFAULT_MEMORY;\n const passes = options?.passes ?? DEFAULT_PASSES;\n\n const nonce = createSalt(saltLength);\n const parameters = { memory, passes, parallelism, nonce };\n const hashBuffer = await createHash(algorithm, password, hashLength, parameters);\n return encode({\n algorithm,\n version: ARGON2_VERSION,\n parameters,\n hash: hashBuffer\n });\n}\n\n/**\n * Verify a password against an Argon2 hash.\n *\n * @param encodedHash - The encoded Argon2 hash to verify against\n * @param password - The plain text password to verify\n * @returns true if password matches the hash, false otherwise\n */\nexport async function verify(encodedHash: string, password: string): Promise<boolean> {\n try {\n const decoded = decode(encodedHash);\n const hashBuffer = await createHash(\n decoded.algorithm,\n password,\n decoded.hash.length,\n decoded.parameters\n );\n return decoded.hash.equals(hashBuffer);\n } catch {\n return false;\n }\n}\n\n", "import { getRandomValues } from 'node:crypto';\n\n/**\n * Create a random salt (nonce) for cryptographic operations.\n *\n * @param length - Length of the salt in bytes\n * @returns Random salt buffer\n */\nexport function createSalt(length: number): Buffer {\n return getRandomValues(Buffer.alloc(length));\n}\n\n", "import net from 'net';\nimport type { ManagementCommand, ManagementEndpoint, SendCommandOptions } from '../../types/manage.d.ts';\n\nexport function sendCommand(\n server: ManagementEndpoint,\n command: ManagementCommand,\n options: SendCommandOptions = {}\n): Promise<unknown> {\n const { timeout = 5000 } = options;\n\n // Determine connection target: named pipe/socket path or port\n const connectOptions: net.NetConnectOpts = server?.path\n ? { path: server.path }\n : { port: server?.port ?? 0 };\n\n const target = server?.path ?? `port ${server?.port}`;\n\n return new Promise((resolve, reject) => {\n const client = net.connect(connectOptions, () => {\n client.write(JSON.stringify(command));\n });\n\n const timeoutId = setTimeout(() => {\n client.destroy();\n reject(new Error(`Connection timed out after ${timeout}`));\n }, timeout);\n\n client.on('data', (data) => {\n clearTimeout(timeoutId);\n try {\n const response = JSON.parse(data.toString());\n if (response.error) {\n reject(new Error(response.error));\n }\n else {\n resolve(response.result);\n }\n }\n catch {\n // Not JSON, return as raw string\n resolve(data.toString());\n }\n client.end();\n });\n\n client.on('error', (err: NodeJS.ErrnoException) => {\n clearTimeout(timeoutId);\n if (err.code === 'ENOENT' || err.code === 'ECONNREFUSED') {\n reject(new Error(`Cannot connect to gateway at ${target}. Make sure the gateway server is running and the path is correct.`, { cause: err }));\n }\n else {\n reject(err);\n }\n });\n });\n}\n\n", "import { KEYUTIL, KJUR, RSAKey, datetozulu } from \"jsrsasign\";\nimport { userInfo, hostname } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\nconst userAndHost = `${userInfo().username}@${hostname()}`;\n\nfunction randomSerialNumber(): string {\n const bytes = randomBytes(16);\n return bytes.toString('hex');\n}\n\nconst DEFAULT_ORGANISATION = `io.Gateway Dev CA`;\nexport const DEFAULT_CA_NAME = `${DEFAULT_ORGANISATION} ${userAndHost}`;\n\nexport function generateRootCA(options?: { name?: string, passphrase?: string } ): { key: string, cert: string } {\n\n const commonName = options?.name || DEFAULT_CA_NAME;\n const passphrase = options?.passphrase;\n\n // STEP 1. generate a key pair for Root CA (secp384r1 for higher security)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp384r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = passphrase\n ? KEYUTIL.getPEM(prv, \"PKCS8PRV\", passphrase, \"AES-256-CBC\")\n : KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // STEP 2: create self-signed CA certificate\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000), false, false), // 10 years\n\n sbjpubkey: pub,\n\n ext: [\n {extname: \"basicConstraints\", critical: true, cA: true},\n {extname: \"keyUsage\", critical: true, names: [\"keyCertSign\"]}\n ],\n\n sigalg: \"SHA384withECDSA\",\n cakey: prv\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n\n\n/**\n * Generate a certificate with custom SAN entries\n * @param cakey - CA private key\n * @param issuer - Issuer DN string\n * @param sanEntries - Array of SAN entry strings (e.g., \"localhost\", \"IP:192.168.1.1\", \"EMAIL:user@example.com\")\n * @param isClient - Generate client cert (clientAuth) vs server cert (serverAuth)\n * @param validityDays - Certificate validity period\n */\nexport function generateCert(\n cakey: string | RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA,\n issuer: string,\n sanEntries: string[],\n isClient: boolean = false,\n validityDays: number = 7\n): {\n key: string,\n cert: string\n} {\n // STEP 1. generate key pair (secp256r1 for faster generation)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp256r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // Parse SAN entries\n const sanArray: Array<{dns?: string, ip?: string, rfc822?: string}> = [];\n let commonName = isClient ? 'dev-user' : 'localhost';\n\n for (const entry of sanEntries) {\n if (entry.toLowerCase().startsWith('ip:')) {\n sanArray.push({ip: entry.substring(3)});\n }\n else if (entry.toLowerCase().startsWith('email:')) {\n sanArray.push({rfc822: entry.substring(6)});\n }\n else {\n const dnsPrefixed = entry.toLowerCase().startsWith('dns:');\n if (isClient) {\n commonName = dnsPrefixed ? entry.substring(4) : entry;\n }\n else {\n const dns = dnsPrefixed ? entry.substring(4) : entry;\n sanArray.push({dns});\n if (sanArray.length === 1) {\n commonName = dns; // Use first DNS as CN\n }\n }\n }\n }\n\n // STEP 2: create certificate signed by CA\n const extensions: Array<{\n extname: string;\n cA?: boolean;\n critical?: boolean;\n names?: string[];\n array?: (string[] | Array<{dns?: string, ip?: string, rfc822?: string}>);\n }> = [\n {extname: \"basicConstraints\", cA: false},\n {\n extname: \"keyUsage\",\n critical: true,\n names: [\"digitalSignature\", \"keyEncipherment\"]\n },\n {\n extname: \"extKeyUsage\",\n array: [isClient ? \"clientAuth\" : \"serverAuth\"]\n }\n ];\n\n // Add SAN only if we have entries\n if (sanArray.length > 0) {\n extensions.push({\n extname: \"subjectAltName\",\n array: sanArray\n });\n }\n\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: issuer },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}`},\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + validityDays * 24 * 60 * 60 * 1000), false, false),\n\n sbjpubkey: pub,\n ext: extensions,\n\n sigalg: \"SHA256withECDSA\",\n cakey: cakey\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n", "import { access, copyFile, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { execFile as execFileCb } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { createHash } from 'node:crypto';\nimport { basename, resolve } from 'node:path';\n\nimport type { BuildSeaOptions } from '../../types/build.d.ts';\n\nconst execFile = promisify(execFileCb);\n\n/**\n * Escapes a string for safe interpolation inside a single-quoted JS string literal.\n */\nfunction escapeForSingleQuotedString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nexport async function buildSea(name: string, options?: BuildSeaOptions): Promise<string> {\n const outDir = options?.outDir ?? './build';\n const nodeExecutable = options?.config?.executable ?? process.execPath;\n\n const safeName = escapeForSingleQuotedString(name);\n const safeVersion = escapeForSingleQuotedString(options?.version ?? '');\n const safeOutDir = escapeForSingleQuotedString(outDir.replace(/\\\\/g, '/'));\n\n // Use the target node executable to create the output directory and resolve\n // platform-specific paths. This also validates the executable is functional.\n const { stdout } = await execFile(nodeExecutable, ['-e', `\n const { mkdirSync } = require('node:fs');\n const path = require('node:path');\n const appVersion = '${safeVersion}'.trim();\n const dirName = '${safeName}' + (appVersion ? '-v' + appVersion : '') + '.' + process.platform + '-' + process.arch;\n const dir = path.resolve('${safeOutDir}', dirName);\n mkdirSync(dir, { recursive: true });\n process.stdout.write(JSON.stringify({ dirName, nodeVersion: process.version, platform: process.platform, arch: process.arch }));\n `.trim()]);\n\n const { dirName, nodeVersion, platform, arch } = JSON.parse(stdout);\n\n // Step 1: Produce the SEA JavaScript file\n let seaMain: string;\n if (options?.esbuild) {\n let esbuild: typeof import('esbuild');\n try {\n esbuild = await import('esbuild');\n }\n catch {\n throw new Error('esbuild is required to bundle the entry point. Install it with:\\n\\n npm install --save-dev esbuild\\n');\n }\n seaMain = `${outDir}/${name}.js`;\n await esbuild.build({\n format: 'cjs',\n target: 'node20',\n platform: 'node',\n bundle: true,\n external: ['esbuild', 'postject'], // exclude esbuild from the bundle since it's only needed at build time\n loader: {\n \".md\": \"file\",\n \".d.ts\": \"file\",\n },\n assetNames: `${dirName}/[name]`,\n entryNames: '[name]',\n outdir: outDir,\n minify: true,\n logLevel: 'info',\n ...options.esbuild,\n });\n }\n else if (options?.config?.main) {\n seaMain = resolve(options.config.main);\n }\n else {\n throw new Error('Either esbuild options (with entryPoints) or config.main must be provided.');\n }\n\n // Write SEA config file in the build folder\n const blobPath = resolve(`${outDir}/${name}.sea.node-${nodeVersion}-${platform}-${arch}.blob`);\n const configPath = resolve(`${outDir}/${name}.sea-config.${dirName}.json`);\n const seaConfig = {\n disableExperimentalSEAWarning: true,\n useSnapshot: false,\n useCodeCache: false,\n ...options?.config,\n main: resolve(seaMain),\n output: blobPath,\n };\n await writeFile(configPath, JSON.stringify(seaConfig, null, 2));\n\n const nativePath = resolve(outDir, dirName);\n\n const isWindows = platform === 'win32';\n const isMacos = platform === 'darwin';\n const targetFile = isWindows ? `${name}.exe` : name;\n const targetPath = `${nativePath}/${targetFile}`;\n\n\n // Check if we can skip the SEA build\n const seaJsContent = await readFile(seaMain);\n const shaPath = `${outDir}/${basename(seaMain)}.sha`;\n\n const currentSha = createHash('sha256').update(seaJsContent).digest('hex');\n let canSkip = false;\n\n try {\n const [previousSha] = await Promise.all([\n readFile(shaPath, 'utf8'),\n access(targetPath)\n ]);\n canSkip = previousSha === currentSha;\n }\n catch {\n // SHA file or target doesn't exist, need to build\n }\n if (canSkip) {\n console.log('SEA build skipped - esbuild output unchanged and target exists');\n return targetPath;\n }\n\n // Step 3: Generate the blob to be injected\n await execFile(nodeExecutable, ['--experimental-sea-config', configPath]);\n\n // Step 4: Copy the Node.js executable to the target path\n await copyFile(nodeExecutable, targetPath);\n\n // Step 5: Remove the signature of the binary\n if (isWindows) {\n try {\n const signtool = await findSigntool();\n if (signtool) {\n console.log(`Found signtool at: ${signtool}`);\n await execFile(signtool, ['remove', '/s', targetPath]);\n console.log(`Signature removed from ${targetPath} executable`);\n }\n }\n catch (e: any) {\n console.warn('Failed to remove signature:', e.message);\n }\n }\n else if (isMacos) {\n try {\n await execFile('codesign', ['--remove-signature', targetPath]);\n console.log(`Signature removed from ${targetPath} executable`);\n }\n catch (e: any) {\n console.warn('Failed to remove signature:', e.message);\n }\n }\n\n // Step 6: Inject the SEA blob into the binary\n type InjectOptions = {\n /**\n * @default '__POSTJECT'\n */\n machoSegmentName?: string;\n /**\n * @default false\n */\n overwrite?: boolean;\n /**\n * @default 'POSTJECT_SENTINEL_fce680ab2cc467b6e072b8b5df1996b2'\n */\n sentinelFuse?: string\n };\n type Inject = (filename: string, resourceName: string, resourceData: Buffer, options?: InjectOptions) => Promise<void>;\n\n let inject: Inject;\n try {\n ({ inject } = await import('postject') as { inject: Inject });\n }\n catch {\n throw new Error('postject is required to build a SEA. Install it with:\\n\\n npm install --save-dev postject\\n');\n }\n\n const resourceData = await readFile(blobPath);\n\n // Construct the sentinel fuse at runtime to avoid the literal appearing in the\n // bundled SEA output \u2014 postject would otherwise find multiple occurrences.\n const sentinelFuse = ['NODE', 'SEA', 'FUSE', 'fce680ab2cc467b6e072b8b5df1996b2'].join('_');\n\n await inject(\n targetPath,\n 'NODE_SEA_BLOB',\n resourceData,\n {\n overwrite: true,\n sentinelFuse,\n ...(isMacos ? { machoSegmentName: 'NODE_SEA' } : {})\n });\n\n // Step 7: Sign the binary\n if (isWindows) {\n try {\n const signtool = await findSigntool();\n if (signtool) {\n console.log(`Signing executable with signtool at: ${signtool}`);\n await execFile(signtool, ['sign', '/fd', 'SHA256', targetPath]);\n console.log(`Executable signed successfully`);\n }\n }\n catch (e: any) {\n console.warn('Failed to sign executable:', e.message);\n }\n }\n else if (isMacos) {\n try {\n await execFile('codesign', ['--sign', '-', targetPath]);\n console.log(`Executable signed successfully`);\n }\n catch (e: any) {\n console.warn('Failed to sign executable:', e.message);\n }\n }\n\n // Save SHA for next build comparison\n await writeFile(shaPath, currentSha);\n return targetPath;\n}\n\nasync function findSigntool(): Promise<string | null> {\n const windowsKitsPath = 'C:\\\\Program Files (x86)\\\\Windows Kits\\\\10\\\\bin';\n\n try {\n const entries = await readdir(windowsKitsPath, { withFileTypes: true });\n\n // Filter directories that match version pattern (e.g., 10.0.22621.0)\n const versionDirs = entries\n .filter(entry => entry.isDirectory() && /^10\\.0\\.\\d+\\.\\d+$/.test(entry.name))\n .map(entry => entry.name)\n .sort((a, b) => {\n // Sort by version number descending to get the latest\n const partsA = a.split('.').map(Number);\n const partsB = b.split('.').map(Number);\n for (let i = 0; i < partsA.length; i++) {\n if (partsA[i] !== partsB[i]) {\n return partsB[i] - partsA[i];\n }\n }\n return 0;\n });\n\n // Try each version directory, starting with the latest\n for (const version of versionDirs) {\n const signtoolPath = `${windowsKitsPath}\\\\${version}\\\\${process.arch}\\\\signtool.exe`;\n try {\n await access(signtoolPath);\n return signtoolPath;\n }\n catch {\n // signtool not found in this version, try next\n }\n }\n\n console.warn('signtool.exe not found in any Windows SDK version');\n return null;\n }\n catch (e: any) {\n console.warn(`Windows SDK not found at ${windowsKitsPath}: ${e.message}`);\n return null;\n }\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "argon2_exports", "build_exports", "keygen_exports", "client_exports", "mkcert_exports", "__toCommonJS", "argon2_exports", "__export", "ARGON2_VERSION", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "DEFAULT_ALGORITHM", "DEFAULT_HASH_LENGTH", "DEFAULT_MEMORY", "DEFAULT_PARALLELISM", "DEFAULT_PASSES", "DEFAULT_SALT_LENGTH", "createHash", "decode", "encode", "hash", "verify", "keygen_exports", "__export", "createSalt", "import_node_crypto", "length", "argon2", "getArgon2", "crypto", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "ARGON2_VERSION", "DEFAULT_ALGORITHM", "DEFAULT_SALT_LENGTH", "DEFAULT_HASH_LENGTH", "DEFAULT_PARALLELISM", "DEFAULT_MEMORY", "DEFAULT_PASSES", "decode", "encodedHash", "parts", "current", "algorithm", "version", "parameters", "paramsParts", "param", "key", "value", "hash", "encode", "hashData", "createHash", "password", "hashLength", "nonce", "createSalt", "memory", "passes", "parallelism", "argon2Params", "argon2Fn", "resolve", "reject", "err", "result", "options", "saltLength", "hashBuffer", "verify", "decoded", "client_exports", "__export", "sendCommand", "import_net", "server", "command", "options", "timeout", "connectOptions", "target", "resolve", "reject", "client", "net", "timeoutId", "data", "response", "err", "mkcert_exports", "__export", "DEFAULT_CA_NAME", "generateCert", "generateRootCA", "import_jsrsasign", "import_node_os", "import_node_crypto", "userAndHost", "randomSerialNumber", "DEFAULT_ORGANISATION", "options", "commonName", "passphrase", "kp", "prv", "pub", "prvPem", "certPem", "cakey", "issuer", "sanEntries", "isClient", "validityDays", "sanArray", "entry", "dnsPrefixed", "dns", "extensions", "build_exports", "__export", "buildSea", "import_promises", "import_node_child_process", "import_node_util", "import_node_crypto", "import_node_path", "execFile", "execFileCb", "escapeForSingleQuotedString", "value", "name", "options", "outDir", "nodeExecutable", "safeName", "safeVersion", "safeOutDir", "stdout", "dirName", "nodeVersion", "platform", "arch", "seaMain", "esbuild", "blobPath", "configPath", "seaConfig", "nativePath", "isWindows", "isMacos", "targetFile", "targetPath", "seaJsContent", "shaPath", "currentSha", "canSkip", "previousSha", "signtool", "findSigntool", "e", "inject", "resourceData", "sentinelFuse", "windowsKitsPath", "versionDirs", "entry", "a", "b", "partsA", "partsB", "version", "signtoolPath"]
|
|
7
7
|
}
|
package/dist/tools.js
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ce=Object.defineProperty;var b=(e,t)=>{for(var n in t)ce(e,n,{get:t[n],enumerable:!0})};var q={};b(q,{ARGON2_VERSION:()=>V,ARGON2_VERSION_10:()=>M,ARGON2_VERSION_13:()=>B,DEFAULT_ALGORITHM:()=>ge,DEFAULT_HASH_LENGTH:()=>J,DEFAULT_MEMORY:()=>L,DEFAULT_PARALLELISM:()=>F,DEFAULT_PASSES:()=>k,DEFAULT_SALT_LENGTH:()=>D,createHash:()=>I,decode:()=>W,encode:()=>G,hash:()=>ue,verify:()=>pe});var H={};b(H,{createSalt:()=>E});import{getRandomValues as le}from"node:crypto";function E(e){return le(Buffer.alloc(e))}var C;async function me(){if(C===void 0)try{let e=await import("node:crypto");if(!e.argon2)throw new Error("argon2 not available");C=e.argon2}catch{throw new Error("argon2 is not available in this Node.js version. Node.js 24.7.0 or later is required for Argon2 password encoding. Please upgrade Node.js or use a different authentication method.")}return C}var M=16,B=19,V=B,ge="argon2id",D=16,J=32,F=4,L=65536,k=3;function W(e){let t=e.split("$");if(t.length<4)throw new Error("Invalid encoded Argon2 hash");let n=1,r=t[n++];if(r!=="argon2d"&&r!=="argon2i"&&r!=="argon2id")throw new Error("Invalid Argon2 type");let s=M;t[n].startsWith("v=")&&(s=parseInt(t[n].substring(2),10),n++);let a={},g=t[n++].split(",");for(let l of g){let[m,o]=l.split("=");switch(m){case"m":a.memory=parseInt(o,10);break;case"t":a.passes=parseInt(o,10);break;case"p":a.parallelism=parseInt(o,10);break}}a.nonce=Buffer.from(t[n++],"base64url");let i=Buffer.from(t[n++],"base64url");return{algorithm:r,version:s,parameters:a,hash:i}}function G(e){let{algorithm:t,version:n,parameters:r,hash:s}=e;return`$${t}$v=${n}$m=${r.memory},t=${r.passes},p=${r.parallelism}$${r.nonce.toString("base64url")}$${s.toString("base64url")}`}async function I(e,t,n,r){let s=r?.nonce??E(D),a=r?.memory??L,g=r?.passes??k,i=r?.parallelism??F,l={message:t,tagLength:n,nonce:s,memory:a,passes:g,parallelism:i},m=await me();return new Promise((o,p)=>{m(e,l,(d,h)=>{d?p(d):h?o(Buffer.from(h)):p(new Error("argon2 returned no result"))})})}async function ue(e,t){let n=t?.algorithm??"argon2id",r=t?.saltLength??D,s=t?.hashLength??J,a=t?.parallelism??F,g=t?.memory??L,i=t?.passes??k,l=E(r),m={memory:g,passes:i,parallelism:a,nonce:l},o=await I(n,e,s,m);return G({algorithm:n,version:V,parameters:m,hash:o})}async function pe(e,t){try{let n=W(e),r=await I(n.algorithm,t,n.hash.length,n.parameters);return n.hash.equals(r)}catch{return!1}}var Y={};b(Y,{sendCommand:()=>de});import fe from"net";function de(e,t,n={}){let{timeout:r=5e3}=n,s=e?.path?{path:e.path}:{port:e?.port??0},a=e?.path??`port ${e?.port}`;return new Promise((g,i)=>{let l=fe.connect(s,()=>{l.write(JSON.stringify(t))}),m=setTimeout(()=>{l.destroy(),i(new Error(`Connection timed out after ${r}`))},r);l.on("data",o=>{clearTimeout(m);try{let p=JSON.parse(o.toString());p.error?i(new Error(p.error)):g(p.result)}catch{g(o.toString())}l.end()}),l.on("error",o=>{clearTimeout(m),o.code==="ENOENT"||o.code==="ECONNREFUSED"?i(new Error(`Cannot connect to gateway at ${a}. Make sure the gateway server is running and the path is correct.`,{cause:o})):i(o)})})}var Z={};b(Z,{DEFAULT_CA_NAME:()=>X,generateCert:()=>Ae,generateRootCA:()=>we});import{KEYUTIL as w,KJUR as z,datetozulu as $}from"jsrsasign";import{userInfo as he,hostname as ye}from"node:os";import{randomBytes as be}from"node:crypto";var N=`${he().username}@${ye()}`;function Q(){return be(16).toString("hex")}var P="io.Gateway Dev CA",X=`${P} ${N}`;function we(e){let t=e?.name||X,n=e?.passphrase,r=w.generateKeypair("EC","secp384r1"),s=r.prvKeyObj,a=r.pubKeyObj,g=n?w.getPEM(s,"PKCS8PRV",n,"AES-256-CBC"):w.getPEM(s,"PKCS8PRV"),l=new z.asn1.x509.Certificate({version:3,serial:{hex:Q()},issuer:{str:`/CN=${t}/O=${P}/OU=${N}`},subject:{str:`/CN=${t}/O=${P}/OU=${N}`},notbefore:$(new Date(Date.now()-60*1e3),!1,!1),notafter:$(new Date(Date.now()+10*365*24*60*60*1e3),!1,!1),sbjpubkey:a,ext:[{extname:"basicConstraints",critical:!0,cA:!0},{extname:"keyUsage",critical:!0,names:["keyCertSign"]}],sigalg:"SHA384withECDSA",cakey:s}).getPEM();return{key:g,cert:l}}function Ae(e,t,n,r=!1,s=7){let a=w.generateKeypair("EC","secp256r1"),g=a.prvKeyObj,i=a.pubKeyObj,l=w.getPEM(g,"PKCS8PRV"),m=[],o=r?"dev-user":"localhost";for(let u of n)if(u.toLowerCase().startsWith("ip:"))m.push({ip:u.substring(3)});else if(u.toLowerCase().startsWith("email:"))m.push({rfc822:u.substring(6)});else{let S=u.toLowerCase().startsWith("dns:");if(r)o=S?u.substring(4):u;else{let x=S?u.substring(4):u;m.push({dns:x}),m.length===1&&(o=x)}}let p=[{extname:"basicConstraints",cA:!1},{extname:"keyUsage",critical:!0,names:["digitalSignature","keyEncipherment"]},{extname:"extKeyUsage",array:[r?"clientAuth":"serverAuth"]}];m.length>0&&p.push({extname:"subjectAltName",array:m});let h=new z.asn1.x509.Certificate({version:3,serial:{hex:Q()},issuer:{str:t},subject:{str:`/CN=${o}/O=${P}/OU=${N}`},notbefore:$(new Date(Date.now()-60*1e3),!1,!1),notafter:$(new Date(Date.now()+s*24*60*60*1e3),!1,!1),sbjpubkey:i,ext:p,sigalg:"SHA256withECDSA",cakey:e}).getPEM();return{key:l,cert:h}}var ne={};b(ne,{buildSea:()=>ve});import{access as re,copyFile as Se,readdir as xe,readFile as j,writeFile as ee}from"node:fs/promises";import{execFile as Ee}from"node:child_process";import{promisify as $e}from"node:util";import{createHash as Ne}from"node:crypto";import{basename as Pe,resolve as A}from"node:path";var y=$e(Ee);function R(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}async function ve(e,t){let n=t?.outDir??"./build",r=t?.config?.executable??process.execPath,s=R(e),a=R(t?.version??""),g=R(n.replace(/\\/g,"/")),{stdout:i}=await y(r,["-e",`
|
|
2
|
+
const { mkdirSync } = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const appVersion = '${a}'.trim();
|
|
5
|
+
const dirName = '${s}' + (appVersion ? '-v' + appVersion : '') + '.' + process.platform + '-' + process.arch;
|
|
6
|
+
const dir = path.resolve('${g}', dirName);
|
|
7
|
+
mkdirSync(dir, { recursive: true });
|
|
8
|
+
process.stdout.write(JSON.stringify({ dirName, nodeVersion: process.version, platform: process.platform, arch: process.arch }));
|
|
9
|
+
`.trim()]),{dirName:l,nodeVersion:m,platform:o,arch:p}=JSON.parse(i),d;if(t?.esbuild){let c;try{c=await import("esbuild")}catch{throw new Error(`esbuild is required to bundle the entry point. Install it with:
|
|
10
|
+
|
|
11
|
+
npm install --save-dev esbuild
|
|
12
|
+
`)}d=`${n}/${e}.js`,await c.build({format:"cjs",target:"node20",platform:"node",bundle:!0,external:["esbuild","postject"],loader:{".md":"file",".d.ts":"file"},assetNames:`${l}/[name]`,entryNames:"[name]",outdir:n,minify:!0,logLevel:"info",...t.esbuild})}else if(t?.config?.main)d=A(t.config.main);else throw new Error("Either esbuild options (with entryPoints) or config.main must be provided.");let h=A(`${n}/${e}.sea.node-${m}-${o}-${p}.blob`),u=A(`${n}/${e}.sea-config.${l}.json`),S={disableExperimentalSEAWarning:!0,useSnapshot:!1,useCodeCache:!1,...t?.config,main:A(d),output:h};await ee(u,JSON.stringify(S,null,2));let x=A(n,l),v=o==="win32",O=o==="darwin",se=v?`${e}.exe`:e,f=`${x}/${se}`,oe=await j(d),U=`${n}/${Pe(d)}.sha`,K=Ne("sha256").update(oe).digest("hex"),_=!1;try{let[c]=await Promise.all([j(U,"utf8"),re(f)]);_=c===K}catch{}if(_)return console.log("SEA build skipped - esbuild output unchanged and target exists"),f;if(await y(r,["--experimental-sea-config",u]),await Se(r,f),v)try{let c=await te();c&&(console.log(`Found signtool at: ${c}`),await y(c,["remove","/s",f]),console.log(`Signature removed from ${f} executable`))}catch(c){console.warn("Failed to remove signature:",c.message)}else if(O)try{await y("codesign",["--remove-signature",f]),console.log(`Signature removed from ${f} executable`)}catch(c){console.warn("Failed to remove signature:",c.message)}let T;try{({inject:T}=await import("postject"))}catch{throw new Error(`postject is required to build a SEA. Install it with:
|
|
13
|
+
|
|
14
|
+
npm install --save-dev postject
|
|
15
|
+
`)}let ae=await j(h),ie=["NODE","SEA","FUSE","fce680ab2cc467b6e072b8b5df1996b2"].join("_");if(await T(f,"NODE_SEA_BLOB",ae,{overwrite:!0,sentinelFuse:ie,...O?{machoSegmentName:"NODE_SEA"}:{}}),v)try{let c=await te();c&&(console.log(`Signing executable with signtool at: ${c}`),await y(c,["sign","/fd","SHA256",f]),console.log("Executable signed successfully"))}catch(c){console.warn("Failed to sign executable:",c.message)}else if(O)try{await y("codesign",["--sign","-",f]),console.log("Executable signed successfully")}catch(c){console.warn("Failed to sign executable:",c.message)}return await ee(U,K),f}async function te(){let e="C:\\Program Files (x86)\\Windows Kits\\10\\bin";try{let n=(await xe(e,{withFileTypes:!0})).filter(r=>r.isDirectory()&&/^10\.0\.\d+\.\d+$/.test(r.name)).map(r=>r.name).sort((r,s)=>{let a=r.split(".").map(Number),g=s.split(".").map(Number);for(let i=0;i<a.length;i++)if(a[i]!==g[i])return g[i]-a[i];return 0});for(let r of n){let s=`${e}\\${r}\\${process.arch}\\signtool.exe`;try{return await re(s),s}catch{}}return console.warn("signtool.exe not found in any Windows SDK version"),null}catch(t){return console.warn(`Windows SDK not found at ${e}: ${t.message}`),null}}export{q as argon2,ne as build,H as keygen,Y as manage,Z as mkcert};
|
|
2
16
|
//# sourceMappingURL=tools.js.map
|
package/dist/tools.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/tools/crypto/argon2.ts", "../src/tools/crypto/keygen.ts", "../src/manage/client.ts", "../src/tools/mkcert.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n Argon2Algorithm,\n Argon2Parameters\n} from 'node:crypto';\n\nimport { createSalt } from './keygen.ts';\nimport type { Argon2Hash, Argon2HashParameters } from '../../../types/crypto/argon2';\n\n// Lazy import for argon2 (added in Node.js 24.7.0)\n// This allows the module to load on older Node.js versions\nlet argon2: typeof import('node:crypto').argon2 | undefined;\n\nasync function getArgon2() {\n if (argon2 === undefined) {\n try {\n const crypto = await import('node:crypto');\n if (!crypto.argon2) {\n throw new Error('argon2 not available');\n }\n argon2 = crypto.argon2;\n } catch (err) {\n throw new Error(\n 'argon2 is not available in this Node.js version. ' +\n 'Node.js 24.7.0 or later is required for Argon2 password encoding. ' +\n 'Please upgrade Node.js or use a different authentication method.'\n );\n }\n }\n return argon2;\n}\n\n// Argon2 version constants\nexport const ARGON2_VERSION_10 = 0x10; // 16\nexport const ARGON2_VERSION_13 = 0x13; // 19\nexport const ARGON2_VERSION = ARGON2_VERSION_13;\n\n// Default parameters for Argon2 hashing\nexport const DEFAULT_ALGORITHM: Argon2Algorithm = 'argon2id';\nexport const DEFAULT_SALT_LENGTH = 16;\nexport const DEFAULT_HASH_LENGTH = 32;\nexport const DEFAULT_PARALLELISM = 4;\nexport const DEFAULT_MEMORY = 65536; // 64 MB in KiB\nexport const DEFAULT_PASSES = 3;\n\n/**\n * Decode an encoded Argon2 hash string into its components.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param encodedHash - The encoded Argon2 hash string\n * @returns Decoded hash components\n * @see https://github.com/P-H-C/phc-winner-argon2/blob/master/src/encoding.c#L244\n */\nexport function decode(encodedHash: string): Argon2Hash {\n const parts = encodedHash.split('$'); // ['', 'argon2id', 'v=19', 'm=65536,t=3,p=4', 'base64salt', 'base64hash']\n if (parts.length < 4) {\n throw new Error('Invalid encoded Argon2 hash');\n }\n let current = 1;\n const algorithm = parts[current++];\n if (algorithm !== 'argon2d' && algorithm !== 'argon2i' && algorithm !== 'argon2id') {\n throw new Error('Invalid Argon2 type');\n }\n let version = ARGON2_VERSION_10;\n if (parts[current].startsWith('v=')) {\n version = parseInt(parts[current].substring(2), 10);\n current++;\n }\n const parameters: Partial<Argon2HashParameters> = {};\n const paramsParts = parts[current++].split(',');\n\n for (const param of paramsParts) {\n const [key, value] = param.split('=');\n switch (key) {\n case 'm':\n parameters.memory = parseInt(value, 10);\n break;\n case 't':\n parameters.passes = parseInt(value, 10);\n break;\n case 'p':\n parameters.parallelism = parseInt(value, 10);\n break;\n }\n }\n parameters.nonce = Buffer.from(parts[current++], 'base64url');\n const hash = Buffer.from(parts[current++], 'base64url');\n\n return { algorithm, version, parameters: parameters as Argon2Hash['parameters'], hash };\n}\n\n/**\n * Encode Argon2 hash components into a standard string format.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param hashData - The hash components to encode\n * @returns Encoded hash string\n */\nexport function encode(hashData: Argon2Hash): string {\n const { algorithm, version, parameters, hash } = hashData;\n return `$${algorithm}$v=${version}$m=${parameters.memory},t=${parameters.passes},p=${parameters.parallelism}$${parameters.nonce.toString('base64url')}$${hash.toString('base64url')}`;\n}\n\n\n/**\n * Create an Argon2 hash from parameters.\n * Low-level wrapper around node:crypto's argon2.\n *\n * @param algorithm - Argon2 algorithm variant ('argon2d' | 'argon2i' | 'argon2id')\n * @param password - The password to hash\n * @param hashLength - Length of the output hash in bytes\n * @param parameters - Argon2 parameters (nonce, memory, passes, parallelism). If not provided, defaults will be used.\n * @returns The hash buffer\n */\nexport async function createHash(\n algorithm: Argon2Algorithm,\n password: string,\n hashLength: number,\n parameters?: Argon2Hash['parameters']\n): Promise<Buffer> {\n const nonce = parameters?.nonce ?? createSalt(DEFAULT_SALT_LENGTH);\n const memory = parameters?.memory ?? DEFAULT_MEMORY;\n const passes = parameters?.passes ?? DEFAULT_PASSES;\n const parallelism = parameters?.parallelism ?? DEFAULT_PARALLELISM;\n\n const argon2Params: Argon2Parameters = {\n message: password,\n tagLength: hashLength,\n nonce,\n memory,\n passes,\n parallelism\n };\n const argon2Fn = await getArgon2();\n\n // Wrap callback-based argon2 in a Promise\n return new Promise((resolve, reject) => {\n argon2Fn(algorithm, argon2Params, (err: Error | null, result?: Uint8Array) => {\n if (err) {\n reject(err);\n }\n else if (result) {\n resolve(Buffer.from(result));\n }\n else {\n reject(new Error('argon2 returned no result'));\n }\n });\n });\n}\n\n\n/**\n * Hash a password using Argon2.\n *\n * @param password - The plain text password to hash\n * @param options - Optional parameters object. If not provided, defaults will be used.\n * @returns The encoded Argon2 hash string\n */\nexport async function hash(\n password: string,\n options?: {\n algorithm?: Argon2Algorithm;\n saltLength?: number;\n hashLength?: number;\n parallelism?: number;\n memory?: number;\n passes?: number;\n }\n): Promise<string> {\n const algorithm = options?.algorithm ?? 'argon2id';\n const saltLength = options?.saltLength ?? DEFAULT_SALT_LENGTH;\n const hashLength = options?.hashLength ?? DEFAULT_HASH_LENGTH;\n const parallelism = options?.parallelism ?? DEFAULT_PARALLELISM;\n const memory = options?.memory ?? DEFAULT_MEMORY;\n const passes = options?.passes ?? DEFAULT_PASSES;\n\n const nonce = createSalt(saltLength);\n const parameters = { memory, passes, parallelism, nonce };\n const hashBuffer = await createHash(algorithm, password, hashLength, parameters);\n return encode({\n algorithm,\n version: ARGON2_VERSION,\n parameters,\n hash: hashBuffer\n });\n}\n\n/**\n * Verify a password against an Argon2 hash.\n *\n * @param encodedHash - The encoded Argon2 hash to verify against\n * @param password - The plain text password to verify\n * @returns true if password matches the hash, false otherwise\n */\nexport async function verify(encodedHash: string, password: string): Promise<boolean> {\n try {\n const decoded = decode(encodedHash);\n const hashBuffer = await createHash(\n decoded.algorithm,\n password,\n decoded.hash.length,\n decoded.parameters\n );\n return decoded.hash.equals(hashBuffer);\n } catch {\n return false;\n }\n}\n\n", "import { getRandomValues } from 'node:crypto';\n\n/**\n * Create a random salt (nonce) for cryptographic operations.\n *\n * @param length - Length of the salt in bytes\n * @returns Random salt buffer\n */\nexport function createSalt(length: number): Buffer {\n return getRandomValues(Buffer.alloc(length));\n}\n\n", "import net from 'net';\nimport type { ManagementCommand, ManagementEndpoint, SendCommandOptions } from '../../types/manage.d.ts';\n\nexport function sendCommand(\n server: ManagementEndpoint,\n command: ManagementCommand,\n options: SendCommandOptions = {}\n): Promise<unknown> {\n const { timeout = 5000 } = options;\n\n // Determine connection target: named pipe/socket path or port\n const connectOptions: net.NetConnectOpts = server?.path\n ? { path: server.path }\n : { port: server?.port ?? 0 };\n\n const target = server?.path ?? `port ${server?.port}`;\n\n return new Promise((resolve, reject) => {\n const client = net.connect(connectOptions, () => {\n client.write(JSON.stringify(command));\n });\n\n const timeoutId = setTimeout(() => {\n client.destroy();\n reject(new Error(`Connection timed out after ${timeout}`));\n }, timeout);\n\n client.on('data', (data) => {\n clearTimeout(timeoutId);\n try {\n const response = JSON.parse(data.toString());\n if (response.error) {\n reject(new Error(response.error));\n }\n else {\n resolve(response.result);\n }\n }\n catch {\n // Not JSON, return as raw string\n resolve(data.toString());\n }\n client.end();\n });\n\n client.on('error', (err: NodeJS.ErrnoException) => {\n clearTimeout(timeoutId);\n if (err.code === 'ENOENT' || err.code === 'ECONNREFUSED') {\n reject(new Error(`Cannot connect to gateway at ${target}. Make sure the gateway server is running and the path is correct.`, { cause: err }));\n }\n else {\n reject(err);\n }\n });\n });\n}\n\n", "import { KEYUTIL, KJUR, RSAKey, datetozulu } from \"jsrsasign\";\nimport { userInfo, hostname } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\nconst userAndHost = `${userInfo().username}@${hostname()}`;\n\nfunction randomSerialNumber(): string {\n const bytes = randomBytes(16);\n return bytes.toString('hex');\n}\n\nconst DEFAULT_ORGANISATION = `io.Gateway Dev CA`;\nexport const DEFAULT_CA_NAME = `${DEFAULT_ORGANISATION} ${userAndHost}`;\n\nexport function generateRootCA(options?: { name?: string, passphrase?: string } ): { key: string, cert: string } {\n\n const commonName = options?.name || DEFAULT_CA_NAME;\n const passphrase = options?.passphrase;\n\n // STEP 1. generate a key pair for Root CA (secp384r1 for higher security)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp384r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = passphrase\n ? KEYUTIL.getPEM(prv, \"PKCS8PRV\", passphrase, \"AES-256-CBC\")\n : KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // STEP 2: create self-signed CA certificate\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000), false, false), // 10 years\n\n sbjpubkey: pub,\n\n ext: [\n {extname: \"basicConstraints\", critical: true, cA: true},\n {extname: \"keyUsage\", critical: true, names: [\"keyCertSign\"]}\n ],\n\n sigalg: \"SHA384withECDSA\",\n cakey: prv\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n\n\n/**\n * Generate a certificate with custom SAN entries\n * @param cakey - CA private key\n * @param issuer - Issuer DN string\n * @param sanEntries - Array of SAN entry strings (e.g., \"localhost\", \"IP:192.168.1.1\", \"EMAIL:user@example.com\")\n * @param isClient - Generate client cert (clientAuth) vs server cert (serverAuth)\n * @param validityDays - Certificate validity period\n */\nexport function generateCert(\n cakey: string | RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA,\n issuer: string,\n sanEntries: string[],\n isClient: boolean = false,\n validityDays: number = 7\n): {\n key: string,\n cert: string\n} {\n // STEP 1. generate key pair (secp256r1 for faster generation)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp256r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // Parse SAN entries\n const sanArray: Array<{dns?: string, ip?: string, rfc822?: string}> = [];\n let commonName = isClient ? 'dev-user' : 'localhost';\n\n for (const entry of sanEntries) {\n if (entry.toLowerCase().startsWith('ip:')) {\n sanArray.push({ip: entry.substring(3)});\n }\n else if (entry.toLowerCase().startsWith('email:')) {\n sanArray.push({rfc822: entry.substring(6)});\n }\n else {\n const dnsPrefixed = entry.toLowerCase().startsWith('dns:');\n if (isClient) {\n commonName = dnsPrefixed ? entry.substring(4) : entry;\n }\n else {\n const dns = dnsPrefixed ? entry.substring(4) : entry;\n sanArray.push({dns});\n if (sanArray.length === 1) {\n commonName = dns; // Use first DNS as CN\n }\n }\n }\n }\n\n // STEP 2: create certificate signed by CA\n const extensions: Array<{\n extname: string;\n cA?: boolean;\n critical?: boolean;\n names?: string[];\n array?: (string[] | Array<{dns?: string, ip?: string, rfc822?: string}>);\n }> = [\n {extname: \"basicConstraints\", cA: false},\n {\n extname: \"keyUsage\",\n critical: true,\n names: [\"digitalSignature\", \"keyEncipherment\"]\n },\n {\n extname: \"extKeyUsage\",\n array: [isClient ? \"clientAuth\" : \"serverAuth\"]\n }\n ];\n\n // Add SAN only if we have entries\n if (sanArray.length > 0) {\n extensions.push({\n extname: \"subjectAltName\",\n array: sanArray\n });\n }\n\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: issuer },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}`},\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + validityDays * 24 * 60 * 60 * 1000), false, false),\n\n sbjpubkey: pub,\n ext: extensions,\n\n sigalg: \"SHA256withECDSA\",\n cakey: cakey\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["argon2_exports", "__export", "ARGON2_VERSION", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "DEFAULT_ALGORITHM", "DEFAULT_HASH_LENGTH", "DEFAULT_MEMORY", "DEFAULT_PARALLELISM", "DEFAULT_PASSES", "DEFAULT_SALT_LENGTH", "createHash", "decode", "encode", "hash", "verify", "keygen_exports", "__export", "createSalt", "getRandomValues", "length", "argon2", "getArgon2", "crypto", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "ARGON2_VERSION", "DEFAULT_ALGORITHM", "DEFAULT_SALT_LENGTH", "DEFAULT_HASH_LENGTH", "DEFAULT_PARALLELISM", "DEFAULT_MEMORY", "DEFAULT_PASSES", "decode", "encodedHash", "parts", "current", "algorithm", "version", "parameters", "paramsParts", "param", "key", "value", "hash", "encode", "hashData", "createHash", "password", "hashLength", "nonce", "createSalt", "memory", "passes", "parallelism", "argon2Params", "argon2Fn", "resolve", "reject", "err", "result", "options", "saltLength", "hashBuffer", "verify", "decoded", "client_exports", "__export", "sendCommand", "net", "server", "command", "options", "timeout", "connectOptions", "target", "resolve", "reject", "client", "timeoutId", "data", "response", "err", "mkcert_exports", "__export", "DEFAULT_CA_NAME", "generateCert", "generateRootCA", "KEYUTIL", "KJUR", "datetozulu", "userInfo", "hostname", "randomBytes", "userAndHost", "randomSerialNumber", "DEFAULT_ORGANISATION", "options", "commonName", "passphrase", "kp", "prv", "pub", "prvPem", "certPem", "cakey", "issuer", "sanEntries", "isClient", "validityDays", "sanArray", "entry", "dnsPrefixed", "dns", "extensions"]
|
|
3
|
+
"sources": ["../src/tools/crypto/argon2.ts", "../src/tools/crypto/keygen.ts", "../src/manage/client.ts", "../src/tools/mkcert.ts", "../src/tools/build.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n Argon2Algorithm,\n Argon2Parameters\n} from 'node:crypto';\n\nimport { createSalt } from './keygen.ts';\nimport type { Argon2Hash, Argon2HashParameters } from '../../../types/crypto/argon2';\n\n// Lazy import for argon2 (added in Node.js 24.7.0)\n// This allows the module to load on older Node.js versions\nlet argon2: typeof import('node:crypto').argon2 | undefined;\n\nasync function getArgon2() {\n if (argon2 === undefined) {\n try {\n const crypto = await import('node:crypto');\n if (!crypto.argon2) {\n throw new Error('argon2 not available');\n }\n argon2 = crypto.argon2;\n } catch (err) {\n throw new Error(\n 'argon2 is not available in this Node.js version. ' +\n 'Node.js 24.7.0 or later is required for Argon2 password encoding. ' +\n 'Please upgrade Node.js or use a different authentication method.'\n );\n }\n }\n return argon2;\n}\n\n// Argon2 version constants\nexport const ARGON2_VERSION_10 = 0x10; // 16\nexport const ARGON2_VERSION_13 = 0x13; // 19\nexport const ARGON2_VERSION = ARGON2_VERSION_13;\n\n// Default parameters for Argon2 hashing\nexport const DEFAULT_ALGORITHM: Argon2Algorithm = 'argon2id';\nexport const DEFAULT_SALT_LENGTH = 16;\nexport const DEFAULT_HASH_LENGTH = 32;\nexport const DEFAULT_PARALLELISM = 4;\nexport const DEFAULT_MEMORY = 65536; // 64 MB in KiB\nexport const DEFAULT_PASSES = 3;\n\n/**\n * Decode an encoded Argon2 hash string into its components.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param encodedHash - The encoded Argon2 hash string\n * @returns Decoded hash components\n * @see https://github.com/P-H-C/phc-winner-argon2/blob/master/src/encoding.c#L244\n */\nexport function decode(encodedHash: string): Argon2Hash {\n const parts = encodedHash.split('$'); // ['', 'argon2id', 'v=19', 'm=65536,t=3,p=4', 'base64salt', 'base64hash']\n if (parts.length < 4) {\n throw new Error('Invalid encoded Argon2 hash');\n }\n let current = 1;\n const algorithm = parts[current++];\n if (algorithm !== 'argon2d' && algorithm !== 'argon2i' && algorithm !== 'argon2id') {\n throw new Error('Invalid Argon2 type');\n }\n let version = ARGON2_VERSION_10;\n if (parts[current].startsWith('v=')) {\n version = parseInt(parts[current].substring(2), 10);\n current++;\n }\n const parameters: Partial<Argon2HashParameters> = {};\n const paramsParts = parts[current++].split(',');\n\n for (const param of paramsParts) {\n const [key, value] = param.split('=');\n switch (key) {\n case 'm':\n parameters.memory = parseInt(value, 10);\n break;\n case 't':\n parameters.passes = parseInt(value, 10);\n break;\n case 'p':\n parameters.parallelism = parseInt(value, 10);\n break;\n }\n }\n parameters.nonce = Buffer.from(parts[current++], 'base64url');\n const hash = Buffer.from(parts[current++], 'base64url');\n\n return { algorithm, version, parameters: parameters as Argon2Hash['parameters'], hash };\n}\n\n/**\n * Encode Argon2 hash components into a standard string format.\n * Format: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash\n *\n * @param hashData - The hash components to encode\n * @returns Encoded hash string\n */\nexport function encode(hashData: Argon2Hash): string {\n const { algorithm, version, parameters, hash } = hashData;\n return `$${algorithm}$v=${version}$m=${parameters.memory},t=${parameters.passes},p=${parameters.parallelism}$${parameters.nonce.toString('base64url')}$${hash.toString('base64url')}`;\n}\n\n\n/**\n * Create an Argon2 hash from parameters.\n * Low-level wrapper around node:crypto's argon2.\n *\n * @param algorithm - Argon2 algorithm variant ('argon2d' | 'argon2i' | 'argon2id')\n * @param password - The password to hash\n * @param hashLength - Length of the output hash in bytes\n * @param parameters - Argon2 parameters (nonce, memory, passes, parallelism). If not provided, defaults will be used.\n * @returns The hash buffer\n */\nexport async function createHash(\n algorithm: Argon2Algorithm,\n password: string,\n hashLength: number,\n parameters?: Argon2Hash['parameters']\n): Promise<Buffer> {\n const nonce = parameters?.nonce ?? createSalt(DEFAULT_SALT_LENGTH);\n const memory = parameters?.memory ?? DEFAULT_MEMORY;\n const passes = parameters?.passes ?? DEFAULT_PASSES;\n const parallelism = parameters?.parallelism ?? DEFAULT_PARALLELISM;\n\n const argon2Params: Argon2Parameters = {\n message: password,\n tagLength: hashLength,\n nonce,\n memory,\n passes,\n parallelism\n };\n const argon2Fn = await getArgon2();\n\n // Wrap callback-based argon2 in a Promise\n return new Promise((resolve, reject) => {\n argon2Fn(algorithm, argon2Params, (err: Error | null, result?: Uint8Array) => {\n if (err) {\n reject(err);\n }\n else if (result) {\n resolve(Buffer.from(result));\n }\n else {\n reject(new Error('argon2 returned no result'));\n }\n });\n });\n}\n\n\n/**\n * Hash a password using Argon2.\n *\n * @param password - The plain text password to hash\n * @param options - Optional parameters object. If not provided, defaults will be used.\n * @returns The encoded Argon2 hash string\n */\nexport async function hash(\n password: string,\n options?: {\n algorithm?: Argon2Algorithm;\n saltLength?: number;\n hashLength?: number;\n parallelism?: number;\n memory?: number;\n passes?: number;\n }\n): Promise<string> {\n const algorithm = options?.algorithm ?? 'argon2id';\n const saltLength = options?.saltLength ?? DEFAULT_SALT_LENGTH;\n const hashLength = options?.hashLength ?? DEFAULT_HASH_LENGTH;\n const parallelism = options?.parallelism ?? DEFAULT_PARALLELISM;\n const memory = options?.memory ?? DEFAULT_MEMORY;\n const passes = options?.passes ?? DEFAULT_PASSES;\n\n const nonce = createSalt(saltLength);\n const parameters = { memory, passes, parallelism, nonce };\n const hashBuffer = await createHash(algorithm, password, hashLength, parameters);\n return encode({\n algorithm,\n version: ARGON2_VERSION,\n parameters,\n hash: hashBuffer\n });\n}\n\n/**\n * Verify a password against an Argon2 hash.\n *\n * @param encodedHash - The encoded Argon2 hash to verify against\n * @param password - The plain text password to verify\n * @returns true if password matches the hash, false otherwise\n */\nexport async function verify(encodedHash: string, password: string): Promise<boolean> {\n try {\n const decoded = decode(encodedHash);\n const hashBuffer = await createHash(\n decoded.algorithm,\n password,\n decoded.hash.length,\n decoded.parameters\n );\n return decoded.hash.equals(hashBuffer);\n } catch {\n return false;\n }\n}\n\n", "import { getRandomValues } from 'node:crypto';\n\n/**\n * Create a random salt (nonce) for cryptographic operations.\n *\n * @param length - Length of the salt in bytes\n * @returns Random salt buffer\n */\nexport function createSalt(length: number): Buffer {\n return getRandomValues(Buffer.alloc(length));\n}\n\n", "import net from 'net';\nimport type { ManagementCommand, ManagementEndpoint, SendCommandOptions } from '../../types/manage.d.ts';\n\nexport function sendCommand(\n server: ManagementEndpoint,\n command: ManagementCommand,\n options: SendCommandOptions = {}\n): Promise<unknown> {\n const { timeout = 5000 } = options;\n\n // Determine connection target: named pipe/socket path or port\n const connectOptions: net.NetConnectOpts = server?.path\n ? { path: server.path }\n : { port: server?.port ?? 0 };\n\n const target = server?.path ?? `port ${server?.port}`;\n\n return new Promise((resolve, reject) => {\n const client = net.connect(connectOptions, () => {\n client.write(JSON.stringify(command));\n });\n\n const timeoutId = setTimeout(() => {\n client.destroy();\n reject(new Error(`Connection timed out after ${timeout}`));\n }, timeout);\n\n client.on('data', (data) => {\n clearTimeout(timeoutId);\n try {\n const response = JSON.parse(data.toString());\n if (response.error) {\n reject(new Error(response.error));\n }\n else {\n resolve(response.result);\n }\n }\n catch {\n // Not JSON, return as raw string\n resolve(data.toString());\n }\n client.end();\n });\n\n client.on('error', (err: NodeJS.ErrnoException) => {\n clearTimeout(timeoutId);\n if (err.code === 'ENOENT' || err.code === 'ECONNREFUSED') {\n reject(new Error(`Cannot connect to gateway at ${target}. Make sure the gateway server is running and the path is correct.`, { cause: err }));\n }\n else {\n reject(err);\n }\n });\n });\n}\n\n", "import { KEYUTIL, KJUR, RSAKey, datetozulu } from \"jsrsasign\";\nimport { userInfo, hostname } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\nconst userAndHost = `${userInfo().username}@${hostname()}`;\n\nfunction randomSerialNumber(): string {\n const bytes = randomBytes(16);\n return bytes.toString('hex');\n}\n\nconst DEFAULT_ORGANISATION = `io.Gateway Dev CA`;\nexport const DEFAULT_CA_NAME = `${DEFAULT_ORGANISATION} ${userAndHost}`;\n\nexport function generateRootCA(options?: { name?: string, passphrase?: string } ): { key: string, cert: string } {\n\n const commonName = options?.name || DEFAULT_CA_NAME;\n const passphrase = options?.passphrase;\n\n // STEP 1. generate a key pair for Root CA (secp384r1 for higher security)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp384r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = passphrase\n ? KEYUTIL.getPEM(prv, \"PKCS8PRV\", passphrase, \"AES-256-CBC\")\n : KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // STEP 2: create self-signed CA certificate\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}` },\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000), false, false), // 10 years\n\n sbjpubkey: pub,\n\n ext: [\n {extname: \"basicConstraints\", critical: true, cA: true},\n {extname: \"keyUsage\", critical: true, names: [\"keyCertSign\"]}\n ],\n\n sigalg: \"SHA384withECDSA\",\n cakey: prv\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n\n\n/**\n * Generate a certificate with custom SAN entries\n * @param cakey - CA private key\n * @param issuer - Issuer DN string\n * @param sanEntries - Array of SAN entry strings (e.g., \"localhost\", \"IP:192.168.1.1\", \"EMAIL:user@example.com\")\n * @param isClient - Generate client cert (clientAuth) vs server cert (serverAuth)\n * @param validityDays - Certificate validity period\n */\nexport function generateCert(\n cakey: string | RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA,\n issuer: string,\n sanEntries: string[],\n isClient: boolean = false,\n validityDays: number = 7\n): {\n key: string,\n cert: string\n} {\n // STEP 1. generate key pair (secp256r1 for faster generation)\n const kp = KEYUTIL.generateKeypair(\"EC\", \"secp256r1\");\n const prv = kp.prvKeyObj;\n const pub = kp.pubKeyObj;\n\n const prvPem = KEYUTIL.getPEM(prv, \"PKCS8PRV\");\n\n // Parse SAN entries\n const sanArray: Array<{dns?: string, ip?: string, rfc822?: string}> = [];\n let commonName = isClient ? 'dev-user' : 'localhost';\n\n for (const entry of sanEntries) {\n if (entry.toLowerCase().startsWith('ip:')) {\n sanArray.push({ip: entry.substring(3)});\n }\n else if (entry.toLowerCase().startsWith('email:')) {\n sanArray.push({rfc822: entry.substring(6)});\n }\n else {\n const dnsPrefixed = entry.toLowerCase().startsWith('dns:');\n if (isClient) {\n commonName = dnsPrefixed ? entry.substring(4) : entry;\n }\n else {\n const dns = dnsPrefixed ? entry.substring(4) : entry;\n sanArray.push({dns});\n if (sanArray.length === 1) {\n commonName = dns; // Use first DNS as CN\n }\n }\n }\n }\n\n // STEP 2: create certificate signed by CA\n const extensions: Array<{\n extname: string;\n cA?: boolean;\n critical?: boolean;\n names?: string[];\n array?: (string[] | Array<{dns?: string, ip?: string, rfc822?: string}>);\n }> = [\n {extname: \"basicConstraints\", cA: false},\n {\n extname: \"keyUsage\",\n critical: true,\n names: [\"digitalSignature\", \"keyEncipherment\"]\n },\n {\n extname: \"extKeyUsage\",\n array: [isClient ? \"clientAuth\" : \"serverAuth\"]\n }\n ];\n\n // Add SAN only if we have entries\n if (sanArray.length > 0) {\n extensions.push({\n extname: \"subjectAltName\",\n array: sanArray\n });\n }\n\n const cert = new KJUR.asn1.x509.Certificate({\n version: 3,\n serial: { hex: randomSerialNumber() },\n issuer: { str: issuer },\n subject: { str: `/CN=${commonName}/O=${DEFAULT_ORGANISATION}/OU=${userAndHost}`},\n\n notbefore: datetozulu(new Date(Date.now() - 60 * 1000), false, false),\n notafter: datetozulu(new Date(Date.now() + validityDays * 24 * 60 * 60 * 1000), false, false),\n\n sbjpubkey: pub,\n ext: extensions,\n\n sigalg: \"SHA256withECDSA\",\n cakey: cakey\n });\n\n const certPem = cert.getPEM();\n\n return {\n key: prvPem,\n cert: certPem\n };\n}\n", "import { access, copyFile, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { execFile as execFileCb } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { createHash } from 'node:crypto';\nimport { basename, resolve } from 'node:path';\n\nimport type { BuildSeaOptions } from '../../types/build.d.ts';\n\nconst execFile = promisify(execFileCb);\n\n/**\n * Escapes a string for safe interpolation inside a single-quoted JS string literal.\n */\nfunction escapeForSingleQuotedString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nexport async function buildSea(name: string, options?: BuildSeaOptions): Promise<string> {\n const outDir = options?.outDir ?? './build';\n const nodeExecutable = options?.config?.executable ?? process.execPath;\n\n const safeName = escapeForSingleQuotedString(name);\n const safeVersion = escapeForSingleQuotedString(options?.version ?? '');\n const safeOutDir = escapeForSingleQuotedString(outDir.replace(/\\\\/g, '/'));\n\n // Use the target node executable to create the output directory and resolve\n // platform-specific paths. This also validates the executable is functional.\n const { stdout } = await execFile(nodeExecutable, ['-e', `\n const { mkdirSync } = require('node:fs');\n const path = require('node:path');\n const appVersion = '${safeVersion}'.trim();\n const dirName = '${safeName}' + (appVersion ? '-v' + appVersion : '') + '.' + process.platform + '-' + process.arch;\n const dir = path.resolve('${safeOutDir}', dirName);\n mkdirSync(dir, { recursive: true });\n process.stdout.write(JSON.stringify({ dirName, nodeVersion: process.version, platform: process.platform, arch: process.arch }));\n `.trim()]);\n\n const { dirName, nodeVersion, platform, arch } = JSON.parse(stdout);\n\n // Step 1: Produce the SEA JavaScript file\n let seaMain: string;\n if (options?.esbuild) {\n let esbuild: typeof import('esbuild');\n try {\n esbuild = await import('esbuild');\n }\n catch {\n throw new Error('esbuild is required to bundle the entry point. Install it with:\\n\\n npm install --save-dev esbuild\\n');\n }\n seaMain = `${outDir}/${name}.js`;\n await esbuild.build({\n format: 'cjs',\n target: 'node20',\n platform: 'node',\n bundle: true,\n external: ['esbuild', 'postject'], // exclude esbuild from the bundle since it's only needed at build time\n loader: {\n \".md\": \"file\",\n \".d.ts\": \"file\",\n },\n assetNames: `${dirName}/[name]`,\n entryNames: '[name]',\n outdir: outDir,\n minify: true,\n logLevel: 'info',\n ...options.esbuild,\n });\n }\n else if (options?.config?.main) {\n seaMain = resolve(options.config.main);\n }\n else {\n throw new Error('Either esbuild options (with entryPoints) or config.main must be provided.');\n }\n\n // Write SEA config file in the build folder\n const blobPath = resolve(`${outDir}/${name}.sea.node-${nodeVersion}-${platform}-${arch}.blob`);\n const configPath = resolve(`${outDir}/${name}.sea-config.${dirName}.json`);\n const seaConfig = {\n disableExperimentalSEAWarning: true,\n useSnapshot: false,\n useCodeCache: false,\n ...options?.config,\n main: resolve(seaMain),\n output: blobPath,\n };\n await writeFile(configPath, JSON.stringify(seaConfig, null, 2));\n\n const nativePath = resolve(outDir, dirName);\n\n const isWindows = platform === 'win32';\n const isMacos = platform === 'darwin';\n const targetFile = isWindows ? `${name}.exe` : name;\n const targetPath = `${nativePath}/${targetFile}`;\n\n\n // Check if we can skip the SEA build\n const seaJsContent = await readFile(seaMain);\n const shaPath = `${outDir}/${basename(seaMain)}.sha`;\n\n const currentSha = createHash('sha256').update(seaJsContent).digest('hex');\n let canSkip = false;\n\n try {\n const [previousSha] = await Promise.all([\n readFile(shaPath, 'utf8'),\n access(targetPath)\n ]);\n canSkip = previousSha === currentSha;\n }\n catch {\n // SHA file or target doesn't exist, need to build\n }\n if (canSkip) {\n console.log('SEA build skipped - esbuild output unchanged and target exists');\n return targetPath;\n }\n\n // Step 3: Generate the blob to be injected\n await execFile(nodeExecutable, ['--experimental-sea-config', configPath]);\n\n // Step 4: Copy the Node.js executable to the target path\n await copyFile(nodeExecutable, targetPath);\n\n // Step 5: Remove the signature of the binary\n if (isWindows) {\n try {\n const signtool = await findSigntool();\n if (signtool) {\n console.log(`Found signtool at: ${signtool}`);\n await execFile(signtool, ['remove', '/s', targetPath]);\n console.log(`Signature removed from ${targetPath} executable`);\n }\n }\n catch (e: any) {\n console.warn('Failed to remove signature:', e.message);\n }\n }\n else if (isMacos) {\n try {\n await execFile('codesign', ['--remove-signature', targetPath]);\n console.log(`Signature removed from ${targetPath} executable`);\n }\n catch (e: any) {\n console.warn('Failed to remove signature:', e.message);\n }\n }\n\n // Step 6: Inject the SEA blob into the binary\n type InjectOptions = {\n /**\n * @default '__POSTJECT'\n */\n machoSegmentName?: string;\n /**\n * @default false\n */\n overwrite?: boolean;\n /**\n * @default 'POSTJECT_SENTINEL_fce680ab2cc467b6e072b8b5df1996b2'\n */\n sentinelFuse?: string\n };\n type Inject = (filename: string, resourceName: string, resourceData: Buffer, options?: InjectOptions) => Promise<void>;\n\n let inject: Inject;\n try {\n ({ inject } = await import('postject') as { inject: Inject });\n }\n catch {\n throw new Error('postject is required to build a SEA. Install it with:\\n\\n npm install --save-dev postject\\n');\n }\n\n const resourceData = await readFile(blobPath);\n\n // Construct the sentinel fuse at runtime to avoid the literal appearing in the\n // bundled SEA output \u2014 postject would otherwise find multiple occurrences.\n const sentinelFuse = ['NODE', 'SEA', 'FUSE', 'fce680ab2cc467b6e072b8b5df1996b2'].join('_');\n\n await inject(\n targetPath,\n 'NODE_SEA_BLOB',\n resourceData,\n {\n overwrite: true,\n sentinelFuse,\n ...(isMacos ? { machoSegmentName: 'NODE_SEA' } : {})\n });\n\n // Step 7: Sign the binary\n if (isWindows) {\n try {\n const signtool = await findSigntool();\n if (signtool) {\n console.log(`Signing executable with signtool at: ${signtool}`);\n await execFile(signtool, ['sign', '/fd', 'SHA256', targetPath]);\n console.log(`Executable signed successfully`);\n }\n }\n catch (e: any) {\n console.warn('Failed to sign executable:', e.message);\n }\n }\n else if (isMacos) {\n try {\n await execFile('codesign', ['--sign', '-', targetPath]);\n console.log(`Executable signed successfully`);\n }\n catch (e: any) {\n console.warn('Failed to sign executable:', e.message);\n }\n }\n\n // Save SHA for next build comparison\n await writeFile(shaPath, currentSha);\n return targetPath;\n}\n\nasync function findSigntool(): Promise<string | null> {\n const windowsKitsPath = 'C:\\\\Program Files (x86)\\\\Windows Kits\\\\10\\\\bin';\n\n try {\n const entries = await readdir(windowsKitsPath, { withFileTypes: true });\n\n // Filter directories that match version pattern (e.g., 10.0.22621.0)\n const versionDirs = entries\n .filter(entry => entry.isDirectory() && /^10\\.0\\.\\d+\\.\\d+$/.test(entry.name))\n .map(entry => entry.name)\n .sort((a, b) => {\n // Sort by version number descending to get the latest\n const partsA = a.split('.').map(Number);\n const partsB = b.split('.').map(Number);\n for (let i = 0; i < partsA.length; i++) {\n if (partsA[i] !== partsB[i]) {\n return partsB[i] - partsA[i];\n }\n }\n return 0;\n });\n\n // Try each version directory, starting with the latest\n for (const version of versionDirs) {\n const signtoolPath = `${windowsKitsPath}\\\\${version}\\\\${process.arch}\\\\signtool.exe`;\n try {\n await access(signtoolPath);\n return signtoolPath;\n }\n catch {\n // signtool not found in this version, try next\n }\n }\n\n console.warn('signtool.exe not found in any Windows SDK version');\n return null;\n }\n catch (e: any) {\n console.warn(`Windows SDK not found at ${windowsKitsPath}: ${e.message}`);\n return null;\n }\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["argon2_exports", "__export", "ARGON2_VERSION", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "DEFAULT_ALGORITHM", "DEFAULT_HASH_LENGTH", "DEFAULT_MEMORY", "DEFAULT_PARALLELISM", "DEFAULT_PASSES", "DEFAULT_SALT_LENGTH", "createHash", "decode", "encode", "hash", "verify", "keygen_exports", "__export", "createSalt", "getRandomValues", "length", "argon2", "getArgon2", "crypto", "ARGON2_VERSION_10", "ARGON2_VERSION_13", "ARGON2_VERSION", "DEFAULT_ALGORITHM", "DEFAULT_SALT_LENGTH", "DEFAULT_HASH_LENGTH", "DEFAULT_PARALLELISM", "DEFAULT_MEMORY", "DEFAULT_PASSES", "decode", "encodedHash", "parts", "current", "algorithm", "version", "parameters", "paramsParts", "param", "key", "value", "hash", "encode", "hashData", "createHash", "password", "hashLength", "nonce", "createSalt", "memory", "passes", "parallelism", "argon2Params", "argon2Fn", "resolve", "reject", "err", "result", "options", "saltLength", "hashBuffer", "verify", "decoded", "client_exports", "__export", "sendCommand", "net", "server", "command", "options", "timeout", "connectOptions", "target", "resolve", "reject", "client", "timeoutId", "data", "response", "err", "mkcert_exports", "__export", "DEFAULT_CA_NAME", "generateCert", "generateRootCA", "KEYUTIL", "KJUR", "datetozulu", "userInfo", "hostname", "randomBytes", "userAndHost", "randomSerialNumber", "DEFAULT_ORGANISATION", "options", "commonName", "passphrase", "kp", "prv", "pub", "prvPem", "certPem", "cakey", "issuer", "sanEntries", "isClient", "validityDays", "sanArray", "entry", "dnsPrefixed", "dns", "extensions", "build_exports", "__export", "buildSea", "access", "copyFile", "readdir", "readFile", "writeFile", "execFileCb", "promisify", "createHash", "basename", "resolve", "execFile", "escapeForSingleQuotedString", "value", "name", "options", "outDir", "nodeExecutable", "safeName", "safeVersion", "safeOutDir", "stdout", "dirName", "nodeVersion", "platform", "arch", "seaMain", "esbuild", "blobPath", "configPath", "seaConfig", "nativePath", "isWindows", "isMacos", "targetFile", "targetPath", "seaJsContent", "shaPath", "currentSha", "canSkip", "previousSha", "signtool", "findSigntool", "e", "inject", "resourceData", "sentinelFuse", "windowsKitsPath", "versionDirs", "entry", "a", "b", "partsA", "partsB", "version", "signtoolPath"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interopio/gateway-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"gateway",
|
|
6
6
|
"server",
|
|
@@ -91,13 +91,13 @@
|
|
|
91
91
|
"node": ">=20.18 || >=22.12 || >=24"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"@interopio/gateway": "^0.25.
|
|
95
|
-
"tough-cookie": "^6.0.
|
|
94
|
+
"@interopio/gateway": "^0.25.1",
|
|
95
|
+
"tough-cookie": "^6.0.1",
|
|
96
96
|
"http-cookie-agent": "^7.0.3",
|
|
97
97
|
"ws": "^8.19.0"
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|
|
100
|
-
"undici": "^7.
|
|
100
|
+
"undici": "^7.24.4"
|
|
101
101
|
},
|
|
102
102
|
"peerDependenciesMeta": {
|
|
103
103
|
"undici": {
|
package/types/build.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { BuildOptions } from 'esbuild';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for building a Single Executable Application (SEA) with `buildSea`.
|
|
5
|
+
*/
|
|
6
|
+
export interface BuildSeaOptions {
|
|
7
|
+
|
|
8
|
+
/** Application version included in the output directory name (e.g. `1.2.3` → `<name>-v1.2.3.<platform>-<arch>`). */
|
|
9
|
+
version?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* esbuild options used to bundle the entry point into `<name>.sea.js`.
|
|
13
|
+
* Must include at least `entryPoints`. When provided, `esbuild` is loaded
|
|
14
|
+
* dynamically — install it with `npm install --save-dev esbuild`.
|
|
15
|
+
*
|
|
16
|
+
* Mutually exclusive with `config.main` — provide one or the other.
|
|
17
|
+
*/
|
|
18
|
+
esbuild?: BuildOptions;
|
|
19
|
+
|
|
20
|
+
/** Output directory for build artifacts (default: `./build`). */
|
|
21
|
+
outDir?: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* SEA configuration written to the `<name>.sea-config.json` file.
|
|
25
|
+
* When `esbuild` is not provided, `main` must point to a pre-built script.
|
|
26
|
+
*
|
|
27
|
+
* @see https://nodejs.org/api/single-executable-applications.html#generating-single-executable-preparation-blobs
|
|
28
|
+
*/
|
|
29
|
+
config?: {
|
|
30
|
+
/** Path to the pre-built script to embed. Required when `esbuild` is not provided. */
|
|
31
|
+
main: string;
|
|
32
|
+
mainFormat?: 'commonjs' | 'module';
|
|
33
|
+
executable?: string;
|
|
34
|
+
output: string;
|
|
35
|
+
disableExperimentalSEAWarning?: boolean;
|
|
36
|
+
useSnapshot?: false;
|
|
37
|
+
useCodeCache?: false;
|
|
38
|
+
execArgv?: string[];
|
|
39
|
+
execArgvExtension: 'none' | 'env' | 'cli';
|
|
40
|
+
assets?: {
|
|
41
|
+
[assetKey: string]: string;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Builds a Node.js Single Executable Application (SEA).
|
|
48
|
+
*
|
|
49
|
+
* Provide **either** `esbuild` (to bundle an entry point on the fly) **or**
|
|
50
|
+
* `config.main` (to use a pre-built script). At least one must be specified.
|
|
51
|
+
*
|
|
52
|
+
* When `esbuild` is provided, the entry point is bundled into `<outDir>/<name>.sea.js`
|
|
53
|
+
* and that file is used as the SEA main script. Both `esbuild` and `postject` are
|
|
54
|
+
* loaded lazily — they are only required as dev dependencies.
|
|
55
|
+
*
|
|
56
|
+
* The build is skipped when the SHA-256 of the bundled script is unchanged and the
|
|
57
|
+
* target executable already exists.
|
|
58
|
+
*
|
|
59
|
+
* @param name - Base name for the executable and intermediate files (e.g. `gateway-server`, `io-bridge`)
|
|
60
|
+
* @param options - Build options
|
|
61
|
+
* @returns The path to the built executable
|
|
62
|
+
*/
|
|
63
|
+
export function buildSea(name: string, options?: BuildSeaOptions): Promise<string>;
|
package/types/tools.d.ts
CHANGED