From fbed5b7d028ecea6e444270ef44c0d6d4b213e65 Mon Sep 17 00:00:00 2001 From: PathGao Date: Mon, 3 Aug 2026 06:54:21 +0800 Subject: [PATCH] fix(capabilities): give open_path a scope so it can actually run `opener:allow-open-path` grants the command but carries no scope, and `allow-default-urls` - which has no commands, so its scope lands in the plugin's global scope and applies to every opener command - contains only URL entries. In tauri-plugin-opener, `Entry::Url::matches_path_program` returns false unconditionally, and the fs allow-list is empty, so `is_path_allowed` is false on both conjuncts. Every `open_path` call returns ForbiddenPath. The one place that calls it today is the "Open exported HTML file now?" prompt, whose Yes button has therefore never worked; it reports the failure as a toast rather than doing nothing, which is likely why it read as an ordinary error. `**` matches the width the app already has: `assetProtocol.scope` is `["**"]`, and the file commands take arbitrary paths from the frontend with no scope check, so read and write access to the filesystem is already unrestricted. The genuine increment is that `open_path` hands a path to the OS default handler, which for an executable means launching it - and that matters at the call site that takes untrusted input, not in the ACL. Co-Authored-By: Claude Opus 5 --- src-tauri/capabilities/default.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index c41704e0..f347af6c 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -11,7 +11,10 @@ "core:default", "opener:default", "opener:allow-open-url", - "opener:allow-open-path", + { + "identifier": "opener:allow-open-path", + "allow": [{ "path": "**" }] + }, "dialog:default", "core:webview:allow-print", "core:window:allow-start-dragging",