fix(startup): allow case-insensitive renderer paths on Windows

Normalizes local renderer file URLs to filesystem paths before comparison so Windows path casing cannot block the packaged application during initial navigation. Adds a regression test covering case-insensitive packaged renderer URLs and records the v2.0.27 release notes.
This commit is contained in:
Sucukdeluxe
2026-08-12 21:31:08 +02:00
parent 12179af243
commit d58c3a262f
5 changed files with 33 additions and 4 deletions
+7
View File
@@ -2,6 +2,13 @@
All notable changes to Multi-Debrid Downloader are documented in this file. All notable changes to Multi-Debrid Downloader are documented in this file.
## [2.0.27] - 2026-08-12
### Startup reliability
- Fixed Windows renderer startup validation so the packaged application accepts its own local renderer path regardless of path casing.
- Prevented the startup navigation guard from blocking the application window on case-insensitive Windows file systems.
## [2.0.26] - 2026-08-12 ## [2.0.26] - 2026-08-12
### Log storage ### Log storage
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "2.0.26", "version": "2.0.27",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "2.0.26", "version": "2.0.27",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"adm-zip": "0.6.0", "adm-zip": "0.6.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "2.0.26", "version": "2.0.27",
"description": "Desktop downloader", "description": "Desktop downloader",
"main": "build/main/main/main.js", "main": "build/main/main/main.js",
"author": "Sucukdeluxe", "author": "Sucukdeluxe",
+10 -1
View File
@@ -1,3 +1,5 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { shell, type WebPreferences } from "electron"; import { shell, type WebPreferences } from "electron";
export type HttpsHostRule = { export type HttpsHostRule = {
@@ -144,7 +146,14 @@ function isExpectedRendererUrl(rawUrl: string, expectedUrl: string): boolean {
const parsed = new URL(String(rawUrl || "")); const parsed = new URL(String(rawUrl || ""));
const expected = new URL(String(expectedUrl || "")); const expected = new URL(String(expectedUrl || ""));
if (expected.protocol === "file:") { if (expected.protocol === "file:") {
return parsed.protocol === "file:" && parsed.host === expected.host && parsed.pathname === expected.pathname; if (parsed.protocol !== "file:") {
return false;
}
const actualPath = path.resolve(fileURLToPath(parsed));
const expectedPath = path.resolve(fileURLToPath(expected));
return process.platform === "win32"
? actualPath.toLowerCase() === expectedPath.toLowerCase()
: actualPath === expectedPath;
} }
return parsed.origin === expected.origin; return parsed.origin === expected.origin;
} catch { } catch {
+13
View File
@@ -157,6 +157,19 @@ describe("browser-security", () => {
expect(attacker.preventDefault).toHaveBeenCalledTimes(1); expect(attacker.preventDefault).toHaveBeenCalledTimes(1);
}); });
it("allows the packaged renderer file despite Windows path casing differences", () => {
const harness = createWindow();
const rendererUrl = "file:///C:/Program%20Files/MDD/resources/app.asar/build/renderer/index.html";
applyMainWindowSecurity(harness.window, {
rendererUrl,
externalHosts: githubOnly
});
const renderer = harness.navigate("file:///c:/program%20files/mdd/resources/app.asar/build/renderer/index.html");
expect(renderer.preventDefault).not.toHaveBeenCalled();
});
it("denies popups while allowing exact allowlisted HTTPS popup URLs through the shell", () => { it("denies popups while allowing exact allowlisted HTTPS popup URLs through the shell", () => {
const harness = createWindow(); const harness = createWindow();
applyMainWindowSecurity(harness.window, { applyMainWindowSecurity(harness.window, {