feat(cli): list/get 子命令 — 脚本集成 TOTP 获取

- winauth list: tabwriter 列出所有条目(名称/vendor/icon/hotkey)
- winauth get NAME: 输出当前 OTP,-n 不换行,--advance 允许 HOTP
- 加密配置自动 tty 隐藏密码提示(golang.org/x/term)
- --config 改为 PersistentFlag,子命令可继承
- HOTP get 默认拒绝,需 --advance 显式确认并保存配置
- CLI 不运行 GUI、不持有单实例锁
This commit is contained in:
2026-06-12 09:50:07 +08:00
parent 969600b6ee
commit 727be3557a
7 changed files with 265 additions and 7 deletions
+51
View File
@@ -0,0 +1,51 @@
package main
import (
"errors"
"fmt"
"os"
"text/tabwriter"
"github.com/spf13/cobra"
"git.wxccs.org/iceking2nd/winauth-go/internal/config"
"git.wxccs.org/iceking2nd/winauth-go/internal/i18n"
)
func newListCmd() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List all authenticator entries",
Long: "Prints a table of all entries in the config file. For encrypted configs, a password prompt will appear.",
Args: cobra.NoArgs,
RunE: runList,
}
}
func runList(cmd *cobra.Command, args []string) error {
const fn = "cmd.winauth.runList"
path := resolveConfigPath(cmd)
lang := preferredLanguage(path)
_ = i18n.Init(lang) // best-effort; list output is English anyway
cfg, _, err := cliLoadConfig(path)
if err != nil {
if errors.Is(err, config.ErrPasswordWrong) {
return fmt.Errorf("wrong password")
}
return fmt.Errorf("load config: %w", err)
}
if len(cfg.Entries) == 0 {
fmt.Fprintln(os.Stderr, "No entries found.")
return nil
}
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintln(tw, "NAME\tVENDOR\tICON\tHOTKEY")
for _, e := range cfg.Entries {
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", e.Name, e.Vendor, e.IconName, e.Hotkey)
}
return tw.Flush()
}