package cli import ( "bufio" "fmt" "os" "strings" "golang.org/x/term" "git.morlana.online/f.weber/vault-tui/internal/auth" ) // promptMissing fills in any of m's still-missing required fields by // prompting on the controlling TTY. It never blocks when stdin is not a // terminal (e.g. CI/pipes) — callers should check IsInteractive first and // treat a non-empty Missing() list as a hard error in that case instead of // calling this. func promptMissing(m auth.Method, creds auth.Credentials) error { missing := auth.Missing(m, creds) if len(missing) == 0 { return nil } reader := bufio.NewReader(os.Stdin) for _, f := range missing { if f.Kind == auth.FieldSecret { v, err := readPassword(f.Label) if err != nil { return err } creds[f.Name] = v continue } fmt.Fprintf(os.Stderr, "%s: ", f.Label) line, err := reader.ReadString('\n') if err != nil { return fmt.Errorf("reading %s: %w", f.Label, err) } creds[f.Name] = strings.TrimSpace(line) } return nil } func readPassword(label string) (string, error) { fmt.Fprintf(os.Stderr, "%s (will be hidden): ", label) b, err := term.ReadPassword(int(os.Stdin.Fd())) fmt.Fprintln(os.Stderr) if err != nil { return "", fmt.Errorf("reading %s: %w", label, err) } return strings.TrimSpace(string(b)), nil } // IsInteractive reports whether stdin is a terminal we can prompt on. func IsInteractive() bool { return term.IsTerminal(int(os.Stdin.Fd())) }