Compare commits

..

3 Commits

Author SHA1 Message Date
FabianLars a71a0192b8 check progress size in last event instead 2023-10-31 13:29:38 +01:00
FabianLars e7d9efee37 emitlast event 2023-10-31 13:28:31 +01:00
FabianLars dd8bc4ab39 fix(upload) reduce amount of emitted tauri events 2023-10-31 13:23:16 +01:00
165 changed files with 9198 additions and 3234 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"stronghold-js": patch
---
Change the argument name of the `Stronghold.remove` from `location` to `recordPath` to match the Stronghold command argument
+5
View File
@@ -0,0 +1,5 @@
---
"stronghold": patch
---
Added `Builder::with_argon2`.
+5
View File
@@ -0,0 +1,5 @@
---
"stronghold-js": minor
---
Added `Stronghold.load` and removed its constructor.
+5
View File
@@ -0,0 +1,5 @@
---
"positioner": patch
---
`TrayLeft`, `TrayRight` and `TrayCenter` will now position the window according to the tray position relative to the monitor dimensions to prevent windows being displayed partially off-screen.
+1 -1
View File
@@ -7,7 +7,7 @@
"prettier",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:security/recommended-legacy"
"plugin:security/recommended"
],
"overrides": [],
"parser": "@typescript-eslint/parser",
-31
View File
@@ -1,31 +0,0 @@
<svg class="crabnebula-logo" width="100%" height="100%" viewBox="0 0 1204 210" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve" xmlns:serif="http://www.serif.com/"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<style>
.crabnebula-logo path,
.crabnebula-logo rect {
fill: #001e42;
}
@media (prefers-color-scheme: dark) {
.crabnebula-logo path, .crabnebula-logo rect {
fill: #fff;
}
}
html[data-color-mode="dark"] .crabnebula-logo path,
html[data-color-mode="dark"] .crabnebula-logo rect {
fill: #fff;
}
</style>
<path d="M351.903,162.334C344.288,162.334 337.123,160.881 330.41,157.975C323.696,155.069 317.834,151.11 312.824,146.099C307.914,141.089 304.006,135.276 301.101,128.662C298.195,121.948 296.742,114.783 296.742,107.167C296.742,99.55 298.195,92.435 301.101,85.821C304.006,79.107 307.914,73.244 312.824,68.234C317.834,63.223 323.696,59.265 330.41,56.358C337.123,53.452 344.288,51.999 351.903,51.999C357.414,51.999 362.675,52.701 367.685,54.103C372.795,55.507 377.455,57.511 381.663,60.116C385.972,62.622 389.83,65.678 393.237,69.286C396.644,72.793 399.499,76.752 401.804,81.161L380.762,92.586C377.756,87.174 373.848,82.915 369.038,79.808C364.328,76.702 358.617,75.148 351.903,75.148C347.494,75.148 343.386,76 339.578,77.704C335.871,79.407 332.614,81.762 329.809,84.769C327.003,87.675 324.798,91.082 323.195,94.991C321.592,98.799 320.79,102.857 320.79,107.167C320.79,111.476 321.592,115.584 323.195,119.493C324.798,123.301 327.003,126.708 329.809,129.715C332.614,132.621 335.871,134.926 339.578,136.629C343.386,138.333 347.494,139.185 351.903,139.185C358.617,139.185 364.328,137.631 369.038,134.525C373.848,131.418 377.756,127.159 380.762,121.748L401.804,133.172C399.499,137.581 396.644,141.59 393.237,145.198C389.83,148.705 385.972,151.762 381.663,154.367C377.455,156.872 372.795,158.827 367.685,160.23C362.675,161.633 357.414,162.334 351.903,162.334Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M413.821,85.37L436.517,85.37L436.517,96.644C437.72,93.337 439.924,90.481 443.131,88.076C446.437,85.671 450.195,84.468 454.403,84.468C455.506,84.468 456.658,84.518 457.86,84.619C459.063,84.719 460.366,84.969 461.768,85.37L461.768,108.369C460.065,107.768 458.412,107.317 456.808,107.016C455.205,106.716 453.502,106.565 451.698,106.565C446.788,106.565 443.03,108.269 440.425,111.676C437.82,115.083 436.517,119.493 436.517,124.904L436.517,160.53L413.821,160.53L413.821,85.37Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M502.161,162.184C497.251,162.184 492.642,161.132 488.333,159.027C484.125,156.923 480.467,154.117 477.361,150.609C474.255,147.001 471.8,142.843 469.996,138.133C468.193,133.322 467.291,128.261 467.291,122.95C467.291,117.639 468.193,112.628 469.996,107.918C471.8,103.108 474.255,98.949 477.361,95.442C480.467,91.834 484.125,88.978 488.333,86.873C492.642,84.769 497.251,83.717 502.161,83.717C504.666,83.717 506.971,84.017 509.075,84.619C511.28,85.12 513.234,85.821 514.937,86.723C516.741,87.625 518.244,88.627 519.446,89.729C520.749,90.832 521.801,91.884 522.603,92.886L522.603,85.37L545.299,85.37L545.299,160.53L522.603,160.53L522.603,153.014C521.801,154.016 520.749,155.069 519.446,156.171C518.244,157.273 516.741,158.275 514.937,159.177C513.234,160.079 511.28,160.781 509.075,161.282C506.971,161.883 504.666,162.184 502.161,162.184ZM507.272,141.59C512.382,141.59 516.49,139.836 519.597,136.329C522.803,132.821 524.406,128.362 524.406,122.95C524.406,117.539 522.803,113.079 519.597,109.572C516.49,106.064 512.382,104.31 507.272,104.31C502.161,104.31 498.003,106.064 494.796,109.572C491.69,113.079 490.137,117.539 490.137,122.95C490.137,128.362 491.69,132.821 494.796,136.329C498.003,139.836 502.161,141.59 507.272,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M607.116,162.184C604.611,162.184 602.256,161.883 600.051,161.282C597.947,160.781 595.993,160.079 594.19,159.177C592.486,158.275 590.983,157.273 589.681,156.171C588.378,155.069 587.376,154.016 586.674,153.014L586.674,160.53L563.979,160.53L563.979,47.79L586.674,47.79L586.674,92.886C587.376,91.884 588.378,90.832 589.681,89.729C590.983,88.627 592.486,87.625 594.19,86.723C595.993,85.821 597.947,85.12 600.051,84.619C602.256,84.017 604.611,83.717 607.116,83.717C612.026,83.717 616.585,84.769 620.793,86.873C625.102,88.978 628.81,91.834 631.916,95.442C635.022,98.949 637.477,103.108 639.281,107.918C641.084,112.628 641.986,117.639 641.986,122.95C641.986,128.261 641.084,133.322 639.281,138.133C637.477,142.843 635.022,147.001 631.916,150.609C628.81,154.117 625.102,156.923 620.793,159.027C616.585,161.132 612.026,162.184 607.116,162.184ZM602.005,141.59C607.116,141.59 611.224,139.836 614.33,136.329C617.537,132.821 619.14,128.362 619.14,122.95C619.14,117.539 617.537,113.079 614.33,109.572C611.224,106.064 607.116,104.31 602.005,104.31C596.895,104.31 592.737,106.064 589.53,109.572C586.424,113.079 584.871,117.539 584.871,122.95C584.871,128.362 586.424,132.821 589.53,136.329C592.737,139.836 596.895,141.59 602.005,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M732.106,160.53L680.101,94.54L680.101,160.53L656.203,160.53L656.203,53.803L676.795,53.803L728.649,119.793L728.649,53.803L752.698,53.803L752.698,160.53L732.106,160.53Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M806.852,162.184C801.341,162.184 796.13,161.282 791.22,159.478C786.411,157.674 782.202,155.069 778.595,151.661C774.988,148.254 772.132,144.145 770.028,139.335C767.923,134.425 766.871,128.963 766.871,122.95C766.871,117.338 767.823,112.177 769.727,107.467C771.731,102.657 774.487,98.498 777.994,94.991C781.601,91.483 785.809,88.727 790.619,86.723C795.429,84.719 800.69,83.717 806.401,83.717C811.311,83.717 816.021,84.518 820.53,86.122C825.139,87.625 829.147,89.93 832.554,93.036C835.961,96.043 838.666,99.851 840.67,104.461C842.775,108.97 843.827,114.282 843.827,120.395C843.827,121.397 843.777,122.549 843.677,123.852C843.677,125.055 843.576,126.558 843.376,128.362L788.816,128.362C789.517,132.871 791.671,136.228 795.279,138.433C798.886,140.538 802.844,141.59 807.153,141.59C811.562,141.59 815.319,140.738 818.425,139.034C821.632,137.231 823.937,135.226 825.339,133.022L842.173,145.649C838.666,150.659 833.857,154.668 827.744,157.674C821.732,160.681 814.768,162.184 806.852,162.184ZM821.281,113.48C820.279,109.471 818.275,106.615 815.269,104.912C812.263,103.108 809.107,102.206 805.8,102.206C804.096,102.206 802.393,102.406 800.69,102.807C798.986,103.208 797.383,103.859 795.88,104.761C794.377,105.663 793.024,106.816 791.822,108.219C790.719,109.622 789.918,111.376 789.417,113.48L821.281,113.48Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M901.265,162.184C898.76,162.184 896.405,161.883 894.201,161.282C892.097,160.781 890.143,160.079 888.339,159.177C886.636,158.275 885.133,157.273 883.83,156.171C882.527,155.069 881.525,154.016 880.824,153.014L880.824,160.53L858.128,160.53L858.128,47.79L880.824,47.79L880.824,92.886C881.525,91.884 882.527,90.832 883.83,89.729C885.133,88.627 886.636,87.625 888.339,86.723C890.143,85.821 892.097,85.12 894.201,84.619C896.405,84.017 898.76,83.717 901.265,83.717C906.175,83.717 910.734,84.769 914.943,86.873C919.252,88.978 922.959,91.834 926.065,95.442C929.172,98.949 931.627,103.108 933.43,107.918C935.234,112.628 936.136,117.639 936.136,122.95C936.136,128.261 935.234,133.322 933.43,138.133C931.627,142.843 929.172,147.001 926.065,150.609C922.959,154.117 919.252,156.923 914.943,159.027C910.734,161.132 906.175,162.184 901.265,162.184ZM896.155,141.59C901.265,141.59 905.374,139.836 908.48,136.329C911.686,132.821 913.29,128.362 913.29,122.95C913.29,117.539 911.686,113.079 908.48,109.572C905.374,106.064 901.265,104.31 896.155,104.31C891.045,104.31 886.886,106.064 883.68,109.572C880.573,113.079 879.02,117.539 879.02,122.95C879.02,128.362 880.573,132.821 883.68,136.329C886.886,139.836 891.045,141.59 896.155,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M977.812,162.184C968.493,162.184 961.429,159.077 956.619,152.864C951.81,146.651 949.405,138.433 949.405,128.211L949.405,85.37L972.101,85.37L972.101,124.303C972.101,129.815 972.952,134.074 974.656,137.08C976.459,140.087 979.466,141.59 983.674,141.59C987.983,141.59 991.39,140.037 993.895,136.93C996.5,133.823 997.803,128.813 997.803,121.898L997.803,85.37L1020.5,85.37L1020.5,160.53L997.803,160.53L997.803,152.864C995.999,155.469 993.444,157.674 990.137,159.478C986.83,161.282 982.722,162.184 977.812,162.184Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<rect x="1039.11" y="47.79" width="22.701" height="112.74" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M1110.86,162.184C1105.95,162.184 1101.34,161.132 1097.03,159.027C1092.83,156.923 1089.17,154.117 1086.06,150.609C1082.96,147.001 1080.5,142.843 1078.7,138.133C1076.89,133.322 1075.99,128.261 1075.99,122.95C1075.99,117.639 1076.89,112.628 1078.7,107.918C1080.5,103.108 1082.96,98.949 1086.06,95.442C1089.17,91.834 1092.83,88.978 1097.03,86.873C1101.34,84.769 1105.95,83.717 1110.86,83.717C1113.37,83.717 1115.67,84.017 1117.78,84.619C1119.98,85.12 1121.94,85.821 1123.64,86.723C1125.44,87.625 1126.95,88.627 1128.15,89.729C1129.45,90.832 1130.5,91.884 1131.3,92.886L1131.3,85.37L1154,85.37L1154,160.53L1131.3,160.53L1131.3,153.014C1130.5,154.016 1129.45,155.069 1128.15,156.171C1126.95,157.273 1125.44,158.275 1123.64,159.177C1121.94,160.079 1119.98,160.781 1117.78,161.282C1115.67,161.883 1113.37,162.184 1110.86,162.184ZM1115.97,141.59C1121.08,141.59 1125.19,139.836 1128.3,136.329C1131.5,132.821 1133.11,128.362 1133.11,122.95C1133.11,117.539 1131.5,113.079 1128.3,109.572C1125.19,106.064 1121.08,104.31 1115.97,104.31C1110.86,104.31 1106.7,106.064 1103.5,109.572C1100.39,113.079 1098.84,117.539 1098.84,122.95C1098.84,128.362 1100.39,132.821 1103.5,136.329C1106.7,139.836 1110.86,141.59 1115.97,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
<path d="M146.48,54.585C119.724,89.866 119.878,134.941 146.826,155.264C153.908,160.605 162.136,163.705 170.903,164.732C146.032,184.934 117.382,191.203 98.037,178.045C71.507,160 72.524,112.249 100.309,71.391C123.51,37.273 158.039,18.749 184.247,24.072C170.404,30.195 157.116,40.561 146.48,54.585ZM181.638,99.643C169.141,111.453 154.859,119.304 142.801,121.916C149.921,147.367 177.29,149.323 177.29,149.323C177.29,149.323 193.578,145.578 205.877,117.941C216.005,95.183 215.122,71.668 204.914,59.7C204.065,71.267 195.731,86.324 181.638,99.643Z" style="stroke:black;stroke-width:0.55px;"/>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

-2
View File
@@ -33,5 +33,3 @@ 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' || '' }}
+1
View File
@@ -1,3 +1,4 @@
target
node_modules
dist
dist-js
Generated
+195 -428
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
[workspace]
members = ["plugins/*", "plugins/*/examples/*/src-tauri"]
members = ["plugins/*"]
resolver = "2"
[workspace.dependencies]
-16
View File
@@ -19,19 +19,3 @@
| [window-state](plugins/window-state) | Persist window sizes and positions. | ✅ | ✅ | ✅ | ? | ? |
_This repo and all plugins require a Rust version of at least **1.64**_
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src=".github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
+12 -12
View File
@@ -12,19 +12,19 @@
"devDependencies": {
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "11.1.6",
"@typescript-eslint/eslint-plugin": "7.3.0",
"@typescript-eslint/parser": "7.3.0",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-config-standard-with-typescript": "43.0.1",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-n": "16.6.2",
"@rollup/plugin-typescript": "11.1.5",
"@typescript-eslint/eslint-plugin": "6.9.1",
"@typescript-eslint/parser": "6.9.1",
"eslint": "8.52.0",
"eslint-config-prettier": "9.0.0",
"eslint-config-standard-with-typescript": "39.1.1",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-n": "16.2.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-security": "2.1.1",
"prettier": "3.2.5",
"rollup": "4.13.0",
"typescript": "5.4.2"
"eslint-plugin-security": "1.7.1",
"prettier": "3.0.3",
"rollup": "4.2.0",
"typescript": "5.2.2"
},
"resolutions": {
"semver": ">=7.5.2",
+10 -12
View File
@@ -2,27 +2,25 @@
name = "tauri-plugin-authenticator"
version = "0.0.0"
description = "Use hardware security-keys in your Tauri App."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
authenticator = "0.3.1"
once_cell = "1"
sha2 = "0.10"
base64 = "0.21"
u2f = "0.2"
chrono = "0.4"
bytes = "1"
byteorder = "1"
openssl = "0.10"
[dev-dependencies]
rand = "0.8"
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-authenticator](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/authenticator/banner.png)
![plugin-authenticator](banner.png)
Use hardware security-keys in your Tauri App.
@@ -103,22 +103,6 @@ if (counter && counter > 0) {
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ pub enum Error {
#[error(transparent)]
JSON(#[from] serde_json::Error),
#[error(transparent)]
U2F(#[from] crate::u2f_crate::u2ferror::U2fError),
U2F(#[from] u2f::u2ferror::U2fError),
#[error(transparent)]
Auth(#[from] authenticator::errors::AuthenticatorError),
}
-1
View File
@@ -5,7 +5,6 @@
mod auth;
mod error;
mod u2f;
mod u2f_crate;
use tauri::{
plugin::{Builder as PluginBuilder, TauriPlugin},
+3 -3
View File
@@ -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";
@@ -1,8 +0,0 @@
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.
@@ -1,65 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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()
}
@@ -1,156 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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)?)
}
}
@@ -1,54 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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,
}
@@ -1,12 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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;
@@ -1,191 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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(&reg.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),
}
}
}
@@ -1,101 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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())),
}
}
@@ -1,39 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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),
}
@@ -1,66 +0,0 @@
// Copyright 2021 Flavio Oliveira
// 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()
}
+9 -9
View File
@@ -2,17 +2,17 @@
name = "tauri-plugin-autostart"
version = "0.0.0"
description = "Automatically launch your application at startup."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
auto-launch = "0.5"
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-autostart](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/autostart/banner.png)
![plugin-autostart](banner.png)
Automatically launch your application at startup. Supports Windows, Mac (via AppleScript or Launch Agent), and Linux.
@@ -66,22 +66,6 @@ disable();
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+1 -1
View File
@@ -27,6 +27,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+5 -6
View File
@@ -119,12 +119,11 @@ pub fn init<R: Runtime>(
// exe path to not break it.
let exe_path = current_exe.canonicalize()?.display().to_string();
let parts: Vec<&str> = exe_path.split(".app/").collect();
let app_path =
if parts.len() == 2 && matches!(macos_launcher, MacosLauncher::AppleScript) {
format!("{}.app", parts.get(0).unwrap().to_string())
} else {
exe_path
};
let app_path = if parts.len() == 2 {
format!("{}.app", parts.get(0).unwrap().to_string())
} else {
exe_path
};
info!("auto_start path {}", &app_path);
builder.set_app_path(&app_path);
}
+9 -9
View File
@@ -2,16 +2,16 @@
name = "tauri-plugin-fs-extra"
version = "0.0.0"
description = "Additional file system methods not included in the core API."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-fs-extra](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/fs-extra/banner.png)
![tauri-plugin-fs-extra](banner.png)
Additional file system methods not included in the core API.
@@ -60,22 +60,6 @@ await metadata("/path/to/file");
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+9 -9
View File
@@ -2,18 +2,18 @@
name = "tauri-plugin-fs-watch"
version = "0.0.0"
description = "Watch files and directories for changes."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
notify = { version = "6" , features = ["serde"] }
notify-debouncer-mini = { version = "0.4" , features = ["serde"] }
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-fs-watch](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/fs-watch/banner.png)
![plugin-fs-watch](banner.png)
Watch files and directories for changes using [notify](https://github.com/notify-rs/notify).
@@ -75,22 +75,6 @@ const stopRawWatcher = await watchImmediate(
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+2 -2
View File
@@ -35,8 +35,8 @@ type RawEventKind =
| "other";
export type DebouncedEvent =
| { kind: "Any"; path: string }[]
| { kind: "AnyContinuous"; path: string }[];
| { kind: "any"; path: string }
| { kind: "AnyContinous"; path: string };
async function unwatch(id: number): Promise<void> {
await invoke("plugin:fs-watch|unwatch", { id });
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+10 -10
View File
@@ -2,18 +2,18 @@
name = "tauri-plugin-localhost"
version = "0.1.0"
description = "Expose your apps assets through a localhost server instead of the default custom protocol."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
tiny_http = "0.12"
http = "1"
http = "0.2"
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-localhost](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/localhost/banner.png)
![plugin-localhost](banner.png)
Expose your apps assets through a localhost server instead of the default custom protocol.
@@ -67,22 +67,6 @@ fn main() {
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+9 -9
View File
@@ -2,22 +2,22 @@
name = "tauri-plugin-log"
version = "0.0.0"
description = "Configurable logging for your Tauri app."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
serde_repr = "0.1"
byte-unit = "5"
byte-unit = "4.0"
fern = "0.6"
log = { workspace = true, features = ["kv_unstable"] }
time = { version = "0.3", features = ["formatting", "local-offset"] }
[features]
colored = ["fern/colored"]
colored = ["fern/colored"]
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-log](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/log/banner.png)
![plugin-log](banner.png)
Configurable logging for your Tauri app.
@@ -83,22 +83,6 @@ Now, you can use the macros provided by the log crate to log messages from your
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+7 -26
View File
@@ -1,5 +1,5 @@
import { invoke } from "@tauri-apps/api/tauri";
import { listen, type UnlistenFn, type Event } from "@tauri-apps/api/event";
import { listen, UnlistenFn } from "@tauri-apps/api/event";
export type LogOptions = {
file?: string;
@@ -184,38 +184,19 @@ interface RecordPayload {
message: string;
}
type LoggerFn = (fn: RecordPayload) => void;
/**
* Attaches a listener for the log, and calls the passed function for each log entry.
* @param fn
*
* @returns a function to cancel the listener.
*/
export async function attachLogger(fn: LoggerFn): Promise<UnlistenFn> {
return await listen("log://log", (event: Event<RecordPayload>) => {
const { level } = event.payload;
let { message } = event.payload;
export async function attachConsole(): Promise<UnlistenFn> {
return await listen("log://log", (event) => {
const payload = event.payload as RecordPayload;
// Strip ANSI escape codes
message = message.replace(
const message = payload.message.replace(
// TODO: Investigate security/detect-unsafe-regex
// eslint-disable-next-line no-control-regex, security/detect-unsafe-regex
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
"",
);
fn({ message, level });
});
}
/**
* Attaches a listener that writes log entries to the console as they come in.
*
* @returns a function to cancel the listener.
*/
export async function attachConsole(): Promise<UnlistenFn> {
return attachLogger(({ level, message }: RecordPayload) => {
switch (level) {
switch (payload.level) {
case LogLevel.Trace:
console.log(message);
break;
@@ -233,7 +214,7 @@ export async function attachConsole(): Promise<UnlistenFn> {
break;
default:
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`unknown log level ${level}`);
throw new Error(`unknown log level ${payload.level}`);
}
});
}
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+9 -9
View File
@@ -2,19 +2,19 @@
name = "tauri-plugin-persisted-scope"
version = "0.1.3"
description = "Save filesystem and asset scopes and restore them when the app is reopened."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
aho-corasick = "1.1"
bincode = "1"
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-persisted-scope](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/persisted-scope/banner.png)
![plugin-persisted-scope](banner.png)
Save filesystem and asset scopes and restore them when the app is reopened.
@@ -42,22 +42,6 @@ Afterwards the plugin will automatically save and restore filesystem and asset s
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
-5
View File
@@ -1,10 +1,5 @@
# Changelog
## \[1.0.5]
- `TrayLeft`, `TrayRight` and `TrayCenter` will now position the window according to the tray position relative to the monitor dimensions to prevent windows being displayed partially off-screen.
- [3d27909](https://github.com/tauri-apps/plugins-workspace/commit/3d279094d44be78cdc5d1de3938f1414e13db6b0) fix(positioner): Prevent tray relative windows from being moved off-screen ([#291](https://github.com/tauri-apps/plugins-workspace/pull/291)) on 2023-09-27
## \[0.2.7]
- Update Tauri to v1.0.0
+13 -11
View File
@@ -1,19 +1,21 @@
[package]
name = "tauri-plugin-positioner"
version = "1.0.5"
version = "1.0.4"
description = "Position your windows at well-known locations."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
serde_repr = "0.1"
[features]
system-tray = [ "tauri/system-tray" ]
system-tray = [ "tauri/system-tray" ]
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-positioner](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/positioner/banner.png)
![plugin-positioner](banner.png)
Position your windows at well-known locations.
@@ -87,22 +87,6 @@ let _ = win.move_window(Position::TopRight);
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2021 - Jonas Kruckenberg. 2021 - Present - The Tauri Programme within The Commons Conservancy.
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+10 -10
View File
@@ -2,23 +2,23 @@
name = "tauri-plugin-single-instance"
version = "0.0.0"
description = "Ensure a single instance of your tauri app is running."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
exclude = ["/examples"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
version = "0.52"
version = "0.48"
features = [
"Win32_System_Threading",
"Win32_System_DataExchange",
+1 -17
View File
@@ -1,4 +1,4 @@
![plugin-single-instance](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/single-instance/banner.png)
![tauri-plugin-single-instance](banner.png)
Ensure a single instance of your tauri app is running.
@@ -52,22 +52,6 @@ fn main() {
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
@@ -1,3 +1 @@
node_modules/
dist/**
!dist/.gitkeep
@@ -9,6 +9,6 @@
"author": "",
"license": "MIT",
"devDependencies": {
"@tauri-apps/cli": "1.5.11"
"@tauri-apps/cli": "1.5.5"
}
}
File diff suppressed because it is too large Load Diff
@@ -1,3 +1,5 @@
[workspace]
[package]
name = "single-instance-example"
version = "0.1.0"
@@ -8,13 +10,14 @@ edition = "2021"
rust-version = "1.57"
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { version = "1", features = ["api-all"] }
tauri-plugin-single-instance = { path = "../../../" }
[build-dependencies]
tauri-build = { workspace = true }
tauri-build = { version = "1", features = [] }
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]
@@ -44,7 +44,7 @@
"active": false
},
"allowlist": {
"all": false
"all": true
},
"windows": [
{
@@ -115,7 +115,7 @@ unsafe extern "system" fn single_instance_window_proc<R: Runtime>(
let data = CStr::from_ptr((*cds_ptr).lpData as _).to_string_lossy();
let mut s = data.split('|');
let cwd = s.next().unwrap();
let args = s.map(|s| s.to_string()).collect();
let args = s.into_iter().map(|s| s.to_string()).collect();
callback(app_handle, args, cwd.to_string());
}
1
+9 -9
View File
@@ -2,20 +2,20 @@
name = "tauri-plugin-sql"
version = "0.0.0"
description = "Interface with SQL databases."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
#rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
#rust-version.workspace = true
rust-version = "1.65"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
futures-core = "0.3"
sqlx = { version = "0.7", features = ["json", "time"] }
time = "0.3"
+1 -78
View File
@@ -1,4 +1,4 @@
![plugin-sql](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/sql/banner.png)
![plugin-sql](banner.png)
Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx). It supports the `sqlite`, `mysql` and `postgres` drivers, enabled by a Cargo feature.
@@ -96,87 +96,10 @@ const result = await db.execute(
);
```
## Migrations
This plugin supports database migrations, allowing you to manage database schema evolution over time.
### Defining Migrations
Migrations are defined in Rust using the `Migration` struct. Each migration should include a unique version number, a description, the SQL to be executed, and the type of migration (Up or Down).
Example of a migration:
```rust
use tauri_plugin_sql::{Migration, MigrationKind};
let migration = Migration {
version: 1,
description: "create_initial_tables",
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);",
kind: MigrationKind::Up,
};
```
### Adding Migrations to the Plugin Builder
Migrations are registered with the `Builder` struct provided by the plugin. Use the `add_migrations` method to add your migrations to the plugin for a specific database connection.
Example of adding migrations:
```rust
use tauri_plugin_sql::{Builder, Migration, MigrationKind};
fn main() {
let migrations = vec![
// Define your migrations here
Migration {
version: 1,
description: "create_initial_tables",
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);",
kind: MigrationKind::Up,
}
];
tauri::Builder::default()
.plugin(
tauri_plugin_sql::Builder::default()
.add_migrations("sqlite:mydatabase.db", migrations)
.build(),
)
...
}
```
### Applying Migrations
Migrations are applied automatically when the plugin is initialized. The plugin runs these migrations against the database specified by the connection string. Ensure that the migrations are defined in the correct order and are idempotent (safe to run multiple times).
### Migration Management
- **Version Control**: Each migration must have a unique version number. This is crucial for ensuring the migrations are applied in the correct order.
- **Idempotency**: Write migrations in a way that they can be safely re-run without causing errors or unintended consequences.
- **Testing**: Thoroughly test migrations to ensure they work as expected and do not compromise the integrity of your database.
## Contributing
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
+1 -1
View File
@@ -28,6 +28,6 @@
"tslib": "2.6.2"
},
"dependencies": {
"@tauri-apps/api": "1.5.3"
"@tauri-apps/api": "1.5.1"
}
}
+9 -9
View File
@@ -2,16 +2,16 @@
name = "tauri-plugin-store"
version = "0.0.0"
description = "Simple, persistent key-value store."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
authors.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde.workspace = true
serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
+2 -18
View File
@@ -1,4 +1,4 @@
![plugin-store](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/store/banner.png)
![plugin-store](banner.png)
Simple, persistent key-value store.
@@ -91,7 +91,7 @@ fn main() {
}
```
As you may have noticed, the Store created above isn't accessible to the frontend. To interoperate with stores created by JS use the exported `with_store` method:
As you may have noticed, the Store crated above isn't accessible to the frontend. To interoperate with stores created by JS use the exported `with_store` method:
```rust
use tauri::Wry;
@@ -107,22 +107,6 @@ with_store(app_handle, stores, path, |store| store.insert("a".to_string(), json!
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
## Partners
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://crabnebula.dev" target="_blank">
<img src="https://github.com/tauri-apps/plugins-workspace/raw/v1/.github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
</a>
</td>
</tr>
</tbody>
</table>
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
## License
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
@@ -1,24 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
#dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
@@ -1,3 +0,0 @@
{
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
}
@@ -1,7 +0,0 @@
# Tauri + Vanilla TS
This template should help get you started developing with Tauri in vanilla HTML, CSS and Typescript.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
@@ -1,54 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="/src/styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri App</title>
<script type="module" src="/src/main.ts" defer></script>
<style>
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.typescript:hover {
filter: drop-shadow(0 0 2em #2d79c7);
}
</style>
</head>
<body>
<div class="container">
<h1>Welcome to Tauri!</h1>
<div class="row">
<a href="https://vitejs.dev" target="_blank">
<img src="/src/assets/vite.svg" class="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img
src="/src/assets/tauri.svg"
class="logo tauri"
alt="Tauri logo"
/>
</a>
<a href="https://www.typescriptlang.org/docs" target="_blank">
<img
src="/src/assets/typescript.svg"
class="logo typescript"
alt="typescript logo"
/>
</a>
</div>
<p>Click on the Tauri logo to learn more about the framework</p>
<!-- <form class="row" id="greet-form">
<input id="greet-input" placeholder="Enter a name..." />
<button type="submit">Greet</button>
</form> -->
<p id="greet-msg"></p>
</div>
</body>
</html>
@@ -1,15 +0,0 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"devDependencies": {
"@tauri-apps/cli": "1.5.11",
"vite": "^5.0.12",
"typescript": "^5.3.3"
}
}
@@ -1,4 +0,0 @@
# Generated by Cargo
# will have compiled files and executables
/target/
@@ -1,24 +0,0 @@
[package]
name = "app_settings_manager"
version = "0.0.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { workspace = true }
[dependencies]
tauri = { workspace = true, features = ["shell-open"] }
serde = { workspace = true }
serde_json = { workspace = true }
tauri-plugin-store = { path = "../../../" }
[features]
# this feature is used for production builds or when `devPath` points to the filesystem
# DO NOT REMOVE!!
custom-protocol = ["tauri/custom-protocol"]
@@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

@@ -1 +0,0 @@
pub mod settings;
@@ -1,29 +0,0 @@
use tauri_plugin_store::Store;
#[derive(Debug, Clone)]
pub struct AppSettings {
pub launch_at_login: bool,
pub theme: String,
}
impl AppSettings {
pub fn load_from_store<R: tauri::Runtime>(
store: &Store<R>,
) -> Result<Self, Box<dyn std::error::Error>> {
let launch_at_login = store
.get("appSettings.launchAtLogin")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let theme = store
.get("appSettings.theme")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
.unwrap_or_else(|| "dark".to_string());
Ok(AppSettings {
launch_at_login,
theme,
})
}
}
@@ -1,40 +0,0 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use tauri_plugin_store::StoreBuilder;
mod app;
use app::settings::AppSettings;
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_store::Builder::default().build())
.setup(|app| {
// Init store and load it from disk
let mut store = StoreBuilder::new(app.handle(), "settings.json".parse()?).build();
// If there are no saved settings yet, this will return an error so we ignore the return value.
let _ = store.load();
let app_settings = AppSettings::load_from_store(&store);
match app_settings {
Ok(app_settings) => {
let theme = app_settings.theme;
let launch_at_login = app_settings.launch_at_login;
println!("theme {}", theme);
println!("launch_at_login {}", launch_at_login);
Ok(())
}
Err(err) => {
eprintln!("Error loading settings: {}", err);
// Handle the error case if needed
Err(err) // Convert the error to a Box<dyn Error> and return Err(err) here
}
}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
@@ -1,46 +0,0 @@
{
"build": {
"beforeDevCommand": "pnpm dev",
"beforeBuildCommand": "pnpm build",
"devPath": "http://localhost:1420",
"distDir": "../dist",
"withGlobalTauri": true
},
"package": {
"productName": "AppSettingsManager",
"version": "0.0.0"
},
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
}
},
"bundle": {
"active": true,
"targets": "all",
"identifier": "com.tauri.dev",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
},
"security": {
"csp": null
},
"windows": [
{
"fullscreen": false,
"resizable": true,
"title": "AppSettingsManager",
"width": 800,
"height": 600
}
]
}
}
@@ -1,6 +0,0 @@
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

@@ -1,25 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#2D79C7" stroke="none">
<path d="M430 5109 c-130 -19 -248 -88 -325 -191 -53 -71 -83 -147 -96 -247
-6 -49 -9 -813 -7 -2166 l3 -2090 22 -65 c54 -159 170 -273 328 -323 l70 -22
2140 0 2140 0 66 23 c160 55 272 169 322 327 l22 70 0 2135 0 2135 -22 70
c-49 157 -155 265 -319 327 l-59 23 -2115 1 c-1163 1 -2140 -2 -2170 -7z
m3931 -2383 c48 -9 120 -26 160 -39 l74 -23 3 -237 c1 -130 0 -237 -2 -237 -3
0 -26 14 -53 30 -61 38 -197 84 -310 106 -110 20 -293 15 -368 -12 -111 -39
-175 -110 -175 -193 0 -110 97 -197 335 -300 140 -61 309 -146 375 -189 30
-20 87 -68 126 -107 119 -117 164 -234 164 -426 0 -310 -145 -518 -430 -613
-131 -43 -248 -59 -445 -60 -243 -1 -405 24 -577 90 l-68 26 0 242 c0 175 -3
245 -12 254 -9 9 -9 12 0 12 7 0 12 -4 12 -9 0 -17 139 -102 223 -138 136 -57
233 -77 382 -76 145 0 224 19 295 68 75 52 100 156 59 242 -41 84 -135 148
-374 253 -367 161 -522 300 -581 520 -23 86 -23 253 -1 337 73 275 312 448
682 492 109 13 401 6 506 -13z m-1391 -241 l0 -205 -320 0 -320 0 0 -915 0
-915 -255 0 -255 0 0 915 0 915 -320 0 -320 0 0 205 0 205 895 0 895 0 0 -205z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,5 +0,0 @@
window.addEventListener("DOMContentLoaded", () => {
document.querySelector("#greet-form")?.addEventListener("submit", (e) => {
e.preventDefault();
});
});
@@ -1,109 +0,0 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}
@@ -1,23 +0,0 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
@@ -1,17 +0,0 @@
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig(async () => ({
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
},
// 3. to make use of `TAURI_DEBUG` and other env variables
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
envPrefix: ["VITE_", "TAURI_"],
}));

Some files were not shown because too many files have changed in this diff Show More