mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 14:17:45 +00:00
Update dependencies and remove old matterclient lib (#2067)
This commit is contained in:
@ -290,7 +290,7 @@ func (proc *Processor) DecodePatches(list *PatchList, initialState HashState, va
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
patchMAC := generatePatchMAC(patch, list.Name, keys.PatchMAC)
|
||||
patchMAC := generatePatchMAC(patch, list.Name, keys.PatchMAC, patch.GetVersion().GetVersion())
|
||||
if !bytes.Equal(patchMAC, patch.GetPatchMac()) {
|
||||
err = fmt.Errorf("failed to verify patch v%d: %w", version, ErrMismatchingPatchMAC)
|
||||
return
|
||||
|
200
vendor/go.mau.fi/whatsmeow/appstate/encode.go
vendored
Normal file
200
vendor/go.mau.fi/whatsmeow/appstate/encode.go
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
package appstate
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
waProto "go.mau.fi/whatsmeow/binary/proto"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/util/cbcutil"
|
||||
)
|
||||
|
||||
// MutationInfo contains information about a single mutation to the app state.
|
||||
type MutationInfo struct {
|
||||
// Index contains the thing being mutated (like `mute` or `pin_v1`), followed by parameters like the target JID.
|
||||
Index []string
|
||||
// Version is a static number that depends on the thing being mutated.
|
||||
Version int32
|
||||
// Value contains the data for the mutation.
|
||||
Value *waProto.SyncActionValue
|
||||
}
|
||||
|
||||
// PatchInfo contains information about a patch to the app state.
|
||||
// A patch can contain multiple mutations, as long as all mutations are in the same app state type.
|
||||
type PatchInfo struct {
|
||||
// Timestamp is the time when the patch was created. This will be filled automatically in EncodePatch if it's zero.
|
||||
Timestamp time.Time
|
||||
// Type is the app state type being mutated.
|
||||
Type WAPatchName
|
||||
// Mutations contains the individual mutations to apply to the app state in this patch.
|
||||
Mutations []MutationInfo
|
||||
}
|
||||
|
||||
// BuildMute builds an app state patch for muting or unmuting a chat.
|
||||
//
|
||||
// If mute is true and the mute duration is zero, the chat is muted forever.
|
||||
func BuildMute(target types.JID, mute bool, muteDuration time.Duration) PatchInfo {
|
||||
var muteEndTimestamp *int64
|
||||
if muteDuration > 0 {
|
||||
muteEndTimestamp = proto.Int64(time.Now().Add(muteDuration).UnixMilli())
|
||||
}
|
||||
|
||||
return PatchInfo{
|
||||
Type: WAPatchRegularHigh,
|
||||
Mutations: []MutationInfo{{
|
||||
Index: []string{IndexMute, target.String()},
|
||||
Version: 2,
|
||||
Value: &waProto.SyncActionValue{
|
||||
MuteAction: &waProto.MuteAction{
|
||||
Muted: proto.Bool(mute),
|
||||
MuteEndTimestamp: muteEndTimestamp,
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func newPinMutationInfo(target types.JID, pin bool) MutationInfo {
|
||||
return MutationInfo{
|
||||
Index: []string{IndexPin, target.String()},
|
||||
Version: 5,
|
||||
Value: &waProto.SyncActionValue{
|
||||
PinAction: &waProto.PinAction{
|
||||
Pinned: &pin,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// BuildPin builds an app state patch for pinning or unpinning a chat.
|
||||
func BuildPin(target types.JID, pin bool) PatchInfo {
|
||||
return PatchInfo{
|
||||
Type: WAPatchRegularLow,
|
||||
Mutations: []MutationInfo{
|
||||
newPinMutationInfo(target, pin),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// BuildArchive builds an app state patch for archiving or unarchiving a chat.
|
||||
//
|
||||
// The last message timestamp and last message key are optional and can be set to zero values (`time.Time{}` and `nil`).
|
||||
//
|
||||
// Archiving a chat will also unpin it automatically.
|
||||
func BuildArchive(target types.JID, archive bool, lastMessageTimestamp time.Time, lastMessageKey *waProto.MessageKey) PatchInfo {
|
||||
if lastMessageTimestamp.IsZero() {
|
||||
lastMessageTimestamp = time.Now()
|
||||
}
|
||||
archiveMutationInfo := MutationInfo{
|
||||
Index: []string{IndexArchive, target.String()},
|
||||
Version: 3,
|
||||
Value: &waProto.SyncActionValue{
|
||||
ArchiveChatAction: &waProto.ArchiveChatAction{
|
||||
Archived: &archive,
|
||||
MessageRange: &waProto.SyncActionMessageRange{
|
||||
LastMessageTimestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
||||
// TODO set LastSystemMessageTimestamp?
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if lastMessageKey != nil {
|
||||
archiveMutationInfo.Value.ArchiveChatAction.MessageRange.Messages = []*waProto.SyncActionMessage{{
|
||||
Key: lastMessageKey,
|
||||
Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
||||
}}
|
||||
}
|
||||
|
||||
mutations := []MutationInfo{archiveMutationInfo}
|
||||
if archive {
|
||||
mutations = append(mutations, newPinMutationInfo(target, false))
|
||||
}
|
||||
|
||||
result := PatchInfo{
|
||||
Type: WAPatchRegularLow,
|
||||
Mutations: mutations,
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (proc *Processor) EncodePatch(keyID []byte, state HashState, patchInfo PatchInfo) ([]byte, error) {
|
||||
keys, err := proc.getAppStateKey(keyID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get app state key details with key ID %x: %w", keyID, err)
|
||||
}
|
||||
|
||||
if patchInfo.Timestamp.IsZero() {
|
||||
patchInfo.Timestamp = time.Now()
|
||||
}
|
||||
|
||||
mutations := make([]*waProto.SyncdMutation, 0, len(patchInfo.Mutations))
|
||||
for _, mutationInfo := range patchInfo.Mutations {
|
||||
mutationInfo.Value.Timestamp = proto.Int64(patchInfo.Timestamp.UnixMilli())
|
||||
|
||||
indexBytes, err := json.Marshal(mutationInfo.Index)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal mutation index: %w", err)
|
||||
}
|
||||
|
||||
pbObj := &waProto.SyncActionData{
|
||||
Index: indexBytes,
|
||||
Value: mutationInfo.Value,
|
||||
Padding: []byte{},
|
||||
Version: &mutationInfo.Version,
|
||||
}
|
||||
|
||||
content, err := proto.Marshal(pbObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal mutation: %w", err)
|
||||
}
|
||||
|
||||
encryptedContent, err := cbcutil.Encrypt(keys.ValueEncryption, nil, content)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encrypt mutation: %w", err)
|
||||
}
|
||||
|
||||
valueMac := generateContentMAC(waProto.SyncdMutation_SET, encryptedContent, keyID, keys.ValueMAC)
|
||||
indexMac := concatAndHMAC(sha256.New, keys.Index, indexBytes)
|
||||
|
||||
mutations = append(mutations, &waProto.SyncdMutation{
|
||||
Operation: waProto.SyncdMutation_SET.Enum(),
|
||||
Record: &waProto.SyncdRecord{
|
||||
Index: &waProto.SyncdIndex{Blob: indexMac},
|
||||
Value: &waProto.SyncdValue{Blob: append(encryptedContent, valueMac...)},
|
||||
KeyId: &waProto.KeyId{Id: keyID},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
warn, err := state.updateHash(mutations, func(indexMAC []byte, _ int) ([]byte, error) {
|
||||
return proc.Store.AppState.GetAppStateMutationMAC(string(patchInfo.Type), indexMAC)
|
||||
})
|
||||
if len(warn) > 0 {
|
||||
proc.Log.Warnf("Warnings while updating hash for %s (sending new app state): %+v", patchInfo.Type, warn)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update state hash: %w", err)
|
||||
}
|
||||
|
||||
state.Version += 1
|
||||
|
||||
syncdPatch := &waProto.SyncdPatch{
|
||||
SnapshotMac: state.generateSnapshotMAC(patchInfo.Type, keys.SnapshotMAC),
|
||||
KeyId: &waProto.KeyId{Id: keyID},
|
||||
Mutations: mutations,
|
||||
}
|
||||
syncdPatch.PatchMac = generatePatchMAC(syncdPatch, patchInfo.Type, keys.PatchMAC, state.Version)
|
||||
|
||||
result, err := proto.Marshal(syncdPatch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal compiled patch: %w", err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
4
vendor/go.mau.fi/whatsmeow/appstate/hash.go
vendored
4
vendor/go.mau.fi/whatsmeow/appstate/hash.go
vendored
@ -77,14 +77,14 @@ func (hs *HashState) generateSnapshotMAC(name WAPatchName, key []byte) []byte {
|
||||
return concatAndHMAC(sha256.New, key, hs.Hash[:], uint64ToBytes(hs.Version), []byte(name))
|
||||
}
|
||||
|
||||
func generatePatchMAC(patch *waProto.SyncdPatch, name WAPatchName, key []byte) []byte {
|
||||
func generatePatchMAC(patch *waProto.SyncdPatch, name WAPatchName, key []byte, version uint64) []byte {
|
||||
dataToHash := make([][]byte, len(patch.GetMutations())+3)
|
||||
dataToHash[0] = patch.GetSnapshotMac()
|
||||
for i, mutation := range patch.Mutations {
|
||||
val := mutation.GetRecord().GetValue().GetBlob()
|
||||
dataToHash[i+1] = val[len(val)-32:]
|
||||
}
|
||||
dataToHash[len(dataToHash)-2] = uint64ToBytes(patch.GetVersion().GetVersion())
|
||||
dataToHash[len(dataToHash)-2] = uint64ToBytes(version)
|
||||
dataToHash[len(dataToHash)-1] = []byte(name)
|
||||
return concatAndHMAC(sha256.New, key, dataToHash...)
|
||||
}
|
||||
|
16
vendor/go.mau.fi/whatsmeow/appstate/keys.go
vendored
16
vendor/go.mau.fi/whatsmeow/appstate/keys.go
vendored
@ -35,6 +35,22 @@ const (
|
||||
// AllPatchNames contains all currently known patch state names.
|
||||
var AllPatchNames = [...]WAPatchName{WAPatchCriticalBlock, WAPatchCriticalUnblockLow, WAPatchRegularHigh, WAPatchRegular, WAPatchRegularLow}
|
||||
|
||||
// Constants for the first part of app state indexes.
|
||||
const (
|
||||
IndexMute = "mute"
|
||||
IndexPin = "pin_v1"
|
||||
IndexArchive = "archive"
|
||||
IndexContact = "contact"
|
||||
IndexClearChat = "clearChat"
|
||||
IndexDeleteChat = "deleteChat"
|
||||
IndexStar = "star"
|
||||
IndexDeleteMessageForMe = "deleteMessageForMe"
|
||||
IndexMarkChatAsRead = "markChatAsRead"
|
||||
IndexSettingPushName = "setting_pushName"
|
||||
IndexSettingUnarchiveChats = "setting_unarchiveChats"
|
||||
IndexUserStatusMute = "userStatusMute"
|
||||
)
|
||||
|
||||
type Processor struct {
|
||||
keyCache map[string]ExpandedAppStateKeys
|
||||
keyCacheLock sync.Mutex
|
||||
|
Reference in New Issue
Block a user