work
This commit is contained in:
814
Cargo.lock
generated
814
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ ron = "0.12.0"
|
|||||||
clap = { version = "4.5.53", features = ["derive"] }
|
clap = { version = "4.5.53", features = ["derive"] }
|
||||||
scrypt = "0.11.0"
|
scrypt = "0.11.0"
|
||||||
ed25519-dalek = { version = "3.0.0-pre.2", features = ["rand_core"] }
|
ed25519-dalek = { version = "3.0.0-pre.2", features = ["rand_core"] }
|
||||||
rand = { version = "0.10.0-rc.5", features = ["chacha"] }
|
rand = { version = "0.10.0-rc.5", features = ["chacha", "sys_rng"] }
|
||||||
keyring = { version = "3.6.3", features = ["apple-native", "sync-secret-service", "windows-native"] }
|
keyring = { version = "3.6.3", features = ["apple-native", "sync-secret-service", "windows-native"] }
|
||||||
bitcode = "0.6.9"
|
bitcode = "0.6.9"
|
||||||
dashmap = "6.1.0"
|
dashmap = "6.1.0"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use ed25519_dalek::SigningKey;
|
use ed25519_dalek::SigningKey;
|
||||||
use rand::{
|
use rand::{
|
||||||
SeedableRng,
|
SeedableRng,
|
||||||
rngs::{OsRng, StdRng},
|
rngs::{StdRng, SysRng},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
@@ -11,7 +11,7 @@ pub struct Account {
|
|||||||
|
|
||||||
impl Account {
|
impl Account {
|
||||||
pub fn new() -> Account {
|
pub fn new() -> Account {
|
||||||
let mut csprng = StdRng::try_from_rng(&mut OsRng).unwrap();
|
let mut csprng = StdRng::try_from_rng(&mut SysRng).unwrap();
|
||||||
let device_key = SigningKey::generate(&mut csprng);
|
let device_key = SigningKey::generate(&mut csprng);
|
||||||
let account_key = SigningKey::generate(&mut csprng);
|
let account_key = SigningKey::generate(&mut csprng);
|
||||||
Account {
|
Account {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ pub fn start(rsc: &mut Rsc) -> WeakWidget {
|
|||||||
|
|
||||||
pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
|
pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
|
||||||
let url = field("", "server", rsc);
|
let url = field("", "server", rsc);
|
||||||
|
let token = field("", "account token", rsc);
|
||||||
let username = field("", "username", rsc);
|
let username = field("", "username", rsc);
|
||||||
let password = field("", "password", rsc);
|
let password = field("", "password", rsc);
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
|
|||||||
rsc.events.register(create, Submit, move |ctx, rsc| {
|
rsc.events.register(create, Submit, move |ctx, rsc| {
|
||||||
create.disable(rsc);
|
create.disable(rsc);
|
||||||
let url = rsc[url].content();
|
let url = rsc[url].content();
|
||||||
|
let token = rsc[token].content();
|
||||||
let username = rsc[username].content();
|
let username = rsc[username].content();
|
||||||
let password = rsc[password].content();
|
let password = rsc[password].content();
|
||||||
let login_key = ctx.state.data.login_key(&username);
|
let login_key = ctx.state.data.login_key(&username);
|
||||||
@@ -72,6 +74,7 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
|
|||||||
.request(CreateAccount {
|
.request(CreateAccount {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|
token,
|
||||||
login_key,
|
login_key,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -84,6 +87,7 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
|
|||||||
(
|
(
|
||||||
wtext("Create Account").text_align(Align::CENTER).size(30),
|
wtext("Create Account").text_align(Align::CENTER).size(30),
|
||||||
field_box(url, rsc),
|
field_box(url, rsc),
|
||||||
|
field_box(token, rsc),
|
||||||
field_box(username, rsc),
|
field_box(username, rsc),
|
||||||
field_box(password, rsc),
|
field_box(password, rsc),
|
||||||
create,
|
create,
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
use std::{
|
use std::{marker::PhantomData, path::Path};
|
||||||
marker::PhantomData,
|
|
||||||
ops::{Deref, DerefMut},
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
use bitcode::{Decode, DecodeOwned, Encode};
|
use bitcode::{Decode, DecodeOwned, Encode};
|
||||||
|
use fjall::{Database, Keyspace, KeyspaceCreateOptions, UserValue};
|
||||||
|
|
||||||
pub const DB_VERSION: u64 = 0;
|
pub struct DbU64(u64);
|
||||||
|
pub const DB_VERSION: DbU64 = DbU64(0);
|
||||||
|
|
||||||
|
impl Into<UserValue> for DbU64 {
|
||||||
|
fn into(self) -> UserValue {
|
||||||
|
UserValue::new(&self.0.to_be_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
@@ -29,7 +33,7 @@ pub struct Db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DbMap<K, V> {
|
pub struct DbMap<K, V> {
|
||||||
tree: fjall::Tree,
|
keyspace: Keyspace,
|
||||||
_pd: PhantomData<(K, V)>,
|
_pd: PhantomData<(K, V)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,42 +68,43 @@ impl Key for u64 {
|
|||||||
|
|
||||||
impl<K: Key, V: Encode + DecodeOwned> DbMap<K, V> {
|
impl<K: Key, V: Encode + DecodeOwned> DbMap<K, V> {
|
||||||
pub fn insert(&self, k: &K, v: &V) {
|
pub fn insert(&self, k: &K, v: &V) {
|
||||||
self.tree.insert_(k, v);
|
self.keyspace.insert_(k, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, k: &K) -> Option<V> {
|
pub fn get(&self, k: &K) -> Option<V> {
|
||||||
self.tree.get_(k)
|
self.keyspace.get_(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_unique(&self, k: &K) -> bool {
|
pub fn init_unique(&self, k: &K) -> bool {
|
||||||
self.tree
|
self.keyspace
|
||||||
.compare_and_swap(k.bytes(), None as Option<&[u8]>, Some(&[0]))
|
.compare_and_swap(k.bytes(), None as Option<&[u8]>, Some(&[0]))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_all(&self) -> impl Iterator<Item = V> {
|
pub fn iter_all(&self) -> impl Iterator<Item = V> {
|
||||||
self.tree.iter_all()
|
self.keyspace.iter_all()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_db(path: impl AsRef<Path>) -> Db {
|
pub fn open_db(path: impl AsRef<Path>) -> Db {
|
||||||
let db = sled::open(path).expect("failed to open database");
|
let config = fjall::Config::new(path.as_ref());
|
||||||
if !db.was_recovered() {
|
let db = Database::open(config).expect("failed to open database");
|
||||||
|
let info = open_ks("info", &db);
|
||||||
|
if !info.contains_key("version").unwrap() {
|
||||||
println!("no previous db found, creating new");
|
println!("no previous db found, creating new");
|
||||||
db.insert_("version", DB_VERSION);
|
info.insert("version", DB_VERSION);
|
||||||
db.flush().unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
let version: u64 = db.get_("version").expect("failed to read db version");
|
let version: u64 = info.get("version").expect("failed to read db version");
|
||||||
println!("found existing db version {version}");
|
println!("found existing db version {version}");
|
||||||
if version != DB_VERSION {
|
if version != DB_VERSION {
|
||||||
panic!("non matching db version! (auto update in the future)");
|
panic!("non matching db version! (auto update in the future)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Db {
|
Db {
|
||||||
msgs: open_tree("msg", &db),
|
msgs: open_ks("msg", &db),
|
||||||
users: open_tree("user", &db),
|
users: open_ks("user", &db),
|
||||||
usernames: open_tree("username", &db),
|
usernames: open_ks("username", &db),
|
||||||
db,
|
db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,32 +139,25 @@ impl DbUtil for Tree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_tree<K, V>(name: &str, db: &sled::Db) -> DbMap<K, V> {
|
pub fn open_ks<K, V>(name: &str, db: &Database) -> DbMap<K, V> {
|
||||||
DbMap {
|
DbMap {
|
||||||
tree: db.open_tree(name).unwrap(),
|
keyspace: db.keyspace(name, KeyspaceCreateOptions::default).unwrap(),
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Db {
|
|
||||||
type Target = sled::Db;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.db
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for Db {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.db
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> Clone for DbMap<K, V> {
|
impl<K, V> Clone for DbMap<K, V> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tree: self.tree.clone(),
|
keyspace: self.keyspace.clone(),
|
||||||
_pd: self._pd,
|
_pd: self._pd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Db {
|
||||||
|
pub fn flush(&self) {
|
||||||
|
// test to see if it gets dropped and just works
|
||||||
|
// self.db.persist(fjall::PersistMode::SyncAll).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ pub async fn run_server(port: u16) {
|
|||||||
let _ = handle.await;
|
let _ = handle.await;
|
||||||
endpoint.wait_idle().await;
|
endpoint.wait_idle().await;
|
||||||
println!("saving...");
|
println!("saving...");
|
||||||
db.flush_async().await.unwrap();
|
db.flush();
|
||||||
println!("saved");
|
println!("saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +162,7 @@ impl RecvHandler<ClientMsgInst> for ClientHandler {
|
|||||||
}
|
}
|
||||||
ClientMsg::CreateAccount(info) => {
|
ClientMsg::CreateAccount(info) => {
|
||||||
let CreateAccount {
|
let CreateAccount {
|
||||||
|
token,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
login_key,
|
login_key,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use rand::TryRngCore;
|
use rand::TryRng;
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
@@ -21,6 +21,7 @@ pub enum ServerMsgInst {
|
|||||||
pub struct CreateAccountV0 {
|
pub struct CreateAccountV0 {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
pub token: String,
|
||||||
pub login_key: LoginKeyV0,
|
pub login_key: LoginKeyV0,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ impl LoginKeyV0 {
|
|||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut key = [0u8; Self::BYTE_LEN];
|
let mut key = [0u8; Self::BYTE_LEN];
|
||||||
rand::rngs::OsRng
|
rand::rngs::SysRng
|
||||||
.try_fill_bytes(&mut key)
|
.try_fill_bytes(&mut key)
|
||||||
.expect("failed to generate random key");
|
.expect("failed to generate random key");
|
||||||
Self(key.to_vec())
|
Self(key.to_vec())
|
||||||
|
|||||||
@@ -27,3 +27,9 @@ impl From<CreateAccount> for ClientMsg {
|
|||||||
Self::CreateAccount(value)
|
Self::CreateAccount(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ServerError> for ServerMsg {
|
||||||
|
fn from(value: ServerError) -> Self {
|
||||||
|
Self::ServerError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user