ACCOUNT CREATION AND LOGIN

This commit is contained in:
2026-02-16 23:56:07 -05:00
parent 79da5e1146
commit 61e9c2ac5c
17 changed files with 2322 additions and 326 deletions

View File

@@ -1,20 +1,101 @@
use openworm::net::{CreateAccount, CreateAccountResp};
use openworm::net::{CreateAccount, CreateAccountResp, Login, LoginResp};
use crate::net::{ConnectInfo, NetHandle};
use crate::{
data::{AccountInfo, ClientData, ServerInfo, ServerList},
net::{ConnectInfo, NetHandle},
};
use super::*;
pub fn start(rsc: &mut Rsc) -> WeakWidget {
pub fn start(rsc: &mut Rsc, data: &ClientData) -> WeakWidget {
let mut accounts = Span::empty(Dir::DOWN);
accounts.push(
wtext("no accounts")
.size(20)
.center_text()
.color(Color::GRAY)
.height(60)
.add_strong(rsc),
);
let accts = data.accounts();
if accts.is_empty() {
accounts.push(
wtext("no accounts")
.size(20)
.center_text()
.color(Color::GRAY)
.height(60)
.add_strong(rsc),
);
} else {
for account in accts.iter() {
let button = Button::new_fg(
wtext(&account.username)
.size(20)
.center_text()
.height(60)
.add(rsc),
color::DARK,
rsc,
)
.add(rsc);
let account = account.clone();
let cert_hex = data
.data
.load::<ServerList>()
.get(&account.url)
.unwrap()
.cert_hex
.clone();
let cert = decode_hex(&cert_hex).unwrap();
keyring::use_native_store(true).unwrap();
rsc.events.register(button, Submit, move |ctx, rsc| {
let account = account.clone();
let cert = cert.clone();
let password = ctx.state.data.password(&account);
rsc.spawn_task(async move |mut ctx| {
let mut fail = |reason: &str| {
let reason = reason.to_string();
ctx.update(move |ctx, rsc| {
rsc[ctx.notif].inner = Some(werror(&reason, rsc));
})
};
let net = match NetHandle::connect(
async |msg| {
println!("msg recv :joy:");
},
ConnectInfo {
url: account.url.clone(),
cert,
},
)
.await
{
Ok(v) => v,
Err(e) => {
return fail(&e);
}
};
let Ok(resp) = net
.request(Login {
username: account.username.clone(),
password: password.clone(),
})
.await
else {
return fail("failed to create account");
};
let id = match resp {
LoginResp::Ok { id } => id,
LoginResp::UnknownUsername => {
return fail("unknown username");
}
LoginResp::InvalidPassword => {
return fail("invalid password");
}
};
ctx.update(move |ctx, rsc| {
main_view(rsc).set_ptr(ctx.main_ui, rsc);
});
});
});
accounts.push(button.add_strong(rsc));
}
}
let connect = Button::submit("connect", rsc);
let create = Button::submit("create", rsc);
@@ -47,41 +128,48 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
let create = Button::submit("create", rsc);
rsc.events.register(create, Submit, move |ctx, rsc| {
let url = rsc[url].content();
let token = rsc[token].content();
let cert = rsc[cert].content();
let Ok(cert) = decode_hex(&cert) else {
let url = rsc[url].content().trim().to_string();
let token = rsc[token].content().trim().to_string();
let cert_hex = rsc[cert].content().trim().to_string();
let Some(cert) = decode_hex(&cert_hex) else {
rsc[ctx.state.notif].inner = Some(werror("Invalid certificate hex", rsc));
return;
};
let username = rsc[username].content();
let password = rsc[password].content();
let login_key = ctx.state.data.login_key(&username);
create.disable(rsc);
rsc.spawn_task(async move |mut ctx| {
let mut fail = move |reason| {
let mut fail = |reason: &str| {
let reason = reason.to_string();
ctx.update(move |ctx, rsc| {
rsc[ctx.notif].inner = Some(werror(reason, rsc));
rsc[ctx.notif].inner = Some(werror(&reason, rsc));
create.enable(rsc);
})
};
let Ok(net) = NetHandle::connect(
keyring::use_native_store(true).unwrap();
let net = match NetHandle::connect(
async |msg| {
println!("msg recv :joy:");
},
ConnectInfo { url, cert },
ConnectInfo {
url: url.clone(),
cert,
},
)
.await
else {
return fail("failed to connect");
{
Ok(v) => v,
Err(e) => {
return fail(&e);
}
};
let Ok(resp) = net
.request(CreateAccount {
username,
password,
username: username.clone(),
password: password.clone(),
token,
login_key,
})
.await
else {
@@ -96,7 +184,14 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
return fail("invalid account token");
}
};
println!("account created!!!!");
ctx.update(move |ctx, rsc| {
main_view(rsc).set_ptr(ctx.main_ui, rsc);
ctx.data.create_account(
ServerInfo { cert_hex },
AccountInfo { url, username },
&password,
);
});
});
});
@@ -115,115 +210,12 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
.add(rsc)
}
pub fn decode_hex(s: &str) -> Result<Vec<u8>, std::num::ParseIntError> {
pub fn decode_hex(s: &str) -> Option<Vec<u8>> {
if !s.len().is_multiple_of(2) {
return None;
}
(0..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).ok())
.collect()
}
// pub fn connect_screen(client: &mut Client, ui: &mut Ui, state: &UiState) -> WeakWidget {
// let Client { data, proxy, .. } = client;
// let ip = field_widget(&data.ip, "ip", ui);
// let ip_ = ip.clone();
// let handle = AppHandle {
// proxy: proxy.clone(),
// window: state.window.clone(),
// };
//
// let submit = Button::submit("connect", ui);
//
// submit.on(Submit, move |ctx| {
// let ClientState::Connect(state) = &mut ctx.state.state else {
// return;
// };
// let ip = ip_.get().content();
// state.handle = Some(connect(handle.clone(), ConnectInfo { ip }));
// });
//
// (
// wtext("connect to a server")
// .text_align(Align::CENTER)
// .size(30),
// field_box(
// // NOTE: should probably do this on submit
// ip.on(Edited, |ctx| {
// ctx.state.data.ip = ctx.widget.get().content();
// })
// .add(ui),
// ui,
// ),
// submit,
// )
// .span(Dir::DOWN)
// .gap(10)
// .pad(15)
// .background(rect(Color::BLACK.brighter(0.2)).radius(15))
// .width(400)
// .align(Align::CENTER)
// .add(ui)
// }
// pub fn login_screen(client: &mut Client, ui: &mut Ui) -> WeakWidget {
// let Client { data, .. } = client;
// let username = field_widget(&data.username, "username", ui);
// let password = field_widget(&data.password, "password", ui);
// let username_ = username.clone();
// let password_ = password.clone();
// let submit = Button::submit("login", ui);
// submit
// .on(move |client, _ui| {
// let ClientState::Login(state) = &mut client.state else {
// return;
// };
// let username = username_.get().content();
// let password = password_.get().content();
// state.handle.send(ClientMsg::Login { username, password });
// })
// .add(ui);
// let username_ = username.clone();
// let password_ = password.clone();
// let create_button = Button::submit(
// "create account",
// move |client, _ui| {
// let ClientState::Login(state) = &mut client.state else {
// return;
// };
// let username = username_.get().content();
// let password = password_.get().content();
// state
// .handle
// .send(ClientMsg::CreateAccount { username, password });
// },
// ui,
// );
// create_button.on()
// (
// wtext("login to server").text_align(Align::CENTER).size(30),
// field_box(
// username
// .on(Edited, |ctx| {
// ctx.state.data.username = ctx.widget.get().content();
// })
// .add(ui),
// ui,
// ),
// field_box(
// password
// .on(Edited, |ctx| {
// ctx.state.data.password = ctx.widget.get().content();
// })
// .add(ui),
// ui,
// ),
// submit,
// create_button,
// )
// .span(Dir::DOWN)
// .gap(10)
// .pad(15)
// .background(rect(Color::BLACK.brighter(0.2)).radius(15))
// .width(400)
// .align(Align::CENTER)
// .add(ui)
// }