فهرست منبع

feat: add support for MFA (2FA) login (#29)

* feat(ui): add ui.NewMfaLoginForm()

* feat: add support for MFA
rigormorrtiss 4 سال پیش
والد
کامیت
5ff13fac2e
2فایلهای تغییر یافته به همراه58 افزوده شده و 20 حذف شده
  1. 38 15
      discordo.go
  2. 20 5
      ui/forms.go

+ 38 - 15
discordo.go

@@ -60,8 +60,7 @@ func main() {
 			SetRoot(mainFlex, true).
 			SetFocus(guildsTreeView)
 
-		discordSession = newSession("", "", t)
-		defer discordSession.Close()
+		discordSession = newSession(t)
 	} else {
 		loginForm = ui.NewLoginForm(onLoginFormLoginButtonSelected)
 		app.SetRoot(loginForm, true)
@@ -106,7 +105,7 @@ func onMessageInputFieldInputCapture(e *tcell.EventKey) *tcell.EventKey {
 	return e
 }
 
-func newSession(email string, password string, token string) (s *session.Session) {
+func newSession(token string) (s *session.Session) {
 	api.UserAgent = "" +
 		"Mozilla/5.0 (X11; Linux x86_64) " +
 		"AppleWebKit/537.36 (KHTML, like Gecko) " +
@@ -116,12 +115,7 @@ func newSession(email string, password string, token string) (s *session.Session
 	gateway.DefaultIdentity.Device = ""
 
 	var err error
-	if email != "" && password != "" {
-		s, err = session.Login(email, password, "")
-	} else if token != "" {
-		s, err = session.New(token)
-	}
-
+	s, err = session.New(token)
 	if err != nil {
 		panic(err)
 	}
@@ -260,12 +254,41 @@ func onLoginFormLoginButtonSelected() {
 		return
 	}
 
-	app.
-		SetRoot(mainFlex, true).
-		SetFocus(guildsTreeView)
+	// Make a scratch HTTP client without a token
+	client := api.NewClient("")
+	// Try to login without TOTP
+	l, err := client.Login(email, password)
+	if err != nil {
+		panic(err)
+	}
 
-	discordSession = newSession(email, password, "")
-	defer discordSession.Close()
+	if l.Token != "" && !l.MFA {
+		app.
+			SetRoot(mainFlex, true).
+			SetFocus(guildsTreeView)
 
-	go util.SetItem(kr, "token", discordSession.Token)
+		discordSession = newSession(l.Token)
+		go util.SetItem(kr, "token", l.Token)
+	} else if l.MFA {
+		loginForm = ui.NewMfaLoginForm(func() {
+			code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
+			if code == "" {
+				return
+			}
+
+			l, err := client.TOTP(code, l.Ticket)
+			if err != nil {
+				panic(err)
+			}
+
+			app.
+				SetRoot(mainFlex, true).
+				SetFocus(guildsTreeView)
+
+			discordSession = newSession(l.Token)
+			go util.SetItem(kr, "token", l.Token)
+		})
+
+		app.SetRoot(loginForm, true)
+	}
 }

+ 20 - 5
ui/forms.go

@@ -5,16 +5,31 @@ import (
 	"github.com/rivo/tview"
 )
 
-func NewLoginForm(onLoginFormLoginButtonSelected func()) (f *tview.Form) {
+func newBaseLoginForm() (f *tview.Form) {
 	f = tview.NewForm()
 	f.
-		AddInputField("Email", "", 0, nil, nil).
-		AddPasswordField("Password", "", 0, 0, nil).
-		AddButton("Login", onLoginFormLoginButtonSelected).
 		SetButtonsAlign(tview.AlignCenter).
 		SetButtonBackgroundColor(tcell.GetColor("#5865F2")).
 		SetBorder(true).
 		SetBorderPadding(0, 0, 1, 0)
 
-	return f
+	return
+}
+
+func NewLoginForm(onLoginFormLoginButtonSelected func()) (f *tview.Form) {
+	f = newBaseLoginForm()
+	f.
+		AddInputField("Email", "", 0, nil, nil).
+		AddPasswordField("Password", "", 0, 0, nil).
+		AddButton("Login", onLoginFormLoginButtonSelected)
+
+	return
+}
+
+func NewMfaLoginForm(onMfaLoginFormLoginButtonSelected func()) (f *tview.Form) {
+	f = newBaseLoginForm().
+		AddPasswordField("Code", "", 0, 0, nil).
+		AddButton("Login", onMfaLoginFormLoginButtonSelected)
+
+	return
 }