check / check (pull_request) Successful in 2m29s
Restore and verify --deep now parse the configured age secret key a single time through a new internal helper that uses age.ParseIdentities and hands every identity to age.Decrypt. A key file with several identities (a whole age-keygen file) is fully accepted, so a blob encrypted to any of its recipients decrypts, not just the first. The helper is the first step of both commands, so a missing or unparseable key now fails before anything is downloaded. Its error names the configuration source (VAULTIK_AGE_SECRET_KEY or age_secret_key) and never echoes the key value. config.extractAgeSecretKey and its silent fallback are removed; the key is stored raw and parsed only where decryption happens, so backup, list and prune are unaffected. README, the restore help, and the missing-key error now show the key read from a file with $(cat ...) rather than typed literally, keeping it out of shell history, and say the variable may hold the whole key file. Model: opus-4-8
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package vaultik_test
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/vaultik/internal/config"
|
|
"sneak.berlin/go/vaultik/internal/ui"
|
|
"sneak.berlin/go/vaultik/internal/vaultik"
|
|
)
|
|
|
|
// TestRestoreRejectsMalformedKeyBeforeDownload verifies that a malformed
|
|
// age secret key stops restore at the parse step: nothing is fetched from
|
|
// the store, and the error does not echo the key value (which is secret).
|
|
func TestRestoreRejectsMalformedKeyBeforeDownload(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const malformed = "this-is-not-a-valid-age-key"
|
|
|
|
mock := NewMockStorer()
|
|
|
|
v := &vaultik.Vaultik{
|
|
Config: &config.Config{AgeSecretKey: malformed},
|
|
Storage: mock,
|
|
Stdout: io.Discard,
|
|
Stderr: io.Discard,
|
|
UI: ui.NewWithColor(io.Discard, false),
|
|
}
|
|
v.SetContext(context.Background())
|
|
|
|
err := v.Restore(&vaultik.RestoreOptions{
|
|
SnapshotID: "any-snapshot",
|
|
TargetDir: t.TempDir(),
|
|
})
|
|
require.Error(t, err)
|
|
require.NotContains(t, err.Error(), malformed,
|
|
"error must not echo the key value")
|
|
require.Contains(t, err.Error(), "age_secret_key",
|
|
"error should name the configuration source")
|
|
require.Empty(t, mock.GetCalls(),
|
|
"a malformed key must fail before anything is fetched")
|
|
}
|