feat: container orchestration, branding overhaul, onboarding logging
Container orchestration: - Health monitor with crash recovery and auto-restart - Doctor service (periodic health checks via systemd timer) - Reconcile service (desired-state convergence) - Stack-aware install/uninstall with dependency tracking Branding: - Custom GRUB background (designer artwork, 1024x768) - ISOLINUX boot menu: centered, orange accents, clean labels - Terminal banners: adaptive width, basic ANSI colors, fits 80-col - Removed auto-generated splash scripts (designer provides assets) - GRUB theme: lowercase branding Frontend: - 401 handler clears localStorage immediately (prevents cascade) Backend: - Onboarding/auth logging ([onboarding] tag in journalctl) - Cookie Secure flag logging for debugging HTTP/HTTPS issues ISO fixes: - Install log saved before unmount (was silently failing) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
6311aa563e
commit
99400a7165
@@ -16,8 +16,10 @@ impl RpcHandler {
|
||||
if !is_setup {
|
||||
// Dev mode: allow default password so UI can log in without running setup
|
||||
if self.config.dev_mode && password == DEV_DEFAULT_PASSWORD {
|
||||
tracing::info!("[onboarding] login via dev default password");
|
||||
return Ok(serde_json::Value::Null);
|
||||
}
|
||||
tracing::warn!("[onboarding] login attempt before setup complete");
|
||||
return Err(anyhow::anyhow!(
|
||||
"User not set up. Please complete setup first."
|
||||
));
|
||||
@@ -25,13 +27,16 @@ impl RpcHandler {
|
||||
|
||||
let valid = self.auth_manager.verify_password(password).await?;
|
||||
if !valid {
|
||||
tracing::warn!("[onboarding] login failed — wrong password");
|
||||
return Err(anyhow::anyhow!("Password Incorrect"));
|
||||
}
|
||||
|
||||
tracing::info!("[onboarding] login successful");
|
||||
Ok(serde_json::Value::Null)
|
||||
}
|
||||
|
||||
pub(super) async fn handle_auth_logout(&self) -> Result<serde_json::Value> {
|
||||
tracing::info!("[onboarding] logout");
|
||||
Ok(serde_json::Value::Null)
|
||||
}
|
||||
|
||||
@@ -78,6 +83,7 @@ impl RpcHandler {
|
||||
// Prevent re-setup if already set up
|
||||
let is_setup = self.auth_manager.is_setup().await?;
|
||||
if is_setup {
|
||||
tracing::warn!("[onboarding] setup rejected — already set up");
|
||||
return Err(anyhow::anyhow!("Already set up. Use auth.changePassword to change."));
|
||||
}
|
||||
|
||||
@@ -88,20 +94,24 @@ impl RpcHandler {
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing password"))?;
|
||||
|
||||
if password.len() < 8 {
|
||||
tracing::warn!("[onboarding] setup rejected — password too short");
|
||||
return Err(anyhow::anyhow!("Password must be at least 8 characters"));
|
||||
}
|
||||
|
||||
self.auth_manager.setup_user(password).await?;
|
||||
tracing::info!("[onboarding] user setup complete");
|
||||
Ok(serde_json::json!(true))
|
||||
}
|
||||
|
||||
pub(super) async fn handle_auth_onboarding_complete(&self) -> Result<serde_json::Value> {
|
||||
self.auth_manager.complete_onboarding().await?;
|
||||
tracing::info!("[onboarding] onboarding marked complete");
|
||||
Ok(serde_json::json!(true))
|
||||
}
|
||||
|
||||
pub(super) async fn handle_auth_is_onboarding_complete(&self) -> Result<serde_json::Value> {
|
||||
let complete = self.auth_manager.is_onboarding_complete().await?;
|
||||
tracing::debug!("[onboarding] isOnboardingComplete={}", complete);
|
||||
Ok(serde_json::json!(complete))
|
||||
}
|
||||
|
||||
@@ -117,10 +127,12 @@ impl RpcHandler {
|
||||
|
||||
let valid = self.auth_manager.verify_password(password).await?;
|
||||
if !valid {
|
||||
tracing::warn!("[onboarding] reset rejected — wrong password");
|
||||
return Err(anyhow::anyhow!("Password Incorrect"));
|
||||
}
|
||||
|
||||
self.auth_manager.reset_onboarding().await?;
|
||||
tracing::info!("[onboarding] onboarding reset");
|
||||
Ok(serde_json::json!(true))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user