feat: Windows .zip download support, binary v145.0.7632.109.2

- Add get_archive_ext() / get_archive_name() for platform-aware archive format (.zip on Windows, .tar.gz elsewhere)
- Add _extract_zip() / extractZip() with path traversal protection
- Python: zipfile module extraction
- JS: PowerShell Expand-Archive on Windows, system unzip on others
- Bump all platform versions to 145.0.7632.109.2 (4 platforms: linux-x64, darwin-arm64, darwin-x64, windows-x64)
- Update checksum lookup, temp file naming, and auto-update asset matching to use archive helpers
This commit is contained in:
CloakHQ
2026-03-04 01:23:07 +01:00
parent 11b3bcb701
commit 46049a15d3
4 changed files with 116 additions and 61 deletions
+15 -9
View File
@@ -27,13 +27,13 @@ export { WRAPPER_VERSION };
// CHROMIUM_VERSION is the latest across all platforms (for display/reference).
// Use getChromiumVersion() for the current platform's actual version.
// ---------------------------------------------------------------------------
export const CHROMIUM_VERSION = "145.0.7632.109";
export const CHROMIUM_VERSION = "145.0.7632.109.2";
export const PLATFORM_CHROMIUM_VERSIONS: Record<string, string> = {
"linux-x64": "145.0.7632.109",
"darwin-arm64": "145.0.7632.109",
"darwin-x64": "145.0.7632.109",
"windows-x64": "145.0.7632.109",
"linux-x64": "145.0.7632.109.2",
"darwin-arm64": "145.0.7632.109.2",
"darwin-x64": "145.0.7632.109.2",
"windows-x64": "145.0.7632.109.2",
};
// ---------------------------------------------------------------------------
@@ -126,16 +126,22 @@ export const GITHUB_API_URL =
export const GITHUB_DOWNLOAD_BASE_URL =
"https://github.com/CloakHQ/cloakbrowser/releases/download";
export function getArchiveExt(): string {
return process.platform === "win32" ? ".zip" : ".tar.gz";
}
export function getArchiveName(tag?: string): string {
return `cloakbrowser-${tag || getPlatformTag()}${getArchiveExt()}`;
}
export function getDownloadUrl(version?: string): string {
const v = version || getChromiumVersion();
const tag = getPlatformTag();
return `${DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
return `${DOWNLOAD_BASE_URL}/chromium-v${v}/${getArchiveName()}`;
}
export function getFallbackDownloadUrl(version?: string): string {
const v = version || getChromiumVersion();
const tag = getPlatformTag();
return `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
return `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${v}/${getArchiveName()}`;
}
export function getEffectiveVersion(): string {
+40 -20
View File
@@ -19,6 +19,8 @@ import {
GITHUB_DOWNLOAD_BASE_URL,
WRAPPER_VERSION,
checkPlatformAvailable,
getArchiveExt,
getArchiveName,
getBinaryDir,
getBinaryPath,
getCacheDir,
@@ -152,7 +154,7 @@ async function downloadAndExtract(version?: string): Promise<void> {
// Download to temp file (atomic — no partial downloads in cache)
const tmpPath = path.join(
path.dirname(binaryDir),
`_download_${Date.now()}.tar.gz`
`_download_${Date.now()}${getArchiveExt()}`
);
try {
@@ -194,7 +196,7 @@ async function downloadAndExtract(version?: string): Promise<void> {
async function verifyDownloadChecksum(filePath: string, version?: string): Promise<void> {
const checksums = await fetchChecksums(version);
const tarballName = `cloakbrowser-${getPlatformTag()}.tar.gz`;
const tarballName = getArchiveName();
if (!checksums) {
console.warn("[cloakbrowser] SHA256SUMS not available for this release — skipping checksum verification");
@@ -342,23 +344,11 @@ async function extractArchive(
}
fs.mkdirSync(destDir, { recursive: true });
// Extract with tar — the 'tar' package handles symlink/traversal safety
await tarExtract({
file: archivePath,
cwd: destDir,
// Security: strip leading path components and reject absolute paths
strip: 0,
filter: (entryPath: string) => {
// Reject absolute paths and path traversal
if (path.isAbsolute(entryPath) || entryPath.includes("..")) {
console.warn(
`[cloakbrowser] Skipping suspicious archive entry: ${entryPath}`
);
return false;
}
return true;
},
});
if (archivePath.endsWith(".zip")) {
await extractZip(archivePath, destDir);
} else {
await extractTar(archivePath, destDir);
}
// Flatten single subdirectory if needed
flattenSingleSubdir(destDir);
@@ -379,6 +369,36 @@ async function extractArchive(
}
}
async function extractTar(archivePath: string, destDir: string): Promise<void> {
await tarExtract({
file: archivePath,
cwd: destDir,
strip: 0,
filter: (entryPath: string) => {
if (path.isAbsolute(entryPath) || entryPath.includes("..")) {
console.warn(
`[cloakbrowser] Skipping suspicious archive entry: ${entryPath}`
);
return false;
}
return true;
},
});
}
async function extractZip(archivePath: string, destDir: string): Promise<void> {
const { execFileSync } = await import("node:child_process");
// Use system unzip — available on Windows (PowerShell), macOS, and Linux
if (process.platform === "win32") {
execFileSync("powershell", [
"-NoProfile", "-Command",
`Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`,
], { timeout: 120_000 });
} else {
execFileSync("unzip", ["-o", archivePath, "-d", destDir], { timeout: 120_000 });
}
}
/**
* If extraction created a single subdirectory, move its contents up.
* Many tarballs wrap files in a top-level directory.
@@ -452,7 +472,7 @@ export async function getLatestChromiumVersion(): Promise<string | null> {
draft: boolean;
assets: Array<{ name: string }>;
}>;
const platformTarball = `cloakbrowser-${getPlatformTag()}.tar.gz`;
const platformTarball = getArchiveName();
for (const release of releases) {
if (release.tag_name.startsWith("chromium-v") && !release.draft) {
const assetNames = new Set(