You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.6 KiB
76 lines
1.6 KiB
package qrlogin |
|
|
|
import ( |
|
"encoding/base64" |
|
"image" |
|
"net/url" |
|
"time" |
|
|
|
"github.com/go-faster/errors" |
|
"rsc.io/qr" |
|
) |
|
|
|
// Token represents Telegram QR Login token. |
|
type Token struct { |
|
token []byte |
|
expires time.Time |
|
} |
|
|
|
// ParseTokenURL creates Token from given URL. |
|
func ParseTokenURL(u string) (Token, error) { |
|
parsed, err := url.Parse(u) |
|
if err != nil { |
|
return Token{}, err |
|
} |
|
switch { |
|
case parsed.Scheme != "tg": |
|
return Token{}, errors.Errorf("unexpected scheme %q", parsed.Scheme) |
|
case parsed.Host != "login": |
|
return Token{}, errors.Errorf("wrong path %q", parsed.Host) |
|
} |
|
|
|
q := parsed.Query() |
|
if q.Get("token") == "" { |
|
return Token{}, errors.New("token is empty") |
|
} |
|
token, err := base64.URLEncoding.DecodeString(q.Get("token")) |
|
if err != nil { |
|
return Token{}, err |
|
} |
|
|
|
return NewToken(token, 0), nil |
|
} |
|
|
|
// NewToken creates new Token. |
|
func NewToken(token []byte, expires int) Token { |
|
return Token{ |
|
token: token, |
|
expires: time.Unix(int64(expires), 0), |
|
} |
|
} |
|
|
|
// Expires returns token expiration time. |
|
func (t Token) Expires() time.Time { |
|
return t.expires |
|
} |
|
|
|
// String implements fmt.Stringer. |
|
func (t Token) String() string { |
|
return base64.URLEncoding.EncodeToString(t.token) |
|
} |
|
|
|
// URL returns login URL. |
|
// |
|
// 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) |
|
} |
|
|
|
// Image returns QR image. |
|
func (t Token) Image(level qr.Level) (image.Image, error) { |
|
code, err := qr.Encode(t.URL(), level) |
|
if err != nil { |
|
return nil, errors.Wrap(err, "encode") |
|
} |
|
return code.Image(), nil |
|
}
|
|
|