use anyhow::{Result, bail};
pub(crate) struct ServeParams {
pub host: Option<String>,
pub port: Option<u16>,
pub token: Option<String>,
pub generate_token: bool,
pub tls_cert: Option<String>,
pub tls_key: Option<String>,
pub force_sandbox: bool,
}
pub(crate) async fn run_serve(params: ServeParams) -> Result<()> {
if params.tls_cert.is_some() != params.tls_key.is_some() {
bail!("Both --tls-cert and --tls-key must be provided together");
}
let config = zag_serve::config::ServeConfig::load();
let host = params.host.unwrap_or(config.server.host.clone());
let port = params.port.unwrap_or(config.server.port);
let (tls_cert, tls_key, is_self_signed) =
if let (Some(cert), Some(key)) = (params.tls_cert, params.tls_key) {
(cert, key, false)
} else if let (Some(cert), Some(key)) = (
config.server.tls_cert.clone(),
config.server.tls_key.clone(),
) {
(cert, key, false)
} else {
let (cert, key) = zag_serve::ensure_self_signed_cert(&host)?;
(cert, key, true)
};
if is_self_signed {
eprintln!(
"WARNING: Using auto-generated self-signed certificate. \
Do not use in production — provide --tls-cert and --tls-key for production deployments."
);
}
let has_user_accounts = zag_serve::user::UserStore::exists();
let token = if let Some(t) = params.token {
Some(t)
} else if let Ok(t) = std::env::var("ZAG_SERVE_TOKEN") {
Some(t)
} else {
match config.server.token {
Some(t) if !params.generate_token => Some(t),
_ => {
if has_user_accounts {
None
} else {
let t = zag_serve::generate_token();
zag_serve::save_token_to_config(&t)?;
Some(t)
}
}
}
};
let force_sandbox = params.force_sandbox || config.server.force_sandbox;
if has_user_accounts {
eprintln!(
"User accounts mode: loaded from {}",
zag_serve::user::UserStore::path().display()
);
}
if let Some(ref t) = token {
eprintln!("Token: {}", t);
}
if force_sandbox {
eprintln!("Force sandbox: enabled (all connected users run in Docker sandboxes)");
}
eprintln!("Starting zag server on https://{}:{}", host, port);
zag_serve::start_server(zag_serve::ServerParams {
host,
port,
token,
tls_cert,
tls_key,
force_sandbox,
})
.await
}