login: increase buffer for QR renewal

This commit is contained in:
Tulir Asokan
2026-04-10 22:58:16 +03:00
parent a5b1927acb
commit 53dec19878
4 changed files with 14 additions and 13 deletions

View File

@@ -133,6 +133,7 @@ func (bl *baseLogin) makeClient(ctx context.Context, dispatcher *tg.UpdateDispat
Logger: zaplog,
Device: bl.main.deviceConfig(),
UpdateHandler: updateManager,
NoUpdates: true,
})
bl.ctx, bl.cancel = context.WithTimeoutCause(log.WithContext(bl.main.Bridge.BackgroundCtx), LoginTimeout, ErrLoginTimeout)

View File

@@ -70,7 +70,8 @@ func (ql *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
loggedIn := make(chan struct{})
dispatcher := tg.NewUpdateDispatcher()
dispatcher.OnLoginToken(func(ctx context.Context, e tg.Entities, update *tg.UpdateLoginToken) error {
loggedIn <- struct{}{}
log.Debug().Msg("Received updateLoginToken")
close(loggedIn)
return nil
})
err := ql.makeClient(ctx, &dispatcher)
@@ -78,13 +79,10 @@ func (ql *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
return nil, err
}
qr := qrlogin.NewQR(ql.client.API(), ql.main.Config.APIID, ql.main.Config.APIHash, qrlogin.Options{
Migrate: ql.client.MigrateTo,
})
ql.qrToken = make(chan qrlogin.Token)
ql.auth = make(chan qrAuthResult)
go func() {
auth, err := qr.Auth(ql.ctx, loggedIn, func(ctx context.Context, token qrlogin.Token) error {
auth, err := ql.client.QR().Auth(ql.ctx, loggedIn, func(ctx context.Context, token qrlogin.Token) error {
ql.qrToken <- token
return nil
})

View File

@@ -140,6 +140,8 @@ func OnLoginToken(d interface {
return loggedIn
}
const QRRenewBuffer = 3 * time.Second
// Auth generates new QR login token, shows it and awaits acceptation.
//
// NB: Show callback may be called more than once if QR expires.
@@ -150,7 +152,7 @@ func (q QR) Auth(
exceptIDs ...int64,
) (*tg.AuthAuthorization, error) {
until := func(token Token) time.Duration {
return token.Expires().Sub(q.clock.Now()).Truncate(time.Second)
return token.Expires().Sub(q.clock.Now()) - QRRenewBuffer
}
token, err := q.Export(ctx, exceptIDs...)
@@ -173,7 +175,7 @@ func (q QR) Auth(
defer clock.StopTimer(timer)
for {
if err := show(ctx, token); err != nil {
if err = show(ctx, token); err != nil {
return nil, errors.Wrap(err, "show")
}
@@ -181,18 +183,17 @@ func (q QR) Auth(
case <-ctx.Done():
return nil, ctx.Err()
case <-timer.C():
t, err := q.Export(ctx, exceptIDs...)
token, err = q.Export(ctx, exceptIDs...)
if err != nil {
return nil, err
}
if t.Empty() {
if token.Empty() {
// If empty token, it means AuthLoginTokenSuccess was returned.
// QR was scanned and accepted, break to import.
break
}
token = t
timer.Reset(until(token))
continue

View File

@@ -4,6 +4,7 @@ import (
"encoding/base64"
"image"
"net/url"
"strings"
"time"
"github.com/go-faster/errors"
@@ -33,7 +34,7 @@ func ParseTokenURL(u string) (Token, error) {
if q.Get("token") == "" {
return Token{}, errors.New("token is empty")
}
token, err := base64.URLEncoding.DecodeString(q.Get("token"))
token, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(q.Get("token"), "="))
if err != nil {
return Token{}, err
}
@@ -56,7 +57,7 @@ func (t Token) Expires() time.Time {
// String implements fmt.Stringer.
func (t Token) String() string {
return base64.URLEncoding.EncodeToString(t.token)
return base64.RawURLEncoding.EncodeToString(t.token)
}
// Empty reports whether token is empty.
@@ -68,7 +69,7 @@ func (t Token) Empty() bool {
//
// See https://core.telegram.org/api/qr-login#exporting-a-login-token.
func (t Token) URL() string {
return "tg://login?token=" + base64.URLEncoding.EncodeToString(t.token)
return "tg://login?token=" + base64.RawURLEncoding.EncodeToString(t.token)
}
// Image returns QR image.