Conversation
16b997d to
47f9e2f
Compare
This implementation currently does not allow creating an archive with a keyfile just yet.
822fc4f to
94e0bdd
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new create/new CLI command to create an empty KeePass (.kdbx) database, and refactors database initialization/opening so tests and commands use a unified kdbx API.
Changes:
- Introduce
create/newcommand with interactive passphrase creation and optional immediate TUI open. - Refactor
pkg/kdbxto useOpenFromPath+NewFromFileand centralize credential setup viaSetPasswordAndKey. - Update CLI/TUI tests and improve error message clarity across several packages.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tui/app.go | Tweaks TUI startup error message formatting. |
| test/tui_test.go | Updates E2E TUI fixture creation to use pkg/kdbx APIs. |
| test/cli_test.go | Updates fixture DB creation; adds help/arg-validation tests for create/new. |
| pkg/log/log.go | Adjusts error messages during log initialization. |
| pkg/kdbx/kdbx_test.go | Updates tests for Database.file pointer change. |
| pkg/kdbx/kdbx.go | Adds OpenFromPath/NewFromFile, credential helper, and updates save/unlock internals. |
| pkg/credentials/credentials.go | Adds MakePassphrase and moves secret reading to pkg/cli. |
| pkg/clipboard/clipboard.go | Improves clipboard error message. |
| pkg/cli/cli.go | Adds shared CLI helpers for secret input and confirmations. |
| main.go | Corrects error namespace for unexpected errors. |
| cmd/root.go | Registers new Create command. |
| cmd/open.go | Switches to OpenFromPath and improves error messages. |
| cmd/list.go | Switches to OpenFromPath. |
| cmd/create.go | New create/new command implementation. |
| cmd/copy.go | Switches to OpenFromPath and improves error messages. |
| CONTRIBUTING.md | Adds manual test checklist for create/new flow. |
| .vimspector.json | Adds a Vimspector debug configuration. |
Comments suppressed due to low confidence (2)
pkg/kdbx/kdbx.go:50
- OpenFromPath opens the file and, if UnlockWithPasswordAndKey returns an error (wrong password/key, decode error, etc.), returns without closing the file descriptor. Consider ensuring the file is closed on all error paths (e.g., close before returning on unlock failure).
func OpenFromPath(filepath, password, keypath string) (*Database, error) {
file, err := os.Open(filepath)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
kdbx, err := NewFromFile(file)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
return nil, err
}
pkg/kdbx/kdbx.go:353
- unlock() calls d.Database.UnlockProtectedEntries() but ignores its returned error. Since UnlockProtectedEntries can fail (and is checked elsewhere in SaveAndUnlockEntries), errors here would be silently ignored and could leave protected values locked. Consider capturing and returning the error.
if err := gokeepasslib.NewDecoder(d.file).Decode(&d.Database); err != nil {
return errors.MakeError("Cannot unlock database: "+err.Error(), "kdbx")
}
d.Database.UnlockProtectedEntries()
return nil
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
In previous implementation, we were accidentally acting on a copy of the entry - which updated the UI, but did not update the archive.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
pkg/kdbx/kdbx.go:49
- OpenFromPath() opens the file with
os.Open, but on error paths after that (e.g., unlock failure), the file handle is never closed. This can leak descriptors and may keep the file locked on some platforms. Consider closingfileifNewFromFileorUnlockWithPasswordAndKeyreturns an error (or have Database take ownership only on success).
file, err := os.Open(filepath)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
kdbx, err := NewFromFile(file)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
return nil, err
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 9 comments.
Comments suppressed due to low confidence (1)
pkg/kdbx/kdbx.go:49
OpenFromPathopens a file handle but does not close it ifUnlockWithPasswordAndKeyfails (e.g., wrong password / decode error). This can leak file descriptors in repeated opens; consider closingfileon error (or adding a defer that closes unless ownership is transferred successfully).
func OpenFromPath(filepath, password, keypath string) (*Database, error) {
file, err := os.Open(filepath)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
kdbx, err := NewFromFile(file)
if err != nil {
return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
}
if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
return nil, err
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This change adds a
new/createcommand to create an empty database.Closes #34
TODO