login_form.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package ui
  2. import (
  3. "errors"
  4. "github.com/ayn2op/discordo/config"
  5. "github.com/diamondburned/arikawa/v3/api"
  6. "github.com/gdamore/tcell/v2"
  7. "github.com/rivo/tview"
  8. "github.com/zalando/go-keyring"
  9. )
  10. type LoginForm struct {
  11. *tview.Form
  12. Token chan string
  13. Error chan error
  14. }
  15. func NewLoginForm() *LoginForm {
  16. lf := &LoginForm{
  17. Form: tview.NewForm(),
  18. Token: make(chan string, 1),
  19. Error: make(chan error, 0),
  20. }
  21. lf.AddInputField("Email", "", 0, nil, nil)
  22. lf.AddPasswordField("Password", "", 0, 0, nil)
  23. lf.AddPasswordField("Code (optional)", "", 0, 0, nil)
  24. lf.AddCheckbox("Remember Me", true, nil)
  25. lf.AddButton("Login", lf.onLoginButtonSelected)
  26. lf.SetTitle("Login")
  27. lf.SetTitleColor(tcell.GetColor(config.Current.Theme.TitleColor))
  28. lf.SetTitleAlign(tview.AlignLeft)
  29. p := config.Current.Theme.BorderPadding
  30. lf.SetBorder(config.Current.Theme.Border)
  31. lf.SetBorderColor(tcell.GetColor(config.Current.Theme.BorderColor))
  32. lf.SetBorderPadding(p[0], p[1], p[2], p[3])
  33. return lf
  34. }
  35. func (lf *LoginForm) onLoginButtonSelected() {
  36. email := lf.GetFormItem(0).(*tview.InputField).GetText()
  37. password := lf.GetFormItem(1).(*tview.InputField).GetText()
  38. if email == "" || password == "" {
  39. return
  40. }
  41. // Create a new API client without an authentication token.
  42. apiClient := api.NewClient("")
  43. // Log in using the provided email and password.
  44. lr, err := apiClient.Login(email, password)
  45. if err != nil {
  46. lf.Error <- err
  47. return
  48. }
  49. // If the account has MFA-enabled, attempt to log in using the provided code.
  50. if lr.MFA && lr.Token == "" {
  51. code := lf.GetFormItem(2).(*tview.InputField).GetText()
  52. if code == "" {
  53. return
  54. }
  55. lr, err = apiClient.TOTP(code, lr.Ticket)
  56. if err != nil {
  57. lf.Error <- err
  58. return
  59. }
  60. }
  61. if lr.Token == "" {
  62. lf.Error <- errors.New("Token is missing")
  63. return
  64. }
  65. rememberMe := lf.GetFormItem(3).(*tview.Checkbox).IsChecked()
  66. if rememberMe {
  67. go keyring.Set(config.Name, "token", lr.Token)
  68. }
  69. lf.Token <- lr.Token
  70. }