Skip to content

Commit 9f09833

Browse files
feat: add output folder button + security hardening
Output Folder Button: - Add open_output_dir Tauri command using opener crate - Add bottom-bar button visible on both tabs (HTML/CSS/JS) - Add shell:allow-open permission Security Fixes: - Enable restrictive Content Security Policy (was null) - Fix XSS in seed list and settings form via DOM API (no innerHTML) - Fix path traversal in remove_seed_file and add_seed_file - Add backend config validation (SSRF/DoS prevention) - Fix URL injection in worker.rs via url crate + query_pairs_mut - Fix race condition in start_processing (atomic check+set) - Handle mutex poisoning gracefully - Remove filepath leakage to frontend (skip_serializing) - Harden capabilities (remove shell:default) - Sanitize error messages of full filesystem paths - Fix max_workers default from 1000 to 50 - Add number input types for numeric settings Also: - Sync tauri Rust crate to v2.11.0 to match JS package - Update Cargo.lock dependencies
1 parent d39613a commit 9f09833

17 files changed

Lines changed: 356 additions & 74 deletions

config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ institucionReceptora = "INSTITUTO MEXICANO DEL SEGURO SOCIAL"
3030

3131
[processing]
3232
batch_size = 100
33-
max_workers = 1000
33+
max_workers = 50
3434

3535
[output]
3636
dir = "output"

docs/superpowers/plans/2026-05-02-output-folder-button.md

Whitespace-only changes.

src-tauri/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ version = "2.0.1"
44
edition = "2021"
55

66
[dependencies]
7-
tauri = { version = "2", features = [] }
7+
tauri = { version = "2.11", features = [] }
88
tauri-plugin-dialog = "2"
99
tauri-plugin-shell = "2"
1010
serde = { version = "1", features = ["derive"] }
1111
serde_json = "1"
1212
toml = "0.8"
13+
url = "2"
1314
reqwest = { version = "0.12", features = ["json"] }
1415
tokio = { version = "1", features = ["full"] }
1516
rusqlite = { version = "0.31", features = ["bundled"] }
@@ -18,6 +19,7 @@ rust_xlsxwriter = "0.79"
1819
sha2 = "0.10"
1920
rand = "0.8"
2021
log = "0.4"
22+
opener = "0.7"
2123
env_logger = "0.11"
2224
sysinfo = "0.33"
2325
chrono = "0.4"

src-tauri/capabilities/default.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
"permissions": [
66
"core:default",
77
"dialog:default",
8-
"shell:default"
8+
"shell:allow-open"
99
]
1010
}

src-tauri/gen/schemas/acl-manifests.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"default":{"identifier":"default","description":"Default capabilities for the main window","local":true,"windows":["main"],"permissions":["core:default","dialog:default","shell:default"]}}
1+
{"default":{"identifier":"default","description":"Default capabilities for the main window","local":true,"windows":["main"],"permissions":["core:default","dialog:default","shell:allow-open"]}}

src-tauri/gen/schemas/desktop-schema.json

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,10 @@
393393
"markdownDescription": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`"
394394
},
395395
{
396-
"description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`",
396+
"description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`",
397397
"type": "string",
398398
"const": "core:app:default",
399-
"markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`"
399+
"markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`"
400400
},
401401
{
402402
"description": "Enables the app_hide command without any pre-configured scope.",
@@ -470,6 +470,12 @@
470470
"const": "core:app:allow-set-dock-visibility",
471471
"markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope."
472472
},
473+
{
474+
"description": "Enables the supports_multiple_windows command without any pre-configured scope.",
475+
"type": "string",
476+
"const": "core:app:allow-supports-multiple-windows",
477+
"markdownDescription": "Enables the supports_multiple_windows command without any pre-configured scope."
478+
},
473479
{
474480
"description": "Enables the tauri_version command without any pre-configured scope.",
475481
"type": "string",
@@ -554,6 +560,12 @@
554560
"const": "core:app:deny-set-dock-visibility",
555561
"markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope."
556562
},
563+
{
564+
"description": "Denies the supports_multiple_windows command without any pre-configured scope.",
565+
"type": "string",
566+
"const": "core:app:deny-supports-multiple-windows",
567+
"markdownDescription": "Denies the supports_multiple_windows command without any pre-configured scope."
568+
},
557569
{
558570
"description": "Denies the tauri_version command without any pre-configured scope.",
559571
"type": "string",
@@ -1077,10 +1089,10 @@
10771089
"markdownDescription": "Denies the close command without any pre-configured scope."
10781090
},
10791091
{
1080-
"description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`",
1092+
"description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`",
10811093
"type": "string",
10821094
"const": "core:tray:default",
1083-
"markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`"
1095+
"markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`"
10841096
},
10851097
{
10861098
"description": "Enables the get_by_id command without any pre-configured scope.",
@@ -1112,6 +1124,12 @@
11121124
"const": "core:tray:allow-set-icon-as-template",
11131125
"markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope."
11141126
},
1127+
{
1128+
"description": "Enables the set_icon_with_as_template command without any pre-configured scope.",
1129+
"type": "string",
1130+
"const": "core:tray:allow-set-icon-with-as-template",
1131+
"markdownDescription": "Enables the set_icon_with_as_template command without any pre-configured scope."
1132+
},
11151133
{
11161134
"description": "Enables the set_menu command without any pre-configured scope.",
11171135
"type": "string",
@@ -1178,6 +1196,12 @@
11781196
"const": "core:tray:deny-set-icon-as-template",
11791197
"markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope."
11801198
},
1199+
{
1200+
"description": "Denies the set_icon_with_as_template command without any pre-configured scope.",
1201+
"type": "string",
1202+
"const": "core:tray:deny-set-icon-with-as-template",
1203+
"markdownDescription": "Denies the set_icon_with_as_template command without any pre-configured scope."
1204+
},
11811205
{
11821206
"description": "Denies the set_menu command without any pre-configured scope.",
11831207
"type": "string",
@@ -1437,10 +1461,16 @@
14371461
"markdownDescription": "Denies the webview_size command without any pre-configured scope."
14381462
},
14391463
{
1440-
"description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`",
1464+
"description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`",
14411465
"type": "string",
14421466
"const": "core:window:default",
1443-
"markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`"
1467+
"markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`"
1468+
},
1469+
{
1470+
"description": "Enables the activity_name command without any pre-configured scope.",
1471+
"type": "string",
1472+
"const": "core:window:allow-activity-name",
1473+
"markdownDescription": "Enables the activity_name command without any pre-configured scope."
14441474
},
14451475
{
14461476
"description": "Enables the available_monitors command without any pre-configured scope.",
@@ -1634,6 +1664,12 @@
16341664
"const": "core:window:allow-scale-factor",
16351665
"markdownDescription": "Enables the scale_factor command without any pre-configured scope."
16361666
},
1667+
{
1668+
"description": "Enables the scene_identifier command without any pre-configured scope.",
1669+
"type": "string",
1670+
"const": "core:window:allow-scene-identifier",
1671+
"markdownDescription": "Enables the scene_identifier command without any pre-configured scope."
1672+
},
16371673
{
16381674
"description": "Enables the set_always_on_bottom command without any pre-configured scope.",
16391675
"type": "string",
@@ -1898,6 +1934,12 @@
18981934
"const": "core:window:allow-unminimize",
18991935
"markdownDescription": "Enables the unminimize command without any pre-configured scope."
19001936
},
1937+
{
1938+
"description": "Denies the activity_name command without any pre-configured scope.",
1939+
"type": "string",
1940+
"const": "core:window:deny-activity-name",
1941+
"markdownDescription": "Denies the activity_name command without any pre-configured scope."
1942+
},
19011943
{
19021944
"description": "Denies the available_monitors command without any pre-configured scope.",
19031945
"type": "string",
@@ -2090,6 +2132,12 @@
20902132
"const": "core:window:deny-scale-factor",
20912133
"markdownDescription": "Denies the scale_factor command without any pre-configured scope."
20922134
},
2135+
{
2136+
"description": "Denies the scene_identifier command without any pre-configured scope.",
2137+
"type": "string",
2138+
"const": "core:window:deny-scene-identifier",
2139+
"markdownDescription": "Denies the scene_identifier command without any pre-configured scope."
2140+
},
20932141
{
20942142
"description": "Denies the set_always_on_bottom command without any pre-configured scope.",
20952143
"type": "string",

0 commit comments

Comments
 (0)