Fix: Undo Path Validation for coming back on a classic one

This commit is contained in:
MasterAcnolo
2026-02-18 14:43:40 +01:00
parent 32c9a66a35
commit 74fcdbb738
4 changed files with 32 additions and 47 deletions

24
main.js
View File

@@ -143,23 +143,23 @@ function validateDownloadPath(userPath) {
// IPC
ipcMain.handle("select-download-folder", async () => {
try {
const result = await dialog.showOpenDialog({ properties: ["openDirectory"] });
if (result.canceled) {
logger.info("Folder selection cancelled by user");
return null;
}
if (result.filePaths.length > 0) {
const selectedPath = result.filePaths[0];
const result = await dialog.showOpenDialog({ properties: ["openDirectory"] });
if (result.canceled) {
logger.info("Folder selection cancelled by user");
return null;
}
if (result.filePaths.length > 0) {
const selectedPath = result.filePaths[0];
try {
const validatedPath = validateDownloadPath(selectedPath);
logger.info(`Folder selected and validated: ${validatedPath}`);
return validatedPath;
} catch (err) {
logger.warn(`Unsafe or invalid folder rejected: ${err.message}`);
throw err; // Propagate error to UI
}
return null;
} catch (err) {
logger.warn(`Unsafe or invalid folder rejected: ${err.message}`);
return null;
}
return null;
});
ipcMain.handle("validate-download-path", (event, userPath) => {

View File

@@ -53,7 +53,7 @@ window.addEventListener("DOMContentLoaded", async () => {
await applyPathFromBack(validatedPath);
} catch (err) {
alert("Folder not allowed.");
alert("This folder is not allowed. Only specific folders (Users, Downloads, Documents) are authorized for downloads.");
}
});
});

View File

@@ -12,35 +12,10 @@ function isValidUrl(url) {
}
function isSafePath(folder) {
if (!folder || typeof folder !== "string") return false;
try {
// Normalize path and resolve symlinks
const resolved = path.resolve(folder).toLowerCase().replace(/\//g, "\\");
// Block Windows system directories (on any drive)
const unsafePaths = [
"\\windows\\",
"\\system32\\",
"\\program files\\",
"\\program files (x86)\\",
"\\programdata\\",
"\\$recycle.bin\\",
"\\system volume information\\"
];
// Check if path contains any unsafe directory
if (unsafePaths.some(unsafe => resolved.includes(unsafe))) {
return false;
}
// Allow all drives (C:, D:, E:, etc.) but block system folders
return true;
} catch (err) {
// In case of path resolution error
return false;
}
if (!folder || folder.length < 3) return false;
const unsafe = ["System32", "\\Windows"];
const resolved = path.resolve(folder);
return !unsafe.some(u => resolved.includes(u));
}
module.exports = { isValidUrl, isSafePath };

View File

@@ -3,23 +3,33 @@ const { userYtDlp, defaultDownloadFolder } = require("../helpers/path");
const fs = require("fs");
const { logger } = require("../logger");
const { buildYtDlpArgs } = require("../helpers/buildArgs");
const notify = require("../helpers/notify")
const notify = require("../helpers/notify");
const path = require("path");
const { isSafePath } = require("../helpers/validation");
function fetchDownload(options, listeners, speedListeners) {
return new Promise((resolve, reject) => {
const outputFolder = options.outputFolder || defaultDownloadFolder;
// Normalize path and validate it's safe (within Users folder)
let safeOutputFolder = path.resolve(outputFolder);
if (!isSafePath(safeOutputFolder)) {
logger.warn(`Path not allowed, using default instead: ${safeOutputFolder}`);
safeOutputFolder = path.resolve(defaultDownloadFolder);
}
// Create download folder if it doesn't exist
try {
fs.mkdirSync(outputFolder, { recursive: true });
logger.info(`Output folder ready: ${outputFolder}`);
fs.mkdirSync(safeOutputFolder, { recursive: true });
logger.info(`Output folder ready: ${safeOutputFolder}`);
} catch (err) {
logger.error(`Failed to create output folder: ${err.message}`);
return reject(new Error(`Unable to create download folder: ${err.message}`));
}
const args = buildYtDlpArgs({ ...options, outputFolder });
const args = buildYtDlpArgs({ ...options, outputFolder: safeOutputFolder });
logger.info(`[yt-dlp args] ${args.join(" ")}`);
const child = execFile(userYtDlp, args);
@@ -28,7 +38,7 @@ function fetchDownload(options, listeners, speedListeners) {
child.on("close", code => {
listeners.forEach(fn => fn("done"));
if (code === 0) resolve(outputFolder);
if (code === 0) resolve(safeOutputFolder);
else reject(new Error(`YT-DLP failed with code : ${code}`));
});