move gotd fork into repo. (#111)

- update to latest telegram layer
- remove some references to fields in tg.Entities that don't exist in
the schema
- originally added here:
https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e
  - referenced here
-
https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3
-
https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
Adam Van Ymeren
2025-06-27 20:03:37 -07:00
committed by GitHub
parent 0952df0244
commit 7a04f298d2
19264 changed files with 1539697 additions and 84 deletions
+158
View File
@@ -0,0 +1,158 @@
// Package session implements session storage.
package session
import (
"context"
"encoding/json"
"github.com/go-faster/errors"
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
)
// Config is subset of tg.Config.
type Config struct {
// Indicates that telegram is probably censored by governments/ISPs in the current region
BlockedMode bool
// Whether to forcefully try connecting using IPv6 dcOptions¹
//
// Links:
// 1) https://core.telegram.org/type/DcOption
ForceTryIpv6 bool
// Current date at the server
Date int
// Expiration date of this config: when it expires it'll have to be refetched using help
// getConfig¹
//
// Links:
// 1) https://core.telegram.org/method/help.getConfig
Expires int
// Whether we're connected to the test DCs
TestMode bool
// ID of the DC that returned the reply
ThisDC int
// DC IP list
DCOptions []tg.DCOption
// Domain name for fetching encrypted DC list from DNS TXT record
DCTxtDomainName string
// Temporary passport¹ sessions
//
// Links:
// 1) https://core.telegram.org/passport
//
// Use SetTmpSessions and GetTmpSessions helpers.
TmpSessions int
// DC ID to use to download webfiles¹
//
// Links:
// 1) https://core.telegram.org/api/files#downloading-webfiles
WebfileDCID int
}
// ConfigFromTG converts tg.Config to Config.
//
// Note that Config is the subset of tg.Config, so data loss is possible.
func ConfigFromTG(c tg.Config) Config {
return Config{
BlockedMode: c.BlockedMode,
ForceTryIpv6: c.ForceTryIpv6,
Date: c.Date,
Expires: c.Expires,
TestMode: c.TestMode,
ThisDC: c.ThisDC,
DCOptions: c.DCOptions,
DCTxtDomainName: c.DCTxtDomainName,
WebfileDCID: c.WebfileDCID,
TmpSessions: c.TmpSessions,
}
}
// TG returns tg.Config from Config.
//
// Note that config is the subset of tg.Config, so some fields will be unset.
func (c Config) TG() tg.Config {
return tg.Config{
BlockedMode: c.BlockedMode,
ForceTryIpv6: c.ForceTryIpv6,
Date: c.Date,
Expires: c.Expires,
TestMode: c.TestMode,
ThisDC: c.ThisDC,
DCOptions: c.DCOptions,
DCTxtDomainName: c.DCTxtDomainName,
WebfileDCID: c.WebfileDCID,
TmpSessions: c.TmpSessions,
}
}
// Data of session.
type Data struct {
Config Config
DC int
Addr string
AuthKey []byte
AuthKeyID []byte
Salt int64
}
// Storage is secure persistent storage for client session.
//
// NB: Implementation security is important, attacker can abuse it not only for
// connecting as authenticated user or bot, but even decrypting previous
// messages in some situations.
type Storage interface {
LoadSession(ctx context.Context) ([]byte, error)
StoreSession(ctx context.Context, data []byte) error
}
// ErrNotFound means that session is not found in storage.
var ErrNotFound = errors.New("session storage: not found")
// Loader wraps Storage implementing Data (un-)marshaling.
type Loader struct {
Storage Storage
}
type jsonData struct {
Version int
Data Data
}
const latestVersion = 1
// Load loads Data from Storage.
func (l *Loader) Load(ctx context.Context) (*Data, error) {
buf, err := l.Storage.LoadSession(ctx)
if err != nil {
return nil, errors.Wrap(err, "load")
}
if len(buf) == 0 {
return nil, ErrNotFound
}
var v jsonData
if err := json.Unmarshal(buf, &v); err != nil {
return nil, errors.Wrap(err, "unmarshal")
}
if v.Version != latestVersion {
// HACK(ernado): backward compatibility super shenanigan.
return nil, errors.Wrapf(ErrNotFound, "version mismatch (%d != %d)", v.Version, latestVersion)
}
return &v.Data, err
}
// Save saves Data to Storage.
func (l *Loader) Save(ctx context.Context, data *Data) error {
v := jsonData{
Version: latestVersion,
Data: *data,
}
buf, err := json.Marshal(v)
if err != nil {
return errors.Wrap(err, "marshal")
}
if err := l.Storage.StoreSession(ctx, buf); err != nil {
return errors.Wrap(err, "store")
}
return nil
}