feat: new passkeys section and implement credentials handling

This commit is contained in:
Suyog Tandel
2026-01-14 14:44:06 +05:30
parent cd5541440e
commit 578bf0032c
36 changed files with 902 additions and 88 deletions
Generated
+29 -3
View File
@@ -21,6 +21,7 @@
"npm:tailwindcss@^4.1.18": "4.1.18",
"npm:tw-animate-css@^1.4.0": "1.4.0",
"npm:typescript@~5.9.3": "5.9.3",
"npm:vaul-svelte@^1.0.0-next.7": "1.0.0-next.7_svelte@5.46.1__acorn@8.15.0",
"npm:vite@^6.0.3": "6.4.1_picomatch@4.0.3"
},
"npm": {
@@ -667,9 +668,9 @@
"@floating-ui/dom",
"@internationalized/date",
"esm-env",
"runed",
"runed@0.35.1_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@5.1.1___svelte@5.46.1____acorn@8.15.0___vite@6.4.1____picomatch@4.0.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@6.4.1___picomatch@4.0.3__acorn@8.15.0_svelte@5.46.1__acorn@8.15.0_@sveltejs+vite-plugin-svelte@5.1.1__svelte@5.46.1___acorn@8.15.0__vite@6.4.1___picomatch@4.0.3_typescript@5.9.3_vite@6.4.1__picomatch@4.0.3",
"svelte",
"svelte-toolbelt",
"svelte-toolbelt@0.10.6_svelte@5.46.1__acorn@8.15.0_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@5.1.1___svelte@5.46.1____acorn@8.15.0___vite@6.4.1____picomatch@4.0.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@6.4.1___picomatch@4.0.3__acorn@8.15.0_@sveltejs+vite-plugin-svelte@5.1.1__svelte@5.46.1___acorn@8.15.0__vite@6.4.1___picomatch@4.0.3_typescript@5.9.3_vite@6.4.1__picomatch@4.0.3",
"tabbable"
]
},
@@ -937,6 +938,13 @@
],
"bin": true
},
"runed@0.23.4_svelte@5.46.1__acorn@8.15.0": {
"integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==",
"dependencies": [
"esm-env",
"svelte"
]
},
"runed@0.35.1_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@5.1.1___svelte@5.46.1____acorn@8.15.0___vite@6.4.1____picomatch@4.0.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@6.4.1___picomatch@4.0.3__acorn@8.15.0_svelte@5.46.1__acorn@8.15.0_@sveltejs+vite-plugin-svelte@5.1.1__svelte@5.46.1___acorn@8.15.0__vite@6.4.1___picomatch@4.0.3_typescript@5.9.3_vite@6.4.1__picomatch@4.0.3": {
"integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==",
"dependencies": [
@@ -993,7 +1001,16 @@
"integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==",
"dependencies": [
"clsx",
"runed",
"runed@0.35.1_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@5.1.1___svelte@5.46.1____acorn@8.15.0___vite@6.4.1____picomatch@4.0.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@6.4.1___picomatch@4.0.3__acorn@8.15.0_svelte@5.46.1__acorn@8.15.0_@sveltejs+vite-plugin-svelte@5.1.1__svelte@5.46.1___acorn@8.15.0__vite@6.4.1___picomatch@4.0.3_typescript@5.9.3_vite@6.4.1__picomatch@4.0.3",
"style-to-object",
"svelte"
]
},
"svelte-toolbelt@0.7.1_svelte@5.46.1__acorn@8.15.0": {
"integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==",
"dependencies": [
"clsx",
"runed@0.23.4_svelte@5.46.1__acorn@8.15.0",
"style-to-object",
"svelte"
]
@@ -1060,6 +1077,14 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"bin": true
},
"vaul-svelte@1.0.0-next.7_svelte@5.46.1__acorn@8.15.0": {
"integrity": "sha512-7zN7Bi3dFQixvvbUJY9uGDe7Ws/dGZeBQR2pXdXmzQiakjrxBvWo0QrmsX3HK+VH+SZOltz378cmgmCS9f9rSg==",
"dependencies": [
"runed@0.23.4_svelte@5.46.1__acorn@8.15.0",
"svelte",
"svelte-toolbelt@0.7.1_svelte@5.46.1__acorn@8.15.0"
]
},
"vite@6.4.1_picomatch@4.0.3": {
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dependencies": [
@@ -1111,6 +1136,7 @@
"npm:tailwindcss@^4.1.18",
"npm:tw-animate-css@^1.4.0",
"npm:typescript@~5.9.3",
"npm:vaul-svelte@^1.0.0-next.7",
"npm:vite@^6.0.3"
]
}
+1
View File
@@ -38,6 +38,7 @@
"tailwind-variants": "^3.2.2",
"tw-animate-css": "^1.4.0",
"typescript": "~5.9.3",
"vaul-svelte": "^1.0.0-next.7",
"vite": "^6.0.3",
"@tauri-apps/cli": "^2"
}
+53 -78
View File
@@ -451,7 +451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
dependencies = [
"serde",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
]
[[package]]
@@ -465,9 +465,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.51"
version = "1.2.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -506,12 +506,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.42"
@@ -782,9 +776,9 @@ dependencies = [
[[package]]
name = "data-encoding"
version = "2.9.0"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
[[package]]
name = "der-parser"
@@ -986,7 +980,7 @@ dependencies = [
"cc",
"memchr",
"rustc_version",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
"vswhom",
"winreg",
]
@@ -1108,15 +1102,15 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
[[package]]
name = "flate2"
version = "1.1.5"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -1390,9 +1384,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
@@ -2315,19 +2309,6 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.10.0",
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@@ -3195,7 +3176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"rand_core 0.9.5",
]
[[package]]
@@ -3225,7 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
"rand_core 0.9.5",
]
[[package]]
@@ -3243,14 +3224,14 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.16",
"getrandom 0.2.17",
]
[[package]]
name = "rand_core"
version = "0.9.3"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
@@ -3294,7 +3275,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom 0.2.16",
"getrandom 0.2.17",
"libredox",
"thiserror 2.0.17",
]
@@ -3391,7 +3372,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.16",
"getrandom 0.2.17",
"libc",
"untrusted",
"windows-sys 0.52.0",
@@ -3890,12 +3871,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "string_cache"
version = "0.8.9"
@@ -4137,7 +4112,7 @@ dependencies = [
"serde_json",
"tauri-utils",
"tauri-winres",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
"walkdir",
]
@@ -4195,7 +4170,7 @@ dependencies = [
"serde",
"serde_json",
"tauri-utils",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
"walkdir",
]
@@ -4325,7 +4300,7 @@ dependencies = [
"serde_with",
"swift-rs",
"thiserror 2.0.17",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
"url",
"urlpattern",
"uuid",
@@ -4340,7 +4315,7 @@ checksum = "1087b111fe2b005e42dbdc1990fc18593234238d47453b0c99b7de1c9ab2c1e0"
dependencies = [
"dunce",
"embed-resource",
"toml 0.9.10+spec-1.1.0",
"toml 0.9.11+spec-1.1.0",
]
[[package]]
@@ -4409,40 +4384,40 @@ dependencies = [
[[package]]
name = "thread-id"
version = "5.0.0"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99043e46c5a15af379c06add30d9c93a6c0e8849de00d244c4a2c417da128d80"
checksum = "2010d27add3f3240c1fef7959f46c814487b216baee662af53be645ba7831c07"
dependencies = [
"libc",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
name = "time"
version = "0.3.44"
version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
[[package]]
name = "time-macros"
version = "0.2.24"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
dependencies = [
"num-conv",
"time-core",
@@ -4499,9 +4474,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.9.10+spec-1.1.0"
version = "0.9.11+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46"
dependencies = [
"indexmap 2.13.0",
"serde_core",
@@ -4583,9 +4558,9 @@ checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607"
[[package]]
name = "tower"
version = "0.5.2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
@@ -5733,9 +5708,9 @@ dependencies = [
[[package]]
name = "zbus"
version = "5.12.0"
version = "5.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91"
checksum = "17f79257df967b6779afa536788657777a0001f5b42524fcaf5038d4344df40b"
dependencies = [
"async-broadcast",
"async-executor",
@@ -5751,8 +5726,9 @@ dependencies = [
"futures-core",
"futures-lite",
"hex",
"nix",
"libc",
"ordered-stream",
"rustix",
"serde",
"serde_repr",
"tracing",
@@ -5767,9 +5743,9 @@ dependencies = [
[[package]]
name = "zbus_macros"
version = "5.12.0"
version = "5.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314"
checksum = "aad23e2d2f91cae771c7af7a630a49e755f1eb74f8a46e9f6d5f7a146edf5a37"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
@@ -5782,12 +5758,11 @@ dependencies = [
[[package]]
name = "zbus_names"
version = "4.2.0"
version = "4.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f"
dependencies = [
"serde",
"static_assertions",
"winnow 0.7.14",
"zvariant",
]
@@ -5868,15 +5843,15 @@ dependencies = [
[[package]]
name = "zmij"
version = "1.0.12"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8"
checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea"
[[package]]
name = "zvariant"
version = "5.8.0"
version = "5.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c"
checksum = "326aaed414f04fe839777b4c443d4e94c74e7b3621093bd9c5e649ac8aa96543"
dependencies = [
"endi",
"enumflags2",
@@ -5888,9 +5863,9 @@ dependencies = [
[[package]]
name = "zvariant_derive"
version = "5.8.0"
version = "5.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006"
checksum = "ba44e1f8f4da9e6e2d25d2a60b116ef8b9d0be174a7685e55bb12a99866279a7"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
@@ -5901,9 +5876,9 @@ dependencies = [
[[package]]
name = "zvariant_utils"
version = "3.2.1"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599"
checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9"
dependencies = [
"proc-macro2",
"quote",
+1 -1
View File
@@ -42,7 +42,7 @@ log4rs = "1" # For logging to output (like stdout)
directories = "6" # For Applcation config/data dir handling
[profile.dev]
incremental = true # Compile your binary in smaller steps.
incremental = true # Compile your binary in smaller steps.
codegen-units = 256
[profile.release]
+60 -2
View File
@@ -5,10 +5,12 @@ pub mod hid;
use crate::{
error::PFError,
types::{AppConfig, DeviceInfo, FidoDeviceInfo, FullDeviceStatus},
types::{AppConfig, DeviceInfo, FidoDeviceInfo, FullDeviceStatus, StoredCredential},
};
use constants::*;
use ctap_hid_fido2::{Cfg, FidoKeyHidFactory};
use ctap_hid_fido2::{
Cfg, FidoKeyHidFactory, public_key_credential_descriptor::PublicKeyCredentialDescriptor,
};
use hid::*;
use serde_cbor_2::{Value, from_slice, to_vec};
use std::collections::{BTreeMap, HashMap};
@@ -81,6 +83,62 @@ pub(crate) fn set_min_pin_length(
))
}
pub(crate) fn get_credentials(pin: String) -> Result<Vec<StoredCredential>, String> {
let cfg = Cfg::init();
let device = FidoKeyHidFactory::create(&cfg)
.map_err(|e| format!("Failed to connect to FIDO device: {:?}", e))?;
let rps = device
.credential_management_enumerate_rps(Some(&pin))
.map_err(|e| format!("Failed to enumerate Relying Parties: {:?}", e))?;
let mut all_credentials = Vec::new();
for rp in rps {
let creds = device
.credential_management_enumerate_credentials(Some(&pin), &rp.rpid_hash)
.map_err(|e| {
format!(
"Failed to enumerate credentials for RP {}: {:?}",
rp.public_key_credential_rp_entity.id, e
)
})?;
for cred in creds {
all_credentials.push(StoredCredential {
credential_id: hex::encode(&cred.public_key_credential_descriptor.id),
rp_id: rp.public_key_credential_rp_entity.id.clone(),
rp_name: rp.public_key_credential_rp_entity.name.clone(),
user_name: cred.public_key_credential_user_entity.name.clone(),
user_display_name: cred.public_key_credential_user_entity.display_name.clone(),
user_id: hex::encode(&cred.public_key_credential_user_entity.id).clone(),
});
}
}
Ok(all_credentials)
}
pub(crate) fn delete_credential(pin: String, credential_id_hex: String) -> Result<String, String> {
let cfg = Cfg::init();
let device = FidoKeyHidFactory::create(&cfg)
.map_err(|e| format!("Failed to connect to FIDO device: {:?}", e))?;
let cred_id_bytes = hex::decode(&credential_id_hex)
.map_err(|_| "Invalid Credential ID Hex string".to_string())?;
let descriptor = PublicKeyCredentialDescriptor {
ctype: "public-key".to_string(),
id: cred_id_bytes,
};
device
.credential_management_delete_credential(Some(&pin), descriptor)
.map_err(|e| format!("Failed to delete credential: {:?}", e))?;
Ok("Credential deleted successfully".into())
}
// Custom Fido functions ( works only with pico-fido firmware )
pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
+14
View File
@@ -43,3 +43,17 @@ pub(crate) fn set_min_pin_length(
pub fn reboot(to_bootsel: bool) -> Result<String, PFError> {
rescue::reboot_device(to_bootsel)
}
#[tauri::command]
pub async fn get_credentials(pin: String) -> Result<Vec<StoredCredential>, String> {
tauri::async_runtime::spawn_blocking(move || {
fido::get_credentials(pin)
}).await.map_err(|e| e.to_string())?
}
#[tauri::command]
pub async fn delete_credential(pin: String, credential_id: String) -> Result<String, String> {
tauri::async_runtime::spawn_blocking(move || {
fido::delete_credential(pin, credential_id)
}).await.map_err(|e| e.to_string())?
}
+3 -1
View File
@@ -1,5 +1,5 @@
use serde::Serialize;
use tauri::{Emitter, Listener, Manager, WebviewWindow};
use tauri::{Emitter, Manager, WebviewWindow};
mod error;
mod fido;
@@ -49,6 +49,8 @@ pub fn run() {
io::write_config,
io::get_fido_info,
io::change_fido_pin,
io::get_credentials,
io::delete_credential,
io::set_min_pin_length,
io::enable_secure_boot,
io::reboot
+11
View File
@@ -72,3 +72,14 @@ pub struct FidoDeviceInfo {
pub min_pin_length: u32,
pub firmware_version: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StoredCredential {
pub rp_id: String,
pub rp_name: String,
pub user_name: String,
pub user_display_name: String,
pub user_id: String,
pub credential_id: String,
}
@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: DialogPrimitive.CloseProps = $props();
</script>
<DialogPrimitive.Close bind:ref data-slot="dialog-close" {...restProps} />
@@ -0,0 +1,45 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import DialogPortal from "./dialog-portal.svelte";
import XIcon from "@lucide/svelte/icons/x";
import type { Snippet } from "svelte";
import * as Dialog from "./index.js";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import type { ComponentProps } from "svelte";
let {
ref = $bindable(null),
class: className,
portalProps,
children,
showCloseButton = true,
...restProps
}: WithoutChildrenOrChild<DialogPrimitive.ContentProps> & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof DialogPortal>>;
children: Snippet;
showCloseButton?: boolean;
} = $props();
</script>
<DialogPortal {...portalProps}>
<Dialog.Overlay />
<DialogPrimitive.Content
bind:ref
data-slot="dialog-content"
class={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
className
)}
{...restProps}
>
{@render children?.()}
{#if showCloseButton}
<DialogPrimitive.Close
class="ring-offset-background focus:ring-ring absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span class="sr-only">Close</span>
</DialogPrimitive.Close>
{/if}
</DialogPrimitive.Content>
</DialogPortal>
@@ -0,0 +1,17 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.DescriptionProps = $props();
</script>
<DialogPrimitive.Description
bind:ref
data-slot="dialog-description"
class={cn("text-muted-foreground text-sm", className)}
{...restProps}
/>
@@ -0,0 +1,20 @@
<script lang="ts">
import { cn, type WithElementRef } from "$lib/utils.js";
import type { HTMLAttributes } from "svelte/elements";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-footer"
class={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
{...restProps}
>
{@render children?.()}
</div>
@@ -0,0 +1,20 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn, type WithElementRef } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-header"
class={cn("flex flex-col gap-2 text-center sm:text-start", className)}
{...restProps}
>
{@render children?.()}
</div>
@@ -0,0 +1,20 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.OverlayProps = $props();
</script>
<DialogPrimitive.Overlay
bind:ref
data-slot="dialog-overlay"
class={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
className
)}
{...restProps}
/>
@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
let { ...restProps }: DialogPrimitive.PortalProps = $props();
</script>
<DialogPrimitive.Portal {...restProps} />
@@ -0,0 +1,17 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.TitleProps = $props();
</script>
<DialogPrimitive.Title
bind:ref
data-slot="dialog-title"
class={cn("text-lg leading-none font-semibold", className)}
{...restProps}
/>
@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: DialogPrimitive.TriggerProps = $props();
</script>
<DialogPrimitive.Trigger bind:ref data-slot="dialog-trigger" {...restProps} />
@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
let { open = $bindable(false), ...restProps }: DialogPrimitive.RootProps = $props();
</script>
<DialogPrimitive.Root bind:open {...restProps} />
+34
View File
@@ -0,0 +1,34 @@
import Root from "./dialog.svelte";
import Portal from "./dialog-portal.svelte";
import Title from "./dialog-title.svelte";
import Footer from "./dialog-footer.svelte";
import Header from "./dialog-header.svelte";
import Overlay from "./dialog-overlay.svelte";
import Content from "./dialog-content.svelte";
import Description from "./dialog-description.svelte";
import Trigger from "./dialog-trigger.svelte";
import Close from "./dialog-close.svelte";
export {
Root,
Title,
Portal,
Footer,
Header,
Trigger,
Overlay,
Content,
Description,
Close,
//
Root as Dialog,
Title as DialogTitle,
Portal as DialogPortal,
Footer as DialogFooter,
Header as DialogHeader,
Trigger as DialogTrigger,
Overlay as DialogOverlay,
Content as DialogContent,
Description as DialogDescription,
Close as DialogClose,
};
@@ -0,0 +1,7 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from "vaul-svelte";
let { ref = $bindable(null), ...restProps }: DrawerPrimitive.CloseProps = $props();
</script>
<DrawerPrimitive.Close bind:ref data-slot="drawer-close" {...restProps} />

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