email-mcp/internal/cli/setup.go
2026-04-13 18:01:28 +02:00

91 lines
2 KiB
Go

package cli
import (
"bufio"
"context"
"fmt"
"io"
"os"
"strings"
frameworkcli "gitea.lclr.dev/AI/mcp-framework/cli"
"email-mcp/internal/secretstore"
)
type InteractiveConfigPrompter struct {
reader *bufio.Reader
stdinFile *os.File
output io.Writer
}
func NewInteractiveConfigPrompter(input io.Reader, output io.Writer) *InteractiveConfigPrompter {
if input == nil {
input = strings.NewReader("")
}
if output == nil {
output = io.Discard
}
prompter := &InteractiveConfigPrompter{
reader: bufio.NewReader(input),
output: output,
}
if file, ok := input.(*os.File); ok {
prompter.stdinFile = file
}
return prompter
}
func (p *InteractiveConfigPrompter) PromptCredential(_ context.Context, existing secretstore.Credential, hasStoredPassword bool) (secretstore.Credential, error) {
host, err := frameworkcli.PromptLine(p.reader, p.output, "IMAP host", existing.Host)
if err != nil {
return secretstore.Credential{}, err
}
username, err := frameworkcli.PromptLine(p.reader, p.output, "Username", existing.Username)
if err != nil {
return secretstore.Credential{}, err
}
password, err := p.promptPassword(existing.Password, hasStoredPassword)
if err != nil {
return secretstore.Credential{}, err
}
cred := secretstore.Credential{
Host: host,
Username: username,
Password: password,
}
if err := cred.Validate(); err != nil {
return secretstore.Credential{}, err
}
return cred, nil
}
func (p *InteractiveConfigPrompter) promptPassword(storedPassword string, hasStoredPassword bool) (string, error) {
if p.stdinFile != nil {
return frameworkcli.PromptSecret(p.stdinFile, p.output, "Password", hasStoredPassword, storedPassword)
}
if hasStoredPassword {
fmt.Fprint(p.output, "Password [stored, leave blank to keep]: ")
} else {
fmt.Fprint(p.output, "Password: ")
}
line, err := p.reader.ReadString('\n')
if err != nil && err != io.EOF {
return "", err
}
password := strings.TrimSpace(line)
if password == "" && hasStoredPassword {
return storedPassword, nil
}
return password, nil
}