From 03bd2b6803a6fd46d7e93330103a9a1ced6457e4 Mon Sep 17 00:00:00 2001 From: Sajid Date: Fri, 20 Mar 2026 22:01:48 +0600 Subject: [PATCH 1/2] fix: resolve Windows machine ID failure due to node-machine-id bundle-time platform detection Problem: node-machine-id constructs the REG.exe command path at module load time using process.platform. When Next.js bundles this module, process.platform is "" (not "win32") in the webpack/build context, so the lookup returns undefined and bakes "undefined\REG.exe ..." permanently into the compiled chunk. At runtime on Windows this causes: Error: Command failed: undefined\REG.exe QUERY HKEY_LOCAL_MACHINE\... The system cannot find the path specified. Fix: Remove the node-machine-id dependency from machineId.ts and replace it with a direct execSync implementation that resolves process.env.SystemRoot at call time (not load time), so the correct Windows path is always used regardless of when or how the module was bundled. Platform support is preserved for Windows, macOS, and Linux/FreeBSD using the same underlying OS queries that node-machine-id used internally. Co-Authored-By: Claude Sonnet 4.6 --- src/shared/utils/machineId.ts | 41 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/shared/utils/machineId.ts b/src/shared/utils/machineId.ts index ef405693..9d64151a 100644 --- a/src/shared/utils/machineId.ts +++ b/src/shared/utils/machineId.ts @@ -1,17 +1,47 @@ -import { machineIdSync } from "node-machine-id"; +import { execSync } from "child_process"; + +function getMachineIdRaw(): string { + if (process.platform === "win32") { + const sysRoot = process.env.SystemRoot || process.env.windir || "C:\\Windows"; + const output = execSync( + `"${sysRoot}\\System32\\REG.exe" QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid`, + { encoding: "utf8" } + ); + return output + .toString() + .split("REG_SZ")[1] + .replace(/\r+|\n+|\s+/gi, "") + .toLowerCase(); + } + if (process.platform === "darwin") { + const output = execSync("ioreg -rd1 -c IOPlatformExpertDevice", { encoding: "utf8" }); + return output + .split("IOPlatformUUID")[1] + .split("\n")[0] + .replace(/\=|\s+|\"/gi, "") + .toLowerCase(); + } + const output = execSync( + "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :", + { encoding: "utf8" } + ); + return output + .toString() + .replace(/\r+|\n+|\s+/gi, "") + .toLowerCase(); +} /** - * Get consistent machine ID using node-machine-id with salt + * Get consistent machine ID using native registry/OS query with salt * This ensures the same physical machine gets the same ID across runs * * @param {string} salt - Optional salt to use (defaults to environment variable) * @returns {Promise} Machine ID (16-character base32) */ export async function getConsistentMachineId(salt = null) { - // For server-side, use node-machine-id with salt const saltValue = salt || process.env.MACHINE_ID_SALT || "endpoint-proxy-salt"; try { - const rawMachineId = machineIdSync(); + const rawMachineId = getMachineIdRaw(); // Create consistent ID using salt const crypto = await import("crypto"); const hashedMachineId = crypto @@ -38,9 +68,8 @@ export async function getConsistentMachineId(salt = null) { * @returns {Promise} Raw machine ID */ export async function getRawMachineId() { - // For server-side, use raw node-machine-id try { - return machineIdSync(); + return getMachineIdRaw(); } catch (error) { console.log("Error getting raw machine ID:", error); // Fallback to random ID if node-machine-id fails From 3e0c322fd44e06742cce187b3df2439593687dea Mon Sep 17 00:00:00 2001 From: Sajid Date: Fri, 20 Mar 2026 23:44:15 +0600 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20address=20Gemini=20code=20review=20?= =?UTF-8?q?=E2=80=94=20use=20execFileSync=20and=20optional=20chaining?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace execSync template string with execFileSync + args array on Windows to prevent command injection via SystemRoot/windir environment variables - Add optional chaining (?.) and nullish coalescing (?? "") on Windows REG_SZ output parsing to prevent crash if REG.exe output is unexpected - Add optional chaining on macOS IOPlatformUUID parsing for the same reason Co-Authored-By: Claude Sonnet 4.6 --- src/shared/utils/machineId.ts | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/shared/utils/machineId.ts b/src/shared/utils/machineId.ts index 9d64151a..981b9340 100644 --- a/src/shared/utils/machineId.ts +++ b/src/shared/utils/machineId.ts @@ -1,25 +1,30 @@ -import { execSync } from "child_process"; +import { execSync, execFileSync } from "child_process"; function getMachineIdRaw(): string { if (process.platform === "win32") { const sysRoot = process.env.SystemRoot || process.env.windir || "C:\\Windows"; - const output = execSync( - `"${sysRoot}\\System32\\REG.exe" QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid`, + const output = execFileSync( + `${sysRoot}\\System32\\REG.exe`, + ["QUERY", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"], { encoding: "utf8" } ); - return output - .toString() - .split("REG_SZ")[1] - .replace(/\r+|\n+|\s+/gi, "") - .toLowerCase(); + return ( + output + .toString() + .split("REG_SZ")[1] + ?.replace(/\r+|\n+|\s+/gi, "") + ?.toLowerCase() ?? "" + ); } if (process.platform === "darwin") { const output = execSync("ioreg -rd1 -c IOPlatformExpertDevice", { encoding: "utf8" }); - return output - .split("IOPlatformUUID")[1] - .split("\n")[0] - .replace(/\=|\s+|\"/gi, "") - .toLowerCase(); + return ( + output + .split("IOPlatformUUID")[1] + ?.split("\n")[0] + ?.replace(/\=|\s+|\"/gi, "") + ?.toLowerCase() ?? "" + ); } const output = execSync( "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :",