feat(login): add qr login

This commit is contained in:
iyear 2023-12-18 10:48:10 +08:00
parent 8753443401
commit ff0d44688f
3 changed files with 106 additions and 0 deletions

103
app/login/qr.go Normal file
View File

@ -0,0 +1,103 @@
package login
import (
"context"
"fmt"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/fatih/color"
"github.com/go-faster/errors"
"github.com/gotd/td/telegram/auth/qrlogin"
"github.com/gotd/td/tg"
"github.com/gotd/td/tgerr"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/skip2/go-qrcode"
"github.com/spf13/viper"
"github.com/iyear/tdl/pkg/consts"
"github.com/iyear/tdl/pkg/key"
"github.com/iyear/tdl/pkg/kv"
"github.com/iyear/tdl/pkg/tclient"
)
func QR(ctx context.Context) error {
kvd, err := kv.From(ctx).Open(viper.GetString(consts.FlagNamespace))
if err != nil {
return errors.Wrap(err, "open kv")
}
if err = kvd.Set(key.App(), []byte(tclient.AppDesktop)); err != nil {
return errors.Wrap(err, "set app")
}
d := tg.NewUpdateDispatcher()
c, err := tclient.New(ctx, tclient.Options{
KV: kvd,
Proxy: viper.GetString(consts.FlagProxy),
NTP: viper.GetString(consts.FlagNTP),
ReconnectTimeout: viper.GetDuration(consts.FlagReconnectTimeout),
Test: viper.GetString(consts.FlagTest) != "",
UpdateHandler: d,
}, true)
if err != nil {
return errors.Wrap(err, "create client")
}
return c.Run(ctx, func(ctx context.Context) error {
color.Blue("Scan QR code with your Telegram app...")
var lines int
_, err = c.QR().Auth(ctx, qrlogin.OnLoginToken(d), func(ctx context.Context, token qrlogin.Token) error {
qr, err := qrcode.New(token.URL(), qrcode.Medium)
if err != nil {
return errors.Wrap(err, "create qr")
}
code := qr.ToSmallString(false)
lines = strings.Count(code, "\n")
fmt.Print(code)
fmt.Print(strings.Repeat(text.CursorUp.Sprint(), lines))
return nil
})
// clear qrcode
out := &strings.Builder{}
for i := 0; i < lines; i++ {
out.WriteString(text.EraseLine.Sprint())
out.WriteString(text.CursorDown.Sprint())
}
out.WriteString(text.CursorUp.Sprintn(lines))
fmt.Print(out.String())
if err != nil {
// https://core.telegram.org/api/auth#2fa
if !tgerr.Is(err, "SESSION_PASSWORD_NEEDED") {
return errors.Wrap(err, "qr auth")
}
pwd := ""
prompt := &survey.Password{
Message: "Enter 2FA Password:",
}
if err = survey.AskOne(prompt, &pwd, survey.WithValidator(survey.Required)); err != nil {
return errors.Wrap(err, "2fa password")
}
if _, err = c.Auth().Password(ctx, pwd); err != nil {
return errors.Wrap(err, "2fa auth")
}
}
user, err := c.Self(ctx)
if err != nil {
return errors.Wrap(err, "get self")
}
fmt.Print(text.EraseLine.Sprint())
color.Green("Login successfully! ID: %d, Username: %s", user.ID, user.Username)
return nil
})
}

1
go.mod
View File

@ -75,6 +75,7 @@ require (
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect

2
go.sum
View File

@ -141,6 +141,8 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=