login_form.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "github.com/diamondburned/arikawa/v3/api"
  6. "github.com/gdamore/tcell/v2"
  7. "github.com/rivo/tview"
  8. )
  9. type LoginForm struct {
  10. *tview.Form
  11. }
  12. func newLoginForm() *LoginForm {
  13. lf := &LoginForm{
  14. Form: tview.NewForm(),
  15. }
  16. lf.AddInputField("Email", "", 0, nil, nil)
  17. lf.AddPasswordField("Password", "", 0, 0, nil)
  18. lf.AddPasswordField("Code (optional)", "", 0, 0, nil)
  19. lf.AddButton("Login", lf.onLoginButtonSelected)
  20. lf.SetTitle("Login")
  21. lf.SetTitleColor(tcell.GetColor(cfg.Theme.TitleColor))
  22. p := cfg.Theme.BorderPadding
  23. lf.SetBorder(cfg.Theme.Border)
  24. lf.SetBorderColor(tcell.GetColor(cfg.Theme.BorderColor))
  25. lf.SetBorderPadding(p[0], p[1], p[2], p[3])
  26. return lf
  27. }
  28. func (lf *LoginForm) onLoginButtonSelected() {
  29. email := lf.GetFormItem(0).(*tview.InputField).GetText()
  30. password := lf.GetFormItem(1).(*tview.InputField).GetText()
  31. if email == "" || password == "" {
  32. return
  33. }
  34. // Make a scratch HTTP client without a token
  35. client := api.NewClient("").WithContext(context.Background())
  36. // Try to login without TOTP
  37. l, err := client.Login(email, password)
  38. if err != nil {
  39. log.Fatal(err)
  40. }
  41. // Retry logging in with a 2FA token
  42. if l.Token == "" && l.MFA {
  43. code := lf.GetFormItem(2).(*tview.InputField).GetText()
  44. if code == "" {
  45. return
  46. }
  47. l, err = client.TOTP(code, l.Ticket)
  48. if err != nil {
  49. log.Fatal(err)
  50. }
  51. }
  52. // We got the token, return with a new Session.
  53. discordState, err = openState(l.Token)
  54. if err != nil {
  55. log.Fatal(err)
  56. }
  57. right := tview.NewFlex()
  58. right.SetDirection(tview.FlexRow)
  59. right.AddItem(messagesText, 0, 1, false)
  60. right.AddItem(messageInput, 3, 1, false)
  61. // The guilds tree is always focused first at start-up.
  62. mainFlex.AddItem(guildsTree, 0, 1, true)
  63. mainFlex.AddItem(right, 0, 4, false)
  64. mainFlex.SetInputCapture(onInputCapture)
  65. app.SetRoot(mainFlex, true)
  66. }