slidge-whatsapp 0.2.6__cp312-cp312-manylinux_2_36_aarch64.whl → 0.2.7__cp312-cp312-manylinux_2_36_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of slidge-whatsapp might be problematic. Click here for more details.
- slidge_whatsapp/event.go +8 -2
- slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.h +164 -164
- slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.so +0 -0
- slidge_whatsapp/generated/build.py +130 -130
- slidge_whatsapp/generated/whatsapp.c +1504 -1504
- slidge_whatsapp/generated/whatsapp.go +1021 -1021
- slidge_whatsapp/generated/whatsapp.py +1209 -1209
- slidge_whatsapp/generated/whatsapp_go.h +164 -164
- slidge_whatsapp/go.mod +6 -6
- slidge_whatsapp/go.sum +12 -18
- slidge_whatsapp/media/media.go +5 -1
- slidge_whatsapp/vendor/go.mau.fi/util/exhttp/json.go +1 -6
- slidge_whatsapp/vendor/go.mau.fi/util/exstrings/stringutil.go +76 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +38 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/binary/encoder.go +1 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +1 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/client.go +64 -27
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/connectionevents.go +8 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/download-to-file.go +19 -12
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/download.go +22 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +2 -2
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +33 -17
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/keepalive.go +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +198 -48
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +12 -7
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/extra.go +7 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/InstamadilloAddMessage.pb.go +983 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/InstamadilloAddMessage.proto +85 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/extra.go +3 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeActionLog/InstamadilloCoreTypeActionLog.pb.go +197 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeActionLog/InstamadilloCoreTypeActionLog.proto +13 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeAdminMessage/InstamadilloCoreTypeAdminMessage.pb.go +279 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeAdminMessage/InstamadilloCoreTypeAdminMessage.proto +21 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeCollection/InstamadilloCoreTypeCollection.pb.go +137 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeCollection/InstamadilloCoreTypeCollection.proto +10 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeLink/InstamadilloCoreTypeLink.pb.go +313 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeLink/InstamadilloCoreTypeLink.proto +27 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeMedia/InstamadilloCoreTypeMedia.pb.go +1299 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeMedia/InstamadilloCoreTypeMedia.proto +112 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeText/InstamadilloCoreTypeText.pb.go +514 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeText/InstamadilloCoreTypeText.proto +47 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/InstamadilloDeleteMessage.pb.go +123 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/InstamadilloDeleteMessage.proto +7 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/extra.go +3 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/InstamadilloSupplementMessage.pb.go +720 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/InstamadilloSupplementMessage.proto +59 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/extra.go +3 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloTransportPayload/InstamadilloTransportPayload.pb.go +365 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloTransportPayload/InstamadilloTransportPayload.proto +33 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloXmaContentRef/InstamadilloXmaContentRef.pb.go +1238 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloXmaContentRef/InstamadilloXmaContentRef.proto +105 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.pb.go +16 -4
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.proto +3 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/WACompanionReg.pb.go +16 -7
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/WACompanionReg.proto +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +2436 -1676
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +85 -7
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waLidMigrationSyncPayload/WAWebProtobufLidMigrationSyncPayload.pb.go +198 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waLidMigrationSyncPayload/WAWebProtobufLidMigrationSyncPayload.proto +14 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgTransport/extra.go +7 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +800 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +72 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +678 -441
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +20 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +11 -3
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +2 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +13 -7
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/reportingfields.json +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/reportingtoken.go +176 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +10 -2
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +32 -17
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +1 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/container.go +9 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/00-latest-schema.sql +4 -2
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/10-chat-db-lid-migration-ts.sql +2 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +2 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/events/events.go +5 -2
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/message.go +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +2 -0
- slidge_whatsapp/vendor/golang.org/x/net/http2/frame.go +8 -8
- slidge_whatsapp/vendor/modules.txt +20 -6
- {slidge_whatsapp-0.2.6.dist-info → slidge_whatsapp-0.2.7.dist-info}/METADATA +1 -1
- {slidge_whatsapp-0.2.6.dist-info → slidge_whatsapp-0.2.7.dist-info}/RECORD +87 -54
- {slidge_whatsapp-0.2.6.dist-info → slidge_whatsapp-0.2.7.dist-info}/LICENSE +0 -0
- {slidge_whatsapp-0.2.6.dist-info → slidge_whatsapp-0.2.7.dist-info}/WHEEL +0 -0
- {slidge_whatsapp-0.2.6.dist-info → slidge_whatsapp-0.2.7.dist-info}/entry_points.txt +0 -0
|
@@ -13,7 +13,7 @@ import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
func (cli *Client) handleCallEvent(node *waBinary.Node) {
|
|
16
|
-
defer cli.maybeDeferredAck(node)()
|
|
16
|
+
defer cli.maybeDeferredAck(cli.BackgroundEventCtx, node)()
|
|
17
17
|
|
|
18
18
|
if len(node.GetChildren()) != 1 {
|
|
19
19
|
cli.dispatchEvent(&events.UnknownCallEvent{Node: node})
|
|
@@ -21,6 +21,7 @@ import (
|
|
|
21
21
|
|
|
22
22
|
"github.com/gorilla/websocket"
|
|
23
23
|
"go.mau.fi/util/exhttp"
|
|
24
|
+
"go.mau.fi/util/exsync"
|
|
24
25
|
"go.mau.fi/util/random"
|
|
25
26
|
"golang.org/x/net/proxy"
|
|
26
27
|
|
|
@@ -39,12 +40,13 @@ import (
|
|
|
39
40
|
|
|
40
41
|
// EventHandler is a function that can handle events from WhatsApp.
|
|
41
42
|
type EventHandler func(evt any)
|
|
43
|
+
type EventHandlerWithSuccessStatus func(evt any) bool
|
|
42
44
|
type nodeHandler func(node *waBinary.Node)
|
|
43
45
|
|
|
44
46
|
var nextHandlerID uint32
|
|
45
47
|
|
|
46
48
|
type wrappedEventHandler struct {
|
|
47
|
-
fn
|
|
49
|
+
fn EventHandlerWithSuccessStatus
|
|
48
50
|
id uint32
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -66,7 +68,7 @@ type Client struct {
|
|
|
66
68
|
wsDialer *websocket.Dialer
|
|
67
69
|
|
|
68
70
|
isLoggedIn atomic.Bool
|
|
69
|
-
expectedDisconnect
|
|
71
|
+
expectedDisconnect *exsync.Event
|
|
70
72
|
EnableAutoReconnect bool
|
|
71
73
|
InitialAutoReconnect bool
|
|
72
74
|
LastSuccessfulConnect time.Time
|
|
@@ -96,6 +98,7 @@ type Client struct {
|
|
|
96
98
|
|
|
97
99
|
historySyncNotifications chan *waE2E.HistorySyncNotification
|
|
98
100
|
historySyncHandlerStarted atomic.Bool
|
|
101
|
+
ManualHistorySyncDownload bool
|
|
99
102
|
|
|
100
103
|
uploadPreKeysLock sync.Mutex
|
|
101
104
|
lastPreKeyUpload time.Time
|
|
@@ -159,6 +162,10 @@ type Client struct {
|
|
|
159
162
|
// Should SubscribePresence return an error if no privacy token is stored for the user?
|
|
160
163
|
ErrorOnSubscribePresenceWithoutToken bool
|
|
161
164
|
|
|
165
|
+
SendReportingTokens bool
|
|
166
|
+
|
|
167
|
+
BackgroundEventCtx context.Context
|
|
168
|
+
|
|
162
169
|
phoneLinkingCache *phoneLinkingCache
|
|
163
170
|
|
|
164
171
|
uniqueID string
|
|
@@ -175,7 +182,7 @@ type Client struct {
|
|
|
175
182
|
// separate library for all the non-e2ee-related stuff like logging in.
|
|
176
183
|
// The library is currently embedded in mautrix-meta (https://github.com/mautrix/meta), but may be separated later.
|
|
177
184
|
MessengerConfig *MessengerConfig
|
|
178
|
-
RefreshCAT func() error
|
|
185
|
+
RefreshCAT func(context.Context) error
|
|
179
186
|
}
|
|
180
187
|
|
|
181
188
|
type groupMetaCache struct {
|
|
@@ -219,18 +226,19 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
|
|
219
226
|
http: &http.Client{
|
|
220
227
|
Transport: (http.DefaultTransport.(*http.Transport)).Clone(),
|
|
221
228
|
},
|
|
222
|
-
proxy:
|
|
223
|
-
Store:
|
|
224
|
-
Log:
|
|
225
|
-
recvLog:
|
|
226
|
-
sendLog:
|
|
227
|
-
uniqueID:
|
|
228
|
-
responseWaiters:
|
|
229
|
-
eventHandlers:
|
|
230
|
-
messageRetries:
|
|
231
|
-
handlerQueue:
|
|
232
|
-
appStateProc:
|
|
233
|
-
socketWait:
|
|
229
|
+
proxy: http.ProxyFromEnvironment,
|
|
230
|
+
Store: deviceStore,
|
|
231
|
+
Log: log,
|
|
232
|
+
recvLog: log.Sub("Recv"),
|
|
233
|
+
sendLog: log.Sub("Send"),
|
|
234
|
+
uniqueID: fmt.Sprintf("%d.%d-", uniqueIDPrefix[0], uniqueIDPrefix[1]),
|
|
235
|
+
responseWaiters: make(map[string]chan<- *waBinary.Node),
|
|
236
|
+
eventHandlers: make([]wrappedEventHandler, 0, 1),
|
|
237
|
+
messageRetries: make(map[string]int),
|
|
238
|
+
handlerQueue: make(chan *waBinary.Node, handlerQueueSize),
|
|
239
|
+
appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")),
|
|
240
|
+
socketWait: make(chan struct{}),
|
|
241
|
+
expectedDisconnect: exsync.NewEvent(),
|
|
234
242
|
|
|
235
243
|
incomingRetryRequestCounter: make(map[incomingRetryKey]int),
|
|
236
244
|
|
|
@@ -248,6 +256,8 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
|
|
248
256
|
|
|
249
257
|
EnableAutoReconnect: true,
|
|
250
258
|
AutoTrustIdentity: true,
|
|
259
|
+
|
|
260
|
+
BackgroundEventCtx: context.Background(),
|
|
251
261
|
}
|
|
252
262
|
cli.nodeHandlers = map[string]nodeHandler{
|
|
253
263
|
"message": cli.handleEncryptedMessage,
|
|
@@ -411,6 +421,8 @@ func (cli *Client) WaitForConnection(timeout time.Duration) bool {
|
|
|
411
421
|
case <-ch:
|
|
412
422
|
case <-timeoutChan:
|
|
413
423
|
return false
|
|
424
|
+
case <-cli.expectedDisconnect.GetChan():
|
|
425
|
+
return false
|
|
414
426
|
}
|
|
415
427
|
cli.socketLock.RLock()
|
|
416
428
|
}
|
|
@@ -425,9 +437,16 @@ func (cli *Client) SetWSDialer(dialer *websocket.Dialer) {
|
|
|
425
437
|
// Connect connects the client to the WhatsApp web websocket. After connection, it will either
|
|
426
438
|
// authenticate if there's data in the device store, or emit a QREvent to set up a new link.
|
|
427
439
|
func (cli *Client) Connect() error {
|
|
428
|
-
|
|
440
|
+
if cli == nil {
|
|
441
|
+
return ErrClientIsNil
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
cli.socketLock.Lock()
|
|
445
|
+
defer cli.socketLock.Unlock()
|
|
446
|
+
|
|
447
|
+
err := cli.unlockedConnect()
|
|
429
448
|
if exhttp.IsNetworkError(err) && cli.InitialAutoReconnect && cli.EnableAutoReconnect {
|
|
430
|
-
cli.Log.Errorf("Initial connection failed but reconnecting in background")
|
|
449
|
+
cli.Log.Errorf("Initial connection failed but reconnecting in background (%v)", err)
|
|
431
450
|
go cli.dispatchEvent(&events.Disconnected{})
|
|
432
451
|
go cli.autoReconnect()
|
|
433
452
|
return nil
|
|
@@ -436,11 +455,13 @@ func (cli *Client) Connect() error {
|
|
|
436
455
|
}
|
|
437
456
|
|
|
438
457
|
func (cli *Client) connect() error {
|
|
439
|
-
if cli == nil {
|
|
440
|
-
return ErrClientIsNil
|
|
441
|
-
}
|
|
442
458
|
cli.socketLock.Lock()
|
|
443
459
|
defer cli.socketLock.Unlock()
|
|
460
|
+
|
|
461
|
+
return cli.unlockedConnect()
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
func (cli *Client) unlockedConnect() error {
|
|
444
465
|
if cli.socket != nil {
|
|
445
466
|
if !cli.socket.IsConnected() {
|
|
446
467
|
cli.unlockedDisconnect()
|
|
@@ -514,15 +535,15 @@ func (cli *Client) onDisconnect(ns *socket.NoiseSocket, remote bool) {
|
|
|
514
535
|
}
|
|
515
536
|
|
|
516
537
|
func (cli *Client) expectDisconnect() {
|
|
517
|
-
cli.expectedDisconnect.
|
|
538
|
+
cli.expectedDisconnect.Set()
|
|
518
539
|
}
|
|
519
540
|
|
|
520
541
|
func (cli *Client) resetExpectedDisconnect() {
|
|
521
|
-
cli.expectedDisconnect.
|
|
542
|
+
cli.expectedDisconnect.Clear()
|
|
522
543
|
}
|
|
523
544
|
|
|
524
545
|
func (cli *Client) isExpectedDisconnect() bool {
|
|
525
|
-
return cli.expectedDisconnect.
|
|
546
|
+
return cli.expectedDisconnect.IsSet()
|
|
526
547
|
}
|
|
527
548
|
|
|
528
549
|
func (cli *Client) autoReconnect() {
|
|
@@ -533,12 +554,17 @@ func (cli *Client) autoReconnect() {
|
|
|
533
554
|
autoReconnectDelay := time.Duration(cli.AutoReconnectErrors) * 2 * time.Second
|
|
534
555
|
cli.Log.Debugf("Automatically reconnecting after %v", autoReconnectDelay)
|
|
535
556
|
cli.AutoReconnectErrors++
|
|
536
|
-
|
|
557
|
+
if cli.expectedDisconnect.WaitTimeout(autoReconnectDelay) {
|
|
558
|
+
return
|
|
559
|
+
}
|
|
537
560
|
err := cli.connect()
|
|
538
561
|
if errors.Is(err, ErrAlreadyConnected) {
|
|
539
562
|
cli.Log.Debugf("Connect() said we're already connected after autoreconnect sleep")
|
|
540
563
|
return
|
|
541
564
|
} else if err != nil {
|
|
565
|
+
if cli.expectedDisconnect.IsSet() {
|
|
566
|
+
return
|
|
567
|
+
}
|
|
542
568
|
cli.Log.Errorf("Error reconnecting after autoreconnect sleep: %v", err)
|
|
543
569
|
if cli.AutoReconnectHook != nil && !cli.AutoReconnectHook(err) {
|
|
544
570
|
cli.Log.Debugf("AutoReconnectHook returned false, not reconnecting")
|
|
@@ -567,10 +593,11 @@ func (cli *Client) IsConnected() bool {
|
|
|
567
593
|
// This will not emit any events, the Disconnected event is only used when the
|
|
568
594
|
// connection is closed by the server or a network error.
|
|
569
595
|
func (cli *Client) Disconnect() {
|
|
570
|
-
if cli == nil
|
|
596
|
+
if cli == nil {
|
|
571
597
|
return
|
|
572
598
|
}
|
|
573
599
|
cli.socketLock.Lock()
|
|
600
|
+
cli.expectDisconnect()
|
|
574
601
|
cli.unlockedDisconnect()
|
|
575
602
|
cli.socketLock.Unlock()
|
|
576
603
|
cli.clearDelayedMessageRequests()
|
|
@@ -657,6 +684,13 @@ func (cli *Client) Logout(ctx context.Context) error {
|
|
|
657
684
|
// // Handle event and access mycli.WAClient
|
|
658
685
|
// }
|
|
659
686
|
func (cli *Client) AddEventHandler(handler EventHandler) uint32 {
|
|
687
|
+
return cli.AddEventHandlerWithSuccessStatus(func(evt any) bool {
|
|
688
|
+
handler(evt)
|
|
689
|
+
return true
|
|
690
|
+
})
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
func (cli *Client) AddEventHandlerWithSuccessStatus(handler EventHandlerWithSuccessStatus) uint32 {
|
|
660
694
|
nextID := atomic.AddUint32(&nextHandlerID, 1)
|
|
661
695
|
cli.eventHandlersLock.Lock()
|
|
662
696
|
cli.eventHandlers = append(cli.eventHandlers, wrappedEventHandler{handler, nextID})
|
|
@@ -803,7 +837,7 @@ func (cli *Client) sendNode(node waBinary.Node) error {
|
|
|
803
837
|
return err
|
|
804
838
|
}
|
|
805
839
|
|
|
806
|
-
func (cli *Client) dispatchEvent(evt any) {
|
|
840
|
+
func (cli *Client) dispatchEvent(evt any) (handlerFailed bool) {
|
|
807
841
|
cli.eventHandlersLock.RLock()
|
|
808
842
|
defer func() {
|
|
809
843
|
cli.eventHandlersLock.RUnlock()
|
|
@@ -813,8 +847,11 @@ func (cli *Client) dispatchEvent(evt any) {
|
|
|
813
847
|
}
|
|
814
848
|
}()
|
|
815
849
|
for _, handler := range cli.eventHandlers {
|
|
816
|
-
handler.fn(evt)
|
|
850
|
+
if !handler.fn(evt) {
|
|
851
|
+
return true
|
|
852
|
+
}
|
|
817
853
|
}
|
|
854
|
+
return false
|
|
818
855
|
}
|
|
819
856
|
|
|
820
857
|
// ParseWebMessage parses a WebMessageInfo object into *events.Message to match what real-time messages have.
|
|
@@ -17,7 +17,7 @@ import (
|
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
func (cli *Client) handleStreamError(node *waBinary.Node) {
|
|
20
|
-
ctx :=
|
|
20
|
+
ctx := cli.BackgroundEventCtx
|
|
21
21
|
cli.isLoggedIn.Store(false)
|
|
22
22
|
cli.clearResponseWaiters(node)
|
|
23
23
|
code, _ := node.Attrs["code"].(string)
|
|
@@ -58,7 +58,7 @@ func (cli *Client) handleStreamError(node *waBinary.Node) {
|
|
|
58
58
|
cli.Log.Infof("Got %s stream error, refreshing CAT before reconnecting...", code)
|
|
59
59
|
cli.socketLock.RLock()
|
|
60
60
|
defer cli.socketLock.RUnlock()
|
|
61
|
-
err := cli.RefreshCAT()
|
|
61
|
+
err := cli.RefreshCAT(ctx)
|
|
62
62
|
if err != nil {
|
|
63
63
|
cli.Log.Errorf("Failed to refresh CAT: %v", err)
|
|
64
64
|
cli.expectDisconnect()
|
|
@@ -94,7 +94,7 @@ func (cli *Client) handleIB(node *waBinary.Node) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
func (cli *Client) handleConnectFailure(node *waBinary.Node) {
|
|
97
|
-
ctx :=
|
|
97
|
+
ctx := cli.BackgroundEventCtx
|
|
98
98
|
ag := node.AttrGetter()
|
|
99
99
|
reason := events.ConnectFailureReason(ag.Int("reason"))
|
|
100
100
|
message := ag.OptionalString("message")
|
|
@@ -136,7 +136,7 @@ func (cli *Client) handleConnectFailure(node *waBinary.Node) {
|
|
|
136
136
|
go cli.dispatchEvent(&events.ClientOutdated{})
|
|
137
137
|
} else if reason == events.ConnectFailureCATInvalid || reason == events.ConnectFailureCATExpired {
|
|
138
138
|
cli.Log.Infof("Got %d/%s connect failure, refreshing CAT before reconnecting...", int(reason), message)
|
|
139
|
-
err := cli.RefreshCAT()
|
|
139
|
+
err := cli.RefreshCAT(ctx)
|
|
140
140
|
if err != nil {
|
|
141
141
|
cli.Log.Errorf("Failed to refresh CAT: %v", err)
|
|
142
142
|
cli.expectDisconnect()
|
|
@@ -151,7 +151,7 @@ func (cli *Client) handleConnectFailure(node *waBinary.Node) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
func (cli *Client) handleConnectSuccess(node *waBinary.Node) {
|
|
154
|
-
ctx :=
|
|
154
|
+
ctx := cli.BackgroundEventCtx
|
|
155
155
|
cli.Log.Infof("Successfully authenticated")
|
|
156
156
|
cli.LastSuccessfulConnect = time.Now()
|
|
157
157
|
cli.AutoReconnectErrors = 0
|
|
@@ -165,8 +165,10 @@ func (cli *Client) handleConnectSuccess(node *waBinary.Node) {
|
|
|
165
165
|
} else {
|
|
166
166
|
cli.Log.Infof("Updated LID to %s", cli.Store.LID)
|
|
167
167
|
}
|
|
168
|
-
cli.StoreLIDPNMapping(ctx, cli.Store.GetLID(), cli.Store.GetJID())
|
|
169
168
|
}
|
|
169
|
+
// Some users are missing their own LID-PN mapping even though it's already in the device table,
|
|
170
|
+
// so do this unconditionally for a few months to ensure everyone gets the row.
|
|
171
|
+
cli.StoreLIDPNMapping(ctx, cli.Store.GetLID(), cli.Store.GetJID())
|
|
170
172
|
go func() {
|
|
171
173
|
if dbCount, err := cli.Store.PreKeys.UploadedPreKeyCount(ctx); err != nil {
|
|
172
174
|
cli.Log.Errorf("Failed to get number of prekeys in database: %v", err)
|
|
@@ -94,8 +94,13 @@ func (cli *Client) DownloadMediaWithPathToFile(
|
|
|
94
94
|
// TODO omit hash for unencrypted media?
|
|
95
95
|
mediaURL := fmt.Sprintf("https://%s%s&hash=%s&mms-type=%s&__wa-mms=", host.Hostname, directPath, base64.URLEncoding.EncodeToString(encFileHash), mmsType)
|
|
96
96
|
err = cli.downloadAndDecryptToFile(ctx, mediaURL, mediaKey, mediaType, fileLength, encFileHash, fileHash, file)
|
|
97
|
-
if err == nil ||
|
|
98
|
-
errors.Is(err,
|
|
97
|
+
if err == nil ||
|
|
98
|
+
errors.Is(err, ErrFileLengthMismatch) ||
|
|
99
|
+
errors.Is(err, ErrInvalidMediaSHA256) ||
|
|
100
|
+
errors.Is(err, ErrMediaDownloadFailedWith403) ||
|
|
101
|
+
errors.Is(err, ErrMediaDownloadFailedWith404) ||
|
|
102
|
+
errors.Is(err, ErrMediaDownloadFailedWith410) ||
|
|
103
|
+
errors.Is(err, context.Canceled) {
|
|
99
104
|
return err
|
|
100
105
|
} else if i >= len(mediaConn.Hosts)-1 {
|
|
101
106
|
return fmt.Errorf("failed to download media from last host: %w", err)
|
|
@@ -127,16 +132,18 @@ func (cli *Client) downloadAndDecryptToFile(
|
|
|
127
132
|
return fmt.Errorf("failed to seek to start of file after validating mac: %w", err)
|
|
128
133
|
} else if err = cbcutil.DecryptFile(cipherKey, iv, file); err != nil {
|
|
129
134
|
return fmt.Errorf("failed to decrypt file: %w", err)
|
|
130
|
-
} else if
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
} else if ReturnDownloadWarnings {
|
|
136
|
+
if info, err := file.Stat(); err != nil {
|
|
137
|
+
return fmt.Errorf("failed to stat file: %w", err)
|
|
138
|
+
} else if fileLength >= 0 && info.Size() != int64(fileLength) {
|
|
139
|
+
return fmt.Errorf("%w: expected %d, got %d", ErrFileLengthMismatch, fileLength, info.Size())
|
|
140
|
+
} else if _, err = file.Seek(0, io.SeekStart); err != nil {
|
|
141
|
+
return fmt.Errorf("failed to seek to start of file after decrypting: %w", err)
|
|
142
|
+
} else if _, err = io.Copy(hasher, file); err != nil {
|
|
143
|
+
return fmt.Errorf("failed to hash file: %w", err)
|
|
144
|
+
} else if !hmac.Equal(fileSHA256, hasher.Sum(nil)) {
|
|
145
|
+
return ErrInvalidMediaSHA256
|
|
146
|
+
}
|
|
140
147
|
}
|
|
141
148
|
return nil
|
|
142
149
|
}
|
|
@@ -130,6 +130,8 @@ var mediaTypeToMMSType = map[MediaType]string{
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
// DownloadAny loops through the downloadable parts of the given message and downloads the first non-nil item.
|
|
133
|
+
//
|
|
134
|
+
// Deprecated: it's recommended to find the specific message type you want to download manually and use the Download method instead.
|
|
133
135
|
func (cli *Client) DownloadAny(ctx context.Context, msg *waE2E.Message) (data []byte, err error) {
|
|
134
136
|
if msg == nil {
|
|
135
137
|
return nil, ErrNothingDownloadableFound
|
|
@@ -161,6 +163,10 @@ func getSize(msg DownloadableMessage) int {
|
|
|
161
163
|
}
|
|
162
164
|
}
|
|
163
165
|
|
|
166
|
+
// ReturnDownloadWarnings controls whether the Download function returns non-fatal validation warnings.
|
|
167
|
+
// Currently, these include [ErrFileLengthMismatch] and [ErrInvalidMediaSHA256].
|
|
168
|
+
var ReturnDownloadWarnings = true
|
|
169
|
+
|
|
164
170
|
// DownloadThumbnail downloads a thumbnail from a message.
|
|
165
171
|
//
|
|
166
172
|
// This is primarily intended for downloading link preview thumbnails, which are in ExtendedTextMessage:
|
|
@@ -257,8 +263,13 @@ func (cli *Client) DownloadMediaWithPath(
|
|
|
257
263
|
// TODO omit hash for unencrypted media?
|
|
258
264
|
mediaURL := fmt.Sprintf("https://%s%s&hash=%s&mms-type=%s&__wa-mms=", host.Hostname, directPath, base64.URLEncoding.EncodeToString(encFileHash), mmsType)
|
|
259
265
|
data, err = cli.downloadAndDecrypt(ctx, mediaURL, mediaKey, mediaType, fileLength, encFileHash, fileHash)
|
|
260
|
-
if err == nil ||
|
|
261
|
-
errors.Is(err,
|
|
266
|
+
if err == nil ||
|
|
267
|
+
errors.Is(err, ErrFileLengthMismatch) ||
|
|
268
|
+
errors.Is(err, ErrInvalidMediaSHA256) ||
|
|
269
|
+
errors.Is(err, ErrMediaDownloadFailedWith403) ||
|
|
270
|
+
errors.Is(err, ErrMediaDownloadFailedWith404) ||
|
|
271
|
+
errors.Is(err, ErrMediaDownloadFailedWith410) ||
|
|
272
|
+
errors.Is(err, context.Canceled) {
|
|
262
273
|
return
|
|
263
274
|
} else if i >= len(mediaConn.Hosts)-1 {
|
|
264
275
|
return nil, fmt.Errorf("failed to download media from last host: %w", err)
|
|
@@ -288,10 +299,12 @@ func (cli *Client) downloadAndDecrypt(
|
|
|
288
299
|
|
|
289
300
|
} else if data, err = cbcutil.Decrypt(cipherKey, iv, ciphertext); err != nil {
|
|
290
301
|
err = fmt.Errorf("failed to decrypt file: %w", err)
|
|
291
|
-
} else if
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
} else if ReturnDownloadWarnings {
|
|
303
|
+
if fileLength >= 0 && len(data) != fileLength {
|
|
304
|
+
err = fmt.Errorf("%w: expected %d, got %d", ErrFileLengthMismatch, fileLength, len(data))
|
|
305
|
+
} else if len(fileSHA256) == 32 && sha256.Sum256(data) != *(*[32]byte)(fileSHA256) {
|
|
306
|
+
err = ErrInvalidMediaSHA256
|
|
307
|
+
}
|
|
295
308
|
}
|
|
296
309
|
return
|
|
297
310
|
}
|
|
@@ -302,6 +315,9 @@ func getMediaKeys(mediaKey []byte, appInfo MediaType) (iv, cipherKey, macKey, re
|
|
|
302
315
|
}
|
|
303
316
|
|
|
304
317
|
func shouldRetryMediaDownload(err error) bool {
|
|
318
|
+
if errors.Is(err, context.Canceled) {
|
|
319
|
+
return false
|
|
320
|
+
}
|
|
305
321
|
var netErr net.Error
|
|
306
322
|
var httpErr DownloadHTTPError
|
|
307
323
|
return errors.As(err, &netErr) ||
|
|
@@ -752,8 +752,8 @@ func (cli *Client) parseGroupChange(node *waBinary.Node) (*events.GroupInfo, err
|
|
|
752
752
|
for _, child := range node.GetChildren() {
|
|
753
753
|
cag := child.AttrGetter()
|
|
754
754
|
if child.Tag == "add" || child.Tag == "remove" || child.Tag == "promote" || child.Tag == "demote" {
|
|
755
|
-
evt.PrevParticipantVersionID = cag.
|
|
756
|
-
evt.ParticipantVersionID = cag.
|
|
755
|
+
evt.PrevParticipantVersionID = cag.OptionalString("prev_v_id")
|
|
756
|
+
evt.ParticipantVersionID = cag.OptionalString("v_id")
|
|
757
757
|
}
|
|
758
758
|
switch child.Tag {
|
|
759
759
|
case "add":
|
|
@@ -67,7 +67,7 @@ func (int *DangerousInternalClient) RequestAppStateKeys(ctx context.Context, raw
|
|
|
67
67
|
int.c.requestAppStateKeys(ctx, rawKeyIDs)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
func (int *DangerousInternalClient) HandleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) bool {
|
|
70
|
+
func (int *DangerousInternalClient) HandleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handled, handlerFailed bool) {
|
|
71
71
|
return int.c.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -99,6 +99,14 @@ func (int *DangerousInternalClient) GetOwnLID() types.JID {
|
|
|
99
99
|
return int.c.getOwnLID()
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
func (int *DangerousInternalClient) Connect() error {
|
|
103
|
+
return int.c.connect()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func (int *DangerousInternalClient) UnlockedConnect() error {
|
|
107
|
+
return int.c.unlockedConnect()
|
|
108
|
+
}
|
|
109
|
+
|
|
102
110
|
func (int *DangerousInternalClient) OnDisconnect(ns *socket.NoiseSocket, remote bool) {
|
|
103
111
|
int.c.onDisconnect(ns, remote)
|
|
104
112
|
}
|
|
@@ -139,8 +147,8 @@ func (int *DangerousInternalClient) SendNode(node waBinary.Node) error {
|
|
|
139
147
|
return int.c.sendNode(node)
|
|
140
148
|
}
|
|
141
149
|
|
|
142
|
-
func (int *DangerousInternalClient) DispatchEvent(evt any) {
|
|
143
|
-
int.c.dispatchEvent(evt)
|
|
150
|
+
func (int *DangerousInternalClient) DispatchEvent(evt any) (handlerFailed bool) {
|
|
151
|
+
return int.c.dispatchEvent(evt)
|
|
144
152
|
}
|
|
145
153
|
|
|
146
154
|
func (int *DangerousInternalClient) HandleStreamError(node *waBinary.Node) {
|
|
@@ -271,16 +279,16 @@ func (int *DangerousInternalClient) ParseMessageInfo(node *waBinary.Node) (*type
|
|
|
271
279
|
return int.c.parseMessageInfo(node)
|
|
272
280
|
}
|
|
273
281
|
|
|
274
|
-
func (int *DangerousInternalClient) HandlePlaintextMessage(ctx context.Context, info *types.MessageInfo, node *waBinary.Node) {
|
|
275
|
-
int.c.handlePlaintextMessage(ctx, info, node)
|
|
282
|
+
func (int *DangerousInternalClient) HandlePlaintextMessage(ctx context.Context, info *types.MessageInfo, node *waBinary.Node) bool {
|
|
283
|
+
return int.c.handlePlaintextMessage(ctx, info, node)
|
|
276
284
|
}
|
|
277
285
|
|
|
278
286
|
func (int *DangerousInternalClient) MigrateSessionStore(ctx context.Context, pn, lid types.JID) {
|
|
279
287
|
int.c.migrateSessionStore(ctx, pn, lid)
|
|
280
288
|
}
|
|
281
289
|
|
|
282
|
-
func (int *DangerousInternalClient) DecryptMessages(ctx context.Context, info *types.MessageInfo, node *waBinary.Node) {
|
|
283
|
-
int.c.decryptMessages(ctx, info, node)
|
|
290
|
+
func (int *DangerousInternalClient) DecryptMessages(ctx context.Context, info *types.MessageInfo, node *waBinary.Node) (handlerFailed bool) {
|
|
291
|
+
return int.c.decryptMessages(ctx, info, node)
|
|
284
292
|
}
|
|
285
293
|
|
|
286
294
|
func (int *DangerousInternalClient) ClearUntrustedIdentity(ctx context.Context, target types.JID) error {
|
|
@@ -307,10 +315,6 @@ func (int *DangerousInternalClient) HandleHistorySyncNotificationLoop() {
|
|
|
307
315
|
int.c.handleHistorySyncNotificationLoop()
|
|
308
316
|
}
|
|
309
317
|
|
|
310
|
-
func (int *DangerousInternalClient) HandleHistorySyncNotification(ctx context.Context, notif *waE2E.HistorySyncNotification) {
|
|
311
|
-
int.c.handleHistorySyncNotification(ctx, notif)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
318
|
func (int *DangerousInternalClient) HandleAppStateSyncKeyShare(ctx context.Context, keys *waE2E.AppStateSyncKeyShare) {
|
|
315
319
|
int.c.handleAppStateSyncKeyShare(ctx, keys)
|
|
316
320
|
}
|
|
@@ -335,8 +339,8 @@ func (int *DangerousInternalClient) StoreHistoricalMessageSecrets(ctx context.Co
|
|
|
335
339
|
int.c.storeHistoricalMessageSecrets(ctx, conversations)
|
|
336
340
|
}
|
|
337
341
|
|
|
338
|
-
func (int *DangerousInternalClient) HandleDecryptedMessage(ctx context.Context, info *types.MessageInfo, msg *waE2E.Message, retryCount int) {
|
|
339
|
-
int.c.handleDecryptedMessage(ctx, info, msg, retryCount)
|
|
342
|
+
func (int *DangerousInternalClient) HandleDecryptedMessage(ctx context.Context, info *types.MessageInfo, msg *waE2E.Message, retryCount int) bool {
|
|
343
|
+
return int.c.handleDecryptedMessage(ctx, info, msg, retryCount)
|
|
340
344
|
}
|
|
341
345
|
|
|
342
346
|
func (int *DangerousInternalClient) SendProtocolMessageReceipt(id types.MessageID, msgType types.ReceiptType) {
|
|
@@ -491,8 +495,8 @@ func (int *DangerousInternalClient) ParseReceipt(node *waBinary.Node) (*events.R
|
|
|
491
495
|
return int.c.parseReceipt(node)
|
|
492
496
|
}
|
|
493
497
|
|
|
494
|
-
func (int *DangerousInternalClient) MaybeDeferredAck(node *waBinary.Node) func() {
|
|
495
|
-
return int.c.maybeDeferredAck(node)
|
|
498
|
+
func (int *DangerousInternalClient) MaybeDeferredAck(ctx context.Context, node *waBinary.Node) func(...*bool) {
|
|
499
|
+
return int.c.maybeDeferredAck(ctx, node)
|
|
496
500
|
}
|
|
497
501
|
|
|
498
502
|
func (int *DangerousInternalClient) SendAck(node *waBinary.Node) {
|
|
@@ -567,6 +571,10 @@ func (int *DangerousInternalClient) DelayedRequestMessageFromPhone(info *types.M
|
|
|
567
571
|
int.c.delayedRequestMessageFromPhone(info)
|
|
568
572
|
}
|
|
569
573
|
|
|
574
|
+
func (int *DangerousInternalClient) ImmediateRequestMessageFromPhone(ctx context.Context, info *types.MessageInfo) {
|
|
575
|
+
int.c.immediateRequestMessageFromPhone(ctx, info)
|
|
576
|
+
}
|
|
577
|
+
|
|
570
578
|
func (int *DangerousInternalClient) ClearDelayedMessageRequests() {
|
|
571
579
|
int.c.clearDelayedMessageRequests()
|
|
572
580
|
}
|
|
@@ -603,8 +611,8 @@ func (int *DangerousInternalClient) SendNewsletter(to types.JID, id types.Messag
|
|
|
603
611
|
return int.c.sendNewsletter(to, id, message, mediaID, timings)
|
|
604
612
|
}
|
|
605
613
|
|
|
606
|
-
func (int *DangerousInternalClient) SendGroup(ctx context.Context, to types.JID, participants []types.JID, id types.MessageID, message *waE2E.Message, timings *MessageDebugTimings, extraParams nodeExtraParams) (string, []byte, error) {
|
|
607
|
-
return int.c.sendGroup(ctx, to, participants, id, message, timings, extraParams)
|
|
614
|
+
func (int *DangerousInternalClient) SendGroup(ctx context.Context, ownID, to types.JID, participants []types.JID, id types.MessageID, message *waE2E.Message, timings *MessageDebugTimings, extraParams nodeExtraParams) (string, []byte, error) {
|
|
615
|
+
return int.c.sendGroup(ctx, ownID, to, participants, id, message, timings, extraParams)
|
|
608
616
|
}
|
|
609
617
|
|
|
610
618
|
func (int *DangerousInternalClient) SendPeerMessage(ctx context.Context, to types.JID, id types.MessageID, message *waE2E.Message, timings *MessageDebugTimings) ([]byte, error) {
|
|
@@ -678,3 +686,11 @@ func (int *DangerousInternalClient) Usync(ctx context.Context, jids []types.JID,
|
|
|
678
686
|
func (int *DangerousInternalClient) ParseBlocklist(node *waBinary.Node) *types.Blocklist {
|
|
679
687
|
return int.c.parseBlocklist(node)
|
|
680
688
|
}
|
|
689
|
+
|
|
690
|
+
func (int *DangerousInternalClient) ShouldIncludeReportingToken(message *waE2E.Message) bool {
|
|
691
|
+
return int.c.shouldIncludeReportingToken(message)
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
func (int *DangerousInternalClient) GetMessageReportingToken(msgProtobuf []byte, msg *waE2E.Message, senderJID, remoteJID types.JID, messageID types.MessageID) waBinary.Node {
|
|
695
|
+
return int.c.getMessageReportingToken(msgProtobuf, msg, senderJID, remoteJID, messageID)
|
|
696
|
+
}
|
|
@@ -46,6 +46,7 @@ func (cli *Client) keepAliveLoop(ctx context.Context) {
|
|
|
46
46
|
if cli.EnableAutoReconnect && time.Since(lastSuccess) > KeepAliveMaxFailTime {
|
|
47
47
|
cli.Log.Debugf("Forcing reconnect due to keepalive failure")
|
|
48
48
|
cli.Disconnect()
|
|
49
|
+
cli.resetExpectedDisconnect()
|
|
49
50
|
go cli.autoReconnect()
|
|
50
51
|
}
|
|
51
52
|
} else {
|