mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 07:17:44 +00:00
Update dependencies (#1784)
This commit is contained in:
15
vendor/go.mau.fi/whatsmeow/client.go
vendored
15
vendor/go.mau.fi/whatsmeow/client.go
vendored
@ -67,11 +67,14 @@ type Client struct {
|
||||
appStateProc *appstate.Processor
|
||||
appStateSyncLock sync.Mutex
|
||||
|
||||
historySyncNotifications chan *waProto.HistorySyncNotification
|
||||
historySyncHandlerStarted uint32
|
||||
|
||||
uploadPreKeysLock sync.Mutex
|
||||
lastPreKeyUpload time.Time
|
||||
|
||||
mediaConn *MediaConn
|
||||
mediaConnLock sync.Mutex
|
||||
mediaConnCache *MediaConn
|
||||
mediaConnLock sync.Mutex
|
||||
|
||||
responseWaiters map[string]chan<- *waBinary.Node
|
||||
responseWaitersLock sync.Mutex
|
||||
@ -102,6 +105,11 @@ type Client struct {
|
||||
// If it returns false, the accepting will be cancelled and the retry receipt will be ignored.
|
||||
PreRetryCallback func(receipt *events.Receipt, retryCount int, msg *waProto.Message) bool
|
||||
|
||||
// Should untrusted identity errors be handled automatically? If true, the stored identity and existing signal
|
||||
// sessions will be removed on untrusted identity errors, and an events.IdentityChange will be dispatched.
|
||||
// If false, decrypting a message from untrusted devices will fail.
|
||||
AutoTrustIdentity bool
|
||||
|
||||
uniqueID string
|
||||
idCounter uint32
|
||||
|
||||
@ -150,6 +158,8 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
||||
handlerQueue: make(chan *waBinary.Node, handlerQueueSize),
|
||||
appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")),
|
||||
|
||||
historySyncNotifications: make(chan *waProto.HistorySyncNotification, 32),
|
||||
|
||||
groupParticipantsCache: make(map[types.JID][]types.JID),
|
||||
userDevicesCache: make(map[types.JID][]types.JID),
|
||||
|
||||
@ -157,6 +167,7 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
||||
GetMessageForRetry: func(to types.JID, id types.MessageID) *waProto.Message { return nil },
|
||||
|
||||
EnableAutoReconnect: true,
|
||||
AutoTrustIdentity: true,
|
||||
}
|
||||
cli.nodeHandlers = map[string]nodeHandler{
|
||||
"message": cli.handleEncryptedMessage,
|
||||
|
7
vendor/go.mau.fi/whatsmeow/download.go
vendored
7
vendor/go.mau.fi/whatsmeow/download.go
vendored
@ -194,19 +194,20 @@ func (cli *Client) Download(msg DownloadableMessage) ([]byte, error) {
|
||||
|
||||
// DownloadMediaWithPath downloads an attachment by manually specifying the path and encryption details.
|
||||
func (cli *Client) DownloadMediaWithPath(directPath string, encFileHash, fileHash, mediaKey []byte, fileLength int, mediaType MediaType, mmsType string) (data []byte, err error) {
|
||||
err = cli.refreshMediaConn(false)
|
||||
var mediaConn *MediaConn
|
||||
mediaConn, err = cli.refreshMediaConn(false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to refresh media connections: %w", err)
|
||||
}
|
||||
if len(mmsType) == 0 {
|
||||
mmsType = mediaTypeToMMSType[mediaType]
|
||||
}
|
||||
for i, host := range cli.mediaConn.Hosts {
|
||||
for i, host := range mediaConn.Hosts {
|
||||
mediaURL := fmt.Sprintf("https://%s%s&hash=%s&mms-type=%s&__wa-mms=", host.Hostname, directPath, base64.URLEncoding.EncodeToString(encFileHash), mmsType)
|
||||
data, err = cli.downloadAndDecrypt(mediaURL, mediaKey, mediaType, fileLength, encFileHash, fileHash)
|
||||
// TODO there are probably some errors that shouldn't retry
|
||||
if err != nil {
|
||||
if i >= len(cli.mediaConn.Hosts)-1 {
|
||||
if i >= len(mediaConn.Hosts)-1 {
|
||||
return nil, fmt.Errorf("failed to download media from last host: %w", err)
|
||||
}
|
||||
cli.Log.Warnf("Failed to download media: %s, trying with next host...", err)
|
||||
|
10
vendor/go.mau.fi/whatsmeow/mediaconn.go
vendored
10
vendor/go.mau.fi/whatsmeow/mediaconn.go
vendored
@ -40,17 +40,17 @@ func (mc *MediaConn) Expiry() time.Time {
|
||||
return mc.FetchedAt.Add(time.Duration(mc.TTL) * time.Second)
|
||||
}
|
||||
|
||||
func (cli *Client) refreshMediaConn(force bool) error {
|
||||
func (cli *Client) refreshMediaConn(force bool) (*MediaConn, error) {
|
||||
cli.mediaConnLock.Lock()
|
||||
defer cli.mediaConnLock.Unlock()
|
||||
if cli.mediaConn == nil || force || time.Now().After(cli.mediaConn.Expiry()) {
|
||||
if cli.mediaConnCache == nil || force || time.Now().After(cli.mediaConnCache.Expiry()) {
|
||||
var err error
|
||||
cli.mediaConn, err = cli.queryMediaConn()
|
||||
cli.mediaConnCache, err = cli.queryMediaConn()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return cli.mediaConnCache, nil
|
||||
}
|
||||
|
||||
func (cli *Client) queryMediaConn() (*MediaConn, error) {
|
||||
|
61
vendor/go.mau.fi/whatsmeow/message.go
vendored
61
vendor/go.mau.fi/whatsmeow/message.go
vendored
@ -13,7 +13,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"go.mau.fi/libsignal/signalerror"
|
||||
@ -162,6 +164,18 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) clearUntrustedIdentity(target types.JID) {
|
||||
err := cli.Store.Identities.DeleteIdentity(target.SignalAddress().String())
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to delete untrusted identity of %s from store: %v", target, err)
|
||||
}
|
||||
err = cli.Store.Sessions.DeleteSession(target.SignalAddress().String())
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to delete session with %s (untrusted identity) from store: %v", target, err)
|
||||
}
|
||||
cli.dispatchEvent(&events.IdentityChange{JID: target, Timestamp: time.Now(), Implicit: true})
|
||||
}
|
||||
|
||||
func (cli *Client) decryptDM(child *waBinary.Node, from types.JID, isPreKey bool) ([]byte, error) {
|
||||
content, _ := child.Content.([]byte)
|
||||
|
||||
@ -174,17 +188,9 @@ func (cli *Client) decryptDM(child *waBinary.Node, from types.JID, isPreKey bool
|
||||
return nil, fmt.Errorf("failed to parse prekey message: %w", err)
|
||||
}
|
||||
plaintext, _, err = cipher.DecryptMessageReturnKey(preKeyMsg)
|
||||
if errors.Is(err, signalerror.ErrUntrustedIdentity) {
|
||||
if cli.AutoTrustIdentity && errors.Is(err, signalerror.ErrUntrustedIdentity) {
|
||||
cli.Log.Warnf("Got %v error while trying to decrypt prekey message from %s, clearing stored identity and retrying", err, from)
|
||||
err = cli.Store.Identities.DeleteIdentity(from.SignalAddress().String())
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to delete identity of %s from store after decryption error: %v", from, err)
|
||||
}
|
||||
err = cli.Store.Sessions.DeleteSession(from.SignalAddress().String())
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to delete session with %s from store after decryption error: %v", from, err)
|
||||
}
|
||||
cli.dispatchEvent(&events.IdentityChange{JID: from, Timestamp: time.Now(), Implicit: true})
|
||||
cli.clearUntrustedIdentity(from)
|
||||
plaintext, _, err = cipher.DecryptMessageReturnKey(preKeyMsg)
|
||||
}
|
||||
if err != nil {
|
||||
@ -261,6 +267,26 @@ func (cli *Client) handleSenderKeyDistributionMessage(chat, from types.JID, rawS
|
||||
cli.Log.Debugf("Processed sender key distribution message from %s in %s", senderKeyName.Sender().String(), senderKeyName.GroupID())
|
||||
}
|
||||
|
||||
func (cli *Client) handleHistorySyncNotificationLoop() {
|
||||
defer func() {
|
||||
atomic.StoreUint32(&cli.historySyncHandlerStarted, 0)
|
||||
err := recover()
|
||||
if err != nil {
|
||||
cli.Log.Errorf("History sync handler panicked: %v\n%s", err, debug.Stack())
|
||||
}
|
||||
|
||||
// Check in case something new appeared in the channel between the loop stopping
|
||||
// and the atomic variable being updated. If yes, restart the loop.
|
||||
if len(cli.historySyncNotifications) > 0 && atomic.CompareAndSwapUint32(&cli.historySyncHandlerStarted, 0, 1) {
|
||||
cli.Log.Warnf("New history sync notifications appeared after loop stopped, restarting loop...")
|
||||
go cli.handleHistorySyncNotificationLoop()
|
||||
}
|
||||
}()
|
||||
for notif := range cli.historySyncNotifications {
|
||||
cli.handleHistorySyncNotification(notif)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotification) {
|
||||
var historySync waProto.HistorySync
|
||||
if data, err := cli.Download(notif); err != nil {
|
||||
@ -272,7 +298,7 @@ func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotif
|
||||
} else if err = proto.Unmarshal(rawData, &historySync); err != nil {
|
||||
cli.Log.Errorf("Failed to unmarshal history sync data: %v", err)
|
||||
} else {
|
||||
cli.Log.Debugf("Received history sync")
|
||||
cli.Log.Debugf("Received history sync (type %s, chunk %d)", historySync.GetSyncType(), historySync.GetChunkOrder())
|
||||
if historySync.GetSyncType() == waProto.HistorySync_PUSH_NAME {
|
||||
go cli.handleHistoricalPushNames(historySync.GetPushnames())
|
||||
}
|
||||
@ -314,16 +340,19 @@ func (cli *Client) handleProtocolMessage(info *types.MessageInfo, msg *waProto.M
|
||||
protoMsg := msg.GetProtocolMessage()
|
||||
|
||||
if protoMsg.GetHistorySyncNotification() != nil && info.IsFromMe {
|
||||
cli.handleHistorySyncNotification(protoMsg.HistorySyncNotification)
|
||||
cli.sendProtocolMessageReceipt(info.ID, "hist_sync")
|
||||
cli.historySyncNotifications <- protoMsg.HistorySyncNotification
|
||||
if atomic.CompareAndSwapUint32(&cli.historySyncHandlerStarted, 0, 1) {
|
||||
go cli.handleHistorySyncNotificationLoop()
|
||||
}
|
||||
go cli.sendProtocolMessageReceipt(info.ID, "hist_sync")
|
||||
}
|
||||
|
||||
if protoMsg.GetAppStateSyncKeyShare() != nil && info.IsFromMe {
|
||||
cli.handleAppStateSyncKeyShare(protoMsg.AppStateSyncKeyShare)
|
||||
go cli.handleAppStateSyncKeyShare(protoMsg.AppStateSyncKeyShare)
|
||||
}
|
||||
|
||||
if info.Category == "peer" {
|
||||
cli.sendProtocolMessageReceipt(info.ID, "peer_msg")
|
||||
go cli.sendProtocolMessageReceipt(info.ID, "peer_msg")
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,7 +376,7 @@ func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto.
|
||||
}
|
||||
}
|
||||
if msg.GetProtocolMessage() != nil {
|
||||
go cli.handleProtocolMessage(info, msg)
|
||||
cli.handleProtocolMessage(info, msg)
|
||||
}
|
||||
|
||||
// Unwrap ephemeral and view-once messages
|
||||
|
6
vendor/go.mau.fi/whatsmeow/send.go
vendored
6
vendor/go.mau.fi/whatsmeow/send.go
vendored
@ -17,6 +17,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mau.fi/libsignal/signalerror"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"go.mau.fi/libsignal/groups"
|
||||
@ -346,6 +347,11 @@ func (cli *Client) encryptMessageForDevice(plaintext []byte, to types.JID, bundl
|
||||
if bundle != nil {
|
||||
cli.Log.Debugf("Processing prekey bundle for %s", to)
|
||||
err := builder.ProcessBundle(bundle)
|
||||
if cli.AutoTrustIdentity && errors.Is(err, signalerror.ErrUntrustedIdentity) {
|
||||
cli.Log.Warnf("Got %v error while trying to process prekey bundle for %s, clearing stored identity and retrying", err, to)
|
||||
cli.clearUntrustedIdentity(to)
|
||||
err = builder.ProcessBundle(bundle)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to process prekey bundle: %w", err)
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func (vc WAVersionContainer) ProtoAppVersion() *waProto.AppVersion {
|
||||
}
|
||||
|
||||
// waVersion is the WhatsApp web client version
|
||||
var waVersion = WAVersionContainer{2, 2208, 14}
|
||||
var waVersion = WAVersionContainer{2, 2210, 9}
|
||||
|
||||
// waVersionHash is the md5 hash of a dot-separated waVersion
|
||||
var waVersionHash [16]byte
|
||||
|
7
vendor/go.mau.fi/whatsmeow/upload.go
vendored
7
vendor/go.mau.fi/whatsmeow/upload.go
vendored
@ -87,7 +87,8 @@ func (cli *Client) Upload(ctx context.Context, plaintext []byte, appInfo MediaTy
|
||||
fileEncSHA256 := sha256.Sum256(dataToUpload)
|
||||
resp.FileEncSHA256 = fileEncSHA256[:]
|
||||
|
||||
err = cli.refreshMediaConn(false)
|
||||
var mediaConn *MediaConn
|
||||
mediaConn, err = cli.refreshMediaConn(false)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to refresh media connections: %w", err)
|
||||
return
|
||||
@ -95,13 +96,13 @@ func (cli *Client) Upload(ctx context.Context, plaintext []byte, appInfo MediaTy
|
||||
|
||||
token := base64.URLEncoding.EncodeToString(resp.FileEncSHA256)
|
||||
q := url.Values{
|
||||
"auth": []string{cli.mediaConn.Auth},
|
||||
"auth": []string{mediaConn.Auth},
|
||||
"token": []string{token},
|
||||
}
|
||||
mmsType := mediaTypeToMMSType[appInfo]
|
||||
uploadURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: cli.mediaConn.Hosts[0].Hostname,
|
||||
Host: mediaConn.Hosts[0].Hostname,
|
||||
Path: fmt.Sprintf("/mms/%s/%s", mmsType, token),
|
||||
RawQuery: q.Encode(),
|
||||
}
|
||||
|
1
vendor/go.mau.fi/whatsmeow/user.go
vendored
1
vendor/go.mau.fi/whatsmeow/user.go
vendored
@ -230,6 +230,7 @@ func (cli *Client) handleHistoricalPushNames(names []*waProto.Pushname) {
|
||||
if cli.Store.Contacts == nil {
|
||||
return
|
||||
}
|
||||
cli.Log.Infof("Updating contact store with %d push names from history sync", len(names))
|
||||
for _, user := range names {
|
||||
if user.GetPushname() == "-" {
|
||||
continue
|
||||
|
Reference in New Issue
Block a user