package secrets import ( "context" "encoding/base64" "fmt" ) // SessionStorage keeps the MTProto session in OpenBao and never on disk. // // gotd's own FileStorage would put a full-account credential in the working // directory, where it outlives the run, gets committed by accident, and is // readable by anything on the box. The session can do everything the operator // account can do, so it is held exactly where the bot token is. type SessionStorage struct { Store *Store } const sessionField = "session_b64" func (s SessionStorage) LoadSession(ctx context.Context) ([]byte, error) { fields, found, err := s.Store.Get(ctx, KeyOperatorSession) if err != nil { return nil, err } if !found || fields[sessionField] == "" { // gotd treats a nil session as "not authenticated yet", which is the // correct reading of an empty path. return nil, nil } raw, err := base64.StdEncoding.DecodeString(fields[sessionField]) if err != nil { return nil, fmt.Errorf("stored session at %s is not decodable; re-run "+ "`provision session bootstrap`", s.Store.Ref(KeyOperatorSession)) } return raw, nil } func (s SessionStorage) StoreSession(ctx context.Context, data []byte) error { return s.Store.Put(ctx, KeyOperatorSession, map[string]string{ sessionField: base64.StdEncoding.EncodeToString(data), }) } // AppCredentials are issued by my.telegram.org and cannot be provisioned; see // docs/seeding-runbook.md step 2. type AppCredentials struct { AppID int AppHash string }