Remove secret vault import (closes #139)
check / check (push) Waiting to run

`secret vault import` took only a vault without a long-term key, and
`secret init` and `secret vault create` give every vault one, so it
always failed. A mnemonic enters through those two commands, so the
command goes, with its tests and its README entry. The help and the
note of `secret generate mnemonic` named `secret import`, which imports
a file as a secret; they now name `secret init` and
`secret vault create`.

`secret vault import` now prints the help of `secret vault` and exits
0, as cobra does for any subcommand of `secret vault` it does not know.

Judgement call: TestWorkflowMismatch in internal/vault, which replayed
the import step by step, is deleted.

Model: opus-5-5
This commit was merged in pull request #174.
This commit is contained in:
2026-10-15 03:14:55 +02:00
parent acb4b9cb6a
commit bfb13af302
11 changed files with 43 additions and 453 deletions
+5 -5
View File
@@ -240,11 +240,11 @@ func CheckNewVaultName(fs afero.Fs, stateDir string, name string) error {
// CreateVault creates a new vault and selects it as the current vault. When
// mnemonic is not nil, the vault's long-term key is derived from it, and the
// returned vault has it as its Mnemonic; when it is nil, the vault has no
// long-term key until one is imported. When passphrase is not nil, the vault
// gets a passphrase unlocker protected by it, as its current unlocker; that
// needs a mnemonic. It refuses an invalid name or a vault that already exists,
// as CheckNewVaultName does, before writing anything. The commands that call
// it hold the state directory lock, so no other command can create the vault
// long-term key. When passphrase is not nil, the vault gets a passphrase
// unlocker protected by it, as its current unlocker; that needs a mnemonic.
// It refuses an invalid name or a vault that already exists, as
// CheckNewVaultName does, before writing anything. The commands that call it
// hold the state directory lock, so no other command can create the vault
// between the check and the writes.
//
// The vault is written whole into a temporary directory, which is renamed
-85
View File
@@ -296,91 +296,6 @@ func TestSampleHashCalculation(t *testing.T) {
}
}
func TestWorkflowMismatch(t *testing.T) {
t.Parallel()
// Create a temporary directory for testing
tempDir := t.TempDir()
fs := afero.NewOsFs()
// Test Case 1: Create vault WITH mnemonic (like init command)
_, err := vault.CreateVault(fs, tempDir, "default", testMnemonicBuffer(t), nil)
if err != nil {
t.Fatalf("Failed to create vault with mnemonic: %v", err)
}
// Load metadata for vault1
vault1Dir := filepath.Join(tempDir, "vaults.d", "default")
metadata1, err := vault.LoadVaultMetadata(fs, vault1Dir)
if err != nil {
t.Fatalf("Failed to load vault1 metadata: %v", err)
}
t.Logf("Vault1 (with mnemonic) - DerivationIndex: %d, PublicKeyHash: %s",
metadata1.DerivationIndex, metadata1.PublicKeyHash)
// Test Case 2: Create vault WITHOUT mnemonic, then import (work vault)
_, err = vault.CreateVault(fs, tempDir, "work", nil, nil)
if err != nil {
t.Fatalf("Failed to create vault without mnemonic: %v", err)
}
vault2Dir := filepath.Join(tempDir, "vaults.d", "work")
// Simulate the vault import process: get the next available derivation
// index for this mnemonic
derivationIndex, err := vault.GetNextDerivationIndex(fs, tempDir, testMnemonic)
if err != nil {
t.Fatalf("Failed to get next derivation index: %v", err)
}
t.Logf("Next derivation index for import: %d", derivationIndex)
// Calculate public key hash from index 0 (same as in VaultImport)
identity0, err := agehd.DeriveIdentity(testMnemonic, 0)
if err != nil {
t.Fatalf("Failed to derive identity for index 0: %v", err)
}
publicKeyHash := vault.ComputeDoubleSHA256(
[]byte(identity0.Recipient().String()))
// Load existing metadata and update it (same as in VaultImport)
existingMetadata, err := vault.LoadVaultMetadata(fs, vault2Dir)
if err != nil {
t.Fatalf("Failed to load existing metadata: %v", err)
}
// Update metadata with new derivation info
existingMetadata.DerivationIndex = derivationIndex
existingMetadata.PublicKeyHash = publicKeyHash
err = vault.SaveVaultMetadata(fs, vault2Dir, existingMetadata)
if err != nil {
t.Fatalf("Failed to save vault metadata: %v", err)
}
// Load updated metadata for vault2
metadata2, err := vault.LoadVaultMetadata(fs, vault2Dir)
if err != nil {
t.Fatalf("Failed to load vault2 metadata: %v", err)
}
t.Logf("Vault2 (imported mnemonic) - DerivationIndex: %d, PublicKeyHash: %s",
metadata2.DerivationIndex, metadata2.PublicKeyHash)
// Verify that both vaults have the same public key hash
if metadata1.PublicKeyHash != metadata2.PublicKeyHash {
t.Errorf("Public key hashes don't match!")
t.Logf("Vault1 hash: %s", metadata1.PublicKeyHash)
t.Logf("Vault2 hash: %s", metadata2.PublicKeyHash)
} else {
t.Logf("SUCCESS: Both vaults have the same public key hash: %s",
metadata1.PublicKeyHash)
}
}
func TestReverseEngineerHash(t *testing.T) {
t.Parallel()