lockbox

password manager
Log | Files | Refs | README | LICENSE

commit 30a8da14bf40544249c6da73a8f548d9c1d1355e
parent 9d9d6d0967faf9732d24856302881b1b68a6bdbc
Author: Sean Enck <sean@ttypty.com>
Date:   Sat, 15 Oct 2022 15:30:12 -0400

introduce insert -totp to help insert totp tokens

Diffstat:
Mcmd/main.go | 15++++++++++++++-
Minternal/backend/actions.go | 3+++
Minternal/cli/completions.bash | 4++--
Minternal/cli/core.go | 5+++++
Minternal/cli/core_test.go | 2+-
Mtests/expected.log | 3+++
Mtests/run.sh | 3+++
7 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go @@ -161,13 +161,20 @@ func run() error { } case cli.InsertCommand: multi := false + isTOTP := false idx := 2 switch len(args) { case 2: return errors.New("insert requires an entry") case 3: case 4: - if args[2] != cli.InsertMultiCommand { + opt := args[2] + switch opt { + case cli.InsertMultiCommand: + multi = true + case cli.InsertTOTPCommand: + isTOTP = true + default: return errors.New("unknown argument") } multi = true @@ -177,6 +184,12 @@ func run() error { } isPipe := inputs.IsInputFromPipe() entry := args[idx] + if isTOTP { + totpToken := inputs.TOTPToken() + if !strings.HasSuffix(entry, backend.NewSuffix(totpToken)) { + entry = backend.NewPath(entry, totpToken) + } + } existing, err := t.Get(entry, backend.BlankValue) if err != nil { return wrapped("unable to check for existing entry", err) diff --git a/internal/backend/actions.go b/internal/backend/actions.go @@ -202,6 +202,9 @@ func (t *Transaction) Move(src QueryEntity, dst string) error { return err } if ok { + if multi { + return errors.New("totp tokens can NOT be multi-line") + } v = inputs.FormatTOTP(v) e.Values = append(e.Values, protectedValue("otp", v)) } diff --git a/internal/cli/completions.bash b/internal/cli/completions.bash @@ -13,7 +13,7 @@ _{{ $.Executable }}() { case ${COMP_WORDS[1]} in {{ if not $.ReadOnly }} "{{ $.InsertCommand }}") - opts="{{ $.InsertMultiCommand }} $({{ $.DoList }})" + opts="{{ $.InsertMultiCommand }} {{ $.InsertTOTPCommand }} $({{ $.DoList }})" ;; "{{ $.MoveCommand }}") opts=$({{ $.DoList }}) @@ -34,7 +34,7 @@ _{{ $.Executable }}() { case "${COMP_WORDS[1]}" in {{ if not $.ReadOnly }} "{{ $.InsertCommand }}") - if [ "${COMP_WORDS[2]}" == "{{ $.InsertMultiCommand }}" ]; then + if [ "${COMP_WORDS[2]}" == "{{ $.InsertMultiCommand }}" ] || [ "${COMP_WORDS[2]}" == "{{ $.InsertTOTPCommand }}" ]; then opts=$({{ $.DoList }}) fi ;; diff --git a/internal/cli/core.go b/internal/cli/core.go @@ -42,6 +42,8 @@ const ( EnvCommand = "env" // InsertMultiCommand handles multi-line inserts InsertMultiCommand = "-multi" + // InsertTOTPCommand is a helper for totp inserts + InsertTOTPCommand = "-totp" // TOTPClipCommand is the argument for copying totp codes to clipboard TOTPClipCommand = "-clip" // TOTPShortCommand is the argument for getting the short version of a code @@ -74,6 +76,7 @@ type ( TOTPOnceCommand string TOTPClipCommand string InsertMultiCommand string + InsertTOTPCommand string RemoveCommand string ClipCommand string ShowCommand string @@ -125,6 +128,7 @@ func BashCompletions(defaults bool) ([]string, error) { ClipCommand: ClipCommand, ShowCommand: ShowCommand, InsertMultiCommand: InsertMultiCommand, + InsertTOTPCommand: InsertTOTPCommand, TOTPCommand: TOTPCommand, MoveCommand: MoveCommand, DoList: fmt.Sprintf("%s %s", name, ListCommand), @@ -182,6 +186,7 @@ func Usage() ([]string, error) { results = append(results, command(HelpCommand, "", "show this usage information")) results = append(results, command(InsertCommand, "entry", "insert a new entry into the store")) results = append(results, subCommand(InsertCommand, InsertMultiCommand, "entry", "insert a multi-line entry")) + results = append(results, subCommand(InsertCommand, InsertTOTPCommand, "entry", "insert a new totp entry")) results = append(results, command(ListCommand, "", "list entries")) results = append(results, command(MoveCommand, "src dst", "move an entry from one location to another with the store")) results = append(results, command(RemoveCommand, "entry", "remove an entry from the store")) diff --git a/internal/cli/core_test.go b/internal/cli/core_test.go @@ -9,7 +9,7 @@ import ( func TestUsage(t *testing.T) { u, _ := cli.Usage() - if len(u) != 19 { + if len(u) != 20 { t.Errorf("invalid usage, out of date? %d", len(u)) } } diff --git a/tests/expected.log b/tests/expected.log @@ -21,6 +21,9 @@ test2 test3 test4 + +test/k + test/k XXXXXX key/a/one: diff --git a/tests/run.sh b/tests/run.sh @@ -28,6 +28,9 @@ _run() { "$BIN/lb" find e "$BIN/lb" show keys/k/one2 "$BIN/lb" show keys2/k/three + echo "5ae472abqdekjqykoyxk7hvc2leklq5n" | "$BIN/lb" insert -totp test/k + echo "5ae472abqdekjqykoyxk7hvc2leklq5n" | "$BIN/lb" insert -totp test/k/totp + "$BIN/lb" "totp" -list echo "5ae472abqdekjqykoyxk7hvc2leklq5n" | "$BIN/lb" insert test/k/totp "$BIN/lb" "totp" -list "$BIN/lb" "totp" test/k | tr '[:digit:]' 'X'