diff --git a/core/startos/bindings/ServerInfo.ts b/core/startos/bindings/ServerInfo.ts index e505c84e7..130a5bafe 100644 --- a/core/startos/bindings/ServerInfo.ts +++ b/core/startos/bindings/ServerInfo.ts @@ -24,7 +24,7 @@ export type ServerInfo = { torAddress: string; ipInfo: { [key: string]: IpInfo }; statusInfo: ServerStatus; - wifi: WifiInfo; + wifi: WifiInfo | null; unreadNotificationCount: number; passwordHash: string; pubkey: string; diff --git a/core/startos/bindings/WifiInfo.ts b/core/startos/bindings/WifiInfo.ts index c949b1e76..59b1b901d 100644 --- a/core/startos/bindings/WifiInfo.ts +++ b/core/startos/bindings/WifiInfo.ts @@ -1,6 +1,7 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. export type WifiInfo = { + interface: string; ssids: Array; selected: string | null; connected: string | null; diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index 4753a4290..41aaeca7b 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -96,7 +96,11 @@ pub async fn recover_full_embassy( .with_kind(ErrorKind::PasswordHashGeneration)?; let db = ctx.db().await?; - db.put(&ROOT, &Database::init(&os_backup.account)?).await?; + db.put( + &ROOT, + &Database::init(&os_backup.account, ctx.config.wifi_interface.clone())?, + ) + .await?; drop(db); init(&ctx.config).await?; diff --git a/core/startos/src/db/model/mod.rs b/core/startos/src/db/model/mod.rs index 9be0f8b68..8b959cdfd 100644 --- a/core/startos/src/db/model/mod.rs +++ b/core/startos/src/db/model/mod.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use patch_db::HasModel; use serde::{Deserialize, Serialize}; -use ts_rs::TS; use crate::account::AccountInfo; use crate::auth::Sessions; @@ -28,9 +27,9 @@ pub struct Database { pub private: Private, } impl Database { - pub fn init(account: &AccountInfo) -> Result { + pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { Ok(Self { - public: Public::init(account)?, + public: Public::init(account, wifi_interface)?, private: Private { key_store: KeyStore::new(account)?, password: account.password.clone(), diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index d1eec5443..5b83eb74d 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -35,7 +35,7 @@ pub struct Public { pub ui: Value, } impl Public { - pub fn init(account: &AccountInfo) -> Result { + pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { let lan_address = account.hostname.lan_address().parse().unwrap(); Ok(Self { server_info: ServerInfo { @@ -60,11 +60,12 @@ impl Public { shutting_down: false, restarting: false, }, - wifi: WifiInfo { + wifi: wifi_interface.map(|interface| WifiInfo { + interface, ssids: Vec::new(), connected: None, selected: None, - }, + }), unread_notification_count: 0, password_hash: account.password.clone(), pubkey: ssh_key::PublicKey::from(&account.ssh_key) @@ -131,7 +132,7 @@ pub struct ServerInfo { pub ip_info: BTreeMap, #[serde(default)] pub status_info: ServerStatus, - pub wifi: WifiInfo, + pub wifi: Option, #[ts(type = "number")] pub unread_notification_count: u64, pub password_hash: String, @@ -206,6 +207,7 @@ pub struct UpdateProgress { #[model = "Model"] #[ts(export)] pub struct WifiInfo { + pub interface: String, pub ssids: Vec, pub selected: Option, pub connected: Option, diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index 46838ed51..47cf30ad5 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -111,7 +111,7 @@ impl VHostServer { _thread: tokio::spawn(async move { loop { match listener.accept().await { - Ok((stream, sock_addr)) => { + Ok((stream, _)) => { let stream = Box::pin(TimeoutStream::new(stream, Duration::from_secs(300))); let mut stream = BackTrackingReader::new(stream); @@ -195,9 +195,22 @@ impl VHostServer { .as_ref() .into_iter() .map(InternedString::intern) - .chain(std::iter::once(InternedString::from_display( - &sock_addr.ip(), - ))) + .chain( + db.peek() + .await + .into_public() + .into_server_info() + .into_ip_info() + .into_entries()? + .into_iter() + .flat_map(|(_, ips)| [ + ips.as_ipv4().de().map(|ip| ip.map(IpAddr::V4)), + ips.as_ipv6().de().map(|ip| ip.map(IpAddr::V6)) + ]) + .filter_map(|a| a.transpose()) + .map(|a| a.map(|ip| InternedString::from_display(&ip))) + .collect::, _>>()?, + ) .collect(); let key = db .mutate(|v| { diff --git a/core/startos/src/properties.rs b/core/startos/src/properties.rs index 5aa8a01d4..f8753ab10 100644 --- a/core/startos/src/properties.rs +++ b/core/startos/src/properties.rs @@ -1,5 +1,5 @@ use clap::Parser; -use imbl_value::Value; +use imbl_value::{json, Value}; use models::PackageId; use rpc_toolkit::command; use serde::{Deserialize, Serialize}; @@ -24,7 +24,10 @@ pub async fn properties( PropertiesParam { id }: PropertiesParam, ) -> Result { match &*ctx.services.get(&id).await { - Some(service) => service.properties().await, + Some(service) => Ok(json!({ + "version": 2, + "data": service.properties().await? + })), None => Err(Error::new( eyre!("Could not find a service with id {id}"), ErrorKind::NotFound, diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index 9120544e3..b8b761e69 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -419,7 +419,11 @@ async fn fresh_setup( ) -> Result<(Hostname, OnionAddressV3, X509), Error> { let account = AccountInfo::new(start_os_password, root_ca_start_time().await?)?; let db = ctx.db().await?; - db.put(&ROOT, &Database::init(&account)?).await?; + db.put( + &ROOT, + &Database::init(&account, ctx.config.wifi_interface.clone())?, + ) + .await?; drop(db); init(&ctx.config).await?; Ok(( diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 8a3f714d1..446bf2424 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -76,6 +76,7 @@ export const mockPatchData: DataModel = { zram: true, governor: 'performance', wifi: { + interface: 'wlan0', ssids: [], selected: null, connected: null,