diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b43e33..6a5f2b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ 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 ### Log storage diff --git a/package-lock.json b/package-lock.json index 3e44f53..20f1fa4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "real-debrid-downloader", - "version": "2.0.26", + "version": "2.0.27", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "real-debrid-downloader", - "version": "2.0.26", + "version": "2.0.27", "license": "MIT", "dependencies": { "adm-zip": "0.6.0", diff --git a/package.json b/package.json index 5d06119..009cf84 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "real-debrid-downloader", - "version": "2.0.26", + "version": "2.0.27", "description": "Desktop downloader", "main": "build/main/main/main.js", "author": "Sucukdeluxe", diff --git a/src/main/browser-security.ts b/src/main/browser-security.ts index c3241e7..be7ac8a 100644 --- a/src/main/browser-security.ts +++ b/src/main/browser-security.ts @@ -1,3 +1,5 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { shell, type WebPreferences } from "electron"; export type HttpsHostRule = { @@ -144,7 +146,14 @@ function isExpectedRendererUrl(rawUrl: string, expectedUrl: string): boolean { const parsed = new URL(String(rawUrl || "")); const expected = new URL(String(expectedUrl || "")); 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; } catch { diff --git a/tests/browser-security.test.ts b/tests/browser-security.test.ts index ad8f8c3..b3637c8 100644 --- a/tests/browser-security.test.ts +++ b/tests/browser-security.test.ts @@ -157,6 +157,19 @@ describe("browser-security", () => { 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", () => { const harness = createWindow(); applyMainWindowSecurity(harness.window, {