This commit is contained in:
bel
2026-02-15 19:33:01 -07:00
parent d6f32f01d1
commit 1b5e3b6f33
2 changed files with 142 additions and 2 deletions

BIN
src/matrix/.client.go.swp Normal file

Binary file not shown.

View File

@@ -1,7 +1,147 @@
package matrix package matrix
import (
"context"
"strings"
"sync"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/crypto"
"maunium.net/go/mautrix/crypto/cryptohelper"
)
type Client struct { type Client struct {
client *mautrix.Client client *mautrix.Client
accessToken string
deviceId string
pickleKeyString string
} }
func New // https://chrastecky.dev/post/11 func NewClient(ctx context.Context, uid, password, recoveryKey string) (*Client, error) {
ctx, can := context.WithCancel(ctx)
defer can()
// uid like @username:homeserver.com
username := strings.Split(uid, ":")[0]
homeserver := strings.Split(uid, ":")[1]
c, err := mautrix.NewClient(homeserver, uid, "")
if err != nil {
return nil, err
}
syncer := mautrix.NewDefaultSyncer()
c.Syncer = syncer
cryptoHelper, err := setupCryptoHelper(ctx, client)
if err != nil {
panic(err)
}
c.Crypto = cryptoHelper
readyChan := make(chan bool)
var once sync.Once
syncer.OnSync(func(ctx context.Context, resp *mautrix.RespSync, since string) bool {
once.Do(func() {
close(readyChan)
})
return true
})
go func() {
if err := c.Sync(); err != nil {
can()
panic(err)
}
}()
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-readyChan:
}
if err := verifyWithRecoveryKey(ctx, cryptoHelper.Machine()); err != nil {
return nil, err
}
client := &Client{
client: c,
}
return client, client.login(ctx, username, password)
}
func (c *Client) login(ctx context.Context, username, password string) error {
if c.accessToken != "" {
return nil
}
resp, err := c.client.Login(ctx, &mautrix.ReqLogin{
Type: mautrix.AuthTypePassword,
Identifier: mautrix.UserIdentifier{
User: username,
Type: mautrix.IdentifierTypeUser,
},
Password: password,
StoreCredentials: true,
})
if err != nil {
return err
}
c.deviceId = resp.DeviceID
c.accessToken = resp.AccessToken
return nil
}
/*
content := event.MessageEventContent{
MsgType: event.MsgText,
Body: "Hello world from Go!",
}
_, err = client.SendMessageEvent(context.Background(), roomID, event.EventMessage, content)
if err != nil {
panic(err)
}
*/
func setupCryptoHelper(ctx context.Context, cli *mautrix.Client) (*cryptohelper.CryptoHelper, error) {
// remember to use a secure key for the pickle key in production
pickleKey := []byte(pickleKeyString)
// this is a path to the SQLite database you will use to store various data about your bot
dbPath := "crypto.db"
helper, err := cryptohelper.NewCryptoHelper(cli, pickleKey, dbPath)
if err != nil {
return nil, err
}
// initialize the database and other stuff
err = helper.Init(ctx)
if err != nil {
return nil, err
}
return helper, nil
}
func verifyWithRecoveryKey(ctx context.Context, machine *crypto.OlmMachine) (err error) {
keyId, keyData, err := machine.SSSS.GetDefaultKeyData(ctx)
if err != nil {
return
}
key, err := keyData.VerifyRecoveryKey(keyId, recoveryKey)
if err != nil {
return
}
err = machine.FetchCrossSigningKeysFromSSSS(ctx, key)
if err != nil {
return
}
err = machine.SignOwnDevice(ctx, machine.OwnIdentity())
if err != nil {
return
}
err = machine.SignOwnMasterKey(ctx)
return
}