Skip to main content

max / goingson

Make the Android build work, and give it a trust store The android tree was a husk: initialized once on mbp at 0.3.0, ignored wholesale, and missing its manifest and gradle files by the time anything looked again. It is regenerated at 0.5.0 and now tracked, because it stopped being purely generated the moment MainActivity called into our own code. The build failed in lettre, and the cause was worth more than the fix. lettre gates its Verifier::new_with_extra_roots call on the cargo feature alone, but rustls-platform-verifier only defines that constructor for apple, windows and others -- never android, where the verifier reaches the system store over JNI and extra roots have nowhere to go. So SMTP takes webpki-roots on android and the platform verifier everywhere else. HTTP and IMAP still honour CAs installed on the device; SMTP does not, which will look like a self-hosted server that fetches but refuses to send. Pulling that thread found two verifiers in the graph. The workspace asked for 0.6 while reqwest and lettre both pulled 0.7, and each version carries its own process-global init state, so one of them was always going to go uninitialized. Unified on 0.7, which is what the "one rustls stack" comment above it had been claiming all along. That crate needs the JVM handed to it before the first handshake and expects it rather than falling back, so an uninitialized verifier is not a degraded trust path, it is a panic on first network use. MainActivity now passes the application context to android_tls.rs before super.onCreate(), since Tauri starts the app inside that call and sync can beat it to the network. The Kotlin half ships inside the rustls-platform-verifier-android crate rather than on Maven Central, so gradle asks cargo where it landed and the version follows Cargo.lock. Verified: the JNI symbol is exported from the .so and CertificateVerifier is in the merged dex, so neither half was silently dropped.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-17 02:48 UTC
Signed with PGP, not checked
Commit: 568361b1240e1d70283caa0e0dc059540cd168b6
Parent: 7489762
48 files changed, +1416 insertions, -62 deletions
M .gitignore +23 -3
@@ -32,9 +32,29 @@
32 32 # Tauri iOS generated asset symlinks (encode ../ as _up_)
33 33 src-tauri/gen/apple/assets/_up_/
34 34
35 - # Tauri Android project — regenerated by `cargo tauri android init`. Android is not a
36 - # bento target; the tree is re-initialized if/when android work resumes.
37 - src-tauri/gen/android/
35 + # Tauri Android project. This used to be ignored wholesale, on the reasoning that
36 + # android was not a bento target and the tree could just be re-initialized when the
37 + # work resumed. It resumed (2026-08-16), and the reasoning did not survive it: the
38 + # tree is no longer purely generated. MainActivity.kt calls into src/android_tls.rs
39 + # and app/build.gradle.kts locates the rustls-platform-verifier aar, and neither
40 + # edit is reproducible by `cargo tauri android init`. Losing them does not fail the
41 + # build, it ships an app that cannot complete a TLS handshake. So the source is
42 + # tracked and only the generated output below is not.
43 + src-tauri/gen/android/.gradle/
44 + src-tauri/gen/android/build/
45 + src-tauri/gen/android/app/build/
46 + src-tauri/gen/android/buildSrc/build/
47 + src-tauri/gen/android/buildSrc/.gradle/
48 + src-tauri/gen/android/.cxx/
49 + src-tauri/gen/android/local.properties
50 + # Built by the rust gradle plugin from target/<triple>/, not by hand.
51 + src-tauri/gen/android/app/src/main/jniLibs/
52 + # Copied in at build time from src-tauri/themes/, which build.rs generates out of
53 + # makeover and which is itself ignored above. Same file, one copy further along.
54 + src-tauri/gen/android/app/src/main/assets/themes/
55 + # Signing. Holds the upload keystore's passwords in plaintext and must never be
56 + # committed; the keystore it names is not in this repo either.
57 + src-tauri/gen/android/key.properties
38 58
39 59 # Claude Code instructions (project-local; not for the public repo)
40 60 CLAUDE.md
M Cargo.lock +14 -24
@@ -2227,6 +2227,7 @@
2227 2227 "hex",
2228 2228 "ical",
2229 2229 "icalendar",
2230 + "jni 0.22.4",
2230 2231 "keyring",
2231 2232 "lettre",
2232 2233 "libsqlite3-sys",
@@ -2250,7 +2251,7 @@
2250 2251 "rfd",
2251 2252 "rusqlite",
2252 2253 "rustls",
2253 - "rustls-platform-verifier 0.6.2",
2254 + "rustls-platform-verifier",
2254 2255 "serde",
2255 2256 "serde_json",
2256 2257 "sha2 0.11.0",
@@ -3217,11 +3218,12 @@
3217 3218 "percent-encoding",
3218 3219 "quoted_printable",
3219 3220 "rustls",
3220 - "rustls-platform-verifier 0.7.0",
3221 + "rustls-platform-verifier",
3221 3222 "socket2",
3222 3223 "tokio",
3223 3224 "tokio-rustls",
3224 3225 "url",
3226 + "webpki-roots",
3225 3227 ]
3226 3228
3227 3229 [[package]]
@@ -4999,7 +5001,7 @@
4999 5001 "pin-project-lite",
5000 5002 "rustls",
5001 5003 "rustls-pki-types",
5002 - "rustls-platform-verifier 0.7.0",
5004 + "rustls-platform-verifier",
5003 5005 "serde",
5004 5006 "serde_json",
5005 5007 "serde_urlencoded",
@@ -5144,27 +5146,6 @@
5144 5146 "zeroize",
5145 5147 ]
5146 5148
5147 - [[package]]
5148 - name = "rustls-platform-verifier"
5149 - version = "0.6.2"
5150 - source = "registry+https://github.com/rust-lang/crates.io-index"
5151 - checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
5152 - dependencies = [
5153 - "core-foundation 0.10.1",
5154 - "core-foundation-sys",
5155 - "jni 0.21.1",
5156 - "log",
5157 - "once_cell",
5158 - "rustls",
5159 - "rustls-native-certs",
5160 - "rustls-platform-verifier-android",
5161 - "rustls-webpki",
5162 - "security-framework",
5163 - "security-framework-sys",
5164 - "webpki-root-certs",
5165 - "windows-sys 0.61.2",
5166 - ]
5167 -
5168 5149 [[package]]
5169 5150 name = "rustls-platform-verifier"
5170 5151 version = "0.7.0"
@@ -7418,6 +7399,15 @@
7418 7399 "rustls-pki-types",
7419 7400 ]
7420 7401
7402 + [[package]]
7403 + name = "webpki-roots"
7404 + version = "1.0.9"
7405 + source = "registry+https://github.com/rust-lang/crates.io-index"
7406 + checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
7407 + dependencies = [
7408 + "rustls-pki-types",
7409 + ]
7410 +
7421 7411 [[package]]
7422 7412 name = "webview2-com"
7423 7413 version = "0.38.2"
M Cargo.toml +12 -2
@@ -46,15 +46,25 @@
46 46 tokio-util = "0.7"
47 47 futures-util = { version = "0.3", default-features = false, features = ["std", "async-await"] }
48 48 mailparse = "0.16"
49 - lettre = { version = "0.11", default-features = false, features = ["tokio1", "tokio1-rustls", "rustls-platform-verifier", "ring", "smtp-transport", "builder"] }
49 + # The trust-source feature is deliberately absent here and set per-target in
50 + # src-tauri/Cargo.toml instead: lettre cannot be built against
51 + # rustls-platform-verifier on Android. See the TLS note below.
52 + lettre = { version = "0.11", default-features = false, features = ["tokio1", "tokio1-rustls", "ring", "smtp-transport", "builder"] }
50 53
51 54 # TLS: one rustls stack across HTTP (reqwest), SMTP (lettre) and IMAP, all validating
52 55 # against the OS-native trust store via rustls-platform-verifier, with a single ring
53 56 # crypto provider installed at startup. Matches the trust source tauri-plugin-updater
54 57 # already uses, so the binary carries one TLS stack instead of native-tls + rustls.
58 + #
59 + # 0.7, not 0.6, and the version matters more than a routine bump would. reqwest's
60 + # `rustls-no-provider` and lettre both pull 0.7, so pinning 0.6 here put *two*
61 + # verifiers in the graph, each with its own process-global init state. One of them
62 + # would have gone uninitialized on Android and failed every handshake it owned.
63 + # Keep this equal to whatever reqwest resolves, and check `cargo tree -d` after a
64 + # reqwest or lettre bump rather than assuming.
55 65 rustls = { version = "0.23", default-features = false, features = ["std", "tls12", "logging", "ring"] }
56 66 tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
57 - rustls-platform-verifier = "0.6"
67 + rustls-platform-verifier = "0.7"
58 68
59 69 # HTTP client
60 70 reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-no-provider", "form", "multipart"] }
@@ -83,7 +83,8 @@
83 83 tokio-util = { workspace = true }
84 84 futures-util = { workspace = true }
85 85 mailparse = { workspace = true }
86 - lettre = { workspace = true }
86 + # lettre's trust source is target-gated further down: the platform verifier
87 + # everywhere it compiles, webpki-roots on Android where it does not.
87 88
88 89 # TLS (rustls stack; ring provider installed at startup)
89 90 rustls = { workspace = true }
@@ -160,9 +161,36 @@
160 161 tauri-plugin-haptics = { workspace = true }
161 162 tauri-plugin-biometric = { workspace = true }
162 163
164 + # SMTP trust source, everywhere lettre can express it: the OS-native store, the
165 + # same one reqwest and IMAP use.
166 + [target.'cfg(not(target_os = "android"))'.dependencies]
167 + lettre = { workspace = true, features = ["rustls-platform-verifier"] }
168 +
163 169 # Android: bundle SQLite (system SQLite not accessible via NDK)
164 170 [target.'cfg(target_os = "android")'.dependencies]
165 171 libsqlite3-sys = { version = "0.38", features = ["bundled"] }
172 + # For src/android_tls.rs only. Track rustls-platform-verifier's jni version, not
173 + # wry's: the handles are passed straight into that crate, so the types have to be
174 + # the ones it compiled against. wry and tauri sit on jni 0.21 and both versions
175 + # coexist in the graph deliberately -- see the module header before "fixing" it.
176 + jni = "0.22"
177 +
178 + # SMTP on Android falls back to the bundled Mozilla root set, and this is a
179 + # workaround rather than a preference. lettre gates its
180 + # `Verifier::new_with_extra_roots` call on the cargo feature alone
181 + # (transport/smtp/client/tls.rs), but rustls-platform-verifier only defines that
182 + # constructor for apple, windows and `others` -- never android, where the verifier
183 + # reaches the system store over JNI and extra roots have nowhere to go. So the
184 + # feature does not merely misbehave on Android, it fails to compile.
185 + #
186 + # Consequence worth knowing before debugging a report: HTTP and IMAP honour CAs the
187 + # user or their employer installed on the device, and SMTP does not. A self-hosted
188 + # mail server behind a private CA will therefore fetch but refuse to send, on
189 + # Android only. Drop this the moment lettre target-gates that call; nothing else
190 + # here has to change when it does.
191 + [target.'cfg(target_os = "android")'.dependencies.lettre]
192 + workspace = true
193 + features = ["webpki-roots"]
166 194
167 195 [dev-dependencies]
168 196 tempfile = "3"
@@ -22,6 +22,11 @@
22 22 pub mod state;
23 23 pub mod syncstore;
24 24
25 + // Android-only: hands the JVM to rustls-platform-verifier before the first
26 + // handshake. Called from Kotlin, so nothing in Rust references it.
27 + #[cfg(target_os = "android")]
28 + pub mod android_tls;
29 +
25 30 // Desktop-only: file watching for external DB changes
26 31 #[cfg(not(any(target_os = "ios", target_os = "android")))]
27 32 pub mod db_watcher;
@@ -176,6 +176,36 @@
176 176 "Identifier": {
177 177 "description": "Permission identifier",
178 178 "oneOf": [
179 + {
180 + "description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
181 + "type": "string",
182 + "const": "biometric:default",
183 + "markdownDescription": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
184 + },
185 + {
186 + "description": "Enables the authenticate command without any pre-configured scope.",
187 + "type": "string",
188 + "const": "biometric:allow-authenticate",
189 + "markdownDescription": "Enables the authenticate command without any pre-configured scope."
190 + },
191 + {
192 + "description": "Enables the status command without any pre-configured scope.",
193 + "type": "string",
194 + "const": "biometric:allow-status",
195 + "markdownDescription": "Enables the status command without any pre-configured scope."
196 + },
197 + {
198 + "description": "Denies the authenticate command without any pre-configured scope.",
199 + "type": "string",
200 + "const": "biometric:deny-authenticate",
201 + "markdownDescription": "Denies the authenticate command without any pre-configured scope."
202 + },
203 + {
204 + "description": "Denies the status command without any pre-configured scope.",
205 + "type": "string",
206 + "const": "biometric:deny-status",
207 + "markdownDescription": "Denies the status command without any pre-configured scope."
208 + },
179 209 {
180 210 "description": "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`",
181 211 "type": "string",
@@ -183,10 +213,10 @@
183 213 "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`"
184 214 },
185 215 {
186 - "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`",
216 + "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`",
187 217 "type": "string",
188 218 "const": "core:app:default",
189 - "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`"
219 + "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`"
190 220 },
191 221 {
192 222 "description": "Enables the app_hide command without any pre-configured scope.",
@@ -260,6 +290,12 @@
260 290 "const": "core:app:allow-set-dock-visibility",
261 291 "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope."
262 292 },
293 + {
294 + "description": "Enables the supports_multiple_windows command without any pre-configured scope.",
295 + "type": "string",
296 + "const": "core:app:allow-supports-multiple-windows",
297 + "markdownDescription": "Enables the supports_multiple_windows command without any pre-configured scope."
298 + },
263 299 {
264 300 "description": "Enables the tauri_version command without any pre-configured scope.",
265 301 "type": "string",
@@ -344,6 +380,12 @@
344 380 "const": "core:app:deny-set-dock-visibility",
345 381 "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope."
346 382 },
383 + {
384 + "description": "Denies the supports_multiple_windows command without any pre-configured scope.",
385 + "type": "string",
386 + "const": "core:app:deny-supports-multiple-windows",
387 + "markdownDescription": "Denies the supports_multiple_windows command without any pre-configured scope."
388 + },
347 389 {
348 390 "description": "Denies the tauri_version command without any pre-configured scope.",
349 391 "type": "string",
@@ -867,10 +909,10 @@
867 909 "markdownDescription": "Denies the close command without any pre-configured scope."
868 910 },
869 911 {
870 - "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`",
912 + "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`",
871 913 "type": "string",
872 914 "const": "core:tray:default",
873 - "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`"
915 + "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`"
874 916 },
875 917 {
876 918 "description": "Enables the get_by_id command without any pre-configured scope.",
@@ -902,6 +944,12 @@
902 944 "const": "core:tray:allow-set-icon-as-template",
903 945 "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope."
904 946 },
947 + {
948 + "description": "Enables the set_icon_with_as_template command without any pre-configured scope.",
949 + "type": "string",
950 + "const": "core:tray:allow-set-icon-with-as-template",
951 + "markdownDescription": "Enables the set_icon_with_as_template command without any pre-configured scope."
952 + },
905 953 {
906 954 "description": "Enables the set_menu command without any pre-configured scope.",
907 955 "type": "string",
@@ -968,6 +1016,12 @@
968 1016 "const": "core:tray:deny-set-icon-as-template",
969 1017 "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope."
970 1018 },
1019 + {
1020 + "description": "Denies the set_icon_with_as_template command without any pre-configured scope.",
1021 + "type": "string",
1022 + "const": "core:tray:deny-set-icon-with-as-template",
1023 + "markdownDescription": "Denies the set_icon_with_as_template command without any pre-configured scope."
1024 + },
971 1025 {
972 1026 "description": "Denies the set_menu command without any pre-configured scope.",
973 1027 "type": "string",
@@ -1227,10 +1281,16 @@
1227 1281 "markdownDescription": "Denies the webview_size command without any pre-configured scope."
1228 1282 },
1229 1283 {
1230 - "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`",
1284 + "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`",
1231 1285 "type": "string",
1232 1286 "const": "core:window:default",
1233 - "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`"
1287 + "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`"
1288 + },
1289 + {
1290 + "description": "Enables the activity_name command without any pre-configured scope.",
1291 + "type": "string",
1292 + "const": "core:window:allow-activity-name",
1293 + "markdownDescription": "Enables the activity_name command without any pre-configured scope."
1234 1294 },
1235 1295 {
1236 1296 "description": "Enables the available_monitors command without any pre-configured scope.",
@@ -1424,6 +1484,12 @@
1424 1484 "const": "core:window:allow-scale-factor",
1425 1485 "markdownDescription": "Enables the scale_factor command without any pre-configured scope."
1426 1486 },
1487 + {
1488 + "description": "Enables the scene_identifier command without any pre-configured scope.",
1489 + "type": "string",
1490 + "const": "core:window:allow-scene-identifier",
1491 + "markdownDescription": "Enables the scene_identifier command without any pre-configured scope."
1492 + },
1427 1493 {
1428 1494 "description": "Enables the set_always_on_bottom command without any pre-configured scope.",
1429 1495 "type": "string",
@@ -1688,6 +1754,12 @@
1688 1754 "const": "core:window:allow-unminimize",
1689 1755 "markdownDescription": "Enables the unminimize command without any pre-configured scope."
1690 1756 },
1757 + {
1758 + "description": "Denies the activity_name command without any pre-configured scope.",
1759 + "type": "string",
1760 + "const": "core:window:deny-activity-name",
1761 + "markdownDescription": "Denies the activity_name command without any pre-configured scope."
1762 + },
1691 1763 {
1692 1764 "description": "Denies the available_monitors command without any pre-configured scope.",
1693 1765 "type": "string",
@@ -1880,6 +1952,12 @@
1880 1952 "const": "core:window:deny-scale-factor",
1881 1953 "markdownDescription": "Denies the scale_factor command without any pre-configured scope."
1882 1954 },
1955 + {
1956 + "description": "Denies the scene_identifier command without any pre-configured scope.",
1957 + "type": "string",
1958 + "const": "core:window:deny-scene-identifier",
1959 + "markdownDescription": "Denies the scene_identifier command without any pre-configured scope."
1960 + },
1883 1961 {
1884 1962 "description": "Denies the set_always_on_bottom command without any pre-configured scope.",
1885 1963 "type": "string",
@@ -2145,22 +2223,22 @@
2145 2223 "markdownDescription": "Denies the unminimize command without any pre-configured scope."
2146 2224 },
2147 2225 {
2148 - "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`",
2226 + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
2149 2227 "type": "string",
2150 2228 "const": "dialog:default",
2151 - "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`"
2229 + "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
2152 2230 },
2153 2231 {
2154 - "description": "Enables the ask command without any pre-configured scope.",
2232 + "description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
2155 2233 "type": "string",
2156 2234 "const": "dialog:allow-ask",
2157 - "markdownDescription": "Enables the ask command without any pre-configured scope."
2235 + "markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
2158 2236 },
2159 2237 {
2160 - "description": "Enables the confirm command without any pre-configured scope.",
2238 + "description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
2161 2239 "type": "string",
2162 2240 "const": "dialog:allow-confirm",
2163 - "markdownDescription": "Enables the confirm command without any pre-configured scope."
2241 + "markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
2164 2242 },
2165 2243 {
2166 2244 "description": "Enables the message command without any pre-configured scope.",
@@ -2181,16 +2259,16 @@
2181 2259 "markdownDescription": "Enables the save command without any pre-configured scope."
2182 2260 },
2183 2261 {
2184 - "description": "Denies the ask command without any pre-configured scope.",
2262 + "description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
2185 2263 "type": "string",
2186 2264 "const": "dialog:deny-ask",
2187 - "markdownDescription": "Denies the ask command without any pre-configured scope."
2265 + "markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
2188 2266 },
2189 2267 {
2190 - "description": "Denies the confirm command without any pre-configured scope.",
2268 + "description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
2191 2269 "type": "string",
2192 2270 "const": "dialog:deny-confirm",
2193 - "markdownDescription": "Denies the confirm command without any pre-configured scope."
2271 + "markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
2194 2272 },
2195 2273 {
2196 2274 "description": "Denies the message command without any pre-configured scope.",
@@ -2209,6 +2287,54 @@
2209 2287 "type": "string",
2210 2288 "const": "dialog:deny-save",
2211 2289 "markdownDescription": "Denies the save command without any pre-configured scope."
2290 + },
2291 + {
2292 + "description": "Enables the impact_feedback command without any pre-configured scope.",
2293 + "type": "string",
2294 + "const": "haptics:allow-impact-feedback",
2295 + "markdownDescription": "Enables the impact_feedback command without any pre-configured scope."
2296 + },
2297 + {
2298 + "description": "Enables the notification_feedback command without any pre-configured scope.",
2299 + "type": "string",
2300 + "const": "haptics:allow-notification-feedback",
2301 + "markdownDescription": "Enables the notification_feedback command without any pre-configured scope."
2302 + },
2303 + {
2304 + "description": "Enables the selection_feedback command without any pre-configured scope.",
2305 + "type": "string",
2306 + "const": "haptics:allow-selection-feedback",
2307 + "markdownDescription": "Enables the selection_feedback command without any pre-configured scope."
2308 + },
2309 + {
2310 + "description": "Enables the vibrate command without any pre-configured scope.",
2311 + "type": "string",
2312 + "const": "haptics:allow-vibrate",
2313 + "markdownDescription": "Enables the vibrate command without any pre-configured scope."
2314 + },
2315 + {
2316 + "description": "Denies the impact_feedback command without any pre-configured scope.",
2317 + "type": "string",
2318 + "const": "haptics:deny-impact-feedback",
2319 + "markdownDescription": "Denies the impact_feedback command without any pre-configured scope."
2320 + },
2321 + {
2322 + "description": "Denies the notification_feedback command without any pre-configured scope.",
2323 + "type": "string",
2324 + "const": "haptics:deny-notification-feedback",
2325 + "markdownDescription": "Denies the notification_feedback command without any pre-configured scope."
2326 + },
2327 + {
2328 + "description": "Denies the selection_feedback command without any pre-configured scope.",
2329 + "type": "string",
2330 + "const": "haptics:deny-selection-feedback",
2331 + "markdownDescription": "Denies the selection_feedback command without any pre-configured scope."
2332 + },
2333 + {
2334 + "description": "Denies the vibrate command without any pre-configured scope.",
2335 + "type": "string",
2336 + "const": "haptics:deny-vibrate",
2337 + "markdownDescription": "Denies the vibrate command without any pre-configured scope."
2212 2338 }
2213 2339 ]
2214 2340 },
@@ -176,6 +176,36 @@
176 176 "Identifier": {
177 177 "description": "Permission identifier",
178 178 "oneOf": [
179 + {
180 + "description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
181 + "type": "string",
182 + "const": "biometric:default",
183 + "markdownDescription": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
184 + },
185 + {
186 + "description": "Enables the authenticate command without any pre-configured scope.",
187 + "type": "string",
188 + "const": "biometric:allow-authenticate",
189 + "markdownDescription": "Enables the authenticate command without any pre-configured scope."
190 + },
191 + {
192 + "description": "Enables the status command without any pre-configured scope.",
193 + "type": "string",
194 + "const": "biometric:allow-status",
195 + "markdownDescription": "Enables the status command without any pre-configured scope."
196 + },
197 + {
198 + "description": "Denies the authenticate command without any pre-configured scope.",
199 + "type": "string",
200 + "const": "biometric:deny-authenticate",
201 + "markdownDescription": "Denies the authenticate command without any pre-configured scope."
202 + },
203 + {
204 + "description": "Denies the status command without any pre-configured scope.",
205 + "type": "string",
206 + "const": "biometric:deny-status",
207 + "markdownDescription": "Denies the status command without any pre-configured scope."
208 + },
179 209 {
180 210 "description": "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`",
181 211 "type": "string",
@@ -183,10 +213,10 @@
183 213 "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`"
184 214 },
185 215 {
186 - "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`",
216 + "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`",
187 217 "type": "string",
188 218 "const": "core:app:default",
189 - "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`"
219 + "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`"
190 220 },
191 221 {
192 222 "description": "Enables the app_hide command without any pre-configured scope.",
@@ -260,6 +290,12 @@
260 290 "const": "core:app:allow-set-dock-visibility",
261 291 "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope."
262 292 },
293 + {
294 + "description": "Enables the supports_multiple_windows command without any pre-configured scope.",
295 + "type": "string",
296 + "const": "core:app:allow-supports-multiple-windows",
297 + "markdownDescription": "Enables the supports_multiple_windows command without any pre-configured scope."
298 + },
263 299 {
264 300 "description": "Enables the tauri_version command without any pre-configured scope.",
265 301 "type": "string",
@@ -344,6 +380,12 @@
344 380 "const": "core:app:deny-set-dock-visibility",
345 381 "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope."
346 382 },
383 + {
384 + "description": "Denies the supports_multiple_windows command without any pre-configured scope.",
385 + "type": "string",
386 + "const": "core:app:deny-supports-multiple-windows",
387 + "markdownDescription": "Denies the supports_multiple_windows command without any pre-configured scope."
388 + },
347 389 {
348 390 "description": "Denies the tauri_version command without any pre-configured scope.",
349 391 "type": "string",
@@ -867,10 +909,10 @@
867 909 "markdownDescription": "Denies the close command without any pre-configured scope."
868 910 },
869 911 {
870 - "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`",
912 + "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`",
871 913 "type": "string",
872 914 "const": "core:tray:default",
873 - "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`"
915 + "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`"
874 916 },
875 917 {
876 918 "description": "Enables the get_by_id command without any pre-configured scope.",
@@ -902,6 +944,12 @@
902 944 "const": "core:tray:allow-set-icon-as-template",
903 945 "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope."
904 946 },
947 + {
948 + "description": "Enables the set_icon_with_as_template command without any pre-configured scope.",
949 + "type": "string",
950 + "const": "core:tray:allow-set-icon-with-as-template",
951 + "markdownDescription": "Enables the set_icon_with_as_template command without any pre-configured scope."
952 + },
905 953 {
906 954 "description": "Enables the set_menu command without any pre-configured scope.",
907 955 "type": "string",
@@ -968,6 +1016,12 @@
968 1016 "const": "core:tray:deny-set-icon-as-template",
969 1017 "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope."
970 1018 },
1019 + {
1020 + "description": "Denies the set_icon_with_as_template command without any pre-configured scope.",
1021 + "type": "string",
1022 + "const": "core:tray:deny-set-icon-with-as-template",
1023 + "markdownDescription": "Denies the set_icon_with_as_template command without any pre-configured scope."
1024 + },
971 1025 {
972 1026 "description": "Denies the set_menu command without any pre-configured scope.",
973 1027 "type": "string",
@@ -1227,10 +1281,16 @@
1227 1281 "markdownDescription": "Denies the webview_size command without any pre-configured scope."
1228 1282 },
1229 1283 {
1230 - "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`",
1284 + "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`",
1231 1285 "type": "string",
1232 1286 "const": "core:window:default",
1233 - "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`"
1287 + "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`"
1288 + },
1289 + {
1290 + "description": "Enables the activity_name command without any pre-configured scope.",
1291 + "type": "string",
1292 + "const": "core:window:allow-activity-name",
1293 + "markdownDescription": "Enables the activity_name command without any pre-configured scope."
1234 1294 },
1235 1295 {
1236 1296 "description": "Enables the available_monitors command without any pre-configured scope.",
@@ -1424,6 +1484,12 @@
1424 1484 "const": "core:window:allow-scale-factor",
1425 1485 "markdownDescription": "Enables the scale_factor command without any pre-configured scope."
1426 1486 },
1487 + {
1488 + "description": "Enables the scene_identifier command without any pre-configured scope.",
1489 + "type": "string",
1490 + "const": "core:window:allow-scene-identifier",
1491 + "markdownDescription": "Enables the scene_identifier command without any pre-configured scope."
1492 + },
1427 1493 {
1428 1494 "description": "Enables the set_always_on_bottom command without any pre-configured scope.",
1429 1495 "type": "string",
@@ -1688,6 +1754,12 @@
1688 1754 "const": "core:window:allow-unminimize",
1689 1755 "markdownDescription": "Enables the unminimize command without any pre-configured scope."
1690 1756 },
1757 + {
1758 + "description": "Denies the activity_name command without any pre-configured scope.",
1759 + "type": "string",
1760 + "const": "core:window:deny-activity-name",
1761 + "markdownDescription": "Denies the activity_name command without any pre-configured scope."
1762 + },
1691 1763 {
1692 1764 "description": "Denies the available_monitors command without any pre-configured scope.",
1693 1765 "type": "string",
@@ -1880,6 +1952,12 @@
1880 1952 "const": "core:window:deny-scale-factor",
1881 1953 "markdownDescription": "Denies the scale_factor command without any pre-configured scope."
1882 1954 },
1955 + {
1956 + "description": "Denies the scene_identifier command without any pre-configured scope.",
1957 + "type": "string",
1958 + "const": "core:window:deny-scene-identifier",
1959 + "markdownDescription": "Denies the scene_identifier command without any pre-configured scope."
1960 + },
1883 1961 {
1884 1962 "description": "Denies the set_always_on_bottom command without any pre-configured scope.",
1885 1963 "type": "string",
@@ -2145,22 +2223,22 @@
2145 2223 "markdownDescription": "Denies the unminimize command without any pre-configured scope."
2146 2224 },
2147 2225 {
2148 - "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`",
2226 + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
2149 2227 "type": "string",
2150 2228 "const": "dialog:default",
2151 - "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`"
2229 + "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
2152 2230 },
2153 2231 {
2154 - "description": "Enables the ask command without any pre-configured scope.",
2232 + "description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
2155 2233 "type": "string",
2156 2234 "const": "dialog:allow-ask",
2157 - "markdownDescription": "Enables the ask command without any pre-configured scope."
2235 + "markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
2158 2236 },
2159 2237 {
2160 - "description": "Enables the confirm command without any pre-configured scope.",
2238 + "description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
2161 2239 "type": "string",
2162 2240 "const": "dialog:allow-confirm",
2163 - "markdownDescription": "Enables the confirm command without any pre-configured scope."
2241 + "markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
2164 2242 },
2165 2243 {
2166 2244 "description": "Enables the message command without any pre-configured scope.",
@@ -2181,16 +2259,16 @@
2181 2259 "markdownDescription": "Enables the save command without any pre-configured scope."
2182 2260 },
2183 2261 {
2184 - "description": "Denies the ask command without any pre-configured scope.",
2262 + "description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
2185 2263 "type": "string",
2186 2264 "const": "dialog:deny-ask",
2187 - "markdownDescription": "Denies the ask command without any pre-configured scope."
2265 + "markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
2188 2266 },
2189 2267 {
2190 - "description": "Denies the confirm command without any pre-configured scope.",
2268 + "description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
2191 2269 "type": "string",
2192 2270 "const": "dialog:deny-confirm",
2193 - "markdownDescription": "Denies the confirm command without any pre-configured scope."
2271 + "markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
2194 2272 },
2195 2273 {
2196 2274 "description": "Denies the message command without any pre-configured scope.",
@@ -2209,6 +2287,54 @@
2209 2287 "type": "string",
2210 2288 "const": "dialog:deny-save",
2211 2289 "markdownDescription": "Denies the save command without any pre-configured scope."
2290 + },
2291 + {
2292 + "description": "Enables the impact_feedback command without any pre-configured scope.",
2293 + "type": "string",
2294 + "const": "haptics:allow-impact-feedback",
2295 + "markdownDescription": "Enables the impact_feedback command without any pre-configured scope."
2296 + },
2297 + {
2298 + "description": "Enables the notification_feedback command without any pre-configured scope.",
2299 + "type": "string",
2300 + "const": "haptics:allow-notification-feedback",
2301 + "markdownDescription": "Enables the notification_feedback command without any pre-configured scope."
2302 + },
2303 + {
2304 + "description": "Enables the selection_feedback command without any pre-configured scope.",
2305 + "type": "string",
2306 + "const": "haptics:allow-selection-feedback",
2307 + "markdownDescription": "Enables the selection_feedback command without any pre-configured scope."
2308 + },
2309 + {
2310 + "description": "Enables the vibrate command without any pre-configured scope.",
2311 + "type": "string",
2312 + "const": "haptics:allow-vibrate",
2313 + "markdownDescription": "Enables the vibrate command without any pre-configured scope."
2314 + },
2315 + {
2316 + "description": "Denies the impact_feedback command without any pre-configured scope.",
2317 + "type": "string",
2318 + "const": "haptics:deny-impact-feedback",
2319 + "markdownDescription": "Denies the impact_feedback command without any pre-configured scope."
2320 + },
2321 + {
2322 + "description": "Denies the notification_feedback command without any pre-configured scope.",
2323 + "type": "string",
2324 + "const": "haptics:deny-notification-feedback",
2325 + "markdownDescription": "Denies the notification_feedback command without any pre-configured scope."
2326 + },
2327 + {
2328 + "description": "Denies the selection_feedback command without any pre-configured scope.",
2329 + "type": "string",
2330 + "const": "haptics:deny-selection-feedback",
2331 + "markdownDescription": "Denies the selection_feedback command without any pre-configured scope."
2332 + },
2333 + {
2334 + "description": "Denies the vibrate command without any pre-configured scope.",
2335 + "type": "string",
2336 + "const": "haptics:deny-vibrate",
2337 + "markdownDescription": "Denies the vibrate command without any pre-configured scope."
2212 2338 }
2213 2339 ]
2214 2340 },
@@ -1,0 +1,12 @@
1 + # EditorConfig is awesome: https://EditorConfig.org
2 +
3 + # top-most EditorConfig file
4 + root = true
5 +
6 + [*]
7 + indent_style = space
8 + indent_size = 2
9 + end_of_line = lf
10 + charset = utf-8
11 + trim_trailing_whitespace = false
12 + insert_final_newline = false
@@ -1,0 +1,20 @@
1 + *.iml
2 + .gradle
3 + /local.properties
4 + /.idea/caches
5 + /.idea/libraries
6 + /.idea/modules.xml
7 + /.idea/workspace.xml
8 + /.idea/navEditor.xml
9 + /.idea/assetWizardSettings.xml
10 + .DS_Store
11 + build
12 + /captures
13 + .externalNativeBuild
14 + .cxx
15 + local.properties
16 + key.properties
17 + keystore.properties
18 +
19 + /.tauri
20 + /tauri.settings.gradle
@@ -1,0 +1,6 @@
1 + /src/main/**/generated
2 + /src/main/jniLibs/**/*.so
3 + /src/main/assets/tauri.conf.json
4 + /tauri.build.gradle.kts
5 + /proguard-tauri.pro
6 + /tauri.properties
@@ -1,0 +1,114 @@
1 + import java.util.Properties
2 +
3 + plugins {
4 + id("com.android.application")
5 + id("org.jetbrains.kotlin.android")
6 + id("rust")
7 + }
8 +
9 + val tauriProperties = Properties().apply {
10 + val propFile = file("tauri.properties")
11 + if (propFile.exists()) {
12 + propFile.inputStream().use { load(it) }
13 + }
14 + }
15 +
16 + android {
17 + compileSdk = 36
18 + namespace = "com.goingson.app"
19 + defaultConfig {
20 + manifestPlaceholders["usesCleartextTraffic"] = "false"
21 + applicationId = "com.goingson.app"
22 + minSdk = 24
23 + targetSdk = 36
24 + versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
25 + versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
26 + }
27 + buildTypes {
28 + getByName("debug") {
29 + manifestPlaceholders["usesCleartextTraffic"] = "true"
30 + isDebuggable = true
31 + isJniDebuggable = true
32 + isMinifyEnabled = false
33 + packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
34 + jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
35 + jniLibs.keepDebugSymbols.add("*/x86/*.so")
36 + jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
37 + }
38 + }
39 + getByName("release") {
40 + isMinifyEnabled = true
41 + proguardFiles(
42 + *fileTree(".") { include("**/*.pro") }
43 + .plus(getDefaultProguardFile("proguard-android-optimize.txt"))
44 + .toList().toTypedArray()
45 + )
46 + }
47 + }
48 + kotlinOptions {
49 + jvmTarget = "1.8"
50 + }
51 + buildFeatures {
52 + buildConfig = true
53 + }
54 + }
55 +
56 + rust {
57 + rootDirRel = "../../../"
58 + }
59 +
60 + // rustls-platform-verifier reaches Android's trust store through the JVM, and the
61 + // Kotlin half of that lives inside the `rustls-platform-verifier-android` crate
62 + // rather than on Maven Central (rustls/rustls-platform-verifier#115). Ask cargo
63 + // where it unpacked the crate and point a Maven repo at the aar it carries, so
64 + // the version follows Cargo.lock instead of being pinned by hand here.
65 + //
66 + // Groovy's JsonSlurper is used rather than kotlinx-serialization purely to avoid
67 + // putting a serialization library on the buildscript classpath for one lookup;
68 + // Gradle bundles Groovy already.
69 + fun rustlsPlatformVerifierMaven(): String {
70 + @Suppress("UnstableApiUsage")
71 + val metadata = providers.exec {
72 + workingDir = project.rootDir
73 + commandLine(
74 + "cargo", "metadata", "--format-version", "1",
75 + "--filter-platform", "aarch64-linux-android",
76 + "--manifest-path", "../../Cargo.toml",
77 + )
78 + }.standardOutput.asText.get()
79 +
80 + @Suppress("UNCHECKED_CAST")
81 + val packages = (groovy.json.JsonSlurper().parseText(metadata) as Map<String, Any>)
82 + .getValue("packages") as List<Map<String, Any>>
83 +
84 + val manifest = packages.firstOrNull { it["name"] == "rustls-platform-verifier-android" }
85 + ?: error(
86 + "rustls-platform-verifier-android is not in the aarch64-linux-android " +
87 + "dependency graph. Android TLS cannot work without it -- check that " +
88 + "rustls-platform-verifier is still a dependency before editing this out."
89 + )
90 +
91 + return File(File(manifest.getValue("manifest_path") as String).parentFile, "maven").path
92 + }
93 +
94 + repositories {
95 + maven {
96 + url = uri(rustlsPlatformVerifierMaven())
97 + // The aar ships without the usual repository metadata.
98 + metadataSources.artifact()
99 + }
100 + }
101 +
102 + dependencies {
103 + implementation("rustls:rustls-platform-verifier:latest.release")
104 + implementation("androidx.webkit:webkit:1.14.0")
105 + implementation("androidx.appcompat:appcompat:1.7.1")
106 + implementation("androidx.activity:activity-ktx:1.10.1")
107 + implementation("com.google.android.material:material:1.12.0")
108 + implementation("androidx.lifecycle:lifecycle-process:2.10.0")
109 + testImplementation("junit:junit:4.13.2")
110 + androidTestImplementation("androidx.test.ext:junit:1.1.4")
111 + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
112 + }
113 +
114 + apply(from = "tauri.build.gradle.kts")
@@ -1,0 +1,21 @@
1 + # Add project specific ProGuard rules here.
2 + # You can control the set of applied configuration files using the
3 + # proguardFiles setting in build.gradle.
4 + #
5 + # For more details, see
6 + # http://developer.android.com/guide/developing/tools/proguard.html
7 +
8 + # If your project uses WebView with JS, uncomment the following
9 + # and specify the fully qualified class name to the JavaScript interface
10 + # class:
11 + #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 + # public *;
13 + #}
14 +
15 + # Uncomment this to preserve the line number information for
16 + # debugging stack traces.
17 + #-keepattributes SourceFile,LineNumberTable
18 +
19 + # If you keep the line number information, uncomment this to
20 + # hide the original source file name.
21 + #-renamesourcefileattribute SourceFile
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file