Published source
Download source ZIP
CH-J Server Manager
Browse directories and files for a specific application release.
Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.
1
"use strict";3
const fs = require("node:fs");4
const path = require("node:path");6
function resolvedCacheRoot(rootDir) {7
const raw = String(rootDir || "").trim();8
if (!raw) throw new Error("Download cache root is required.");9
const resolved = path.resolve(raw);10
if (resolved === path.parse(resolved).root) throw new Error("Refusing to use a filesystem root as a download cache.");11
return resolved;12
}14
function cleanDownloadCache(rootDir) {15
const root = resolvedCacheRoot(rootDir);16
const existed = fs.existsSync(root);17
fs.rmSync(root, { recursive: true, force: true });18
fs.mkdirSync(root, { recursive: true, mode: 0o700 });19
return { cleaned: existed, root };20
}22
function removeCachedFile(rootDir, filePath) {23
const root = resolvedCacheRoot(rootDir);24
const target = path.resolve(String(filePath || ""));25
const relative = path.relative(root, target);26
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {27
throw new Error("Downloaded package path is outside its cache.");28
}29
if (!fs.existsSync(target)) return { removed: false, path: target };30
if (!fs.lstatSync(target).isFile()) throw new Error("Downloaded package is not a regular file.");31
const realRoot = fs.realpathSync(root);32
const realTarget = fs.realpathSync(target);33
const realRelative = path.relative(realRoot, realTarget);34
if (!realRelative || realRelative.startsWith("..") || path.isAbsolute(realRelative)) {35
throw new Error("Downloaded package resolves outside its cache.");36
}37
fs.unlinkSync(target);39
let current = path.dirname(target);40
while (current !== root) {41
try { fs.rmdirSync(current); }42
catch (error) {43
if (error?.code === "ENOTEMPTY" || error?.code === "EEXIST" || error?.code === "ENOENT") break;44
throw error;45
}46
current = path.dirname(current);47
}48
return { removed: true, path: target };49
}51
module.exports = { cleanDownloadCache, removeCachedFile, resolvedCacheRoot };SHA-256: a8d7b86d725cd6d52e5937995e869b1cedadde09458c52442b2eb91009aaccb8
Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0