diff --git a/Cargo.lock b/Cargo.lock index 8ad59809b..5d80e312c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,6 +230,7 @@ dependencies = [ "tauri-plugin-opener", "tauri-plugin-os", "tauri-plugin-process", + "tauri-plugin-secure-storage", "tauri-plugin-shell", "tauri-plugin-store", "tauri-plugin-updater", @@ -300,7 +301,7 @@ dependencies = [ "objc2-foundation 0.3.0", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", + "windows-sys 0.52.0", "wl-clipboard-rs", "x11rb", ] @@ -881,6 +882,15 @@ dependencies = [ "toml", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.2.19" @@ -1044,7 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -1280,7 +1290,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] @@ -1410,6 +1419,36 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + +[[package]] +name = "dbus-secret-service" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42a16374481d92aed73ae45b1f120207d8e71d24fb89f357fadbd8f946fd84b" +dependencies = [ + "aes", + "block-padding", + "cbc", + "dbus", + "futures-util", + "hkdf", + "num", + "once_cell", + "openssl", + "rand 0.8.5", + "sha2", +] + [[package]] name = "deep-link-example" version = "0.0.0" @@ -1816,7 +1855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3241,6 +3280,19 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "keyring" +version = "4.0.0-rc.2" +source = "git+https://github.com/open-source-cooperative/keyring-rs?rev=9635a2f53a19eb7f188cdc4e38982dcb19caee00#9635a2f53a19eb7f188cdc4e38982dcb19caee00" +dependencies = [ + "byteorder", + "dbus-secret-service", + "log", + "security-framework 3.2.0", + "windows-sys 0.59.0", + "zeroize", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -3312,6 +3364,16 @@ version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "libdbus-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "libflate" version = "2.1.0" @@ -3773,6 +3835,30 @@ dependencies = [ "serde", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -3790,6 +3876,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -3816,6 +3911,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -4776,7 +4882,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -5240,7 +5346,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -5253,7 +5359,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6383,7 +6489,6 @@ dependencies = [ "tray-icon", "url", "urlpattern", - "uuid", "webkit2gtk", "webview2-com", "window-vibrancy", @@ -6794,8 +6899,9 @@ dependencies = [ [[package]] name = "tauri-plugin-secure-storage" -version = "1.0.0" +version = "2.0.0" dependencies = [ + "keyring", "log", "serde", "serde_json", @@ -7023,12 +7129,10 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41743bbbeb96c3a100d234e5a0b60a46d5aa068f266160862c7afdbf828ca02e" dependencies = [ - "aes-gcm", "anyhow", "cargo_metadata", "ctor", "dunce", - "getrandom 0.2.15", "glob", "html5ever", "http", @@ -7047,7 +7151,6 @@ dependencies = [ "serde-untagged", "serde_json", "serde_with", - "serialize-to-javascript", "swift-rs", "thiserror 2.0.12", "toml", @@ -7089,7 +7192,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.5", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8161,7 +8264,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/examples/api/package.json b/examples/api/package.json index 8ad47bff0..c05bee723 100644 --- a/examples/api/package.json +++ b/examples/api/package.json @@ -27,6 +27,7 @@ "@tauri-apps/plugin-os": "^2.3.0", "@tauri-apps/plugin-process": "^2.3.0", "@tauri-apps/plugin-shell": "^2.3.0", + "@tauri-apps/plugin-secure-storage": "file:../../plugins/secure-storage", "@tauri-apps/plugin-store": "^2.3.0", "@tauri-apps/plugin-updater": "^2.9.0", "@tauri-apps/plugin-upload": "^2.3.0", diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index 7372de046..d8e1ac6ed 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -12,7 +12,7 @@ name = "api_lib" crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] -tauri-build = { workspace = true, features = ["codegen", "isolation"] } +tauri-build = { workspace = true, features = ["codegen"] } [dependencies] serde_json = { workspace = true } @@ -36,6 +36,7 @@ tauri-plugin-notification = { path = "../../../plugins/notification", version = tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.0" } tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.0" } tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.4.0" } +tauri-plugin-secure-storage = { path = "../../../plugins/secure-storage" } tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.0" } tauri-plugin-store = { path = "../../../plugins/store", version = "2.3.0" } tauri-plugin-upload = { path = "../../../plugins/upload", version = "2.3.0" } @@ -48,7 +49,6 @@ features = [ "x11", "image-ico", "image-png", - "isolation", "macos-private-api", "tray-icon", "protocol-asset", diff --git a/examples/api/src-tauri/capabilities/base.json b/examples/api/src-tauri/capabilities/base.json index 8508bb6bc..8c2c037ba 100644 --- a/examples/api/src-tauri/capabilities/base.json +++ b/examples/api/src-tauri/capabilities/base.json @@ -96,6 +96,8 @@ "identifier": "opener:allow-open-path", "allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }] }, - "upload:default" + "upload:default", + "secure-storage:allow-get-string", + "secure-storage:allow-set-string" ] } diff --git a/examples/api/src-tauri/src/cmd.rs b/examples/api/src-tauri/src/cmd.rs index 734552c63..27d4e7f09 100644 --- a/examples/api/src-tauri/src/cmd.rs +++ b/examples/api/src-tauri/src/cmd.rs @@ -14,11 +14,11 @@ pub struct RequestBody { #[command] pub fn log_operation(event: String, payload: Option) { - log::info!("{} {:?}", event, payload); + log::info!("{event} {payload:?}"); } #[command] pub fn perform_request(endpoint: String, body: RequestBody) -> String { - println!("{} {:?}", endpoint, body); + println!("{endpoint} {body:?}"); "message response".into() } diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 3c58f2c81..5b75f9f23 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -38,6 +38,7 @@ pub fn run() { .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_secure_storage::init()) .plugin(tauri_plugin_store::Builder::default().build()) .plugin(tauri_plugin_upload::init()) .setup(move |app| { diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 00b095be8..cd4a3d026 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -13,12 +13,6 @@ "withGlobalTauri": true, "macOSPrivateApi": true, "security": { - "pattern": { - "use": "isolation", - "options": { - "dir": "../isolation-dist/" - } - }, "csp": { "default-src": "'self' customprotocol: asset:", "connect-src": "ipc: http://ipc.localhost", diff --git a/examples/api/src/App.svelte b/examples/api/src/App.svelte index 8e114c4b9..b053eadb4 100644 --- a/examples/api/src/App.svelte +++ b/examples/api/src/App.svelte @@ -23,6 +23,7 @@ import Biometric from './views/Biometric.svelte' import Geolocation from './views/Geolocation.svelte' import Haptics from './views/Haptics.svelte' + import SecureStorage from './views/SecureStorage.svelte' import { onMount, tick } from 'svelte' import { ask } from '@tauri-apps/plugin-dialog' @@ -103,6 +104,11 @@ component: Store, icon: 'i-codicon-file-code' }, + { + label: 'SecureStorage', + component: SecureStorage, + icon: 'i-codicon-file-code' + }, !isMobile && { label: 'Updater', component: Updater, @@ -213,9 +219,9 @@ ...r, { html: - `
[${new Date().toLocaleTimeString()}]: ` +
-          (typeof value === 'string' ? value : JSON.stringify(value, null, 1)) +
-          '
' + `
[${new Date().toLocaleTimeString()}]: `
+          + (typeof value === 'string' ? value : JSON.stringify(value, null, 1))
+          + '
' } ]) await tick() @@ -229,9 +235,9 @@ ...r, { html: - `
[${new Date().toLocaleTimeString()}]: ` +
-          html +
-          '
' + `
[${new Date().toLocaleTimeString()}]: `
+          + html
+          + '
' } ]) await tick() diff --git a/examples/api/src/views/SecureStorage.svelte b/examples/api/src/views/SecureStorage.svelte new file mode 100644 index 000000000..8f2e396c9 --- /dev/null +++ b/examples/api/src/views/SecureStorage.svelte @@ -0,0 +1,54 @@ + + +
+
+
+ Key: + +
+ +
+ Value: + +
+ +
+ + + +
+
+ +
+ Output: {output} +
+
diff --git a/plugins/secure-storage/Cargo.toml b/plugins/secure-storage/Cargo.toml index 5cca1d209..f85c3b2da 100644 --- a/plugins/secure-storage/Cargo.toml +++ b/plugins/secure-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-plugin-secure-storage" -version = "1.0.0" +version = "2.0.0" edition = { workspace = true } authors = { workspace = true } license = { workspace = true } @@ -33,3 +33,8 @@ serde_json = { workspace = true } tauri = { workspace = true } log = { workspace = true } thiserror = { workspace = true } +# TODO: Non-android only: +keyring = { git = "https://github.com/open-source-cooperative/keyring-rs", rev = "9635a2f53a19eb7f188cdc4e38982dcb19caee00" } + +[features] +vendored = ["keyring/vendored"] \ No newline at end of file diff --git a/plugins/secure-storage/api-iife.js b/plugins/secure-storage/api-iife.js index 490e957da..b0005fd78 100644 --- a/plugins/secure-storage/api-iife.js +++ b/plugins/secure-storage/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_SECURE_STORAGE__=function(_){"use strict";return _.x=function(){},_}({});Object.defineProperty(window.__TAURI__,"secureStorage",{value:__TAURI_PLUGIN_SECURE_STORAGE__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_SECURE_STORAGE__=function(e){"use strict";async function n(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}return"function"==typeof SuppressedError&&SuppressedError,e.getBinary=async function(e){return n("plugin:secure-storage|set_string",{key:e})},e.getString=async function(e){return n("plugin:secure-storage|get_string",{key:e})},e.setBinary=async function(e,r){return n("plugin:secure-storage|set_binary",{key:e,value:r})},e.setString=async function(e,r){return n("plugin:secure-storage|set_string",{key:e,value:r})},e}({});Object.defineProperty(window.__TAURI__,"secureStorage",{value:__TAURI_PLUGIN_SECURE_STORAGE__})} diff --git a/plugins/secure-storage/build.rs b/plugins/secure-storage/build.rs index 16a1438a8..3a3eca52f 100644 --- a/plugins/secure-storage/build.rs +++ b/plugins/secure-storage/build.rs @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -const COMMANDS: &[&str] = &["execute"]; +const COMMANDS: &[&str] = &["set_string", "get_string", "set_binary", "get_binary"]; fn main() { let result = tauri_plugin::Builder::new(COMMANDS) .global_api_script_path("./api-iife.js") .android_path("android") - .ios_path("ios") + //.ios_path("ios") .try_build(); // when building documentation for Android the plugin build result is always Err() and is irrelevant to the crate documentation build diff --git a/plugins/secure-storage/guest-js/index.ts b/plugins/secure-storage/guest-js/index.ts index ffa097873..ced77e58b 100644 --- a/plugins/secure-storage/guest-js/index.ts +++ b/plugins/secure-storage/guest-js/index.ts @@ -2,4 +2,25 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -export function x() {} +import { invoke } from '@tauri-apps/api/core' + +// TODO: functions to delete entries? + +export async function setString(key: string, value: string) { + return invoke('plugin:secure-storage|set_string', { key, value }) +} + +export async function getString(key: string): Promise { + return invoke('plugin:secure-storage|get_string', { key }) +} + +export async function setBinary( + key: string, + value: number[] | Uint8Array | ArrayBuffer +) { + return invoke('plugin:secure-storage|set_binary', { key, value }) +} + +export async function getBinary(key: string): Promise { + return invoke('plugin:secure-storage|set_string', { key }) +} diff --git a/plugins/secure-storage/ios/.gitignore b/plugins/secure-storage/ios/.gitignore deleted file mode 100644 index 5922fdaa5..000000000 --- a/plugins/secure-storage/ios/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ -DerivedData/ -.swiftpm/config/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc -Package.resolved diff --git a/plugins/secure-storage/ios/Package.swift b/plugins/secure-storage/ios/Package.swift deleted file mode 100644 index 50dac0f91..000000000 --- a/plugins/secure-storage/ios/Package.swift +++ /dev/null @@ -1,34 +0,0 @@ -// swift-tools-version:5.3 -// Copyright 2019-2023 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import PackageDescription - -let package = Package( - name: "tauri-plugin-{{ secure-storage }}", - platforms: [ - .macOS(.v10_13), - .iOS(.v13), - ], - products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. - .library( - name: "tauri-plugin-{{ secure-storage }}", - type: .static, - targets: ["tauri-plugin-{{ secure-storage }}"]) - ], - dependencies: [ - .package(name: "Tauri", path: "../.tauri/tauri-api") - ], - targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. - .target( - name: "tauri-plugin-{{ secure-storage }}", - dependencies: [ - .byName(name: "Tauri") - ], - path: "Sources") - ] -) diff --git a/plugins/secure-storage/ios/README.md b/plugins/secure-storage/ios/README.md deleted file mode 100644 index 4d527609c..000000000 --- a/plugins/secure-storage/ios/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Tauri Plugin Secure Storage - -A description of this package. diff --git a/plugins/secure-storage/ios/Sources/ExamplePlugin.swift b/plugins/secure-storage/ios/Sources/ExamplePlugin.swift deleted file mode 100644 index a373abcad..000000000 --- a/plugins/secure-storage/ios/Sources/ExamplePlugin.swift +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2019-2023 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import SwiftRs -import Tauri -import UIKit -import WebKit - -class PingArgs: Decodable { - var value: String? -} - -class ExamplePlugin: Plugin { - @objc public func ping(_ invoke: Invoke) throws { - let args = try invoke.parseArgs(PingArgs.self) - invoke.resolve(["value": args.value ?? ""]) - } -} - -@_cdecl("init_plugin_secure_storage") -func initPlugin() -> Plugin { - return ExamplePlugin() -} diff --git a/plugins/secure-storage/ios/Tests/PluginTests/PluginTests.swift b/plugins/secure-storage/ios/Tests/PluginTests/PluginTests.swift deleted file mode 100644 index 99992ce4c..000000000 --- a/plugins/secure-storage/ios/Tests/PluginTests/PluginTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019-2023 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import XCTest -@testable import ExamplePlugin - -final class ExamplePluginTests: XCTestCase { - func testExample() throws { - let plugin = ExamplePlugin() - } -} diff --git a/plugins/secure-storage/permissions/autogenerated/commands/get_binary.toml b/plugins/secure-storage/permissions/autogenerated/commands/get_binary.toml new file mode 100644 index 000000000..990c48da6 --- /dev/null +++ b/plugins/secure-storage/permissions/autogenerated/commands/get_binary.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-get-binary" +description = "Enables the get_binary command without any pre-configured scope." +commands.allow = ["get_binary"] + +[[permission]] +identifier = "deny-get-binary" +description = "Denies the get_binary command without any pre-configured scope." +commands.deny = ["get_binary"] diff --git a/plugins/secure-storage/permissions/autogenerated/commands/get_string.toml b/plugins/secure-storage/permissions/autogenerated/commands/get_string.toml new file mode 100644 index 000000000..185237dd3 --- /dev/null +++ b/plugins/secure-storage/permissions/autogenerated/commands/get_string.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-get-string" +description = "Enables the get_string command without any pre-configured scope." +commands.allow = ["get_string"] + +[[permission]] +identifier = "deny-get-string" +description = "Denies the get_string command without any pre-configured scope." +commands.deny = ["get_string"] diff --git a/plugins/secure-storage/permissions/autogenerated/commands/set_binary.toml b/plugins/secure-storage/permissions/autogenerated/commands/set_binary.toml new file mode 100644 index 000000000..fdb4dbec9 --- /dev/null +++ b/plugins/secure-storage/permissions/autogenerated/commands/set_binary.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-set-binary" +description = "Enables the set_binary command without any pre-configured scope." +commands.allow = ["set_binary"] + +[[permission]] +identifier = "deny-set-binary" +description = "Denies the set_binary command without any pre-configured scope." +commands.deny = ["set_binary"] diff --git a/plugins/secure-storage/permissions/autogenerated/commands/set_string.toml b/plugins/secure-storage/permissions/autogenerated/commands/set_string.toml new file mode 100644 index 000000000..513f6919b --- /dev/null +++ b/plugins/secure-storage/permissions/autogenerated/commands/set_string.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-set-string" +description = "Enables the set_string command without any pre-configured scope." +commands.allow = ["set_string"] + +[[permission]] +identifier = "deny-set-string" +description = "Denies the set_string command without any pre-configured scope." +commands.deny = ["set_string"] diff --git a/plugins/secure-storage/permissions/autogenerated/reference.md b/plugins/secure-storage/permissions/autogenerated/reference.md index 3f5e27a74..62066409f 100644 --- a/plugins/secure-storage/permissions/autogenerated/reference.md +++ b/plugins/secure-storage/permissions/autogenerated/reference.md @@ -30,6 +30,110 @@ Enables the execute command without any pre-configured scope. Denies the execute command without any pre-configured scope. + + + + + + +`secure-storage:allow-get-binary` + + + + +Enables the get_binary command without any pre-configured scope. + + + + + + + +`secure-storage:deny-get-binary` + + + + +Denies the get_binary command without any pre-configured scope. + + + + + + + +`secure-storage:allow-get-string` + + + + +Enables the get_string command without any pre-configured scope. + + + + + + + +`secure-storage:deny-get-string` + + + + +Denies the get_string command without any pre-configured scope. + + + + + + + +`secure-storage:allow-set-binary` + + + + +Enables the set_binary command without any pre-configured scope. + + + + + + + +`secure-storage:deny-set-binary` + + + + +Denies the set_binary command without any pre-configured scope. + + + + + + + +`secure-storage:allow-set-string` + + + + +Enables the set_string command without any pre-configured scope. + + + + + + + +`secure-storage:deny-set-string` + + + + +Denies the set_string command without any pre-configured scope. + diff --git a/plugins/secure-storage/permissions/schemas/schema.json b/plugins/secure-storage/permissions/schemas/schema.json index 8cc433b48..50dfa65b1 100644 --- a/plugins/secure-storage/permissions/schemas/schema.json +++ b/plugins/secure-storage/permissions/schemas/schema.json @@ -305,6 +305,54 @@ "type": "string", "const": "deny-execute", "markdownDescription": "Denies the execute command without any pre-configured scope." + }, + { + "description": "Enables the get_binary command without any pre-configured scope.", + "type": "string", + "const": "allow-get-binary", + "markdownDescription": "Enables the get_binary command without any pre-configured scope." + }, + { + "description": "Denies the get_binary command without any pre-configured scope.", + "type": "string", + "const": "deny-get-binary", + "markdownDescription": "Denies the get_binary command without any pre-configured scope." + }, + { + "description": "Enables the get_string command without any pre-configured scope.", + "type": "string", + "const": "allow-get-string", + "markdownDescription": "Enables the get_string command without any pre-configured scope." + }, + { + "description": "Denies the get_string command without any pre-configured scope.", + "type": "string", + "const": "deny-get-string", + "markdownDescription": "Denies the get_string command without any pre-configured scope." + }, + { + "description": "Enables the set_binary command without any pre-configured scope.", + "type": "string", + "const": "allow-set-binary", + "markdownDescription": "Enables the set_binary command without any pre-configured scope." + }, + { + "description": "Denies the set_binary command without any pre-configured scope.", + "type": "string", + "const": "deny-set-binary", + "markdownDescription": "Denies the set_binary command without any pre-configured scope." + }, + { + "description": "Enables the set_string command without any pre-configured scope.", + "type": "string", + "const": "allow-set-string", + "markdownDescription": "Enables the set_string command without any pre-configured scope." + }, + { + "description": "Denies the set_string command without any pre-configured scope.", + "type": "string", + "const": "deny-set-string", + "markdownDescription": "Denies the set_string command without any pre-configured scope." } ] } diff --git a/plugins/secure-storage/src/commands.rs b/plugins/secure-storage/src/commands.rs index 99cc0eafa..b8c373204 100644 --- a/plugins/secure-storage/src/commands.rs +++ b/plugins/secure-storage/src/commands.rs @@ -2,14 +2,26 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use tauri::{AppHandle, command, Runtime, Window}; +use tauri::{command, AppHandle, Runtime}; -use crate::Result; +use crate::{Result, SecureStorageExt}; #[command] -pub(crate) async fn execute( - _app: AppHandle, - _window: Window, -) -> Result { - Ok("success".to_string()) +pub(crate) fn set_string(app: AppHandle, key: &str, value: &str) -> Result<()> { + app.secure_storage().set_string(key, value) +} + +#[command] +pub(crate) fn get_string(app: AppHandle, key: &str) -> Result { + app.secure_storage().get_string(key) +} + +#[command] +pub(crate) fn set_binary(app: AppHandle, key: &str, value: &[u8]) -> Result<()> { + app.secure_storage().set_binary(key, value) +} + +#[command] +pub(crate) fn get_binary(app: AppHandle, key: &str) -> Result> { + app.secure_storage().get_binary(key) } diff --git a/plugins/secure-storage/src/desktop.rs b/plugins/secure-storage/src/desktop.rs index 692f84317..411c8b052 100644 --- a/plugins/secure-storage/src/desktop.rs +++ b/plugins/secure-storage/src/desktop.rs @@ -2,10 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +use keyring::Entry; use serde::de::DeserializeOwned; use tauri::{plugin::PluginApi, AppHandle, Runtime}; -use crate::models::*; +use crate::Result; pub fn init( app: &AppHandle, @@ -18,9 +19,19 @@ pub fn init( pub struct SecureStorage(AppHandle); impl SecureStorage { - pub fn ping(&self, payload: PingRequest) -> crate::Result { - Ok(PingResponse { - value: payload.value, - }) + pub fn set_string(&self, key: &str, value: &str) -> Result<()> { + Ok(Entry::new(&self.0.config().identifier, key)?.set_password(value)?) + } + + pub fn get_string(&self, key: &str) -> Result { + Ok(Entry::new(&self.0.config().identifier, key)?.get_password()?) + } + + pub fn set_binary(&self, key: &str, value: &[u8]) -> Result<()> { + Ok(Entry::new(&self.0.config().identifier, key)?.set_secret(value)?) + } + + pub fn get_binary(&self, key: &str) -> Result> { + Ok(Entry::new(&self.0.config().identifier, key)?.get_secret()?) } } diff --git a/plugins/secure-storage/src/error.rs b/plugins/secure-storage/src/error.rs index 339e763b1..5cb1fd10b 100644 --- a/plugins/secure-storage/src/error.rs +++ b/plugins/secure-storage/src/error.rs @@ -8,9 +8,10 @@ pub type Result = std::result::Result; #[derive(Debug, thiserror::Error)] pub enum Error { + #[cfg(not(target_os = "android"))] #[error(transparent)] - Io(#[from] std::io::Error), - #[cfg(mobile)] + Keyring(#[from] keyring::Error), + #[cfg(target_os = "android")] #[error(transparent)] PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError), } diff --git a/plugins/secure-storage/src/lib.rs b/plugins/secure-storage/src/lib.rs index bdb69c42d..378531588 100644 --- a/plugins/secure-storage/src/lib.rs +++ b/plugins/secure-storage/src/lib.rs @@ -9,9 +9,9 @@ use tauri::{ pub use models::*; -#[cfg(desktop)] +#[cfg(not(target_os = "android"))] mod desktop; -#[cfg(mobile)] +#[cfg(target_os = "android")] mod mobile; mod commands; @@ -20,11 +20,13 @@ mod models; pub use error::{Error, Result}; -#[cfg(desktop)] +#[cfg(not(target_os = "android"))] pub use desktop::SecureStorage; -#[cfg(mobile)] +#[cfg(target_os = "android")] pub use mobile::SecureStorage; +// TODO: Consider using a worker thread to handle caveats mentioned by keyring-rs + /// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the secure-storage APIs. pub trait SecureStorageExt { fn secure_storage(&self) -> &SecureStorage; @@ -39,11 +41,16 @@ impl> crate::SecureStorageExt for T { /// Initializes the plugin. pub fn init() -> TauriPlugin { Builder::new("secure-storage") - .invoke_handler(tauri::generate_handler![commands::execute]) + .invoke_handler(tauri::generate_handler![ + commands::set_string, + commands::get_string, + commands::set_binary, + commands::get_binary + ]) .setup(|app, api| { - #[cfg(mobile)] + #[cfg(target_os = "android")] let secure_storage = mobile::init(app, api)?; - #[cfg(desktop)] + #[cfg(not(target_os = "android"))] let secure_storage = desktop::init(app, api)?; app.manage(secure_storage); Ok(()) diff --git a/plugins/secure-storage/src/mobile.rs b/plugins/secure-storage/src/mobile.rs index 2f27facae..e3a7e943f 100644 --- a/plugins/secure-storage/src/mobile.rs +++ b/plugins/secure-storage/src/mobile.rs @@ -13,8 +13,8 @@ use crate::models::*; #[cfg(target_os = "android")] const PLUGIN_IDENTIFIER: &str = "app.tauri.secure_storage"; -#[cfg(target_os = "ios")] -tauri::ios_plugin_binding!(init_plugin_secure_storage); +//#[cfg(target_os = "ios")] +//tauri::ios_plugin_binding!(init_plugin_secure_storage); // initializes the Kotlin or Swift plugin classes pub fn init( @@ -23,8 +23,8 @@ pub fn init( ) -> crate::Result> { #[cfg(target_os = "android")] let handle = api.register_android_plugin(PLUGIN_IDENTIFIER, "ExamplePlugin")?; - #[cfg(target_os = "ios")] - let handle = api.register_ios_plugin(init_plugin_secure_storage)?; + //#[cfg(target_os = "ios")] + //let handle = api.register_ios_plugin(init_plugin_secure_storage)?; Ok(SecureStorage(handle)) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cd5840587..82ee18c91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,6 +101,9 @@ importers: '@tauri-apps/plugin-process': specifier: ^2.3.0 version: link:../../plugins/process + '@tauri-apps/plugin-secure-storage': + specifier: file:../../plugins/secure-storage + version: link:../../plugins/secure-storage '@tauri-apps/plugin-shell': specifier: ^2.3.0 version: link:../../plugins/shell @@ -2348,9 +2351,9 @@ snapshots: - encoding - mocha - '@covector/assemble@0.12.0(mocha@10.8.2)': + '@covector/assemble@0.12.0': dependencies: - '@covector/command': 0.8.0(mocha@10.8.2) + '@covector/command': 0.8.0 '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.8.2) js-yaml: 4.1.0 @@ -2361,10 +2364,9 @@ snapshots: unified: 9.2.2 transitivePeerDependencies: - encoding - - mocha - supports-color - '@covector/changelog@0.12.0(mocha@10.8.2)': + '@covector/changelog@0.12.0': dependencies: '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.8.2) @@ -2374,16 +2376,14 @@ snapshots: unified: 9.2.2 transitivePeerDependencies: - encoding - - mocha - supports-color - '@covector/command@0.8.0(mocha@10.8.2)': + '@covector/command@0.8.0': dependencies: '@effection/process': 2.1.4 effection: 2.0.8(mocha@10.8.2) transitivePeerDependencies: - encoding - - mocha '@covector/files@0.8.0': dependencies: @@ -2430,6 +2430,8 @@ snapshots: dependencies: effection: 2.0.8(mocha@10.8.2) mocha: 10.8.2 + transitivePeerDependencies: + - encoding '@effection/process@2.1.4': dependencies: @@ -2437,6 +2439,8 @@ snapshots: ctrlc-windows: 2.2.0 effection: 2.0.8(mocha@10.8.2) shellwords: 0.1.1 + transitivePeerDependencies: + - encoding '@effection/stream@2.0.6': dependencies: @@ -3267,9 +3271,9 @@ snapshots: dependencies: '@clack/prompts': 0.7.0 '@covector/apply': 0.10.0(mocha@10.8.2) - '@covector/assemble': 0.12.0(mocha@10.8.2) - '@covector/changelog': 0.12.0(mocha@10.8.2) - '@covector/command': 0.8.0(mocha@10.8.2) + '@covector/assemble': 0.12.0 + '@covector/changelog': 0.12.0 + '@covector/command': 0.8.0 '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.8.2) globby: 11.1.0