use colored::Colorize;
use crate::{
crypto::{
initialize_vault_keys,
integrity::{build_encrypted_hash_fields, file_sha256_b64, seal_vault_metadata},
},
domain::{error::DotLockError, model::DotLockResult},
git::install::install_merge_driver_if_in_git_repo,
storage::{
cache::write_cached_dek_for,
project::{self, DOTLOCK_DIR, ensure_project_not_initialized},
secure_fs,
vault_file::save_vault_metadata,
},
};
pub fn init_project() -> DotLockResult<()> {
if let Some(env) = project::active_env() {
return Err(DotLockError::EnvironmentNotInitialized { name: env });
}
ensure_project_not_initialized()?;
init_vault_pair(None)?;
println!(
"{} initialized DotLock project at {}",
"ok:".green().bold(),
DOTLOCK_DIR.bold()
);
println!(
" {} {}",
"created".dimmed(),
project::vault_file_for(None).bold()
);
println!(
" {} {}",
"created".dimmed(),
project::secrets_file_for(None).bold()
);
let _ = install_merge_driver_if_in_git_repo()?;
Ok(())
}
pub fn init_vault_pair(env: Option<&str>) -> DotLockResult<()> {
let lock_dir = project::env_lock_dir_for(env);
let vault_file = project::vault_file_for(env);
let secrets_file = project::secrets_file_for(env);
let environment = env.unwrap_or("dev");
secure_fs::ensure_dir(std::path::Path::new(&lock_dir), 0o700)?;
let mut vault = initialize_vault_keys("dotlock", environment)?;
if !std::path::Path::new(&secrets_file).exists() {
secure_fs::write_string_atomic(std::path::Path::new(&secrets_file), "", 0o700, 0o600)?;
}
let (nonce_b64, hash_b64) = build_encrypted_hash_fields(&secrets_file, &vault.dek)?;
vault.metadata.secrets_hash_nonce_b64 = nonce_b64;
vault.metadata.secrets_hash_b64 = hash_b64;
vault.metadata.secrets_hash_sha256_b64 = file_sha256_b64(&secrets_file)?;
seal_vault_metadata(&mut vault.metadata, &vault.dek)?;
save_vault_metadata(&vault_file, &vault.metadata)?;
write_cached_dek_for(&vault.metadata, &vault.dek)?;
Ok(())
}