diff --git a/cmd/help/main.go b/cmd/help/main.go index 4355d56..0ad2a31 100644 --- a/cmd/help/main.go +++ b/cmd/help/main.go @@ -16,6 +16,8 @@ import ( // TODO consider local-only help command for renaming and adding emails to account +// TODO put colorscheme, prompting stuff into own packages for use in the other commands. would be good to get off of survey. + type colorScheme struct { Header func(string) string Subtitle func(string) string @@ -41,11 +43,23 @@ func newColorScheme() colorScheme { } } -func stringPrompt(cs colorScheme, tty *tty.TTY, prompt string) (string, error) { +type Prompter struct { + cs colorScheme + tty *tty.TTY +} + +func NewPrompter(tty *tty.TTY, cs colorScheme) *Prompter { + return &Prompter{ + cs: cs, + tty: tty, + } +} + +func (p *Prompter) String(prompt string) (string, error) { fmt.Println("") - fmt.Println(cs.Prompt(prompt)) - fmt.Println(cs.Subtitle("(type your answer below and press enter to submit)")) - s, err := tty.ReadString() + fmt.Println(p.cs.Prompt(prompt)) + fmt.Println(p.cs.Subtitle("(type your answer below and press enter to submit)")) + s, err := p.tty.ReadString() if err != nil { return "", fmt.Errorf("couldn't collect input: %w", err) } @@ -53,18 +67,18 @@ func stringPrompt(cs colorScheme, tty *tty.TTY, prompt string) (string, error) { return s, nil } -func numberPrompt(cs colorScheme, tty *tty.TTY, prompt string, opts []string) (int, error) { +func (p *Prompter) Select(prompt string, opts []string) (int, error) { fmt.Println() - fmt.Println(cs.Prompt(prompt)) - fmt.Println(cs.Subtitle("(pick an option using the corresponding number)")) + fmt.Println(p.cs.Prompt(prompt)) + fmt.Println(p.cs.Subtitle("(pick an option using the corresponding number)")) chosen := -1 for chosen < 0 { fmt.Println() for ix, o := range opts { - fmt.Printf("%s: %s\n", cs.Option(fmt.Sprintf("%d", ix+1)), o) + fmt.Printf("%s: %s\n", p.cs.Option(fmt.Sprintf("%d", ix+1)), o) } - r, err := tty.ReadRune() + r, err := p.tty.ReadRune() if err != nil { return -1, fmt.Errorf("could not collect answer for '%s': %w", prompt, err) } @@ -104,12 +118,14 @@ func _main() error { } defer tty.Close() + p := NewPrompter(tty, cs) + options := []string{ "I need to request that a new SSH key be added to my account.", "I have a code from my e-mail to redeem for a new SSH key", "I just want out of here", } - c, err := numberPrompt(cs, tty, "What do you need help with?", options) + c, err := p.Select("What do you need help with?", options) defer func() { fmt.Println() @@ -118,9 +134,9 @@ func _main() error { switch c { case 0: - return collectEmail(db, cs, tty) + return collectEmail(db, cs, p) case 1: - return redeemCode(tty) + return redeemCode(db, cs, p) case 2: return nil } @@ -128,9 +144,9 @@ func _main() error { return nil } -func collectEmail(db *sql.DB, cs colorScheme, tty *tty.TTY) error { +func collectEmail(db *sql.DB, cs colorScheme, p *Prompter) error { fmt.Println(cs.Header("We can send a authorization code to an email associated with your town account.")) - email, err := stringPrompt(cs, tty, "email to send reset code to?") + email, err := p.String("email to send reset code to?") if err != nil { return err } @@ -185,8 +201,25 @@ func collectEmail(db *sql.DB, cs colorScheme, tty *tty.TTY) error { return nil } -func redeemCode(tty *tty.TTY) error { - // TODO deserialize +func redeemCode(db *sql.DB, cs colorScheme, p *Prompter) error { + fmt.Println(cs.Header("redeem an auth code and add a new public key")) + fmt.Println() + c, err := p.String("paste your auth code:") + if err != nil { + // TODO log + return err + } + + parts, err := codes.Decode(c) + if err != nil { + // TODO log + return err + } + code := parts[0] + email := parts[1] + + fmt.Println(code, email) + // TODO verify code // TODO accept key // TODO verify key