use std::path::Path;
use vti_common::error::AppError;
use super::wizard::VtcHostMessages;
pub async fn run_setup_phase1(out_path: &Path, context_id: &str) -> Result<(), AppError> {
let finalise = format!(
"vtc setup --from <your-setup.toml> (with setup_key_file = \"{}\")",
out_path.display()
);
vta_sdk::provision_client::driver::run_phase1_init(
&mut std::io::stderr(),
out_path,
context_id,
&VtcHostMessages,
Some(&finalise),
)
.await
.map_err(|e| AppError::Internal(format!("phase-1 setup-key mint failed: {e}")))?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use vta_sdk::provision_client::{EphemeralSetupKey, OperatorMessages, driver::run_phase1_init};
#[tokio::test]
async fn phase1_persists_loadable_setup_key() {
let dir = tempfile::tempdir().expect("tempdir");
let out = dir.path().join("vtc-setup-key.json");
run_setup_phase1(&out, "default")
.await
.expect("phase 1 succeeds");
let key = EphemeralSetupKey::load_from(&out).expect("load persisted key");
assert!(
key.did.starts_with("did:key:z6Mk"),
"expected an Ed25519 did:key, got {}",
key.did
);
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mode = std::fs::metadata(&out).unwrap().permissions().mode() & 0o777;
assert_eq!(mode, 0o600, "setup key must be 0600");
}
}
#[tokio::test]
async fn phase1_prints_context_scoped_grant_command() {
let dir = tempfile::tempdir().expect("tempdir");
let out = dir.path().join("key.json");
let mut buf: Vec<u8> = Vec::new();
run_phase1_init(&mut buf, &out, "acme", &VtcHostMessages, None)
.await
.expect("run_phase1_init");
let printed = String::from_utf8(buf).expect("utf8");
let did = EphemeralSetupKey::load_from(&out).unwrap().did;
assert!(printed.contains("pnm contexts create"), "{printed}");
assert!(printed.contains("--id acme"), "{printed}");
assert!(printed.contains(&format!("--admin-did {did}")), "{printed}");
assert_eq!(VtcHostMessages.integration_label(), "VTC");
}
}