commit ef72b2499c9a1fefdf3b8813eedd8bac6608173b
parent 404b9c15998d0872510ffbdaed81d2466a8c0cd6
Author: Sean Enck <sean@ttypty.com>
Date: Mon, 9 Jun 2025 15:30:08 -0400
interactive control really wasn't needed
Diffstat:
9 files changed, 14 insertions(+), 83 deletions(-)
diff --git a/cmd/lb/main_test.go b/cmd/lb/main_test.go
@@ -162,7 +162,6 @@ func test(profile string) error {
}
setConfig(r.config)
c := r.newConf()
- c["interactive"] = "false"
keyFile := filepath.Join(r.testDir, "key.file")
hasPass := profile == passProfile || profile == bothProfile
hasFile := profile == keyFileProfile || profile == bothProfile
@@ -180,7 +179,6 @@ func test(profile string) error {
r.writeConfig(c)
r.run("echo testing |", "insert test1/key1/password")
c = r.newConf()
- c["interactive"] = "false"
if hasPass {
c["credentials.password_mode"] = c.quoteString("plaintext")
c["credentials.password"] = c.makePass(testPass)
@@ -191,6 +189,7 @@ func test(profile string) error {
c["credentials.password_mode"] = c.quoteString("none")
}
}
+ c["totp.timeout"] = "1"
r.writeConfig(c)
for _, k := range []string{"test2/key1/password", "test2/key1/notes", "test3", "test3/invalid/", "test3/invalid/still"} {
r.run("echo testing2 |", fmt.Sprintf("insert %s", k))
@@ -216,9 +215,10 @@ func test(profile string) error {
r.run(`printf "otpauth://totp/lbissuer:lbaccount?algorithm=SHA1&digits=6&issuer=lbissuer&period=30&secret=5ae472abqdekjqykoyxk7hvc2leklq5n" |`, "insert test10/key1/otp")
r.run("", "totp ls")
r.run("", "totp ls rooted")
- r.run("", "totp show test6/multiline/otp")
- r.run("", "totp show test10/key1/otp")
- r.run("", "totp once test6/multiline/otp")
+ const grepTOTP = "| sed 's/^[[:space:]]*//g' | grep '^[0-9][0-9][0-9][0-9][0-9][0-9]$'"
+ r.run("", fmt.Sprintf("totp show test6/multiline/otp %s", grepTOTP))
+ r.run("", fmt.Sprintf("totp show test10/key1/otp %s", grepTOTP))
+ r.run("", fmt.Sprintf("totp once test6/multiline/otp %s", grepTOTP))
r.run("", "totp minimal test6/multiline/otp")
r.run("", "totp url test6/multiline/otp")
r.run("", "totp seed test6/multiline/otp")
diff --git a/cmd/lb/tests/expected.log b/cmd/lb/tests/expected.log
@@ -313,7 +313,7 @@ test6/multiline/password
LOCKBOX_CLIP_COPY_COMMAND=[touch testdata/datadir/clip.copy]
LOCKBOX_CLIP_PASTE_COMMAND=[touch testdata/datadir/clip.paste]
LOCKBOX_CLIP_TIMEOUT=3
-LOCKBOX_INTERACTIVE=false
LOCKBOX_JSON_HASH_LENGTH=3
LOCKBOX_JSON_MODE=hash
LOCKBOX_STORE=testdata/datadir/pass.kdbx
+LOCKBOX_TOTP_TIMEOUT=1
diff --git a/internal/app/totp.go b/internal/app/totp.go
@@ -37,18 +37,16 @@ type (
}
// TOTPOptions are TOTP call options
TOTPOptions struct {
- app CommandOptions
- Clear func()
- IsInteractive func() bool
+ app CommandOptions
+ Clear func()
}
)
// NewDefaultTOTPOptions gets the default option set
func NewDefaultTOTPOptions(app CommandOptions) TOTPOptions {
return TOTPOptions{
- app: app,
- Clear: clearFunc,
- IsInteractive: config.EnvInteractive.Get,
+ app: app,
+ Clear: clearFunc,
}
}
@@ -69,7 +67,7 @@ func (w totpWrapper) generateCode() (string, error) {
}
func (args *TOTPArguments) display(opts TOTPOptions) error {
- interactive := opts.IsInteractive()
+ interactive := true
if args.Mode == commands.TOTPMinimal || args.Mode == commands.TOTPSeed || args.Mode == commands.TOTPURL {
interactive = false
}
@@ -202,7 +200,7 @@ func (args *TOTPArguments) Do(opts TOTPOptions) error {
if args.Mode == "" {
return ErrUnknownTOTPMode
}
- if opts.Clear == nil || opts.IsInteractive == nil {
+ if opts.Clear == nil {
return errors.New("invalid option functions")
}
if args.Mode == commands.TOTPList {
diff --git a/internal/app/totp_test.go b/internal/app/totp_test.go
@@ -29,9 +29,6 @@ func newMock(t *testing.T) (*mockOptions, app.TOTPOptions) {
opts := app.NewDefaultTOTPOptions(m)
opts.Clear = func() {
}
- opts.IsInteractive = func() bool {
- return true
- }
return m, opts
}
@@ -134,15 +131,6 @@ func TestDoErrors(t *testing.T) {
opts := app.TOTPOptions{}
opts.Clear = func() {
}
- if err := args.Do(opts); err == nil || err.Error() != "invalid option functions" {
- t.Errorf("invalid error: %v", err)
- }
- if err := args.Do(opts); err == nil || err.Error() != "invalid option functions" {
- t.Errorf("invalid error: %v", err)
- }
- opts.IsInteractive = func() bool {
- return false
- }
if err := args.Do(opts); err == nil || err.Error() != "'' is not a TOTP entry" {
t.Errorf("invalid error: %v", err)
}
@@ -164,23 +152,11 @@ func TestNonListError(t *testing.T) {
setupTOTP(t)
args, _ := app.NewTOTPArguments([]string{"show", "test/test3"})
_, opts := newMock(t)
- opts.IsInteractive = func() bool {
- return false
- }
if err := args.Do(opts); err == nil || err.Error() != "'test/test3' is not a TOTP entry" {
t.Errorf("invalid error: %v", err)
}
args, _ = app.NewTOTPArguments([]string{"clip", "test/test3/otp"})
_, opts = newMock(t)
- opts.IsInteractive = func() bool {
- return false
- }
- if err := args.Do(opts); err == nil || err.Error() != "clipboard not available in non-interactive mode" {
- t.Errorf("invalid error: %v", err)
- }
- opts.IsInteractive = func() bool {
- return true
- }
if err := args.Do(opts); err == nil || err.Error() != "entry does not exist" {
t.Errorf("invalid error: %v", err)
}
@@ -222,21 +198,6 @@ func TestMinimal(t *testing.T) {
}
}
-func TestNonInteractive(t *testing.T) {
- setupTOTP(t)
- args, _ := app.NewTOTPArguments([]string{"show", "test/test3/totp/otp"})
- m, opts := newMock(t)
- opts.IsInteractive = func() bool {
- return false
- }
- if err := args.Do(opts); err != nil {
- t.Errorf("invalid error: %v", err)
- }
- if len(m.buf.String()) != 7 {
- t.Errorf("invalid short: %s", m.buf.String())
- }
-}
-
func TestOnce(t *testing.T) {
setupTOTP(t)
args, _ := app.NewTOTPArguments([]string{"once", "test/test3/totp/otp"})
diff --git a/internal/config/core.go b/internal/config/core.go
@@ -153,7 +153,7 @@ func CanColor() bool {
if _, noColor := os.LookupEnv("NO_COLOR"); noColor {
return false
}
- return EnvInteractive.Get()
+ return true
}
func readNested(v reflect.Type, root string) []string {
diff --git a/internal/config/core_test.go b/internal/config/core_test.go
@@ -1,7 +1,6 @@
package config_test
import (
- "fmt"
"os"
"testing"
@@ -41,21 +40,6 @@ func TestCanColor(t *testing.T) {
if can := config.CanColor(); !can {
t.Error("should be able to color")
}
- for raw, expect := range map[string]bool{
- "INTERACTIVE": true,
- } {
- store.Clear()
- key := fmt.Sprintf("LOCKBOX_%s", raw)
- store.SetBool(key, true)
- if can := config.CanColor(); can != expect {
- t.Errorf("expect != actual: %s", key)
- }
- store.SetBool(key, false)
- if can := config.CanColor(); can == expect {
- t.Errorf("expect == actual: %s", key)
- }
- }
- store.Clear()
t.Setenv("NO_COLOR", "1")
if can := config.CanColor(); can {
t.Error("should NOT be able to color")
diff --git a/internal/config/toml_test.go b/internal/config/toml_test.go
@@ -251,7 +251,7 @@ func TestDefaultTOMLToLoadFile(t *testing.T) {
if err := config.LoadConfigFile(file); err != nil {
t.Errorf("invalid error: %v", err)
}
- if len(store.List()) != 17 {
+ if len(store.List()) != 16 {
t.Errorf("invalid environment after load: %d", len(store.List()))
}
}
diff --git a/internal/config/vars.go b/internal/config/vars.go
@@ -45,14 +45,6 @@ var (
description: "Operate in readonly mode.",
}),
})
- // EnvInteractive indicates if operating in interactive mode
- EnvInteractive = environmentRegister(EnvironmentBool{
- environmentDefault: newDefaultedEnvironment(true,
- environmentBase{
- key: "INTERACTIVE",
- description: "Enable interactive mode.",
- }),
- })
// EnvTOTPTimeout indicates when TOTP display should timeout
EnvTOTPTimeout = environmentRegister(EnvironmentInt{
environmentDefault: newDefaultedEnvironment(120,
diff --git a/internal/config/vars_test.go b/internal/config/vars_test.go
@@ -24,10 +24,6 @@ func checkYesNo(key string, t *testing.T, obj config.EnvironmentBool, onEmpty bo
}
}
-func TestInteractiveSetting(t *testing.T) {
- checkYesNo("LOCKBOX_INTERACTIVE", t, config.EnvInteractive, true)
-}
-
func TestIsReadOnly(t *testing.T) {
checkYesNo("LOCKBOX_READONLY", t, config.EnvReadOnly, false)
}