Add secret-safe copy and reveal UX coverage

This commit is contained in:
Joe Julian
2026-03-29 13:32:21 -07:00
parent dd0b0b6f6e
commit 55ca6352b4
5 changed files with 204 additions and 10 deletions
+18 -2
View File
@@ -2,7 +2,6 @@ package clipboard
import (
"errors"
"fmt"
systemclipboard "github.com/atotto/clipboard"
@@ -10,6 +9,7 @@ import (
)
var ErrUnsupportedTarget = errors.New("unsupported clipboard target")
var ErrWriteFailed = errors.New("clipboard write failed")
type Target string
@@ -39,7 +39,7 @@ func (s Service) Copy(model vault.Model, entryID string, target Target) error {
}
if err := s.writer().WriteText(content); err != nil {
return fmt.Errorf("write clipboard text: %w", err)
return writeError{err: err}
}
return nil
@@ -79,3 +79,19 @@ type systemWriter struct{}
func (systemWriter) WriteText(text string) error {
return systemclipboard.WriteAll(text)
}
type writeError struct {
err error
}
func (e writeError) Error() string {
return ErrWriteFailed.Error()
}
func (e writeError) Unwrap() error {
return e.err
}
func (e writeError) Is(target error) bool {
return target == ErrWriteFailed
}
+27
View File
@@ -68,6 +68,25 @@ func TestServiceRejectsUnknownEntryAndUnsupportedTarget(t *testing.T) {
}
}
func TestServiceSanitizesClipboardWriteErrors(t *testing.T) {
t.Parallel()
service := Service{Writer: failingWriter{err: errors.New("backend refused token-1")}}
model := vault.Model{
Entries: []vault.Entry{
{ID: "git-server", Password: "token-1"},
},
}
err := service.Copy(model, "git-server", TargetPassword)
if !errors.Is(err, ErrWriteFailed) {
t.Fatalf("Copy() write error = %v, want ErrWriteFailed", err)
}
if err.Error() != ErrWriteFailed.Error() {
t.Fatalf("Copy() write error string = %q, want %q", err.Error(), ErrWriteFailed.Error())
}
}
type memoryWriter struct {
content string
}
@@ -76,3 +95,11 @@ func (w *memoryWriter) WriteText(text string) error {
w.content = text
return nil
}
type failingWriter struct {
err error
}
func (w failingWriter) WriteText(string) error {
return w.err
}