diff --git a/app/src/main/java/com/droiddeck/launcher/session/SteamSessionUrl.kt b/app/src/main/java/com/droiddeck/launcher/session/SteamSessionUrl.kt index b5ef3f721..e380a6408 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SteamSessionUrl.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SteamSessionUrl.kt @@ -1,7 +1,7 @@ package com.droiddeck.launcher.session object SteamSessionUrl { - private val allowed = Regex("steam://(?:open/downloads|nav/library|uninstall/[1-9][0-9]{0,9})") + private val allowed = Regex("steam://(?:open/downloads|uninstall/[1-9][0-9]{0,9})") fun isSupported(url: String): Boolean = allowed.matches(url) diff --git a/app/src/main/java/com/droiddeck/launcher/ui/StoreMaintenanceUi.kt b/app/src/main/java/com/droiddeck/launcher/ui/StoreMaintenanceUi.kt index ccb868663..1666f8186 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/StoreMaintenanceUi.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/StoreMaintenanceUi.kt @@ -40,7 +40,6 @@ internal fun SteamClientMaintenanceActions(actions: FrontEndActions) { Column(verticalArrangement = Arrangement.spacedBy(6.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { SecondaryButton("Open Steam downloads") { actions.onSteamUrl("steam://open/downloads") } - SecondaryButton("Open Steam library") { actions.onSteamUrl("steam://nav/library") } } Text("In Steam, open this game’s Properties → Installed Files → Verify integrity.", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant) diff --git a/app/src/test/java/com/droiddeck/launcher/session/SteamSessionUrlTest.kt b/app/src/test/java/com/droiddeck/launcher/session/SteamSessionUrlTest.kt index 275964bfe..47ccaf922 100644 --- a/app/src/test/java/com/droiddeck/launcher/session/SteamSessionUrlTest.kt +++ b/app/src/test/java/com/droiddeck/launcher/session/SteamSessionUrlTest.kt @@ -7,9 +7,9 @@ import org.junit.Test class SteamSessionUrlTest { @Test fun onlySupportedSteamNavigationRoutesAreAccepted() { - listOf("steam://open/downloads", "steam://nav/library", "steam://uninstall/12345") + listOf("steam://open/downloads", "steam://uninstall/12345") .forEach { assertTrue(it, SteamSessionUrl.isSupported(it)) } - listOf("steam://open/settings", "steam://uninstall/0", "steam://uninstall/01", + listOf("steam://open/settings", "steam://nav/library", "steam://uninstall/0", "steam://uninstall/01", "steam://open/downloads\n--exec", "https://example.com") .forEach { assertFalse(it, SteamSessionUrl.isSupported(it)) } } diff --git a/docs/development/store-maintenance.md b/docs/development/store-maintenance.md index 57e46ccc7..e33828f24 100644 --- a/docs/development/store-maintenance.md +++ b/docs/development/store-maintenance.md @@ -28,7 +28,7 @@ its existing engine or client can perform. and space amounts are client-determined. Metadata checks do not claim success when package identity or version information is missing. References: [Xodus](https://github.com/xodus-gaming/xodus), [Nexus](https://github.com/domsvoboda/xodus-nexus), and the [pinned package-update query](https://github.com/domsvoboda/xodus-nexus/blob/396e7fb8fe0e5f00d956091195c614b8a0732ab1/assets/xodus-store-updates.patch). -- **Steam:** navigation to Steam downloads/library and guidance to use the +- **Steam:** navigation to Steam downloads and guidance to use the game's Properties → Installed Files → Verify integrity. The app does not run Steam validation itself. Native Steam apps are distinguished from third-party shortcuts. See [Valve's game-file validation instructions](https://help.steampowered.com/en/faqs/view/0C48-FCBD-DA71-93EB). diff --git a/tools/linuxfs/overlay/usr/local/bin/droiddeck-agent b/tools/linuxfs/overlay/usr/local/bin/droiddeck-agent index d6e689908..87e660a6e 100755 --- a/tools/linuxfs/overlay/usr/local/bin/droiddeck-agent +++ b/tools/linuxfs/overlay/usr/local/bin/droiddeck-agent @@ -1053,7 +1053,7 @@ def handle(agent_dir, req): if kind == "steam-url": url = req.get("url") if not isinstance(url, str) or not re.fullmatch( - r"steam://(?:open/downloads|nav/library|uninstall/[1-9][0-9]{0,9})", url): + r"steam://(?:open/downloads|uninstall/[1-9][0-9]{0,9})", url): raise AgentError("INVALID_REQUEST", "Steam navigation URL is not supported") try: subprocess.Popen(["steam", url], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, diff --git a/tools/tests/test_droiddeck_agent.py b/tools/tests/test_droiddeck_agent.py index 3bdff3159..9865c00b4 100644 --- a/tools/tests/test_droiddeck_agent.py +++ b/tools/tests/test_droiddeck_agent.py @@ -205,7 +205,7 @@ class AgentTest(unittest.TestCase): self.assertTrue(popen.call_args.kwargs["start_new_session"]) def test_steam_url_rejects_untrusted_routes_and_argument_injection(self): - for url in ("steam://open/settings", "steam://open/downloads\n--exec", "https://example.com"): + for url in ("steam://open/settings", "steam://nav/library", "steam://open/downloads\n--exec", "https://example.com"): with self.subTest(url=url), patch.object(agent.subprocess, "Popen") as popen: answer = self.ask({"kind": "steam-url", "url": url}) self.assertFalse(answer["ok"])