mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-01 12:08:06 +02:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dac8b6331c | |||
| 8502b90287 | |||
| fe10ab488f | |||
| 7659b9515d | |||
| 5673a416a8 | |||
| ee910bfcce | |||
| 331a3eaf06 | |||
| cb5ff764a6 | |||
| 0688416425 | |||
| 14f5961569 | |||
| 63afaf1dfa | |||
| abd0176cc1 | |||
| 18e478aba0 | |||
| 2643a4c331 | |||
| d198c01486 | |||
| 506ce4835b | |||
| 15dc7060e8 | |||
| 18cb861b52 | |||
| 8dea78ac7d | |||
| 61edbbec0a | |||
| 0879a87a7e | |||
| 8505a756b5 | |||
| 4e2e77580c | |||
| 8a3db790b8 | |||
| bf5a21d5b2 | |||
| 1b1d795b58 | |||
| ae0cb92438 | |||
| ea8eadce85 | |||
| be5aebdec9 | |||
| b9d29a0154 | |||
| 1a347203a5 | |||
| e80626cf81 | |||
| 2e2fc8de69 | |||
| 85f8419682 | |||
| c60123093d | |||
| 38b5d37b54 | |||
| 8b1d821a37 | |||
| bfa87da848 |
@@ -0,0 +1,57 @@
|
||||
---
|
||||
"authenticator": patch
|
||||
"autostart": patch
|
||||
"barcode-scanner": patch
|
||||
"biometric": patch
|
||||
"cli": patch
|
||||
"clipboard-manager": patch
|
||||
"deep-link": patch
|
||||
"dialog": patch
|
||||
"fs": patch
|
||||
"global-shortcut": patch
|
||||
"http": patch
|
||||
"localhost": patch
|
||||
"log-plugin": patch
|
||||
"nfc": patch
|
||||
"notification": patch
|
||||
"os": patch
|
||||
"persisted-scope": patch
|
||||
"positioner": patch
|
||||
"process": patch
|
||||
"shell": patch
|
||||
"single-instance": patch
|
||||
"sql": patch
|
||||
"store": patch
|
||||
"stronghold": patch
|
||||
"updater": patch
|
||||
"upload": patch
|
||||
"websocket": patch
|
||||
"window-state": patch
|
||||
"authenticator-js": patch
|
||||
"autostart-js": patch
|
||||
"barcode-scanner-js": patch
|
||||
"biometric-js": patch
|
||||
"cli-js": patch
|
||||
"clipboard-manager-js": patch
|
||||
"deep-link-js": patch
|
||||
"dialog-js": patch
|
||||
"fs-js": patch
|
||||
"global-shortcut-js": patch
|
||||
"http-js": patch
|
||||
"log-js": patch
|
||||
"nfc-js": patch
|
||||
"notification-js": patch
|
||||
"os-js": patch
|
||||
"positioner-js": patch
|
||||
"process-js": patch
|
||||
"shell-js": patch
|
||||
"sql-js": patch
|
||||
"store-js": patch
|
||||
"stronghold-js": patch
|
||||
"updater-js": patch
|
||||
"upload-js": patch
|
||||
"websocket-js": patch
|
||||
"window-state-js": patch
|
||||
---
|
||||
|
||||
Update to tauri beta.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"dialog": "patch"
|
||||
---
|
||||
|
||||
On Android, do not add a `Cancel` button to message dialogs.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"shell": patch
|
||||
---
|
||||
|
||||
Fixes a deadlock when reading a stdout or stderr line returns an error.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"fs-js": patch
|
||||
---
|
||||
|
||||
Fix `DebouncedEvent` type to correctly represent the actual type.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"deep-link": patch
|
||||
---
|
||||
|
||||
Fixes issue with tauri alpha.20.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": "patch"
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Fix incorrect `create` option default value for `writeFile` and `writeTextFile` which didn't match documentation.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"notification-js": patch
|
||||
---
|
||||
|
||||
Export the missing `Schedule` class.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"notification": patch
|
||||
"notification-js": patch
|
||||
---
|
||||
|
||||
Fixes deserialization and implementation bugs with scheduled notifications on Android.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": "patch"
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Add `createNew` option for `writeFile` and `writeTextFile` to create the file if doesn't exist and fail if it does.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": "patch"
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Replace `notify-debouncer-mini` with `notify-debouncer-full`. [(plugins-workspace#885)](https://github.com/tauri-apps/plugins-workspace/pull/885)
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": "patch"
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Truncate files when using `writeFile` and `writeTextFile` with `append: false`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Fix `invalid args id for command unwatch` error when trying to unwatch a previously watched file or directory.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": "patch"
|
||||
"fs-js": "patch"
|
||||
---
|
||||
|
||||
Fix panic when using `writeFile` or `writeTextFile` without passing an option object.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"http-js": minor
|
||||
---
|
||||
|
||||
Fix http fetch client option init with parameter `connectTimeout`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"http": minor
|
||||
"http-js": minor
|
||||
---
|
||||
|
||||
Add `proxy` field to `fetch` options to configure proxy.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
"authenticator": patch
|
||||
"autostart": patch
|
||||
"barcode-scanner": patch
|
||||
"barcode-scanner-js": patch
|
||||
"biometric": patch
|
||||
"cli": patch
|
||||
"clipboard-manager": patch
|
||||
"clipboard-manager-js": patch
|
||||
"deep-link": patch
|
||||
"dialog": patch
|
||||
"fs": patch
|
||||
"global-shortcut": patch
|
||||
"global-shortcut-js": patch
|
||||
"http": patch
|
||||
"localhost": patch
|
||||
"log-plugin": patch
|
||||
"nfc": patch
|
||||
"nfc-js": patch
|
||||
"notification": patch
|
||||
"os": patch
|
||||
"persisted-scope": patch
|
||||
"positioner": patch
|
||||
"process": patch
|
||||
"shell": patch
|
||||
"single-instance": patch
|
||||
"sql": patch
|
||||
"store": patch
|
||||
"stronghold": patch
|
||||
"updater": patch
|
||||
"upload": patch
|
||||
"websocket": patch
|
||||
"window-state": patch
|
||||
---
|
||||
|
||||
Add permissions.
|
||||
+23
-1
@@ -9,28 +9,43 @@
|
||||
".changes/api-alpha.12.md",
|
||||
".changes/api-alpha.13.md",
|
||||
".changes/api-alpha.9.md",
|
||||
".changes/beta.md",
|
||||
".changes/biometric-initial-release.md",
|
||||
".changes/deep-link-initial-release.md",
|
||||
".changes/dialog-async-message-dialog.md",
|
||||
".changes/dialog-default-path-windows-slash.md",
|
||||
".changes/dialog-export-fileresponse.md",
|
||||
".changes/dialog-message-android.md",
|
||||
".changes/dialog-pin-rfd.md",
|
||||
".changes/dialog-return-result.md",
|
||||
".changes/fix-cmd-spawn-deadlock.md",
|
||||
".changes/fix-debounced-event-type.md",
|
||||
".changes/fix-deep-link-alpha-20.md",
|
||||
".changes/fix-docs-build.md",
|
||||
".changes/fix-emit-all-usage.md",
|
||||
".changes/fix-fs-write-default-option.md",
|
||||
".changes/fix-invoke-usage.md",
|
||||
".changes/fix-notification-schedule-export.md",
|
||||
".changes/fix-number-query-params.md",
|
||||
".changes/fix-permission-notification.md",
|
||||
".changes/fix-scheduled-notification.md",
|
||||
".changes/fix-updater-macos.md",
|
||||
".changes/fix-window-state-api.md",
|
||||
".changes/fs-create-new.md",
|
||||
".changes/fs-exists-2nd-arg.md",
|
||||
".changes/fs-improve-error-message.md",
|
||||
".changes/fs-improved-apis.md",
|
||||
".changes/fs-replace-notify-debouncer.md",
|
||||
".changes/fs-scope-tauri.md",
|
||||
".changes/fs-trunacte-non-append.md",
|
||||
".changes/fs-unwtach-rid.md",
|
||||
".changes/fs-wiret-binary-file.md",
|
||||
".changes/fs-write-panic.md",
|
||||
".changes/global-shortcut-app-handle.md",
|
||||
".changes/http-init-fetch-option-connectTimeout.md",
|
||||
".changes/http-multipart-refactor.md",
|
||||
".changes/http-plugin-refactor.md",
|
||||
".changes/http-proxy-config.md",
|
||||
".changes/http-remove-cmd-property.md",
|
||||
".changes/http-response.md",
|
||||
".changes/msrv-1.70.md",
|
||||
@@ -41,6 +56,7 @@
|
||||
".changes/os-OsType.md",
|
||||
".changes/os-plugin-refactor.md",
|
||||
".changes/os-reading-undefined.md",
|
||||
".changes/permissions.md",
|
||||
".changes/persisted-scope-asset.md",
|
||||
".changes/persisted-scope-glob.md",
|
||||
".changes/positioner-tray-flag.md",
|
||||
@@ -54,20 +70,26 @@
|
||||
".changes/tauri-alpha-15.md",
|
||||
".changes/tauri-alpha.11.md",
|
||||
".changes/tauri-alpha.12.md",
|
||||
".changes/tauri-http-plugin-errror-invalid-rid.md",
|
||||
".changes/tray-position.md",
|
||||
".changes/updater-appimage.md",
|
||||
".changes/updater-escaped-path.md",
|
||||
".changes/updater-js-started-event.md",
|
||||
".changes/updater-nsis-admin.md",
|
||||
".changes/updater-nsis-basicui.md",
|
||||
".changes/updater-nsis.md",
|
||||
".changes/updater-on-chunk-fn-mut.md",
|
||||
".changes/updater-plugin-refactor.md",
|
||||
".changes/updater-proxy.md",
|
||||
".changes/updater-string-replace-round2.md",
|
||||
".changes/updater-string-replace.md",
|
||||
".changes/updater.md",
|
||||
".changes/upload-bufwriter.md",
|
||||
".changes/v2-alpha.md",
|
||||
".changes/websocket-fix-arg-name.md",
|
||||
".changes/websocket-headers.md",
|
||||
".changes/window-state-decorated.md",
|
||||
".changes/window-state-promise.md"
|
||||
".changes/window-state-promise.md",
|
||||
".changes/window-state-zero-positions.md"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"http": "patch"
|
||||
---
|
||||
|
||||
**Breaking change** Removed `Error::InvalidRequestId` variant and added `Error::Tauri` variant.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": "patch"
|
||||
"updater-js": "patch"
|
||||
---
|
||||
|
||||
Fix `Started` event not emitted to JS when downloading update.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"updater": "patch"
|
||||
---
|
||||
|
||||
**Breaking change**: Changed `Update::download` and `Update::download_and_install` first argument to take `FnMut` instead of just `Fn`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": patch
|
||||
"updater-js": patch
|
||||
---
|
||||
|
||||
Add support for specifying proxy to use for checking and downloading updates.
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
"updater": "patch"
|
||||
---
|
||||
|
||||
Refactored the updater plugin to accommodate to the new changes in tauri config:
|
||||
|
||||
- JSON plugin config:
|
||||
|
||||
- Added `pubkey` option.
|
||||
- Added `windows` option which is a Windows-specific options.
|
||||
- Renamed `installer_args` to `installerArgs`.
|
||||
- Moved `installerArgs` option to the new `windows` object.
|
||||
|
||||
- Rust crate changes:
|
||||
- Added `pubkey` field for `Config`.
|
||||
- Added `windows` field for `Config` option which is a Windows-specific options.
|
||||
- Added `WindowsConfig` and `WindowsUpdateInstallMode`.
|
||||
- Moved `installerArgs` option to the new `windows` object.
|
||||
- Added `Builder::pubkey` and `UpdaterBuilder::pubkey`.
|
||||
- Changed `Builder::installer_args` and `UpdaterBuilder::installer_args` to add to existing installer args, instead of replacing them, use `Builder/UpdaterBuilder::clear_installer_args` to clear existing args.
|
||||
- Added `Builder::installer_arg`, `Builder::clear_installer_args`, `UpdaterBuilder::installer_arg` and `UpdaterBuilder::clear_installer_args`.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"window-state": "patch"
|
||||
---
|
||||
|
||||
Address a couple of issues with restoring positions:
|
||||
|
||||
- Fix restoring window positions correctly when the top-left corner of the window was outside of the monitor.
|
||||
- Fix restore maximization state only maximized on main monitor.
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
"prettier",
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:security/recommended"
|
||||
"plugin:security/recommended-legacy"
|
||||
],
|
||||
"overrides": [],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
|
||||
@@ -37,3 +37,5 @@ jobs:
|
||||
- uses: rustsec/audit-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# https://github.com/tauri-apps/plugins-workspace/issues/774
|
||||
ignore: ${{ github.event_name != 'schedule' && 'RUSTSEC-2023-0071' || '' }}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
target
|
||||
node_modules
|
||||
dist
|
||||
dist-js
|
||||
dist-js
|
||||
dist
|
||||
+2
-1
@@ -8,4 +8,5 @@ Cargo.lock
|
||||
build
|
||||
api-iife.js
|
||||
init-iife.js
|
||||
intermediates/
|
||||
intermediates/
|
||||
*schema.json
|
||||
@@ -9,7 +9,11 @@ import readline from "readline";
|
||||
const header = `Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
SPDX-License-Identifier: MIT`;
|
||||
const ignoredLicense = "// Copyright 2021 Jonas Kruckenberg";
|
||||
const ignoredLicenses = [
|
||||
"// Copyright 2021 Flavio Oliveira",
|
||||
"// Copyright 2021 Jonas Kruckenberg",
|
||||
"// Copyright 2018-2023 the Deno authors.",
|
||||
];
|
||||
|
||||
const extensions = [".rs", ".js", ".ts", ".yml", ".swift", ".kt"];
|
||||
const ignore = [
|
||||
@@ -44,7 +48,7 @@ async function checkFile(file) {
|
||||
line.length === 0 ||
|
||||
line.startsWith("#!") ||
|
||||
line.startsWith("// swift-tools-version:") ||
|
||||
line === ignoredLicense
|
||||
ignoredLicenses.includes(line)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Generated
+833
-216
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -10,11 +10,13 @@ resolver = "2"
|
||||
[workspace.dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = "2.0.0-alpha.20"
|
||||
tauri-build = "2.0.0-alpha.13"
|
||||
tauri = "2.0.0-beta.1"
|
||||
tauri-build = "2.0.0-beta.0"
|
||||
tauri-plugin = "2.0.0-beta.0"
|
||||
serde_json = "1"
|
||||
thiserror = "1"
|
||||
url = "2"
|
||||
schemars = "0.8"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `barcode-scanner-js@2.0.0-beta.0`
|
||||
- Upgraded to `biometric-js@2.0.0-beta.0`
|
||||
- Upgraded to `cli-js@2.0.0-beta.0`
|
||||
- Upgraded to `clipboard-manager-js@2.0.0-beta.0`
|
||||
- Upgraded to `dialog-js@2.0.0-beta.0`
|
||||
- Upgraded to `fs-js@2.0.0-beta.0`
|
||||
- Upgraded to `global-shortcut-js@2.0.0-beta.0`
|
||||
- Upgraded to `http-js@2.0.0-beta.0`
|
||||
- Upgraded to `log-js@2.0.0-beta.0`
|
||||
- Upgraded to `nfc-js@2.0.0-beta.0`
|
||||
- Upgraded to `notification-js@2.0.0-beta.0`
|
||||
- Upgraded to `os-js@2.0.0-beta.0`
|
||||
- Upgraded to `process-js@2.0.0-beta.0`
|
||||
- Upgraded to `shell-js@2.0.0-beta.0`
|
||||
- Upgraded to `updater-js@2.0.0-beta.0`
|
||||
|
||||
## \[2.0.0-alpha.9]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `fs-js@2.0.0-alpha.6`
|
||||
|
||||
## \[2.0.0-alpha.8]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `http-js@2.0.0-alpha.6`
|
||||
|
||||
## \[2.0.0-alpha.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
+18
-18
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "svelte-app",
|
||||
"private": true,
|
||||
"version": "2.0.0-alpha.7",
|
||||
"version": "2.0.0-beta.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --clearScreen false",
|
||||
@@ -9,32 +9,32 @@
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.0.0-alpha.13",
|
||||
"@tauri-apps/plugin-barcode-scanner": "2.0.0-alpha.4",
|
||||
"@tauri-apps/plugin-biometric": "2.0.0-alpha.0",
|
||||
"@tauri-apps/plugin-cli": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-dialog": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-fs": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-global-shortcut": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-http": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-nfc": "2.0.0-alpha.0",
|
||||
"@tauri-apps/plugin-notification": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-os": "2.0.0-alpha.6",
|
||||
"@tauri-apps/plugin-process": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-shell": "2.0.0-alpha.5",
|
||||
"@tauri-apps/plugin-updater": "2.0.0-alpha.5",
|
||||
"@tauri-apps/api": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-barcode-scanner": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-biometric": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-cli": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-dialog": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-fs": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-global-shortcut": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-http": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-nfc": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-notification": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-os": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-process": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-shell": "2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-updater": "2.0.0-beta.0",
|
||||
"@zerodevx/svelte-json-view": "1.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/codicon": "^1.1.37",
|
||||
"@iconify-json/ph": "^1.1.8",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.1",
|
||||
"@tauri-apps/cli": "2.0.0-alpha.20",
|
||||
"@tauri-apps/cli": "2.0.0-beta.0",
|
||||
"@unocss/extractor-svelte": "^0.58.0",
|
||||
"internal-ip": "^8.0.0",
|
||||
"svelte": "^4.2.8",
|
||||
"unocss": "^0.58.0",
|
||||
"vite": "^5.0.6"
|
||||
"vite": "^5.0.12"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `barcode-scanner@2.0.0-beta.0`
|
||||
- Upgraded to `biometric@2.0.0-beta.0`
|
||||
- Upgraded to `cli@2.0.0-beta.0`
|
||||
- Upgraded to `clipboard-manager@2.0.0-beta.0`
|
||||
- Upgraded to `dialog@2.0.0-beta.0`
|
||||
- Upgraded to `fs@2.0.0-beta.0`
|
||||
- Upgraded to `global-shortcut@2.0.0-beta.0`
|
||||
- Upgraded to `http@2.0.0-beta.0`
|
||||
- Upgraded to `log@2.0.0-beta.0`
|
||||
- Upgraded to `nfc@2.0.0-beta.0`
|
||||
- Upgraded to `notification@2.0.0-beta.0`
|
||||
- Upgraded to `os@2.0.0-beta.0`
|
||||
- Upgraded to `process@2.0.0-beta.0`
|
||||
- Upgraded to `shell@2.0.0-beta.0`
|
||||
- Upgraded to `updater@2.0.0-beta.0`
|
||||
|
||||
## \[2.0.0-alpha.11]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `fs@2.0.0-alpha.7`
|
||||
- Upgraded to `dialog@2.0.0-alpha.7`
|
||||
- Upgraded to `http@2.0.0-alpha.9`
|
||||
|
||||
## \[2.0.0-alpha.10]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `http@2.0.0-alpha.8`
|
||||
|
||||
## \[2.0.0-alpha.9]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "api"
|
||||
publish = false
|
||||
version = "2.0.0-alpha.9"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "An example Tauri Application showcasing the api"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
@@ -19,15 +19,15 @@ serde_json = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
tiny_http = "0.11"
|
||||
log = { workspace = true }
|
||||
tauri-plugin-log = { path = "../../../plugins/log", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-http = { path = "../../../plugins/http", features = [ "multipart" ], version = "2.0.0-alpha.7" }
|
||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-alpha.7", features = [ "windows7-compat" ] }
|
||||
tauri-plugin-os = { path = "../../../plugins/os", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-process = { path = "../../../plugins/process", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-log = { path = "../../../plugins/log", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-beta.0", features = [ "watch" ] }
|
||||
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-http = { path = "../../../plugins/http", features = [ "multipart" ], version = "2.0.0-beta.0" }
|
||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-beta.0", features = [ "windows7-compat" ] }
|
||||
tauri-plugin-os = { path = "../../../plugins/os", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-process = { path = "../../../plugins/process", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-beta.0" }
|
||||
|
||||
[dependencies.tauri]
|
||||
workspace = true
|
||||
@@ -41,14 +41,14 @@ tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-alpha.6
|
||||
]
|
||||
|
||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-alpha.6" }
|
||||
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-beta.0" }
|
||||
|
||||
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
|
||||
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-alpha.4" }
|
||||
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.0.0-alpha.0" }
|
||||
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.0.0-alpha.0" }
|
||||
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.0.0-beta.0" }
|
||||
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.0.0-beta.0" }
|
||||
|
||||
[target."cfg(target_os = \"windows\")".dependencies]
|
||||
window-shadows = "0.2"
|
||||
|
||||
@@ -7,6 +7,7 @@ fn main() {
|
||||
if !cfg!(feature = "custom-protocol") {
|
||||
codegen = codegen.dev();
|
||||
}
|
||||
codegen.build();
|
||||
tauri_build::build();
|
||||
|
||||
tauri_build::try_build(tauri_build::Attributes::new().codegen(codegen))
|
||||
.expect("failed to run tauri_build::try_build");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"$schema": "schemas/desktop-schema.json",
|
||||
"identifier": "run-app-base",
|
||||
"description": "Base permissions to run the app",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"log:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
{
|
||||
"url": "http://localhost:3003"
|
||||
}
|
||||
]
|
||||
},
|
||||
"app:default",
|
||||
"resources:default",
|
||||
"fs:default",
|
||||
"menu:default",
|
||||
"path:default",
|
||||
"tray:default",
|
||||
"event:default",
|
||||
"window:default",
|
||||
"notification:default",
|
||||
"os:allow-platform",
|
||||
"dialog:allow-open",
|
||||
"dialog:allow-save",
|
||||
"dialog:allow-confirm",
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": [
|
||||
{
|
||||
"name": "sh",
|
||||
"cmd": "sh",
|
||||
"args": [
|
||||
"-c",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cmd",
|
||||
"cmd": "cmd",
|
||||
"args": [
|
||||
"/C",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"shell:allow-kill",
|
||||
"shell:allow-stdin-write",
|
||||
"clipboard-manager:allow-read",
|
||||
"clipboard-manager:allow-write",
|
||||
"fs:allow-rename",
|
||||
"fs:allow-mkdir",
|
||||
"fs:allow-remove",
|
||||
"fs:allow-write-text-file",
|
||||
"fs:scope-download-recursive",
|
||||
"fs:scope-resource-recursive",
|
||||
{
|
||||
"identifier": "fs:scope-appdata-recursive",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$APPDATA/db/**"
|
||||
}
|
||||
],
|
||||
"deny": [
|
||||
{
|
||||
"path": "$APPDATA/db/*.stronghold"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "./schemas/desktop-schema.json",
|
||||
"identifier": "run-app-desktop",
|
||||
"description": "Permissions to run the app (desktop only)",
|
||||
"windows": ["main"],
|
||||
"platforms": ["linux", "macOS", "windows"],
|
||||
"permissions": [
|
||||
"cli:default",
|
||||
"updater:default",
|
||||
"global-shortcut:allow-unregister",
|
||||
"global-shortcut:allow-register",
|
||||
"global-shortcut:allow-unregister-all"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "./schemas/mobile-schema.json",
|
||||
"identifier": "run-app-mobile",
|
||||
"description": "Permissions to run the app (mobile only)",
|
||||
"windows": ["main"],
|
||||
"platforms": ["android", "iOS"],
|
||||
"permissions": [
|
||||
"nfc:allow-write",
|
||||
"nfc:allow-scan",
|
||||
"biometric:allow-authenticate",
|
||||
"barcode-scanner:allow-scan",
|
||||
"barcode-scanner:allow-cancel",
|
||||
"barcode-scanner:allow-request-permissions",
|
||||
"barcode-scanner:allow-check-permissions"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
*.json
|
||||
!desktop-schema.json
|
||||
!mobile-schema.json
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -10,7 +10,7 @@
|
||||
<option name="gradleJvm" value="jbr-17" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$USER_HOME$/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tauri-2.0.0-alpha.17/mobile/android" />
|
||||
<option value="$USER_HOME$/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tauri-2.0.0-beta.0/mobile/android" />
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/buildSrc" />
|
||||
|
||||
@@ -7,7 +7,7 @@ mod cmd;
|
||||
mod tray;
|
||||
|
||||
use serde::Serialize;
|
||||
use tauri::{window::WindowBuilder, App, AppHandle, Manager, RunEvent, WindowUrl};
|
||||
use tauri::{webview::WebviewWindowBuilder, App, AppHandle, Manager, RunEvent, WebviewUrl};
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
struct Reply {
|
||||
@@ -51,10 +51,11 @@ pub fn run() {
|
||||
app.handle().plugin(tauri_plugin_biometric::init())?;
|
||||
}
|
||||
|
||||
let mut window_builder = WindowBuilder::new(app, "main", WindowUrl::default());
|
||||
let mut webview_window_builder =
|
||||
WebviewWindowBuilder::new(app, "main", WebviewUrl::default());
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
window_builder = window_builder
|
||||
webview_window_builder = webview_window_builder
|
||||
.user_agent(&format!("Tauri API - {}", std::env::consts::OS))
|
||||
.title("Tauri API Validation")
|
||||
.inner_size(1000., 800.)
|
||||
@@ -64,7 +65,7 @@ pub fn run() {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
window_builder = window_builder
|
||||
webview_window_builder = webview_window_builder
|
||||
.transparent(true)
|
||||
.shadow(true)
|
||||
.decorations(false);
|
||||
@@ -72,15 +73,14 @@ pub fn run() {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
window_builder = window_builder.transparent(true);
|
||||
webview_window_builder = webview_window_builder.transparent(true);
|
||||
}
|
||||
|
||||
let window = window_builder.build().unwrap();
|
||||
let webview = webview_window_builder.build().unwrap();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
window.open_devtools();
|
||||
webview.open_devtools();
|
||||
|
||||
#[cfg(desktop)]
|
||||
std::thread::spawn(|| {
|
||||
let server = match tiny_http::Server::http("localhost:3003") {
|
||||
Ok(s) => s,
|
||||
@@ -107,15 +107,15 @@ pub fn run() {
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.on_page_load(|window, _| {
|
||||
let window_ = window.clone();
|
||||
window.listen("js-event", move |event| {
|
||||
.on_page_load(|webview, _| {
|
||||
let webview_ = webview.clone();
|
||||
webview.listen("js-event", move |event| {
|
||||
println!("got js-event with message '{:?}'", event.payload());
|
||||
let reply = Reply {
|
||||
data: "something else".to_string(),
|
||||
};
|
||||
|
||||
window_
|
||||
webview_
|
||||
.emit("rust-event", Some(reply))
|
||||
.expect("failed to emit");
|
||||
});
|
||||
|
||||
@@ -6,19 +6,20 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use tauri::{
|
||||
menu::{Menu, MenuItem},
|
||||
tray::{ClickType, TrayIconBuilder},
|
||||
Manager, Runtime, WindowBuilder, WindowUrl,
|
||||
Manager, Runtime, WebviewUrl, WebviewWindowBuilder,
|
||||
};
|
||||
|
||||
pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
||||
let toggle_i = MenuItem::with_id(app, "toggle", "Toggle", true, None);
|
||||
let new_window_i = MenuItem::with_id(app, "new-window", "New window", true, None);
|
||||
let icon_i_1 = MenuItem::with_id(app, "icon-1", "Icon 1", true, None);
|
||||
let icon_i_2 = MenuItem::with_id(app, "icon-2", "Icon 2", true, None);
|
||||
let toggle_i = MenuItem::with_id(app, "toggle", "Toggle", true, None::<&str>)?;
|
||||
let new_window_i = MenuItem::with_id(app, "new-window", "New window", true, None::<&str>)?;
|
||||
let icon_i_1 = MenuItem::with_id(app, "icon-1", "Icon 1", true, None::<&str>)?;
|
||||
let icon_i_2 = MenuItem::with_id(app, "icon-2", "Icon 2", true, None::<&str>)?;
|
||||
#[cfg(target_os = "macos")]
|
||||
let set_title_i = MenuItem::with_id(app, "set-title", "Set Title", true, None);
|
||||
let switch_i = MenuItem::with_id(app, "switch-menu", "Switch Menu", true, None);
|
||||
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None);
|
||||
let remove_tray_i = MenuItem::with_id(app, "remove-tray", "Remove Tray icon", true, None);
|
||||
let set_title_i = MenuItem::with_id(app, "set-title", "Set Title", true, None::<&str>)?;
|
||||
let switch_i = MenuItem::with_id(app, "switch-menu", "Switch Menu", true, None::<&str>)?;
|
||||
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
|
||||
let remove_tray_i =
|
||||
MenuItem::with_id(app, "remove-tray", "Remove Tray icon", true, None::<&str>)?;
|
||||
let menu1 = Menu::with_items(
|
||||
app,
|
||||
&[
|
||||
@@ -53,7 +54,7 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
||||
app.remove_tray_by_id("tray-1");
|
||||
}
|
||||
"toggle" => {
|
||||
if let Some(window) = app.get_window("main") {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let new_title = if window.is_visible().unwrap_or_default() {
|
||||
let _ = window.hide();
|
||||
"Show"
|
||||
@@ -66,7 +67,7 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
||||
}
|
||||
}
|
||||
"new-window" => {
|
||||
let _ = WindowBuilder::new(app, "new", WindowUrl::App("index.html".into()))
|
||||
let _ = WebviewWindowBuilder::new(app, "new", WebviewUrl::App("index.html".into()))
|
||||
.title("Tauri")
|
||||
.build();
|
||||
}
|
||||
@@ -104,7 +105,7 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
||||
.on_tray_icon_event(|tray, event| {
|
||||
if event.click_type == ClickType::Left {
|
||||
let app = tray.app_handle();
|
||||
if let Some(window) = app.get_window("main") {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"productName": "Tauri API",
|
||||
"version": "2.0.0",
|
||||
"identifier": "com.tauri.api",
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
"devPath": "http://localhost:5173",
|
||||
"devUrl": "http://localhost:5173",
|
||||
"frontendDist": "../dist",
|
||||
"beforeDevCommand": "yarn dev",
|
||||
"beforeBuildCommand": "yarn build",
|
||||
"withGlobalTauri": true
|
||||
"beforeBuildCommand": "yarn build"
|
||||
},
|
||||
"package": {
|
||||
"productName": "Tauri API",
|
||||
"version": "2.0.0"
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"macOSPrivateApi": true,
|
||||
"security": {
|
||||
"pattern": {
|
||||
"use": "isolation",
|
||||
"options": {
|
||||
"dir": "../isolation-dist/"
|
||||
}
|
||||
},
|
||||
"csp": {
|
||||
"default-src": "'self' customprotocol: asset:",
|
||||
"connect-src": "ipc: http://ipc.localhost",
|
||||
"font-src": ["https://fonts.gstatic.com"],
|
||||
"img-src": "'self' asset: http://asset.localhost blob: data:",
|
||||
"style-src": "'unsafe-inline' 'self' http://fonts.googleapis.com"
|
||||
},
|
||||
"freezePrototype": true,
|
||||
"assetProtocol": {
|
||||
"enable": true,
|
||||
"scope": {
|
||||
"allow": ["$APPDATA/db/**", "$RESOURCE/**"],
|
||||
"deny": ["$APPDATA/db/*.stronghold"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"cli": {
|
||||
@@ -47,95 +72,33 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs": {
|
||||
"scope": {
|
||||
"allow": ["$APPDATA/db/**", "$DOWNLOAD/**", "$RESOURCE/**"],
|
||||
"deny": ["$APPDATA/db/*.stronghold"]
|
||||
}
|
||||
},
|
||||
"shell": {
|
||||
"open": true,
|
||||
"scope": [
|
||||
{
|
||||
"name": "sh",
|
||||
"cmd": "sh",
|
||||
"args": [
|
||||
"-c",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cmd",
|
||||
"cmd": "cmd",
|
||||
"args": [
|
||||
"/C",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"http": {
|
||||
"scope": ["http://localhost:3003"]
|
||||
"open": true
|
||||
},
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDE5QzMxNjYwNTM5OEUwNTgKUldSWTRKaFRZQmJER1h4d1ZMYVA3dnluSjdpN2RmMldJR09hUFFlZDY0SlFqckkvRUJhZDJVZXAK",
|
||||
"endpoints": [
|
||||
"https://tauri-update-server.vercel.app/update/{{target}}/{{current_version}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tauri": {
|
||||
"pattern": {
|
||||
"use": "isolation",
|
||||
"options": {
|
||||
"dir": "../isolation-dist/"
|
||||
}
|
||||
},
|
||||
"macOSPrivateApi": true,
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"identifier": "com.tauri.api",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"windows": {
|
||||
"wix": {
|
||||
"language": {
|
||||
"en-US": {},
|
||||
"pt-BR": {
|
||||
"localePath": "locales/pt-BR.wxl"
|
||||
}
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"windows": {
|
||||
"wix": {
|
||||
"language": {
|
||||
"en-US": {},
|
||||
"pt-BR": {
|
||||
"localePath": "locales/pt-BR.wxl"
|
||||
}
|
||||
}
|
||||
},
|
||||
"updater": {
|
||||
"active": true,
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDE5QzMxNjYwNTM5OEUwNTgKUldSWTRKaFRZQmJER1h4d1ZMYVA3dnluSjdpN2RmMldJR09hUFFlZDY0SlFqckkvRUJhZDJVZXAK"
|
||||
}
|
||||
},
|
||||
"windows": [],
|
||||
"security": {
|
||||
"csp": {
|
||||
"default-src": "'self' customprotocol: asset:",
|
||||
"connect-src": "ipc: http://ipc.localhost",
|
||||
"font-src": ["https://fonts.gstatic.com"],
|
||||
"img-src": "'self' asset: http://asset.localhost blob: data:",
|
||||
"style-src": "'unsafe-inline' 'self' http://fonts.googleapis.com"
|
||||
},
|
||||
"freezePrototype": true,
|
||||
"assetProtocol": {
|
||||
"enable": true,
|
||||
"scope": {
|
||||
"allow": ["$APPDATA/db/**", "$RESOURCE/**"],
|
||||
"deny": ["$APPDATA/db/*.stronghold"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { open, save, confirm } from "@tauri-apps/plugin-dialog";
|
||||
import { open, save, confirm, message } from "@tauri-apps/plugin-dialog";
|
||||
import { readFile } from "@tauri-apps/plugin-fs";
|
||||
|
||||
export let onMessage;
|
||||
@@ -22,6 +22,16 @@
|
||||
}
|
||||
|
||||
async function prompt() {
|
||||
confirm("Do you want to do something?")
|
||||
.then((res) =>
|
||||
onMessage(
|
||||
res ? "Yes" : "No"
|
||||
)
|
||||
)
|
||||
.catch(onMessage);
|
||||
}
|
||||
|
||||
async function promptCustom() {
|
||||
confirm("Is Tauri awesome?", {
|
||||
okLabel: "Absolutely",
|
||||
cancelLabel: "Totally",
|
||||
@@ -34,6 +44,10 @@
|
||||
.catch(onMessage);
|
||||
}
|
||||
|
||||
async function msg() {
|
||||
await message("Tauri is awesome!");
|
||||
}
|
||||
|
||||
function openDialog() {
|
||||
open({
|
||||
title: "My wonderful open dialog",
|
||||
@@ -130,3 +144,5 @@
|
||||
>Open save dialog</button
|
||||
>
|
||||
<button class="btn" id="prompt-dialog" on:click={prompt}>Prompt</button>
|
||||
<button class="btn" id="custom-prompt-dialog" on:click={promptCustom}>Prompt (custom)</button>
|
||||
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
let img;
|
||||
let file;
|
||||
let renameTo;
|
||||
let watchPath = "";
|
||||
let watchDebounceDelay = 0;
|
||||
let watchRecursive = false;
|
||||
let unwatchFn;
|
||||
let unwatchPath = "";
|
||||
|
||||
function getDir() {
|
||||
const dirSelect = document.getElementById("dir");
|
||||
@@ -141,6 +146,41 @@
|
||||
function setSrc() {
|
||||
img.src = convertFileSrc(path);
|
||||
}
|
||||
|
||||
function watch() {
|
||||
unwatch();
|
||||
if (watchPath) {
|
||||
onMessage(`Watching ${watchPath} for changes`);
|
||||
let options = {
|
||||
recursive: watchRecursive,
|
||||
delayMs: parseInt(watchDebounceDelay),
|
||||
};
|
||||
if (options.delayMs === 0) {
|
||||
fs.watchImmediate(watchPath, onMessage, options)
|
||||
.then((fn) => {
|
||||
unwatchFn = fn;
|
||||
unwatchPath = watchPath;
|
||||
})
|
||||
.catch(onMessage);
|
||||
} else {
|
||||
fs.watch(watchPath, onMessage, options)
|
||||
.then((fn) => {
|
||||
unwatchFn = fn;
|
||||
unwatchPath = watchPath;
|
||||
})
|
||||
.catch(onMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unwatch() {
|
||||
if (unwatchFn) {
|
||||
onMessage(`Stopped watching ${unwatchPath} for changes`);
|
||||
unwatchFn();
|
||||
}
|
||||
unwatchFn = undefined;
|
||||
unwatchPath = undefined;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col">
|
||||
@@ -175,6 +215,33 @@
|
||||
<button class="btn" on:click={stat}>Stat</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h3>Watch</h3>
|
||||
|
||||
<input
|
||||
class="input grow"
|
||||
placeholder="Type the path to watch..."
|
||||
bind:value={watchPath}
|
||||
/>
|
||||
<br />
|
||||
<div>
|
||||
<label for="watch-debounce-delay">Debounce delay in milliseconds (`0` disables the debouncer)</label>
|
||||
<input
|
||||
class="input"
|
||||
id="watch-debounce-delay"
|
||||
bind:value={watchDebounceDelay}
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<input type="checkbox" id="watch-recursive" bind:checked={watchRecursive} />
|
||||
<label for="watch-recursive">Recursive</label>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<button class="btn" on:click={watch}>Watch</button>
|
||||
<button class="btn" on:click={unwatch}>Unwatch</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
@@ -11,8 +11,8 @@ import process from "process";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(async () => {
|
||||
const host =
|
||||
process.env.TAURI_PLATFORM === "android" ||
|
||||
process.env.TAURI_PLATFORM === "ios"
|
||||
process.env.TAURI_ENV_PLATFORM === "android" ||
|
||||
process.env.TAURI_ENV_PLATFORM === "ios"
|
||||
? await internalIpV4()
|
||||
: "localhost";
|
||||
return {
|
||||
|
||||
+11
-11
@@ -12,20 +12,20 @@
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"@rollup/plugin-terser": "0.4.4",
|
||||
"@rollup/plugin-typescript": "11.1.5",
|
||||
"@typescript-eslint/eslint-plugin": "6.13.2",
|
||||
"@typescript-eslint/parser": "6.13.2",
|
||||
"@rollup/plugin-typescript": "11.1.6",
|
||||
"@typescript-eslint/eslint-plugin": "6.20.0",
|
||||
"@typescript-eslint/parser": "6.20.0",
|
||||
"covector": "^0.10.2",
|
||||
"eslint": "8.55.0",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-config-standard-with-typescript": "40.0.0",
|
||||
"eslint-plugin-import": "2.29.0",
|
||||
"eslint-plugin-n": "16.3.1",
|
||||
"eslint-config-standard-with-typescript": "43.0.1",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-n": "16.6.2",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
"eslint-plugin-security": "1.7.1",
|
||||
"prettier": "3.1.0",
|
||||
"rollup": "4.6.1",
|
||||
"typescript": "5.3.2"
|
||||
"eslint-plugin-security": "2.1.0",
|
||||
"prettier": "3.2.2",
|
||||
"rollup": "4.9.6",
|
||||
"typescript": "5.3.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"semver": ">=7.5.2",
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
- [`d198c01`](https://github.com/tauri-apps/plugins-workspace/commit/d198c014863ee260cb0de88a14b7fc4356ef7474)([#862](https://github.com/tauri-apps/plugins-workspace/pull/862)) Update to tauri beta.
|
||||
|
||||
## \[2.0.0-alpha.5]
|
||||
|
||||
- [`387c2f9`](https://github.com/tauri-apps/plugins-workspace/commit/387c2f9e0ce4c75c07ffa3fd76391a25b58f5daf)([#802](https://github.com/tauri-apps/plugins-workspace/pull/802)) Update to @tauri-apps/api v2.0.0-alpha.13.
|
||||
@@ -32,3 +36,4 @@
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- [`717ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
[package]
|
||||
name = "tauri-plugin-authenticator"
|
||||
version = "2.0.0-alpha.6"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Use hardware security-keys in your Tauri App."
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
links = "tauri-plugin-authenticator"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustc-args = [ "--cfg", "docsrs" ]
|
||||
rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-plugin = { workspace = true, features = [ "build" ] }
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
@@ -23,8 +27,10 @@ authenticator = "0.3.1"
|
||||
once_cell = "1"
|
||||
sha2 = "0.10"
|
||||
base64 = "0.21"
|
||||
u2f = "0.2"
|
||||
chrono = ">= 0.4.0, <0.4.30"
|
||||
chrono = "0.4"
|
||||
bytes = "1"
|
||||
byteorder = "1"
|
||||
openssl = "0.10"
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8"
|
||||
|
||||
@@ -21,7 +21,7 @@ Install the authenticator plugin by adding the following lines to your `Cargo.to
|
||||
```toml
|
||||
# you can add the dependencies on the `[dependencies]` section if you do not target mobile
|
||||
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
|
||||
tauri-plugin-authenticator = "2.0.0-alpha"
|
||||
tauri-plugin-authenticator = "2.0.0-beta"
|
||||
# alternatively with Git:
|
||||
tauri-plugin-authenticator = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
|
||||
```
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const COMMANDS: &[&str] = &[
|
||||
"init_auth",
|
||||
"register",
|
||||
"verify_registration",
|
||||
"sign",
|
||||
"verify_signature",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
tauri_plugin::Builder::new(COMMANDS).build();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-authenticator",
|
||||
"version": "2.0.0-alpha.5",
|
||||
"version": "2.0.0-beta.0",
|
||||
"description": "Use hardware security-keys in your Tauri App.",
|
||||
"license": "MIT or APACHE-2.0",
|
||||
"authors": [
|
||||
@@ -24,6 +24,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.0.0-alpha.13"
|
||||
"@tauri-apps/api": "2.0.0-beta.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-init-auth"
|
||||
description = "Enables the init_auth command without any pre-configured scope."
|
||||
commands.allow = ["init_auth"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-init-auth"
|
||||
description = "Denies the init_auth command without any pre-configured scope."
|
||||
commands.deny = ["init_auth"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-register"
|
||||
description = "Enables the register command without any pre-configured scope."
|
||||
commands.allow = ["register"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-register"
|
||||
description = "Denies the register command without any pre-configured scope."
|
||||
commands.deny = ["register"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-sign"
|
||||
description = "Enables the sign command without any pre-configured scope."
|
||||
commands.allow = ["sign"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-sign"
|
||||
description = "Denies the sign command without any pre-configured scope."
|
||||
commands.deny = ["sign"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-verify-registration"
|
||||
description = "Enables the verify_registration command without any pre-configured scope."
|
||||
commands.allow = ["verify_registration"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-verify-registration"
|
||||
description = "Denies the verify_registration command without any pre-configured scope."
|
||||
commands.deny = ["verify_registration"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-verify-signature"
|
||||
description = "Enables the verify_signature command without any pre-configured scope."
|
||||
commands.allow = ["verify_signature"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-verify-signature"
|
||||
description = "Denies the verify_signature command without any pre-configured scope."
|
||||
commands.deny = ["verify_signature"]
|
||||
@@ -0,0 +1,42 @@
|
||||
# Permissions
|
||||
|
||||
## allow-init-auth
|
||||
|
||||
Enables the init_auth command without any pre-configured scope.
|
||||
|
||||
## deny-init-auth
|
||||
|
||||
Denies the init_auth command without any pre-configured scope.
|
||||
|
||||
## allow-register
|
||||
|
||||
Enables the register command without any pre-configured scope.
|
||||
|
||||
## deny-register
|
||||
|
||||
Denies the register command without any pre-configured scope.
|
||||
|
||||
## allow-sign
|
||||
|
||||
Enables the sign command without any pre-configured scope.
|
||||
|
||||
## deny-sign
|
||||
|
||||
Denies the sign command without any pre-configured scope.
|
||||
|
||||
## allow-verify-registration
|
||||
|
||||
Enables the verify_registration command without any pre-configured scope.
|
||||
|
||||
## deny-verify-registration
|
||||
|
||||
Denies the verify_registration command without any pre-configured scope.
|
||||
|
||||
## allow-verify-signature
|
||||
|
||||
Enables the verify_signature command without any pre-configured scope.
|
||||
|
||||
## deny-verify-signature
|
||||
|
||||
Denies the verify_signature command without any pre-configured scope.
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PermissionFile",
|
||||
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "The default permission set for the plugin",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/DefaultPermission"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"set": {
|
||||
"description": "A list of permissions sets defined",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionSet"
|
||||
}
|
||||
},
|
||||
"permission": {
|
||||
"description": "A list of inlined permissions",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Permission"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DefaultPermission": {
|
||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PermissionSet": {
|
||||
"description": "A set of direct permissions grouped together under a new name.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description",
|
||||
"identifier",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": "string"
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionKind"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Permission": {
|
||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"description": "Allowed or denied commands when using this permission.",
|
||||
"default": {
|
||||
"allow": [],
|
||||
"deny": []
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope": {
|
||||
"description": "Allowed or denied scoped when using this permission.",
|
||||
"default": {},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Scopes"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Commands": {
|
||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Allowed command.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Denied command, which takes priority.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scopes": {
|
||||
"description": "A restriction of the command/endpoint functionality.\n\nIt can be of any serde serializable type and is used for allowing or preventing certain actions inside a Tauri command.\n\nThe scope is passed to the command and handled/enforced by the command itself.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionKind": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "allow-init-auth -> Enables the init_auth command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-init-auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-init-auth -> Denies the init_auth command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-init-auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-register -> Enables the register command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-register"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-register -> Denies the register command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-register"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-sign -> Enables the sign command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-sign"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-sign -> Denies the sign command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-sign"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-verify-registration -> Enables the verify_registration command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-verify-registration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-verify-registration -> Denies the verify_registration command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-verify-registration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-verify-signature -> Enables the verify_signature command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-verify-signature"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-verify-signature -> Denies the verify_signature command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-verify-signature"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ pub enum Error {
|
||||
#[error(transparent)]
|
||||
JSON(#[from] serde_json::Error),
|
||||
#[error(transparent)]
|
||||
U2F(#[from] u2f::u2ferror::U2fError),
|
||||
U2F(#[from] crate::u2f_crate::u2ferror::U2fError),
|
||||
#[error(transparent)]
|
||||
Auth(#[from] authenticator::errors::AuthenticatorError),
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
mod auth;
|
||||
mod error;
|
||||
mod u2f;
|
||||
mod u2f_crate;
|
||||
|
||||
use tauri::{
|
||||
plugin::{Builder as PluginBuilder, TauriPlugin},
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::u2f_crate::messages::*;
|
||||
use crate::u2f_crate::protocol::*;
|
||||
use crate::u2f_crate::register::*;
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
|
||||
use chrono::prelude::*;
|
||||
use serde::Serialize;
|
||||
use std::convert::Into;
|
||||
use u2f::messages::*;
|
||||
use u2f::protocol::*;
|
||||
use u2f::register::*;
|
||||
|
||||
static VERSION: &str = "U2F_V2";
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Copyright (c) 2017
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license (http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use bytes::{Buf, BufMut};
|
||||
use openssl::sha::sha256;
|
||||
use serde::Serialize;
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::u2f_crate::u2ferror::U2fError;
|
||||
|
||||
/// The `Result` type used in this crate.
|
||||
type Result<T> = ::std::result::Result<T, U2fError>;
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Authorization {
|
||||
pub counter: u32,
|
||||
pub user_presence: bool,
|
||||
}
|
||||
|
||||
pub fn parse_sign_response(
|
||||
app_id: String,
|
||||
client_data: Vec<u8>,
|
||||
public_key: Vec<u8>,
|
||||
sign_data: Vec<u8>,
|
||||
) -> Result<Authorization> {
|
||||
if sign_data.len() <= 5 {
|
||||
return Err(U2fError::InvalidSignatureData);
|
||||
}
|
||||
|
||||
let user_presence_flag = &sign_data[0];
|
||||
let counter = &sign_data[1..=4];
|
||||
let signature = &sign_data[5..];
|
||||
|
||||
// Let's build the msg to verify the signature
|
||||
let app_id_hash = sha256(&app_id.into_bytes());
|
||||
let client_data_hash = sha256(&client_data[..]);
|
||||
|
||||
let mut msg = vec![];
|
||||
msg.put(app_id_hash.as_ref());
|
||||
msg.put_u8(*user_presence_flag);
|
||||
msg.put(counter);
|
||||
msg.put(client_data_hash.as_ref());
|
||||
|
||||
let public_key = super::crypto::NISTP256Key::from_bytes(&public_key)?;
|
||||
|
||||
// The signature is to be verified by the relying party using the public key obtained during registration.
|
||||
let verified = public_key.verify_signature(signature, msg.as_ref())?;
|
||||
if !verified {
|
||||
return Err(U2fError::BadSignature);
|
||||
}
|
||||
|
||||
let authorization = Authorization {
|
||||
counter: get_counter(counter),
|
||||
user_presence: true,
|
||||
};
|
||||
|
||||
Ok(authorization)
|
||||
}
|
||||
|
||||
fn get_counter(counter: &[u8]) -> u32 {
|
||||
let mut buf = Cursor::new(counter);
|
||||
buf.get_u32()
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Cryptographic operation wrapper for Webauthn. This module exists to
|
||||
//! allow ease of auditing, safe operation wrappers for the webauthn library,
|
||||
//! and cryptographic provider abstraction. This module currently uses OpenSSL
|
||||
//! as the cryptographic primitive provider.
|
||||
|
||||
// Source can be found here: https://github.com/Firstyear/webauthn-rs/blob/master/src/crypto.rs
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use openssl::{bn, ec, hash, nid, sign, x509};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
// use super::constants::*;
|
||||
use crate::u2f_crate::u2ferror::U2fError;
|
||||
use openssl::pkey::Public;
|
||||
|
||||
// use super::proto::*;
|
||||
|
||||
// Why OpenSSL over another rust crate?
|
||||
// - Well, the openssl crate allows us to reconstruct a public key from the
|
||||
// x/y group coords, where most others want a pkcs formatted structure. As
|
||||
// a result, it's easiest to use openssl as it gives us exactly what we need
|
||||
// for these operations, and despite it's many challenges as a library, it
|
||||
// has resources and investment into it's maintenance, so we can a least
|
||||
// assert a higher level of confidence in it that <backyard crypto here>.
|
||||
|
||||
// Object({Integer(-3): Bytes([48, 185, 178, 204, 113, 186, 105, 138, 190, 33, 160, 46, 131, 253, 100, 177, 91, 243, 126, 128, 245, 119, 209, 59, 186, 41, 215, 196, 24, 222, 46, 102]), Integer(-2): Bytes([158, 212, 171, 234, 165, 197, 86, 55, 141, 122, 253, 6, 92, 242, 242, 114, 158, 221, 238, 163, 127, 214, 120, 157, 145, 226, 232, 250, 144, 150, 218, 138]), Integer(-1): U64(1), Integer(1): U64(2), Integer(3): I64(-7)})
|
||||
//
|
||||
|
||||
/// An X509PublicKey. This is what is otherwise known as a public certificate
|
||||
/// which comprises a public key and other signed metadata related to the issuer
|
||||
/// of the key.
|
||||
pub struct X509PublicKey {
|
||||
pubk: x509::X509,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for X509PublicKey {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "X509PublicKey")
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&[u8]> for X509PublicKey {
|
||||
type Error = U2fError;
|
||||
|
||||
// Must be DER bytes. If you have PEM, base64decode first!
|
||||
fn try_from(d: &[u8]) -> Result<Self, Self::Error> {
|
||||
let pubk = x509::X509::from_der(d)?;
|
||||
Ok(X509PublicKey { pubk })
|
||||
}
|
||||
}
|
||||
|
||||
impl X509PublicKey {
|
||||
pub(crate) fn common_name(&self) -> Option<String> {
|
||||
let cert = &self.pubk;
|
||||
|
||||
let subject = cert.subject_name();
|
||||
let common = subject
|
||||
.entries_by_nid(openssl::nid::Nid::COMMONNAME)
|
||||
.next()
|
||||
.map(|b| b.data().as_slice());
|
||||
|
||||
if let Some(common) = common {
|
||||
std::str::from_utf8(common).ok().map(|s| s.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_secp256r1(&self) -> Result<bool, U2fError> {
|
||||
// Can we get the public key?
|
||||
let pk = self.pubk.public_key()?;
|
||||
|
||||
let ec_key = pk.ec_key()?;
|
||||
|
||||
ec_key.check_key()?;
|
||||
|
||||
let ec_grpref = ec_key.group();
|
||||
|
||||
let ec_curve = ec_grpref.curve_name().ok_or(U2fError::OpenSSLNoCurveName)?;
|
||||
|
||||
Ok(ec_curve == nid::Nid::X9_62_PRIME256V1)
|
||||
}
|
||||
|
||||
pub(crate) fn verify_signature(
|
||||
&self,
|
||||
signature: &[u8],
|
||||
verification_data: &[u8],
|
||||
) -> Result<bool, U2fError> {
|
||||
let pkey = self.pubk.public_key()?;
|
||||
|
||||
// TODO: Should this determine the hash type from the x509 cert? Or other?
|
||||
let mut verifier = sign::Verifier::new(hash::MessageDigest::sha256(), &pkey)?;
|
||||
verifier.update(verification_data)?;
|
||||
Ok(verifier.verify(signature)?)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NISTP256Key {
|
||||
/// The key's public X coordinate.
|
||||
pub x: [u8; 32],
|
||||
/// The key's public Y coordinate.
|
||||
pub y: [u8; 32],
|
||||
}
|
||||
|
||||
impl NISTP256Key {
|
||||
pub fn from_bytes(public_key_bytes: &[u8]) -> Result<Self, U2fError> {
|
||||
if public_key_bytes.len() != 65 {
|
||||
return Err(U2fError::InvalidPublicKey);
|
||||
}
|
||||
|
||||
if public_key_bytes[0] != 0x04 {
|
||||
return Err(U2fError::InvalidPublicKey);
|
||||
}
|
||||
|
||||
let mut x: [u8; 32] = Default::default();
|
||||
x.copy_from_slice(&public_key_bytes[1..=32]);
|
||||
|
||||
let mut y: [u8; 32] = Default::default();
|
||||
y.copy_from_slice(&public_key_bytes[33..=64]);
|
||||
|
||||
Ok(NISTP256Key { x, y })
|
||||
}
|
||||
|
||||
fn get_key(&self) -> Result<ec::EcKey<Public>, U2fError> {
|
||||
let ec_group = ec::EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1)?;
|
||||
|
||||
let xbn = bn::BigNum::from_slice(&self.x)?;
|
||||
let ybn = bn::BigNum::from_slice(&self.y)?;
|
||||
|
||||
let ec_key = openssl::ec::EcKey::from_public_key_affine_coordinates(&ec_group, &xbn, &ybn)?;
|
||||
|
||||
// Validate the key is sound. IIRC this actually checks the values
|
||||
// are correctly on the curve as specified
|
||||
ec_key.check_key()?;
|
||||
|
||||
Ok(ec_key)
|
||||
}
|
||||
|
||||
pub fn verify_signature(
|
||||
&self,
|
||||
signature: &[u8],
|
||||
verification_data: &[u8],
|
||||
) -> Result<bool, U2fError> {
|
||||
let pkey = self.get_key()?;
|
||||
|
||||
let signature = openssl::ecdsa::EcdsaSig::from_der(signature)?;
|
||||
let hash = openssl::sha::sha256(verification_data);
|
||||
|
||||
Ok(signature.verify(hash.as_ref(), &pkey)?)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// As defined by FIDO U2F Javascript API.
|
||||
// https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-javascript-api.html#registration
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct U2fRegisterRequest {
|
||||
pub app_id: String,
|
||||
pub register_requests: Vec<RegisterRequest>,
|
||||
pub registered_keys: Vec<RegisteredKey>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RegisterRequest {
|
||||
pub version: String,
|
||||
pub challenge: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RegisteredKey {
|
||||
pub version: String,
|
||||
pub key_handle: Option<String>,
|
||||
pub app_id: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RegisterResponse {
|
||||
pub registration_data: String,
|
||||
pub version: String,
|
||||
pub client_data: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct U2fSignRequest {
|
||||
pub app_id: String,
|
||||
pub challenge: String,
|
||||
pub registered_keys: Vec<RegisteredKey>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SignResponse {
|
||||
pub key_handle: String,
|
||||
pub signature_data: String,
|
||||
pub client_data: String,
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
mod util;
|
||||
|
||||
pub mod authorization;
|
||||
mod crypto;
|
||||
pub mod messages;
|
||||
pub mod protocol;
|
||||
pub mod register;
|
||||
pub mod u2ferror;
|
||||
@@ -0,0 +1,192 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::u2f_crate::authorization::*;
|
||||
use crate::u2f_crate::messages::*;
|
||||
use crate::u2f_crate::register::*;
|
||||
use crate::u2f_crate::u2ferror::U2fError;
|
||||
use crate::u2f_crate::util::*;
|
||||
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
|
||||
use chrono::prelude::*;
|
||||
use chrono::Duration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
type Result<T> = ::std::result::Result<T, U2fError>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct U2f {
|
||||
app_id: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Challenge {
|
||||
pub app_id: String,
|
||||
pub challenge: String,
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
impl Challenge {
|
||||
// Not used in this plugin.
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Self {
|
||||
Challenge {
|
||||
app_id: String::new(),
|
||||
challenge: String::new(),
|
||||
timestamp: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl U2f {
|
||||
// The app ID is a string used to uniquely identify an U2F app
|
||||
pub fn new(app_id: String) -> Self {
|
||||
U2f { app_id }
|
||||
}
|
||||
|
||||
// Not used in this plugin.
|
||||
#[allow(dead_code)]
|
||||
pub fn generate_challenge(&self) -> Result<Challenge> {
|
||||
let utc: DateTime<Utc> = Utc::now();
|
||||
|
||||
let challenge_bytes = generate_challenge(32)?;
|
||||
let challenge = Challenge {
|
||||
challenge: URL_SAFE_NO_PAD.encode(challenge_bytes),
|
||||
timestamp: format!("{:?}", utc),
|
||||
app_id: self.app_id.clone(),
|
||||
};
|
||||
|
||||
Ok(challenge.clone())
|
||||
}
|
||||
|
||||
// Not used in this plugin.
|
||||
#[allow(dead_code)]
|
||||
pub fn request(
|
||||
&self,
|
||||
challenge: Challenge,
|
||||
registrations: Vec<Registration>,
|
||||
) -> Result<U2fRegisterRequest> {
|
||||
let u2f_request = U2fRegisterRequest {
|
||||
app_id: self.app_id.clone(),
|
||||
register_requests: self.register_request(challenge),
|
||||
registered_keys: self.registered_keys(registrations),
|
||||
};
|
||||
|
||||
Ok(u2f_request)
|
||||
}
|
||||
|
||||
fn register_request(&self, challenge: Challenge) -> Vec<RegisterRequest> {
|
||||
let mut requests: Vec<RegisterRequest> = vec![];
|
||||
|
||||
let request = RegisterRequest {
|
||||
version: U2F_V2.into(),
|
||||
challenge: challenge.challenge,
|
||||
};
|
||||
requests.push(request);
|
||||
|
||||
requests
|
||||
}
|
||||
|
||||
pub fn register_response(
|
||||
&self,
|
||||
challenge: Challenge,
|
||||
response: RegisterResponse,
|
||||
) -> Result<Registration> {
|
||||
if expiration(challenge.timestamp) > Duration::seconds(300) {
|
||||
return Err(U2fError::ChallengeExpired);
|
||||
}
|
||||
|
||||
let registration_data: Vec<u8> = URL_SAFE_NO_PAD
|
||||
.decode(&response.registration_data[..])
|
||||
.unwrap();
|
||||
let client_data: Vec<u8> = URL_SAFE_NO_PAD.decode(&response.client_data[..]).unwrap();
|
||||
|
||||
parse_registration(challenge.app_id, client_data, registration_data)
|
||||
}
|
||||
|
||||
fn registered_keys(&self, registrations: Vec<Registration>) -> Vec<RegisteredKey> {
|
||||
let mut keys: Vec<RegisteredKey> = vec![];
|
||||
|
||||
for registration in registrations {
|
||||
keys.push(get_registered_key(
|
||||
self.app_id.clone(),
|
||||
registration.key_handle,
|
||||
));
|
||||
}
|
||||
|
||||
keys
|
||||
}
|
||||
|
||||
// Not used in this plugin.
|
||||
#[allow(dead_code)]
|
||||
pub fn sign_request(
|
||||
&self,
|
||||
challenge: Challenge,
|
||||
registrations: Vec<Registration>,
|
||||
) -> U2fSignRequest {
|
||||
let mut keys: Vec<RegisteredKey> = vec![];
|
||||
|
||||
for registration in registrations {
|
||||
keys.push(get_registered_key(
|
||||
self.app_id.clone(),
|
||||
registration.key_handle,
|
||||
));
|
||||
}
|
||||
|
||||
let signed_request = U2fSignRequest {
|
||||
app_id: self.app_id.clone(),
|
||||
challenge: URL_SAFE_NO_PAD.encode(challenge.challenge.as_bytes()),
|
||||
registered_keys: keys,
|
||||
};
|
||||
|
||||
signed_request
|
||||
}
|
||||
|
||||
pub fn sign_response(
|
||||
&self,
|
||||
challenge: Challenge,
|
||||
reg: Registration,
|
||||
sign_resp: SignResponse,
|
||||
counter: u32,
|
||||
) -> Result<u32> {
|
||||
if expiration(challenge.timestamp) > Duration::seconds(300) {
|
||||
return Err(U2fError::ChallengeExpired);
|
||||
}
|
||||
|
||||
if sign_resp.key_handle != get_encoded(®.key_handle[..]) {
|
||||
return Err(U2fError::WrongKeyHandler);
|
||||
}
|
||||
|
||||
let client_data: Vec<u8> = URL_SAFE_NO_PAD
|
||||
.decode(&sign_resp.client_data[..])
|
||||
.map_err(|_e| U2fError::InvalidClientData)?;
|
||||
let sign_data: Vec<u8> = URL_SAFE_NO_PAD
|
||||
.decode(&sign_resp.signature_data[..])
|
||||
.map_err(|_e| U2fError::InvalidSignatureData)?;
|
||||
|
||||
let public_key = reg.pub_key;
|
||||
|
||||
let auth = parse_sign_response(
|
||||
self.app_id.clone(),
|
||||
client_data.clone(),
|
||||
public_key,
|
||||
sign_data.clone(),
|
||||
);
|
||||
|
||||
match auth {
|
||||
Ok(ref res) => {
|
||||
// CounterTooLow is raised when the counter value received from the device is
|
||||
// lower than last stored counter value.
|
||||
if res.counter < counter {
|
||||
Err(U2fError::CounterTooLow)
|
||||
} else {
|
||||
Ok(res.counter)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use bytes::{BufMut, Bytes};
|
||||
use openssl::sha::sha256;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::u2f_crate::messages::RegisteredKey;
|
||||
use crate::u2f_crate::u2ferror::U2fError;
|
||||
use crate::u2f_crate::util::*;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// The `Result` type used in this crate.
|
||||
type Result<T> = ::std::result::Result<T, U2fError>;
|
||||
|
||||
// Single enrolment or pairing between an application and a token.
|
||||
#[derive(Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Registration {
|
||||
pub key_handle: Vec<u8>,
|
||||
pub pub_key: Vec<u8>,
|
||||
|
||||
// AttestationCert can be null for Authenticate requests.
|
||||
pub attestation_cert: Option<Vec<u8>>,
|
||||
pub device_name: Option<String>,
|
||||
}
|
||||
|
||||
pub fn parse_registration(
|
||||
app_id: String,
|
||||
client_data: Vec<u8>,
|
||||
registration_data: Vec<u8>,
|
||||
) -> Result<Registration> {
|
||||
let reserved_byte = registration_data[0];
|
||||
if reserved_byte != 0x05 {
|
||||
return Err(U2fError::InvalidReservedByte);
|
||||
}
|
||||
|
||||
let mut mem = Bytes::from(registration_data);
|
||||
|
||||
//Start parsing ... advance the reserved byte.
|
||||
let _ = mem.split_to(1);
|
||||
|
||||
// P-256 NIST elliptic curve
|
||||
let public_key = mem.split_to(65);
|
||||
|
||||
// Key Handle
|
||||
let key_handle_size = mem.split_to(1);
|
||||
let key_len = BigEndian::read_uint(&key_handle_size[..], 1);
|
||||
let key_handle = mem.split_to(key_len as usize);
|
||||
|
||||
// The certificate length needs to be inferred by parsing.
|
||||
let cert_len = asn_length(mem.clone()).unwrap();
|
||||
let attestation_certificate = mem.split_to(cert_len);
|
||||
|
||||
// Remaining data corresponds to the signature
|
||||
let signature = mem;
|
||||
|
||||
// Let's build the msg to verify the signature
|
||||
let app_id_hash = sha256(&app_id.into_bytes());
|
||||
let client_data_hash = sha256(&client_data[..]);
|
||||
|
||||
let mut msg = vec![0x00]; // A byte reserved for future use [1 byte] with the value 0x00
|
||||
msg.put(app_id_hash.as_ref());
|
||||
msg.put(client_data_hash.as_ref());
|
||||
msg.put(key_handle.clone());
|
||||
msg.put(public_key.clone());
|
||||
|
||||
// The signature is to be verified by the relying party using the public key certified
|
||||
// in the attestation certificate.
|
||||
let cerificate_public_key =
|
||||
super::crypto::X509PublicKey::try_from(&attestation_certificate[..])?;
|
||||
|
||||
if !(cerificate_public_key.is_secp256r1()?) {
|
||||
return Err(U2fError::BadCertificate);
|
||||
}
|
||||
|
||||
let verified = cerificate_public_key.verify_signature(&signature[..], &msg[..])?;
|
||||
|
||||
if !verified {
|
||||
return Err(U2fError::BadCertificate);
|
||||
}
|
||||
|
||||
let registration = Registration {
|
||||
key_handle: key_handle[..].to_vec(),
|
||||
pub_key: public_key[..].to_vec(),
|
||||
attestation_cert: Some(attestation_certificate[..].to_vec()),
|
||||
device_name: cerificate_public_key.common_name(),
|
||||
};
|
||||
|
||||
Ok(registration)
|
||||
}
|
||||
|
||||
pub fn get_registered_key(app_id: String, key_handle: Vec<u8>) -> RegisteredKey {
|
||||
RegisteredKey {
|
||||
app_id,
|
||||
version: U2F_V2.into(),
|
||||
key_handle: Some(get_encoded(key_handle.as_slice())),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum U2fError {
|
||||
#[error("ASM1 Decoder error")]
|
||||
Asm1DecoderError,
|
||||
#[error("Not able to verify signature")]
|
||||
BadSignature,
|
||||
#[error("Not able to generate random bytes")]
|
||||
RandomSecureBytesError,
|
||||
#[error("Invalid Reserved Byte")]
|
||||
InvalidReservedByte,
|
||||
#[error("Challenge Expired")]
|
||||
ChallengeExpired,
|
||||
#[error("Wrong Key Handler")]
|
||||
WrongKeyHandler,
|
||||
#[error("Invalid Client Data")]
|
||||
InvalidClientData,
|
||||
#[error("Invalid Signature Data")]
|
||||
InvalidSignatureData,
|
||||
#[error("Invalid User Presence Byte")]
|
||||
InvalidUserPresenceByte,
|
||||
#[error("Failed to parse certificate")]
|
||||
BadCertificate,
|
||||
#[error("Not Trusted Anchor")]
|
||||
NotTrustedAnchor,
|
||||
#[error("Counter too low")]
|
||||
CounterTooLow,
|
||||
#[error("Invalid public key")]
|
||||
OpenSSLNoCurveName,
|
||||
#[error("OpenSSL no curve name")]
|
||||
InvalidPublicKey,
|
||||
#[error(transparent)]
|
||||
OpenSSLError(#[from] openssl::error::ErrorStack),
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright 2021 Flavio Oliveira
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::u2f_crate::u2ferror::U2fError;
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
|
||||
use bytes::Bytes;
|
||||
use chrono::prelude::*;
|
||||
use chrono::Duration;
|
||||
use openssl::rand;
|
||||
|
||||
/// The `Result` type used in this crate.
|
||||
type Result<T> = ::std::result::Result<T, U2fError>;
|
||||
|
||||
pub const U2F_V2: &str = "U2F_V2";
|
||||
|
||||
// Generates a challenge from a secure, random source.
|
||||
pub fn generate_challenge(size: usize) -> Result<Vec<u8>> {
|
||||
let mut bytes: Vec<u8> = vec![0; size];
|
||||
rand::rand_bytes(&mut bytes).map_err(|_e| U2fError::RandomSecureBytesError)?;
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
pub fn expiration(timestamp: String) -> Duration {
|
||||
let now: DateTime<Utc> = Utc::now();
|
||||
|
||||
let ts = timestamp.parse::<DateTime<Utc>>();
|
||||
|
||||
now.signed_duration_since(ts.unwrap())
|
||||
}
|
||||
|
||||
// Decode initial bytes of buffer as ASN and return the length of the encoded structure.
|
||||
// http://en.wikipedia.org/wiki/X.690
|
||||
pub fn asn_length(mem: Bytes) -> Result<usize> {
|
||||
let buffer: &[u8] = &mem[..];
|
||||
|
||||
if mem.len() < 2 || buffer[0] != 0x30 {
|
||||
// Type
|
||||
return Err(U2fError::Asm1DecoderError);
|
||||
}
|
||||
|
||||
let len = buffer[1]; // Len
|
||||
if len & 0x80 == 0 {
|
||||
return Ok((len & 0x7f) as usize);
|
||||
}
|
||||
|
||||
let numbem_of_bytes = len & 0x7f;
|
||||
if numbem_of_bytes == 0 {
|
||||
return Err(U2fError::Asm1DecoderError);
|
||||
}
|
||||
|
||||
let mut length: usize = 0;
|
||||
for num in 0..numbem_of_bytes {
|
||||
length = length * 0x100 + (buffer[(2 + num) as usize] as usize);
|
||||
}
|
||||
|
||||
length += numbem_of_bytes as usize;
|
||||
|
||||
Ok(length + 2) // Add the 2 initial bytes: type and length.
|
||||
}
|
||||
|
||||
pub fn get_encoded(data: &[u8]) -> String {
|
||||
let encoded: String = URL_SAFE_NO_PAD.encode(data);
|
||||
|
||||
encoded.trim_end_matches('=').to_string()
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
- [`d198c01`](https://github.com/tauri-apps/plugins-workspace/commit/d198c014863ee260cb0de88a14b7fc4356ef7474)([#862](https://github.com/tauri-apps/plugins-workspace/pull/862)) Update to tauri beta.
|
||||
|
||||
## \[2.0.0-alpha.5]
|
||||
|
||||
- [`387c2f9`](https://github.com/tauri-apps/plugins-workspace/commit/387c2f9e0ce4c75c07ffa3fd76391a25b58f5daf)([#802](https://github.com/tauri-apps/plugins-workspace/pull/802)) Update to @tauri-apps/api v2.0.0-alpha.13.
|
||||
@@ -32,3 +36,4 @@
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- [`717ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
[package]
|
||||
name = "tauri-plugin-autostart"
|
||||
version = "2.0.0-alpha.6"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Automatically launch your application at startup."
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
links = "tauri-plugin-autostart"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustc-args = [ "--cfg", "docsrs" ]
|
||||
rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-plugin = { workspace = true, features = [ "build" ] }
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -18,7 +18,7 @@ Install the Core plugin by adding the following to your `Cargo.toml` file:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tauri-plugin-autostart = "2.0.0-alpha"
|
||||
tauri-plugin-autostart = "2.0.0-beta"
|
||||
# alternatively with Git:
|
||||
tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
|
||||
```
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const COMMANDS: &[&str] = &["enable", "disable", "is_enabled"];
|
||||
|
||||
fn main() {
|
||||
tauri_plugin::Builder::new(COMMANDS).build();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-autostart",
|
||||
"version": "2.0.0-alpha.5",
|
||||
"version": "2.0.0-beta.0",
|
||||
"license": "MIT or APACHE-2.0",
|
||||
"authors": [
|
||||
"Tauri Programme within The Commons Conservancy"
|
||||
@@ -23,6 +23,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.0.0-alpha.13"
|
||||
"@tauri-apps/api": "2.0.0-beta.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-disable"
|
||||
description = "Enables the disable command without any pre-configured scope."
|
||||
commands.allow = ["disable"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-disable"
|
||||
description = "Denies the disable command without any pre-configured scope."
|
||||
commands.deny = ["disable"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-enable"
|
||||
description = "Enables the enable command without any pre-configured scope."
|
||||
commands.allow = ["enable"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-enable"
|
||||
description = "Denies the enable command without any pre-configured scope."
|
||||
commands.deny = ["enable"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-is-enabled"
|
||||
description = "Enables the is_enabled command without any pre-configured scope."
|
||||
commands.allow = ["is_enabled"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-is-enabled"
|
||||
description = "Denies the is_enabled command without any pre-configured scope."
|
||||
commands.deny = ["is_enabled"]
|
||||
@@ -0,0 +1,26 @@
|
||||
# Permissions
|
||||
|
||||
## allow-disable
|
||||
|
||||
Enables the disable command without any pre-configured scope.
|
||||
|
||||
## deny-disable
|
||||
|
||||
Denies the disable command without any pre-configured scope.
|
||||
|
||||
## allow-enable
|
||||
|
||||
Enables the enable command without any pre-configured scope.
|
||||
|
||||
## deny-enable
|
||||
|
||||
Denies the enable command without any pre-configured scope.
|
||||
|
||||
## allow-is-enabled
|
||||
|
||||
Enables the is_enabled command without any pre-configured scope.
|
||||
|
||||
## deny-is-enabled
|
||||
|
||||
Denies the is_enabled command without any pre-configured scope.
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PermissionFile",
|
||||
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "The default permission set for the plugin",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/DefaultPermission"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"set": {
|
||||
"description": "A list of permissions sets defined",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionSet"
|
||||
}
|
||||
},
|
||||
"permission": {
|
||||
"description": "A list of inlined permissions",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Permission"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DefaultPermission": {
|
||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PermissionSet": {
|
||||
"description": "A set of direct permissions grouped together under a new name.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description",
|
||||
"identifier",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": "string"
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionKind"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Permission": {
|
||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"description": "Allowed or denied commands when using this permission.",
|
||||
"default": {
|
||||
"allow": [],
|
||||
"deny": []
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope": {
|
||||
"description": "Allowed or denied scoped when using this permission.",
|
||||
"default": {},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Scopes"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Commands": {
|
||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Allowed command.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Denied command, which takes priority.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scopes": {
|
||||
"description": "A restriction of the command/endpoint functionality.\n\nIt can be of any serde serializable type and is used for allowing or preventing certain actions inside a Tauri command.\n\nThe scope is passed to the command and handled/enforced by the command itself.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionKind": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "allow-disable -> Enables the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-disable -> Denies the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-enable -> Enables the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-enable -> Denies the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-is-enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-is-enabled"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
- [`d198c01`](https://github.com/tauri-apps/plugins-workspace/commit/d198c014863ee260cb0de88a14b7fc4356ef7474)([#862](https://github.com/tauri-apps/plugins-workspace/pull/862)) Update to tauri beta.
|
||||
- [`d198c01`](https://github.com/tauri-apps/plugins-workspace/commit/d198c014863ee260cb0de88a14b7fc4356ef7474)([#862](https://github.com/tauri-apps/plugins-workspace/pull/862)) Add permissions.
|
||||
|
||||
## \[2.0.0-alpha.4]
|
||||
|
||||
- [`387c2f9`](https://github.com/tauri-apps/plugins-workspace/commit/387c2f9e0ce4c75c07ffa3fd76391a25b58f5daf)([#802](https://github.com/tauri-apps/plugins-workspace/pull/802)) Update to @tauri-apps/api v2.0.0-alpha.13.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-barcode-scanner"
|
||||
version = "2.0.0-alpha.4"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS"
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
@@ -14,7 +14,7 @@ rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
targets = [ "x86_64-linux-android" ]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true }
|
||||
tauri-plugin = { workspace = true, features = [ "build" ] }
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
|
||||
@@ -18,7 +18,7 @@ Install the Core plugin by adding the following to your `Cargo.toml` file:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tauri-plugin-barcode-scanner = "2.0.0-alpha"
|
||||
tauri-plugin-barcode-scanner = "2.0.0-beta"
|
||||
# alternatively with Git:
|
||||
tauri-plugin-barcode-scanner = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
|
||||
```
|
||||
|
||||
@@ -2,11 +2,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const COMMANDS: &[&str] = &[
|
||||
"scan",
|
||||
"cancel",
|
||||
"request_permissions",
|
||||
"check_permissions",
|
||||
"open_app_settings",
|
||||
"vibrate",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
if let Err(error) = tauri_build::mobile::PluginBuilder::new()
|
||||
if let Err(error) = tauri_plugin::Builder::new(COMMANDS)
|
||||
.android_path("android")
|
||||
.ios_path("ios")
|
||||
.run()
|
||||
.try_build()
|
||||
{
|
||||
println!("{error:#}");
|
||||
// when building documentation for Android the plugin build result is irrelevant to the crate itself
|
||||
|
||||
@@ -39,14 +39,14 @@ export interface Scanned {
|
||||
* @param options
|
||||
*/
|
||||
export async function scan(options?: ScanOptions): Promise<Scanned> {
|
||||
return await invoke("plugin:barcodeScanner|scan", { ...options });
|
||||
return await invoke("plugin:barcode-scanner|scan", { ...options });
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the current scan process.
|
||||
*/
|
||||
export async function cancel(): Promise<void> {
|
||||
return await invoke("plugin:barcodeScanner|cancel");
|
||||
return await invoke("plugin:barcode-scanner|cancel");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ export async function cancel(): Promise<void> {
|
||||
*/
|
||||
export async function checkPermissions(): Promise<PermissionState> {
|
||||
return await invoke<{ camera: PermissionState }>(
|
||||
"plugin:barcodeScanner|checkPermissions",
|
||||
"plugin:barcode-scanner|check_permissions",
|
||||
).then((r) => r.camera);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export async function checkPermissions(): Promise<PermissionState> {
|
||||
*/
|
||||
export async function requestPermissions(): Promise<PermissionState> {
|
||||
return await invoke<{ camera: PermissionState }>(
|
||||
"plugin:barcodeScanner|requestPermissions",
|
||||
"plugin:barcode-scanner|request_permissions",
|
||||
).then((r) => r.camera);
|
||||
}
|
||||
|
||||
@@ -71,5 +71,5 @@ export async function requestPermissions(): Promise<PermissionState> {
|
||||
* Open application settings. Useful if permission was denied and the user must manually enable it.
|
||||
*/
|
||||
export async function openAppSettings(): Promise<void> {
|
||||
return await invoke("plugin:barcodeScanner|openAppSettings");
|
||||
return await invoke("plugin:barcode-scanner|open_app_settings");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-barcode-scanner",
|
||||
"version": "2.0.0-alpha.4",
|
||||
"version": "2.0.0-beta.0",
|
||||
"description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS",
|
||||
"license": "MIT or APACHE-2.0",
|
||||
"authors": [
|
||||
@@ -24,6 +24,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.0.0-alpha.13"
|
||||
"@tauri-apps/api": "2.0.0-beta.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-cancel"
|
||||
description = "Enables the cancel command without any pre-configured scope."
|
||||
commands.allow = ["cancel"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-cancel"
|
||||
description = "Denies the cancel command without any pre-configured scope."
|
||||
commands.deny = ["cancel"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-check-permissions"
|
||||
description = "Enables the check_permissions command without any pre-configured scope."
|
||||
commands.allow = ["check_permissions"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-check-permissions"
|
||||
description = "Denies the check_permissions command without any pre-configured scope."
|
||||
commands.deny = ["check_permissions"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-open-app-settings"
|
||||
description = "Enables the open_app_settings command without any pre-configured scope."
|
||||
commands.allow = ["open_app_settings"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-open-app-settings"
|
||||
description = "Denies the open_app_settings command without any pre-configured scope."
|
||||
commands.deny = ["open_app_settings"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-request-permissions"
|
||||
description = "Enables the request_permissions command without any pre-configured scope."
|
||||
commands.allow = ["request_permissions"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-request-permissions"
|
||||
description = "Denies the request_permissions command without any pre-configured scope."
|
||||
commands.deny = ["request_permissions"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-scan"
|
||||
description = "Enables the scan command without any pre-configured scope."
|
||||
commands.allow = ["scan"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-scan"
|
||||
description = "Denies the scan command without any pre-configured scope."
|
||||
commands.deny = ["scan"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-vibrate"
|
||||
description = "Enables the vibrate command without any pre-configured scope."
|
||||
commands.allow = ["vibrate"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-vibrate"
|
||||
description = "Denies the vibrate command without any pre-configured scope."
|
||||
commands.deny = ["vibrate"]
|
||||
@@ -0,0 +1,50 @@
|
||||
# Permissions
|
||||
|
||||
## allow-cancel
|
||||
|
||||
Enables the cancel command without any pre-configured scope.
|
||||
|
||||
## deny-cancel
|
||||
|
||||
Denies the cancel command without any pre-configured scope.
|
||||
|
||||
## allow-check-permissions
|
||||
|
||||
Enables the check_permissions command without any pre-configured scope.
|
||||
|
||||
## deny-check-permissions
|
||||
|
||||
Denies the check_permissions command without any pre-configured scope.
|
||||
|
||||
## allow-open-app-settings
|
||||
|
||||
Enables the open_app_settings command without any pre-configured scope.
|
||||
|
||||
## deny-open-app-settings
|
||||
|
||||
Denies the open_app_settings command without any pre-configured scope.
|
||||
|
||||
## allow-request-permissions
|
||||
|
||||
Enables the request_permissions command without any pre-configured scope.
|
||||
|
||||
## deny-request-permissions
|
||||
|
||||
Denies the request_permissions command without any pre-configured scope.
|
||||
|
||||
## allow-scan
|
||||
|
||||
Enables the scan command without any pre-configured scope.
|
||||
|
||||
## deny-scan
|
||||
|
||||
Denies the scan command without any pre-configured scope.
|
||||
|
||||
## allow-vibrate
|
||||
|
||||
Enables the vibrate command without any pre-configured scope.
|
||||
|
||||
## deny-vibrate
|
||||
|
||||
Denies the vibrate command without any pre-configured scope.
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PermissionFile",
|
||||
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "The default permission set for the plugin",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/DefaultPermission"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"set": {
|
||||
"description": "A list of permissions sets defined",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionSet"
|
||||
}
|
||||
},
|
||||
"permission": {
|
||||
"description": "A list of inlined permissions",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Permission"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DefaultPermission": {
|
||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PermissionSet": {
|
||||
"description": "A set of direct permissions grouped together under a new name.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description",
|
||||
"identifier",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": "string"
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionKind"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Permission": {
|
||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"description": "Allowed or denied commands when using this permission.",
|
||||
"default": {
|
||||
"allow": [],
|
||||
"deny": []
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope": {
|
||||
"description": "Allowed or denied scoped when using this permission.",
|
||||
"default": {},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Scopes"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Commands": {
|
||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Allowed command.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Denied command, which takes priority.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scopes": {
|
||||
"description": "A restriction of the command/endpoint functionality.\n\nIt can be of any serde serializable type and is used for allowing or preventing certain actions inside a Tauri command.\n\nThe scope is passed to the command and handled/enforced by the command itself.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionKind": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "allow-cancel -> Enables the cancel command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-cancel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-cancel -> Denies the cancel command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-cancel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-check-permissions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-check-permissions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-open-app-settings -> Enables the open_app_settings command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-open-app-settings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-open-app-settings -> Denies the open_app_settings command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-open-app-settings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-request-permissions -> Enables the request_permissions command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-request-permissions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-request-permissions -> Denies the request_permissions command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-request-permissions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-scan -> Enables the scan command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-scan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-scan -> Denies the scan command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-scan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allow-vibrate -> Enables the vibrate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"allow-vibrate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deny-vibrate -> Denies the vibrate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deny-vibrate"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODESCANNER__=function(n){"use strict";async function e(n,e={},r){return window.__TAURI_INTERNALS__.invoke(n,e,r)}var r;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(r=n.Format||(n.Format={})).QRCode="QR_CODE",r.UPC_A="UPC_A",r.UPC_E="UPC_E",r.EAN8="EAN_8",r.EAN13="EAN_13",r.Code39="CODE_39",r.Code93="CODE_93",r.Code128="CODE_128",r.Codabar="CODABAR",r.ITF="ITF",r.Aztec="AZTEC",r.DataMatrix="DATA_MATRIX",r.PDF417="PDF_417",n.cancel=async function(){return await e("plugin:barcodeScanner|cancel")},n.checkPermissions=async function(){return await e("plugin:barcodeScanner|checkPermissions").then((n=>n.camera))},n.openAppSettings=async function(){return await e("plugin:barcodeScanner|openAppSettings")},n.requestPermissions=async function(){return await e("plugin:barcodeScanner|requestPermissions").then((n=>n.camera))},n.scan=async function(n){return await e("plugin:barcodeScanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODESCANNER__})}
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODESCANNER__=function(n){"use strict";async function e(n,e={},r){return window.__TAURI_INTERNALS__.invoke(n,e,r)}var r;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(r=n.Format||(n.Format={})).QRCode="QR_CODE",r.UPC_A="UPC_A",r.UPC_E="UPC_E",r.EAN8="EAN_8",r.EAN13="EAN_13",r.Code39="CODE_39",r.Code93="CODE_93",r.Code128="CODE_128",r.Codabar="CODABAR",r.ITF="ITF",r.Aztec="AZTEC",r.DataMatrix="DATA_MATRIX",r.PDF417="PDF_417",n.cancel=async function(){return await e("plugin:barcode-scanner|cancel")},n.checkPermissions=async function(){return await e("plugin:barcode-scanner|check_permissions").then((n=>n.camera))},n.openAppSettings=async function(){return await e("plugin:barcode-scanner|open_app_settings")},n.requestPermissions=async function(){return await e("plugin:barcode-scanner|request_permissions").then((n=>n.camera))},n.scan=async function(n){return await e("plugin:barcode-scanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODESCANNER__})}
|
||||
|
||||
@@ -40,7 +40,7 @@ impl<R: Runtime, T: Manager<R>> crate::BarcodeScannerExt<R> for T {
|
||||
|
||||
/// Initializes the plugin.
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
Builder::new("barcodeScanner")
|
||||
Builder::new("barcode-scanner")
|
||||
.setup(|app, api| {
|
||||
#[cfg(target_os = "android")]
|
||||
let handle = api.register_android_plugin(PLUGIN_IDENTIFIER, "BarcodeScannerPlugin")?;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
- [`d198c01`](https://github.com/tauri-apps/plugins-workspace/commit/d198c014863ee260cb0de88a14b7fc4356ef7474)([#862](https://github.com/tauri-apps/plugins-workspace/pull/862)) Update to tauri beta.
|
||||
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- [`8df28a9`](https://github.com/tauri-apps/plugins-workspace/commit/8df28a987519ecfa03dcb8635443025f8d010362)([#829](https://github.com/tauri-apps/plugins-workspace/pull/829)) Initial release.
|
||||
- [`8df28a9`](https://github.com/tauri-apps/plugins-workspace/commit/8df28a987519ecfa03dcb8635443025f8d010362)([#829](https://github.com/tauri-apps/plugins-workspace/pull/829)) Initial release.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user