mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-26 00:52:18 +03:00
fix(tailscale): validate ports and quote MSI paths (#11534)
Validated in a combined 10-PR batch worktree off release/v3.8.51 tip. - Focused test: tests/unit/tailscale-validation.test.ts — 2/2 pass plus 13/13 related Tailscale tests - typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity gates — all OK - Full-repo lint: 503 pre-existing problems confirmed identical on the pure release/v3.8.51 tip — unrelated to this diff ⚠️ base-red inherited: #11449 Thanks for rejecting out-of-range Tailscale ports and escaping apostrophes before they reach the Windows MSI installer PowerShell command.
This commit is contained in:
1
changelog.d/fixes/tailscale-port-and-windows-path.md
Normal file
1
changelog.d/fixes/tailscale-port-and-windows-path.md
Normal file
@@ -0,0 +1 @@
|
||||
- Fixed Tailscale tunnel setup to reject ports outside the valid 1-65535 range and safely install Windows MSI packages from paths containing apostrophes.
|
||||
@@ -6,7 +6,7 @@ import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
export const tailscaleEnableSchema = z.object({
|
||||
sudoPassword: z.string().optional(),
|
||||
hostname: z.string().optional(),
|
||||
port: z.number().int().positive().optional(),
|
||||
port: z.number().int().min(1).max(65535).optional(),
|
||||
});
|
||||
|
||||
export const tailscaleLoginSchema = z.object({
|
||||
|
||||
@@ -1104,6 +1104,11 @@ async function installTailscaleLinux(password: string, onProgress?: (message: st
|
||||
});
|
||||
}
|
||||
|
||||
export function buildWindowsTailscaleInstallCommand(msiPath: string): string {
|
||||
const escapedMsiPath = msiPath.replace(/'/g, "''");
|
||||
return `Start-Process msiexec -ArgumentList '/i','${escapedMsiPath}','TS_NOLAUNCH=true','/quiet','/norestart' -Verb RunAs -Wait`;
|
||||
}
|
||||
|
||||
async function installTailscaleWindows(onProgress?: (message: string) => void) {
|
||||
const msiUrl = "https://pkgs.tailscale.com/stable/tailscale-setup-latest-amd64.msi";
|
||||
const msiPath = path.join(os.tmpdir(), "tailscale-setup.msi");
|
||||
@@ -1125,12 +1130,7 @@ async function installTailscaleWindows(onProgress?: (message: string) => void) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const child = spawn(
|
||||
"powershell",
|
||||
[
|
||||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"-Command",
|
||||
`Start-Process msiexec -ArgumentList '/i','${msiPath}','TS_NOLAUNCH=true','/quiet','/norestart' -Verb RunAs -Wait`,
|
||||
],
|
||||
["-NoProfile", "-NonInteractive", "-Command", buildWindowsTailscaleInstallCommand(msiPath)],
|
||||
{
|
||||
windowsHide: true,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
|
||||
19
tests/unit/tailscale-validation.test.ts
Normal file
19
tests/unit/tailscale-validation.test.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { tailscaleEnableSchema } from "../../src/app/api/tunnels/tailscale/routeUtils.ts";
|
||||
import { buildWindowsTailscaleInstallCommand } from "../../src/lib/tailscaleTunnel.ts";
|
||||
|
||||
test("tailscale enable accepts only valid TCP ports", () => {
|
||||
assert.equal(tailscaleEnableSchema.safeParse({ port: 1 }).success, true);
|
||||
assert.equal(tailscaleEnableSchema.safeParse({ port: 65535 }).success, true);
|
||||
assert.equal(tailscaleEnableSchema.safeParse({ port: 0 }).success, false);
|
||||
assert.equal(tailscaleEnableSchema.safeParse({ port: 65536 }).success, false);
|
||||
});
|
||||
|
||||
test("Windows installer command escapes apostrophes in MSI paths", () => {
|
||||
assert.equal(
|
||||
buildWindowsTailscaleInstallCommand("C:\\Users\\O'Brien\\tailscale-setup.msi"),
|
||||
"Start-Process msiexec -ArgumentList '/i','C:\\Users\\O''Brien\\tailscale-setup.msi','TS_NOLAUNCH=true','/quiet','/norestart' -Verb RunAs -Wait"
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user