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:
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.wxccs.org/iceking2nd/winauth-go/internal/config"
|
||||
)
|
||||
|
||||
// resolveConfigPath returns the config file path from the --config
|
||||
// flag or the default location.
|
||||
func resolveConfigPath(cmd *cobra.Command) string {
|
||||
if p, _ := cmd.Root().PersistentFlags().GetString("config"); p != "" {
|
||||
return p
|
||||
}
|
||||
return config.DefaultPath()
|
||||
}
|
||||
|
||||
// cliLoadConfig loads the config at path, prompting for a password if
|
||||
// the file is encrypted. Returns the config and the passphrase (empty
|
||||
// for plaintext configs). Up to 3 password attempts are allowed.
|
||||
func cliLoadConfig(path string) (*config.Config, []byte, error) {
|
||||
cfg, err := config.LoadYAML(path, nil)
|
||||
if err == nil {
|
||||
return cfg, nil, nil
|
||||
}
|
||||
if !errors.Is(err, config.ErrPasswordRequired) {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for attempt := 0; attempt < 3; attempt++ {
|
||||
pw, err := readPassword("Password: ")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("read password: %w", err)
|
||||
}
|
||||
cfg, err = config.LoadYAML(path, pw)
|
||||
if err == nil {
|
||||
return cfg, pw, nil
|
||||
}
|
||||
if errors.Is(err, config.ErrPasswordWrong) {
|
||||
fmt.Fprintln(os.Stderr, "Wrong password.")
|
||||
continue
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
return nil, nil, fmt.Errorf("too many failed password attempts")
|
||||
}
|
||||
Reference in New Issue
Block a user