fix(terminal): get channel from server heartbeat response, not env/build

This commit is contained in:
Mitchell R 2026-05-22 20:51:18 +02:00
parent 98723f21b8
commit 9ebdc894a1
No known key found for this signature in database
3 changed files with 34 additions and 9 deletions

View file

@ -164,14 +164,12 @@ pub fn check_terminal_access() -> Result<(), String> {
if is_locked() {
return Err("locked".to_string());
}
// Check firmware channel — only dev allowed. The channel comes from
// the server-side kiosk config, delivered via heartbeat. Read from the
// cached bundle or the kiosk_app_version string (dev builds contain
// "-dev." in the version). No env var dependency.
let version = option_env!("BF_BUILD_VERSION")
.unwrap_or(env!("CARGO_PKG_VERSION"));
let is_dev = version.contains("-dev.");
if !is_dev {
// Check channel — terminal allowed when EITHER firmware or OS channel
// is "dev". Channels pushed from server via heartbeat response, cached
// in server.rs. No env var, no build-time check.
let fw = crate::server::cached_firmware_channel();
let os = crate::server::cached_os_channel();
if fw != "dev" && os != "dev" {
return Err("terminal access requires dev channel".to_string());
}
Ok(())

View file

@ -418,6 +418,31 @@ pub fn heartbeat(
}))
.timeout(Duration::from_secs(5))
.send()
.map(|r| r.status().is_success())
.and_then(|r| {
if !r.status().is_success() {
return Ok(false);
}
// Parse channels from heartbeat response and cache for terminal access check.
if let Ok(body) = r.json::<serde_json::Value>() {
if let Some(fc) = body.get("firmware_channel").and_then(|v| v.as_str()) {
CACHED_FIRMWARE_CHANNEL.lock().unwrap().replace(fc.to_string());
}
if let Some(oc) = body.get("os_update_channel").and_then(|v| v.as_str()) {
CACHED_OS_CHANNEL.lock().unwrap().replace(oc.to_string());
}
}
Ok(true)
})
.unwrap_or(false)
}
use std::sync::Mutex as StdMutex;
static CACHED_FIRMWARE_CHANNEL: StdMutex<Option<String>> = StdMutex::new(None);
static CACHED_OS_CHANNEL: StdMutex<Option<String>> = StdMutex::new(None);
pub fn cached_firmware_channel() -> String {
CACHED_FIRMWARE_CHANNEL.lock().unwrap().clone().unwrap_or_else(|| "stable".to_string())
}
pub fn cached_os_channel() -> String {
CACHED_OS_CHANNEL.lock().unwrap().clone().unwrap_or_else(|| "stable".to_string())
}

View file

@ -479,6 +479,8 @@ function registerKioskRoutes(
return {
ok: true,
now: new Date().toISOString(),
firmware_channel: fresh?.firmware_channel ?? "stable",
os_update_channel: fresh?.os_update_channel ?? "stable",
...(pendingConfig ? { pending_config: pendingConfig } : {}),
};
});