mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-17 12:42:21 +03:00
fix(startup): read platform at runtime via os.platform() so Windows Tailscale branches survive bundle DCE (#10293)
This commit is contained in:
@@ -15,9 +15,15 @@ const execFileAsync = promisify(execFile);
|
||||
|
||||
const WINDOWS_TAILSCALE_BIN = "C:\\Program Files\\Tailscale\\tailscale.exe";
|
||||
const WINDOWS_TAILSCALED_BIN = "C:\\Program Files\\Tailscale\\tailscaled.exe";
|
||||
const IS_MAC = process.platform === "darwin";
|
||||
const IS_LINUX = process.platform === "linux";
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
|
||||
// Runtime platform getter. A bundler (Turbopack in `next build`) constant-folds
|
||||
// `process.platform` to the BUILD machine's value on a non-Windows runner and prunes
|
||||
// the other branches as dead code (#10293). `os.platform()` is a runtime call a
|
||||
// bundler cannot fold, so Windows/macOS/Linux branches survive on any build machine.
|
||||
function getCurrentPlatform(): NodeJS.Platform {
|
||||
return os.platform();
|
||||
}
|
||||
|
||||
const EXTENDED_PATH = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:${process.env.PATH || ""}`;
|
||||
const LOGIN_TIMEOUT_MS = 15000;
|
||||
const FUNNEL_TIMEOUT_MS = 30000;
|
||||
@@ -35,12 +41,7 @@ type JsonRecord = Record<string, unknown>;
|
||||
|
||||
export type TailscaleTunnelInstallSource = "managed" | "path" | "env" | "windows-default";
|
||||
export type TailscaleTunnelPhase =
|
||||
| "unsupported"
|
||||
| "not_installed"
|
||||
| "needs_login"
|
||||
| "stopped"
|
||||
| "running"
|
||||
| "error";
|
||||
"unsupported" | "not_installed" | "needs_login" | "stopped" | "running" | "error";
|
||||
|
||||
type PersistedTailscaleState = {
|
||||
binaryPath?: string | null;
|
||||
@@ -61,8 +62,7 @@ type BinaryResolution = {
|
||||
type TailscaleLoginResult = { alreadyLoggedIn: true } | { authUrl: string };
|
||||
|
||||
type TailscaleFunnelResult =
|
||||
| { tunnelUrl: string }
|
||||
| { funnelNotEnabled: true; enableUrl: string | null };
|
||||
{ tunnelUrl: string } | { funnelNotEnabled: true; enableUrl: string | null };
|
||||
|
||||
export type TailscaleCheckStatus = {
|
||||
supported: boolean;
|
||||
@@ -124,7 +124,7 @@ function shellEscape(value: string) {
|
||||
return `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
||||
}
|
||||
|
||||
function isSupportedPlatform(platform = process.platform) {
|
||||
function isSupportedPlatform(platform = os.platform()) {
|
||||
return platform === "darwin" || platform === "linux" || platform === "win32";
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ function getTailscaleDir() {
|
||||
return path.join(resolveDataDir(), "tailscale");
|
||||
}
|
||||
|
||||
function getManagedBinaryPath(platform = process.platform) {
|
||||
function getManagedBinaryPath(platform = os.platform()) {
|
||||
return path.join(getTailscaleDir(), "bin", platform === "win32" ? "tailscale.exe" : "tailscale");
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ function getTailscaleApiUrl(tunnelUrl: string | null) {
|
||||
}
|
||||
|
||||
async function resolvePathCommand(command: string) {
|
||||
const lookupCommand = process.platform === "win32" ? "where" : "which";
|
||||
const lookupCommand = os.platform() === "win32" ? "where" : "which";
|
||||
try {
|
||||
const { stdout } = await execFileAsync(lookupCommand, [command], {
|
||||
timeout: 3000,
|
||||
@@ -248,7 +248,7 @@ async function resolveBinary(): Promise<BinaryResolution> {
|
||||
return { binaryPath: pathBinary, installSource: "path", managedInstall: false };
|
||||
}
|
||||
|
||||
if (IS_WINDOWS && fs.existsSync(WINDOWS_TAILSCALE_BIN)) {
|
||||
if (getCurrentPlatform() === "win32" && fs.existsSync(WINDOWS_TAILSCALE_BIN)) {
|
||||
return {
|
||||
binaryPath: WINDOWS_TAILSCALE_BIN,
|
||||
installSource: "windows-default",
|
||||
@@ -263,7 +263,7 @@ async function resolveDaemonBinary(tailscaleBinaryPath: string | null) {
|
||||
const envPath = toNonEmptyString(process.env.TAILSCALED_BIN);
|
||||
if (envPath && fs.existsSync(envPath)) return envPath;
|
||||
|
||||
const daemonFilename = process.platform === "win32" ? "tailscaled.exe" : "tailscaled";
|
||||
const daemonFilename = os.platform() === "win32" ? "tailscaled.exe" : "tailscaled";
|
||||
const siblingDir = tailscaleBinaryPath ? path.dirname(tailscaleBinaryPath) : null;
|
||||
// path.format avoids the path.join/resolve pattern flagged by CWE-22 linters;
|
||||
// siblingDir is path.dirname of a trusted system binary from resolveBinary(), not user input.
|
||||
@@ -273,7 +273,8 @@ async function resolveDaemonBinary(tailscaleBinaryPath: string | null) {
|
||||
const pathBinary = await resolvePathCommand("tailscaled");
|
||||
if (pathBinary) return pathBinary;
|
||||
|
||||
if (IS_WINDOWS && fs.existsSync(WINDOWS_TAILSCALED_BIN)) return WINDOWS_TAILSCALED_BIN;
|
||||
if (getCurrentPlatform() === "win32" && fs.existsSync(WINDOWS_TAILSCALED_BIN))
|
||||
return WINDOWS_TAILSCALED_BIN;
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -298,7 +299,9 @@ async function getActiveSocketPath(): Promise<string> {
|
||||
}
|
||||
|
||||
// Check system sockets first
|
||||
const systemSocket = IS_LINUX ? SYSTEM_SOCKET_LINUX : IS_MAC ? SYSTEM_SOCKET_MAC : null;
|
||||
const platform = getCurrentPlatform();
|
||||
const systemSocket =
|
||||
platform === "linux" ? SYSTEM_SOCKET_LINUX : platform === "darwin" ? SYSTEM_SOCKET_MAC : null;
|
||||
if (systemSocket && fs.existsSync(systemSocket)) {
|
||||
_cachedActiveSocket = systemSocket;
|
||||
_cachedActiveSocketTimestamp = now;
|
||||
@@ -314,7 +317,9 @@ async function getActiveSocketPath(): Promise<string> {
|
||||
|
||||
/** Synchronous check: is the system daemon socket available? */
|
||||
function isSystemDaemonAvailable(): boolean {
|
||||
const systemSocket = IS_LINUX ? SYSTEM_SOCKET_LINUX : IS_MAC ? SYSTEM_SOCKET_MAC : null;
|
||||
const platform = getCurrentPlatform();
|
||||
const systemSocket =
|
||||
platform === "linux" ? SYSTEM_SOCKET_LINUX : platform === "darwin" ? SYSTEM_SOCKET_MAC : null;
|
||||
return Boolean(systemSocket && fs.existsSync(systemSocket));
|
||||
}
|
||||
|
||||
@@ -341,19 +346,20 @@ export function tailscaleUpArgs(hostname?: string, authKey?: string): string[] {
|
||||
}
|
||||
|
||||
async function buildTailscaleArgs(...args: string[]) {
|
||||
if (IS_WINDOWS) return args;
|
||||
if (getCurrentPlatform() === "win32") return args;
|
||||
const socket = await getActiveSocketPath();
|
||||
return ["--socket", socket, ...args];
|
||||
}
|
||||
|
||||
/** Synchronous variant for places that cannot await */
|
||||
function buildTailscaleArgsSync(...args: string[]) {
|
||||
if (IS_WINDOWS) return args;
|
||||
if (getCurrentPlatform() === "win32") return args;
|
||||
// Use cached socket or default to system socket if available
|
||||
const platform = getCurrentPlatform();
|
||||
const socket =
|
||||
_cachedActiveSocket ||
|
||||
(isSystemDaemonAvailable()
|
||||
? IS_LINUX
|
||||
? platform === "linux"
|
||||
? SYSTEM_SOCKET_LINUX
|
||||
: SYSTEM_SOCKET_MAC
|
||||
: getTailscaleSocketPath());
|
||||
@@ -443,7 +449,7 @@ function getLastError(state: PersistedTailscaleState) {
|
||||
}
|
||||
|
||||
async function hasBrew() {
|
||||
if (!IS_MAC) return false;
|
||||
if (getCurrentPlatform() !== "darwin") return false;
|
||||
try {
|
||||
await execFileAsync("which", ["brew"], {
|
||||
timeout: 3000,
|
||||
@@ -487,7 +493,7 @@ export async function getTailscaleCheckStatus(): Promise<TailscaleCheckStatus> {
|
||||
running: isFunnelRunning(funnelPayload),
|
||||
tunnelUrl,
|
||||
apiUrl: getTailscaleApiUrl(tunnelUrl),
|
||||
platform: process.platform,
|
||||
platform: os.platform(),
|
||||
brewAvailable,
|
||||
lastError: getLastError(state),
|
||||
pid: await readPidFile(),
|
||||
@@ -561,7 +567,7 @@ export async function startTailscaleDaemon({
|
||||
return { started: false };
|
||||
}
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
if (getCurrentPlatform() === "win32") {
|
||||
try {
|
||||
await execFileAsync("net", ["start", "Tailscale"], {
|
||||
timeout: 10000,
|
||||
@@ -816,7 +822,7 @@ export async function stopTailscaleDaemon({
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_WINDOWS) {
|
||||
if (getCurrentPlatform() !== "win32") {
|
||||
try {
|
||||
await execFileAsync("pkill", ["-x", "tailscaled"], {
|
||||
timeout: 3000,
|
||||
@@ -1155,7 +1161,7 @@ export async function installTailscale({
|
||||
onProgress?: (message: string) => void;
|
||||
} = {}) {
|
||||
if (!isSupportedPlatform()) {
|
||||
throw new Error(`Unsupported platform for Tailscale install: ${process.platform}`);
|
||||
throw new Error(`Unsupported platform for Tailscale install: ${os.platform()}`);
|
||||
}
|
||||
|
||||
const password = toNonEmptyString(sudoPassword) || getCachedPassword() || "";
|
||||
@@ -1167,13 +1173,13 @@ export async function installTailscale({
|
||||
const existingBinary = await resolveBinary();
|
||||
if (existingBinary.binaryPath) {
|
||||
onProgress?.("Tailscale is already installed.");
|
||||
} else if (IS_WINDOWS) {
|
||||
} else if (getCurrentPlatform() === "win32") {
|
||||
onProgress?.("Downloading and installing Tailscale for Windows...");
|
||||
await installTailscaleWindows(onProgress);
|
||||
} else if (IS_MAC) {
|
||||
} else if (getCurrentPlatform() === "darwin") {
|
||||
onProgress?.("Installing Tailscale on macOS...");
|
||||
await installTailscaleMac(password, onProgress);
|
||||
} else if (IS_LINUX) {
|
||||
} else if (getCurrentPlatform() === "linux") {
|
||||
onProgress?.("Installing Tailscale on Linux...");
|
||||
await installTailscaleLinux(password, onProgress);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user