use iroh::SecretKey;
use crate::{Identity, RoomTicket};
pub fn stored_identity(key: &str) -> Identity {
let Some(storage) = storage() else {
return Identity::Ephemeral;
};
if let Ok(Some(hex)) = storage.get_item(key)
&& let Some(secret) = from_hex(&hex)
{
return Identity::Key(secret);
}
let secret = SecretKey::generate();
let _ = storage.set_item(key, &to_hex(&secret.to_bytes()));
Identity::Key(secret)
}
pub fn ticket_from_url(param: &str) -> Option<RoomTicket> {
let search = web_sys::window()?.location().search().ok()?;
let query = search.strip_prefix('?').unwrap_or(&search);
query.split('&').find_map(|pair| {
let (k, v) = pair.split_once('=')?;
(k == param).then(|| v.parse().ok()).flatten()
})
}
pub fn share_ticket_in_url(param: &str, ticket: &RoomTicket) {
let Some(window) = web_sys::window() else {
return;
};
let Ok(path) = window.location().pathname() else {
return;
};
let url = format!("{path}?{param}={ticket}");
if let Ok(history) = window.history() {
let _ = history.replace_state_with_url(&wasm_bindgen::JsValue::NULL, "", Some(&url));
}
}
fn storage() -> Option<web_sys::Storage> {
web_sys::window()?.local_storage().ok().flatten()
}
fn to_hex(bytes: &[u8]) -> String {
bytes.iter().map(|b| format!("{b:02x}")).collect()
}
fn from_hex(hex: &str) -> Option<SecretKey> {
let hex = hex.trim();
if hex.len() != 64 {
return None;
}
let mut bytes = [0u8; 32];
for (i, chunk) in hex.as_bytes().chunks(2).enumerate() {
let s = std::str::from_utf8(chunk).ok()?;
bytes[i] = u8::from_str_radix(s, 16).ok()?;
}
Some(SecretKey::from_bytes(&bytes))
}