slidge-whatsapp 0.3.1__cp313-cp313-manylinux_2_36_aarch64.whl → 0.3.4__cp313-cp313-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/generated/_whatsapp.cpython-313-aarch64-linux-gnu.h +175 -175
- slidge_whatsapp/generated/_whatsapp.cpython-313-aarch64-linux-gnu.so +0 -0
- slidge_whatsapp/generated/build.py +141 -141
- slidge_whatsapp/generated/go.py +1 -1
- slidge_whatsapp/generated/whatsapp.c +1423 -1423
- slidge_whatsapp/generated/whatsapp.go +1230 -1230
- slidge_whatsapp/generated/whatsapp.py +1337 -1337
- slidge_whatsapp/generated/whatsapp_go.h +175 -175
- slidge_whatsapp/go.mod +9 -9
- slidge_whatsapp/go.sum +18 -18
- slidge_whatsapp/vendor/go.mau.fi/libsignal/session/SessionCipher.go +7 -2
- slidge_whatsapp/vendor/go.mau.fi/util/dbutil/module.go +2 -1
- slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgradetable.go +3 -0
- slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncmap.go +48 -7
- slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncset.go +13 -0
- slidge_whatsapp/vendor/go.mau.fi/util/jsontime/helpers.go +16 -5
- slidge_whatsapp/vendor/go.mau.fi/util/jsontime/integer.go +27 -12
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +39 -28
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +17 -2
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +2 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +18 -6
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +40 -16
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +24 -21
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/prekeys.go +21 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +3213 -2851
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +108 -74
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +7 -3
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +7 -3
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +1 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +35 -23
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +5 -3
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +47 -16
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +4 -10
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +28 -42
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +33 -32
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +1 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/noop.go +5 -1
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sessioncache.go +125 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/signal.go +8 -0
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +34 -11
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +5 -3
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/jid.go +24 -9
- slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +12 -1
- slidge_whatsapp/vendor/golang.org/x/crypto/curve25519/curve25519.go +7 -4
- slidge_whatsapp/vendor/golang.org/x/net/http2/config.go +11 -6
- slidge_whatsapp/vendor/golang.org/x/net/http2/config_go125.go +15 -0
- slidge_whatsapp/vendor/golang.org/x/net/http2/config_go126.go +15 -0
- slidge_whatsapp/vendor/golang.org/x/net/http2/frame.go +24 -1
- slidge_whatsapp/vendor/golang.org/x/net/http2/http2.go +0 -1
- slidge_whatsapp/vendor/golang.org/x/net/http2/server.go +35 -26
- slidge_whatsapp/vendor/golang.org/x/net/http2/transport.go +4 -2
- slidge_whatsapp/vendor/golang.org/x/net/http2/writesched.go +2 -0
- slidge_whatsapp/vendor/golang.org/x/net/http2/{writesched_priority.go → writesched_priority_rfc7540.go} +52 -52
- slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go +209 -0
- slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_roundrobin.go +1 -1
- slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/request.go +2 -2
- slidge_whatsapp/vendor/golang.org/x/net/internal/socks/socks.go +1 -1
- slidge_whatsapp/vendor/golang.org/x/sys/unix/affinity_linux.go +9 -0
- slidge_whatsapp/vendor/golang.org/x/sys/unix/fdset.go +1 -3
- slidge_whatsapp/vendor/golang.org/x/sys/unix/ifreq_linux.go +1 -3
- slidge_whatsapp/vendor/golang.org/x/sys/unix/mkall.sh +1 -0
- slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_linux.go +1 -3
- slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_netbsd.go +17 -0
- slidge_whatsapp/vendor/golang.org/x/sys/windows/syscall_windows.go +2 -0
- slidge_whatsapp/vendor/golang.org/x/sys/windows/types_windows.go +16 -0
- slidge_whatsapp/vendor/golang.org/x/sys/windows/zsyscall_windows.go +18 -0
- slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/core.go +2 -9
- slidge_whatsapp/vendor/modules.txt +10 -10
- {slidge_whatsapp-0.3.1.dist-info → slidge_whatsapp-0.3.4.dist-info}/METADATA +1 -1
- {slidge_whatsapp-0.3.1.dist-info → slidge_whatsapp-0.3.4.dist-info}/RECORD +74 -70
- {slidge_whatsapp-0.3.1.dist-info → slidge_whatsapp-0.3.4.dist-info}/WHEEL +0 -0
- {slidge_whatsapp-0.3.1.dist-info → slidge_whatsapp-0.3.4.dist-info}/entry_points.txt +0 -0
- {slidge_whatsapp-0.3.1.dist-info → slidge_whatsapp-0.3.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -10,12 +10,19 @@ import (
|
|
|
10
10
|
"time"
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
+
func zeroSafeUnixToTime(val int64, fn func(int64) time.Time) time.Time {
|
|
14
|
+
if val == 0 {
|
|
15
|
+
return time.Time{}
|
|
16
|
+
}
|
|
17
|
+
return fn(val)
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
func UM(time time.Time) UnixMilli {
|
|
14
21
|
return UnixMilli{Time: time}
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
func UMInt(ts int64) UnixMilli {
|
|
18
|
-
return UM(time.UnixMilli
|
|
25
|
+
return UM(zeroSafeUnixToTime(ts, time.UnixMilli))
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
func UnixMilliNow() UnixMilli {
|
|
@@ -26,8 +33,8 @@ func UMicro(time time.Time) UnixMicro {
|
|
|
26
33
|
return UnixMicro{Time: time}
|
|
27
34
|
}
|
|
28
35
|
|
|
29
|
-
func
|
|
30
|
-
return UMicro(time.UnixMicro
|
|
36
|
+
func UMicroInt(ts int64) UnixMicro {
|
|
37
|
+
return UMicro(zeroSafeUnixToTime(ts, time.UnixMicro))
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
func UnixMicroNow() UnixMicro {
|
|
@@ -39,7 +46,9 @@ func UN(time time.Time) UnixNano {
|
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
func UNInt(ts int64) UnixNano {
|
|
42
|
-
return UN(
|
|
49
|
+
return UN(zeroSafeUnixToTime(ts, func(i int64) time.Time {
|
|
50
|
+
return time.Unix(0, i)
|
|
51
|
+
}))
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
func UnixNanoNow() UnixNano {
|
|
@@ -51,7 +60,9 @@ func U(time time.Time) Unix {
|
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
func UInt(ts int64) Unix {
|
|
54
|
-
return U(
|
|
63
|
+
return U(zeroSafeUnixToTime(ts, func(i int64) time.Time {
|
|
64
|
+
return time.Unix(i, 0)
|
|
65
|
+
}))
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
func UnixNow() Unix {
|
|
@@ -57,6 +57,13 @@ func anyIntegerToTime(src any, unixConv func(int64) time.Time, into *time.Time)
|
|
|
57
57
|
return nil
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
func zeroSafeUnix(t time.Time, method func(time.Time) int64) int64 {
|
|
61
|
+
if t.IsZero() {
|
|
62
|
+
return 0
|
|
63
|
+
}
|
|
64
|
+
return method(t)
|
|
65
|
+
}
|
|
66
|
+
|
|
60
67
|
var _ sql.Scanner = &UnixMilli{}
|
|
61
68
|
var _ driver.Valuer = UnixMilli{}
|
|
62
69
|
|
|
@@ -65,9 +72,6 @@ type UnixMilli struct {
|
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
func (um UnixMilli) MarshalJSON() ([]byte, error) {
|
|
68
|
-
if um.IsZero() {
|
|
69
|
-
return []byte{'0'}, nil
|
|
70
|
-
}
|
|
71
75
|
return json.Marshal(um.UnixMilli())
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -83,6 +87,11 @@ func (um *UnixMilli) Scan(src any) error {
|
|
|
83
87
|
return anyIntegerToTime(src, time.UnixMilli, &um.Time)
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
func (um UnixMilli) Unix() int64 { return zeroSafeUnix(um.Time, time.Time.Unix) }
|
|
91
|
+
func (um UnixMilli) UnixMilli() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMilli) }
|
|
92
|
+
func (um UnixMilli) UnixMicro() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMicro) }
|
|
93
|
+
func (um UnixMilli) UnixNano() int64 { return zeroSafeUnix(um.Time, time.Time.UnixNano) }
|
|
94
|
+
|
|
86
95
|
var _ sql.Scanner = &UnixMicro{}
|
|
87
96
|
var _ driver.Valuer = UnixMicro{}
|
|
88
97
|
|
|
@@ -91,9 +100,6 @@ type UnixMicro struct {
|
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
func (um UnixMicro) MarshalJSON() ([]byte, error) {
|
|
94
|
-
if um.IsZero() {
|
|
95
|
-
return []byte{'0'}, nil
|
|
96
|
-
}
|
|
97
103
|
return json.Marshal(um.UnixMicro())
|
|
98
104
|
}
|
|
99
105
|
|
|
@@ -109,6 +115,11 @@ func (um *UnixMicro) Scan(src any) error {
|
|
|
109
115
|
return anyIntegerToTime(src, time.UnixMicro, &um.Time)
|
|
110
116
|
}
|
|
111
117
|
|
|
118
|
+
func (um UnixMicro) Unix() int64 { return zeroSafeUnix(um.Time, time.Time.Unix) }
|
|
119
|
+
func (um UnixMicro) UnixMilli() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMilli) }
|
|
120
|
+
func (um UnixMicro) UnixMicro() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMicro) }
|
|
121
|
+
func (um UnixMicro) UnixNano() int64 { return zeroSafeUnix(um.Time, time.Time.UnixNano) }
|
|
122
|
+
|
|
112
123
|
var _ sql.Scanner = &UnixNano{}
|
|
113
124
|
var _ driver.Valuer = UnixNano{}
|
|
114
125
|
|
|
@@ -117,9 +128,6 @@ type UnixNano struct {
|
|
|
117
128
|
}
|
|
118
129
|
|
|
119
130
|
func (un UnixNano) MarshalJSON() ([]byte, error) {
|
|
120
|
-
if un.IsZero() {
|
|
121
|
-
return []byte{'0'}, nil
|
|
122
|
-
}
|
|
123
131
|
return json.Marshal(un.UnixNano())
|
|
124
132
|
}
|
|
125
133
|
|
|
@@ -139,14 +147,16 @@ func (un *UnixNano) Scan(src any) error {
|
|
|
139
147
|
}, &un.Time)
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
func (un UnixNano) Unix() int64 { return zeroSafeUnix(un.Time, time.Time.Unix) }
|
|
151
|
+
func (un UnixNano) UnixMilli() int64 { return zeroSafeUnix(un.Time, time.Time.UnixMilli) }
|
|
152
|
+
func (un UnixNano) UnixMicro() int64 { return zeroSafeUnix(un.Time, time.Time.UnixMicro) }
|
|
153
|
+
func (un UnixNano) UnixNano() int64 { return zeroSafeUnix(un.Time, time.Time.UnixNano) }
|
|
154
|
+
|
|
142
155
|
type Unix struct {
|
|
143
156
|
time.Time
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
func (u Unix) MarshalJSON() ([]byte, error) {
|
|
147
|
-
if u.IsZero() {
|
|
148
|
-
return []byte{'0'}, nil
|
|
149
|
-
}
|
|
150
160
|
return json.Marshal(u.Unix())
|
|
151
161
|
}
|
|
152
162
|
|
|
@@ -168,3 +178,8 @@ func (u *Unix) Scan(src any) error {
|
|
|
168
178
|
return time.Unix(i, 0)
|
|
169
179
|
}, &u.Time)
|
|
170
180
|
}
|
|
181
|
+
|
|
182
|
+
func (u Unix) Unix() int64 { return zeroSafeUnix(u.Time, time.Time.Unix) }
|
|
183
|
+
func (u Unix) UnixMilli() int64 { return zeroSafeUnix(u.Time, time.Time.UnixMilli) }
|
|
184
|
+
func (u Unix) UnixMicro() int64 { return zeroSafeUnix(u.Time, time.Time.UnixMicro) }
|
|
185
|
+
func (u Unix) UnixNano() int64 { return zeroSafeUnix(u.Time, time.Time.UnixNano) }
|
|
@@ -93,30 +93,18 @@ func BuildPin(target types.JID, pin bool) PatchInfo {
|
|
|
93
93
|
//
|
|
94
94
|
// Archiving a chat will also unpin it automatically.
|
|
95
95
|
func BuildArchive(target types.JID, archive bool, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
|
|
96
|
-
if lastMessageTimestamp.IsZero() {
|
|
97
|
-
lastMessageTimestamp = time.Now()
|
|
98
|
-
}
|
|
99
96
|
archiveMutationInfo := MutationInfo{
|
|
100
97
|
Index: []string{IndexArchive, target.String()},
|
|
101
98
|
Version: 3,
|
|
102
99
|
Value: &waSyncAction.SyncActionValue{
|
|
103
100
|
ArchiveChatAction: &waSyncAction.ArchiveChatAction{
|
|
104
|
-
Archived:
|
|
105
|
-
MessageRange:
|
|
106
|
-
|
|
107
|
-
// TODO set LastSystemMessageTimestamp?
|
|
108
|
-
},
|
|
101
|
+
Archived: &archive,
|
|
102
|
+
MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
|
|
103
|
+
// TODO set LastSystemMessageTimestamp?
|
|
109
104
|
},
|
|
110
105
|
},
|
|
111
106
|
}
|
|
112
107
|
|
|
113
|
-
if lastMessageKey != nil {
|
|
114
|
-
archiveMutationInfo.Value.ArchiveChatAction.MessageRange.Messages = []*waSyncAction.SyncActionMessage{{
|
|
115
|
-
Key: lastMessageKey,
|
|
116
|
-
Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
|
117
|
-
}}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
108
|
mutations := []MutationInfo{archiveMutationInfo}
|
|
121
109
|
if archive {
|
|
122
110
|
mutations = append(mutations, newPinMutationInfo(target, false))
|
|
@@ -132,20 +120,9 @@ func BuildArchive(target types.JID, archive bool, lastMessageTimestamp time.Time
|
|
|
132
120
|
|
|
133
121
|
// BuildMarkChatAsRead builds an app state patch for marking a chat as read or unread.
|
|
134
122
|
func BuildMarkChatAsRead(target types.JID, read bool, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
|
|
135
|
-
if lastMessageTimestamp.IsZero() {
|
|
136
|
-
lastMessageTimestamp = time.Now()
|
|
137
|
-
}
|
|
138
123
|
action := &waSyncAction.MarkChatAsReadAction{
|
|
139
|
-
Read:
|
|
140
|
-
MessageRange:
|
|
141
|
-
LastMessageTimestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
|
142
|
-
},
|
|
143
|
-
}
|
|
144
|
-
if lastMessageKey != nil {
|
|
145
|
-
action.MessageRange.Messages = []*waSyncAction.SyncActionMessage{{
|
|
146
|
-
Key: lastMessageKey,
|
|
147
|
-
Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
|
148
|
-
}}
|
|
124
|
+
Read: proto.Bool(read),
|
|
125
|
+
MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
|
|
149
126
|
}
|
|
150
127
|
|
|
151
128
|
return PatchInfo{
|
|
@@ -355,3 +332,37 @@ func (proc *Processor) EncodePatch(ctx context.Context, keyID []byte, state Hash
|
|
|
355
332
|
|
|
356
333
|
return result, nil
|
|
357
334
|
}
|
|
335
|
+
|
|
336
|
+
// BuildDeleteChat builds an app state patch for deleting a chat.
|
|
337
|
+
func BuildDeleteChat(target types.JID, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
|
|
338
|
+
action := &waSyncAction.DeleteChatAction{
|
|
339
|
+
MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return PatchInfo{
|
|
343
|
+
Type: WAPatchRegular,
|
|
344
|
+
Mutations: []MutationInfo{{
|
|
345
|
+
Index: []string{IndexDeleteChat, target.String()},
|
|
346
|
+
Version: 6,
|
|
347
|
+
Value: &waSyncAction.SyncActionValue{
|
|
348
|
+
DeleteChatAction: action,
|
|
349
|
+
},
|
|
350
|
+
}},
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
func newMessageRange(lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) *waSyncAction.SyncActionMessageRange {
|
|
355
|
+
if lastMessageTimestamp.IsZero() {
|
|
356
|
+
lastMessageTimestamp = time.Now()
|
|
357
|
+
}
|
|
358
|
+
messageRange := &waSyncAction.SyncActionMessageRange{
|
|
359
|
+
LastMessageTimestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
|
360
|
+
}
|
|
361
|
+
if lastMessageKey != nil {
|
|
362
|
+
messageRange.Messages = []*waSyncAction.SyncActionMessage{{
|
|
363
|
+
Key: lastMessageKey,
|
|
364
|
+
Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
|
|
365
|
+
}}
|
|
366
|
+
}
|
|
367
|
+
return messageRange
|
|
368
|
+
}
|
|
@@ -351,13 +351,17 @@ func (cli *Client) requestAppStateKeys(ctx context.Context, rawKeyIDs [][]byte)
|
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
// SendAppState sends the given app state patch, then
|
|
354
|
+
// SendAppState sends the given app state patch, then triggers a background resync of that app state type
|
|
355
355
|
// to update local caches and send events for the updates.
|
|
356
356
|
//
|
|
357
357
|
// You can use the Build methods in the appstate package to build the parameter for this method, e.g.
|
|
358
358
|
//
|
|
359
359
|
// cli.SendAppState(ctx, appstate.BuildMute(targetJID, true, 24 * time.Hour))
|
|
360
360
|
func (cli *Client) SendAppState(ctx context.Context, patch appstate.PatchInfo) error {
|
|
361
|
+
return cli.sendAppState(ctx, patch, false)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
func (cli *Client) sendAppState(ctx context.Context, patch appstate.PatchInfo, waitForSync bool) error {
|
|
361
365
|
if cli == nil {
|
|
362
366
|
return ErrClientIsNil
|
|
363
367
|
}
|
|
@@ -412,5 +416,16 @@ func (cli *Client) SendAppState(ctx context.Context, patch appstate.PatchInfo) e
|
|
|
412
416
|
return fmt.Errorf("%w: %s", ErrAppStateUpdate, respCollection.XMLString())
|
|
413
417
|
}
|
|
414
418
|
|
|
415
|
-
|
|
419
|
+
if waitForSync {
|
|
420
|
+
return cli.FetchAppState(ctx, patch.Type, false, false)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
go func() {
|
|
424
|
+
err := cli.FetchAppState(ctx, patch.Type, false, false)
|
|
425
|
+
if err != nil {
|
|
426
|
+
cli.Log.Errorf("Failed to resync app state %s after sending update: %v", patch.Type, err)
|
|
427
|
+
}
|
|
428
|
+
}()
|
|
429
|
+
|
|
430
|
+
return nil
|
|
416
431
|
}
|
|
@@ -22,10 +22,11 @@ import (
|
|
|
22
22
|
"go.mau.fi/whatsmeow/types/events"
|
|
23
23
|
)
|
|
24
24
|
|
|
25
|
-
func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed bool) {
|
|
25
|
+
func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
|
|
26
26
|
dec, err := decodeArmadillo(decrypted)
|
|
27
27
|
if err != nil {
|
|
28
28
|
cli.Log.Warnf("Failed to decode armadillo message from %s: %v", info.SourceString(), err)
|
|
29
|
+
protobufFailed = true
|
|
29
30
|
return
|
|
30
31
|
}
|
|
31
32
|
dec.Info = *info
|
|
@@ -67,7 +67,11 @@ func (int *DangerousInternalClient) RequestAppStateKeys(ctx context.Context, raw
|
|
|
67
67
|
int.c.requestAppStateKeys(ctx, rawKeyIDs)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
func (int *DangerousInternalClient)
|
|
70
|
+
func (int *DangerousInternalClient) SendAppState(ctx context.Context, patch appstate.PatchInfo, waitForSync bool) error {
|
|
71
|
+
return int.c.sendAppState(ctx, patch, waitForSync)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func (int *DangerousInternalClient) HandleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
|
|
71
75
|
return int.c.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -479,6 +483,10 @@ func (int *DangerousInternalClient) UploadPreKeys(ctx context.Context) {
|
|
|
479
483
|
int.c.uploadPreKeys(ctx)
|
|
480
484
|
}
|
|
481
485
|
|
|
486
|
+
func (int *DangerousInternalClient) FetchPreKeysNoError(ctx context.Context, retryDevices []types.JID) map[types.JID]*prekey.Bundle {
|
|
487
|
+
return int.c.fetchPreKeysNoError(ctx, retryDevices)
|
|
488
|
+
}
|
|
489
|
+
|
|
482
490
|
func (int *DangerousInternalClient) FetchPreKeys(ctx context.Context, users []types.JID) (map[types.JID]preKeyResp, error) {
|
|
483
491
|
return int.c.fetchPreKeys(ctx, users)
|
|
484
492
|
}
|
|
@@ -511,16 +519,20 @@ func (int *DangerousInternalClient) ParseReceipt(node *waBinary.Node) (*events.R
|
|
|
511
519
|
return int.c.parseReceipt(node)
|
|
512
520
|
}
|
|
513
521
|
|
|
522
|
+
func (int *DangerousInternalClient) BackgroundIfAsyncAck(fn func()) {
|
|
523
|
+
int.c.backgroundIfAsyncAck(fn)
|
|
524
|
+
}
|
|
525
|
+
|
|
514
526
|
func (int *DangerousInternalClient) MaybeDeferredAck(ctx context.Context, node *waBinary.Node) func(...*bool) {
|
|
515
527
|
return int.c.maybeDeferredAck(ctx, node)
|
|
516
528
|
}
|
|
517
529
|
|
|
518
|
-
func (int *DangerousInternalClient) SendAck(node *waBinary.Node) {
|
|
519
|
-
int.c.sendAck(node)
|
|
530
|
+
func (int *DangerousInternalClient) SendAck(node *waBinary.Node, error int) {
|
|
531
|
+
int.c.sendAck(node, error)
|
|
520
532
|
}
|
|
521
533
|
|
|
522
|
-
func (int *DangerousInternalClient) SendMessageReceipt(info *types.MessageInfo) {
|
|
523
|
-
int.c.sendMessageReceipt(info)
|
|
534
|
+
func (int *DangerousInternalClient) SendMessageReceipt(info *types.MessageInfo, node *waBinary.Node) {
|
|
535
|
+
int.c.sendMessageReceipt(info, node)
|
|
524
536
|
}
|
|
525
537
|
|
|
526
538
|
func (int *DangerousInternalClient) GenerateRequestID() string {
|
|
@@ -611,7 +623,7 @@ func (int *DangerousInternalClient) PrepareMessageNodeV3(ctx context.Context, to
|
|
|
611
623
|
return int.c.prepareMessageNodeV3(ctx, to, ownID, id, payload, skdm, msgAttrs, frankingTag, participants, timings)
|
|
612
624
|
}
|
|
613
625
|
|
|
614
|
-
func (int *DangerousInternalClient) EncryptMessageForDevicesV3(ctx context.Context, allDevices []types.JID, ownID types.JID, id string, payload *waMsgTransport.MessageTransport_Payload, skdm *waMsgTransport.MessageTransport_Protocol_Ancillary_SenderKeyDistributionMessage, dsm *waMsgTransport.MessageTransport_Protocol_Integral_DeviceSentMessage, encAttrs waBinary.Attrs) []waBinary.Node {
|
|
626
|
+
func (int *DangerousInternalClient) EncryptMessageForDevicesV3(ctx context.Context, allDevices []types.JID, ownID types.JID, id string, payload *waMsgTransport.MessageTransport_Payload, skdm *waMsgTransport.MessageTransport_Protocol_Ancillary_SenderKeyDistributionMessage, dsm *waMsgTransport.MessageTransport_Protocol_Integral_DeviceSentMessage, encAttrs waBinary.Attrs) ([]waBinary.Node, error) {
|
|
615
627
|
return int.c.encryptMessageForDevicesV3(ctx, allDevices, ownID, id, payload, skdm, dsm, encAttrs)
|
|
616
628
|
}
|
|
617
629
|
|
|
@@ -124,6 +124,11 @@ func (cli *Client) parseMessageSource(node *waBinary.Node, requireParticipant bo
|
|
|
124
124
|
source.Sender = from
|
|
125
125
|
// TODO IsFromMe?
|
|
126
126
|
} else if from.User == clientID.User || from.User == clientLID.User {
|
|
127
|
+
if from.Server == types.HostedServer {
|
|
128
|
+
from.Server = types.DefaultUserServer
|
|
129
|
+
} else if from.Server == types.HostedLIDServer {
|
|
130
|
+
from.Server = types.HiddenUserServer
|
|
131
|
+
}
|
|
127
132
|
source.IsFromMe = true
|
|
128
133
|
source.Sender = from
|
|
129
134
|
recipient := ag.OptionalJID("recipient")
|
|
@@ -132,7 +137,7 @@ func (cli *Client) parseMessageSource(node *waBinary.Node, requireParticipant bo
|
|
|
132
137
|
} else {
|
|
133
138
|
source.Chat = from.ToNonAD()
|
|
134
139
|
}
|
|
135
|
-
if source.Chat.Server == types.HiddenUserServer {
|
|
140
|
+
if source.Chat.Server == types.HiddenUserServer || source.Chat.Server == types.HostedLIDServer {
|
|
136
141
|
source.RecipientAlt = ag.OptionalJIDOrEmpty("peer_recipient_pn")
|
|
137
142
|
} else {
|
|
138
143
|
source.RecipientAlt = ag.OptionalJIDOrEmpty("peer_recipient_lid")
|
|
@@ -148,9 +153,14 @@ func (cli *Client) parseMessageSource(node *waBinary.Node, requireParticipant bo
|
|
|
148
153
|
source.Chat = from
|
|
149
154
|
}
|
|
150
155
|
} else {
|
|
156
|
+
if from.Server == types.HostedServer {
|
|
157
|
+
from.Server = types.DefaultUserServer
|
|
158
|
+
} else if from.Server == types.HostedLIDServer {
|
|
159
|
+
from.Server = types.HiddenUserServer
|
|
160
|
+
}
|
|
151
161
|
source.Chat = from.ToNonAD()
|
|
152
162
|
source.Sender = from
|
|
153
|
-
if source.Sender.Server == types.HiddenUserServer {
|
|
163
|
+
if source.Sender.Server == types.HiddenUserServer || source.Chat.Server == types.HostedLIDServer {
|
|
154
164
|
source.SenderAlt = ag.OptionalJIDOrEmpty("sender_pn")
|
|
155
165
|
} else {
|
|
156
166
|
source.SenderAlt = ag.OptionalJIDOrEmpty("sender_lid")
|
|
@@ -291,13 +301,10 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
|
|
291
301
|
if ok && len(node.GetChildrenByTag("enc")) == 0 {
|
|
292
302
|
uType := events.UnavailableType(unavailableNode.AttrGetter().String("type"))
|
|
293
303
|
cli.Log.Warnf("Unavailable message %s from %s (type: %q)", info.ID, info.SourceString(), uType)
|
|
294
|
-
|
|
304
|
+
cli.backgroundIfAsyncAck(func() {
|
|
295
305
|
cli.immediateRequestMessageFromPhone(ctx, info)
|
|
296
|
-
cli.sendAck(node)
|
|
297
|
-
}
|
|
298
|
-
go cli.delayedRequestMessageFromPhone(info)
|
|
299
|
-
go cli.sendAck(node)
|
|
300
|
-
}
|
|
306
|
+
cli.sendAck(node, 0)
|
|
307
|
+
})
|
|
301
308
|
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: true, UnavailableType: uType})
|
|
302
309
|
return
|
|
303
310
|
}
|
|
@@ -320,10 +327,12 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
|
|
320
327
|
cli.Log.Warnf("No LID found for %s", info.Sender)
|
|
321
328
|
}
|
|
322
329
|
}
|
|
330
|
+
var recognizedStanza, protobufFailed bool
|
|
323
331
|
for _, child := range children {
|
|
324
332
|
if child.Tag != "enc" {
|
|
325
333
|
continue
|
|
326
334
|
}
|
|
335
|
+
recognizedStanza = true
|
|
327
336
|
ag := child.AttrGetter()
|
|
328
337
|
encType, ok := ag.GetString("type", false)
|
|
329
338
|
if !ok {
|
|
@@ -371,16 +380,26 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
|
|
371
380
|
if errors.Is(err, EventAlreadyProcessed) {
|
|
372
381
|
cli.Log.Debugf("Ignoring message %s from %s: %v", info.ID, info.SourceString(), err)
|
|
373
382
|
continue
|
|
383
|
+
} else if errors.Is(err, signalerror.ErrOldCounter) {
|
|
384
|
+
cli.Log.Warnf("Ignoring message %s from %s: %v", info.ID, info.SourceString(), err)
|
|
385
|
+
continue
|
|
374
386
|
} else if err != nil {
|
|
375
387
|
cli.Log.Warnf("Error decrypting message %s from %s: %v", info.ID, info.SourceString(), err)
|
|
376
388
|
if ctx.Err() != nil || errors.Is(err, context.Canceled) {
|
|
377
389
|
return
|
|
378
390
|
}
|
|
379
391
|
isUnavailable := encType == "skmsg" && !containsDirectMsg && errors.Is(err, signalerror.ErrNoSenderKeyForUser)
|
|
380
|
-
if
|
|
392
|
+
if encType == "msmsg" {
|
|
393
|
+
cli.backgroundIfAsyncAck(func() {
|
|
394
|
+
cli.sendAck(node, NackMissingMessageSecret)
|
|
395
|
+
})
|
|
396
|
+
} else if cli.SynchronousAck {
|
|
381
397
|
cli.sendRetryReceipt(ctx, node, info, isUnavailable)
|
|
398
|
+
// TODO this probably isn't supposed to ack
|
|
399
|
+
cli.sendAck(node, 0)
|
|
382
400
|
} else {
|
|
383
401
|
go cli.sendRetryReceipt(context.WithoutCancel(ctx), node, info, isUnavailable)
|
|
402
|
+
go cli.sendAck(node, 0)
|
|
384
403
|
}
|
|
385
404
|
cli.dispatchEvent(&events.UndecryptableMessage{
|
|
386
405
|
Info: *info,
|
|
@@ -396,15 +415,16 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
|
|
396
415
|
var handlerFailed bool
|
|
397
416
|
switch ag.Int("v") {
|
|
398
417
|
case 2:
|
|
399
|
-
// TODO send nack instead of receipt for proto unmarshal errors (both this one and armadillo)
|
|
400
418
|
err = proto.Unmarshal(decrypted, &msg)
|
|
401
419
|
if err != nil {
|
|
402
420
|
cli.Log.Warnf("Error unmarshaling decrypted message from %s: %v", info.SourceString(), err)
|
|
421
|
+
protobufFailed = true
|
|
403
422
|
continue
|
|
404
423
|
}
|
|
424
|
+
protobufFailed = false
|
|
405
425
|
handlerFailed = cli.handleDecryptedMessage(ctx, info, &msg, retryCount)
|
|
406
426
|
case 3:
|
|
407
|
-
handlerFailed = cli.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
|
427
|
+
handlerFailed, protobufFailed = cli.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
|
408
428
|
default:
|
|
409
429
|
cli.Log.Warnf("Unknown version %d in decrypted message from %s", ag.Int("v"), info.SourceString())
|
|
410
430
|
}
|
|
@@ -438,11 +458,15 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
|
|
438
458
|
}
|
|
439
459
|
}
|
|
440
460
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
461
|
+
cli.backgroundIfAsyncAck(func() {
|
|
462
|
+
if !recognizedStanza {
|
|
463
|
+
cli.sendAck(node, NackUnrecognizedStanza)
|
|
464
|
+
} else if protobufFailed {
|
|
465
|
+
cli.sendAck(node, NackInvalidProtobuf)
|
|
466
|
+
} else {
|
|
467
|
+
cli.sendMessageReceipt(info, node)
|
|
468
|
+
}
|
|
469
|
+
})
|
|
446
470
|
return
|
|
447
471
|
}
|
|
448
472
|
|
|
@@ -26,10 +26,11 @@ import (
|
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
var (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
AdvAccountSignaturePrefix = []byte{6, 0}
|
|
30
|
+
AdvDeviceSignaturePrefix = []byte{6, 1}
|
|
31
|
+
|
|
32
|
+
AdvHostedAccountSignaturePrefix = []byte{6, 5}
|
|
33
|
+
AdvHostedDeviceSignaturePrefix = []byte{6, 6}
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
func (cli *Client) handleIQ(node *waBinary.Node) {
|
|
@@ -113,11 +114,11 @@ func (cli *Client) handlePair(ctx context.Context, deviceIdentityBytes []byte, r
|
|
|
113
114
|
cli.sendPairError(reqID, 500, "internal-error")
|
|
114
115
|
return &PairProtoError{"failed to parse device identity container in pair success message", err}
|
|
115
116
|
}
|
|
116
|
-
isHostedAccount := deviceIdentityContainer.AccountType != nil && *deviceIdentityContainer.AccountType == waAdv.ADVEncryptionType_HOSTED
|
|
117
117
|
|
|
118
118
|
h := hmac.New(sha256.New, cli.Store.AdvSecretKey)
|
|
119
|
-
if
|
|
120
|
-
h.Write(
|
|
119
|
+
if deviceIdentityContainer.GetAccountType() == waAdv.ADVEncryptionType_HOSTED {
|
|
120
|
+
h.Write(AdvHostedAccountSignaturePrefix)
|
|
121
|
+
//cli.Store.IsHosted = true
|
|
121
122
|
}
|
|
122
123
|
h.Write(deviceIdentityContainer.Details)
|
|
123
124
|
|
|
@@ -134,13 +135,6 @@ func (cli *Client) handlePair(ctx context.Context, deviceIdentityBytes []byte, r
|
|
|
134
135
|
return &PairProtoError{"failed to parse signed device identity in pair success message", err}
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
if !verifyDeviceIdentityAccountSignature(&deviceIdentity, cli.Store.IdentityKey) {
|
|
138
|
-
cli.sendPairError(reqID, 401, "signature-mismatch")
|
|
139
|
-
return ErrPairInvalidDeviceSignature
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
deviceIdentity.DeviceSignature = generateDeviceSignature(&deviceIdentity, cli.Store.IdentityKey, isHostedAccount)[:]
|
|
143
|
-
|
|
144
138
|
var deviceIdentityDetails waAdv.ADVDeviceIdentity
|
|
145
139
|
err = proto.Unmarshal(deviceIdentity.Details, &deviceIdentityDetails)
|
|
146
140
|
if err != nil {
|
|
@@ -148,6 +142,13 @@ func (cli *Client) handlePair(ctx context.Context, deviceIdentityBytes []byte, r
|
|
|
148
142
|
return &PairProtoError{"failed to parse device identity details in pair success message", err}
|
|
149
143
|
}
|
|
150
144
|
|
|
145
|
+
if !verifyAccountSignature(&deviceIdentity, cli.Store.IdentityKey, deviceIdentityDetails.GetDeviceType() == waAdv.ADVEncryptionType_HOSTED) {
|
|
146
|
+
cli.sendPairError(reqID, 401, "signature-mismatch")
|
|
147
|
+
return ErrPairInvalidDeviceSignature
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
deviceIdentity.DeviceSignature = generateDeviceSignature(&deviceIdentity, cli.Store.IdentityKey)[:]
|
|
151
|
+
|
|
151
152
|
if cli.PrePairCallback != nil && !cli.PrePairCallback(jid, platform, businessName) {
|
|
152
153
|
cli.sendPairError(reqID, 500, "internal-error")
|
|
153
154
|
return ErrPairRejectedLocally
|
|
@@ -224,7 +225,7 @@ func concatBytes(data ...[]byte) []byte {
|
|
|
224
225
|
return output
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
func
|
|
228
|
+
func verifyAccountSignature(deviceIdentity *waAdv.ADVSignedDeviceIdentity, ikp *keys.KeyPair, isHosted bool) bool {
|
|
228
229
|
if len(deviceIdentity.AccountSignatureKey) != 32 || len(deviceIdentity.AccountSignature) != 64 {
|
|
229
230
|
return false
|
|
230
231
|
}
|
|
@@ -232,15 +233,17 @@ func verifyDeviceIdentityAccountSignature(deviceIdentity *waAdv.ADVSignedDeviceI
|
|
|
232
233
|
signatureKey := ecc.NewDjbECPublicKey(*(*[32]byte)(deviceIdentity.AccountSignatureKey))
|
|
233
234
|
signature := *(*[64]byte)(deviceIdentity.AccountSignature)
|
|
234
235
|
|
|
235
|
-
|
|
236
|
+
prefix := AdvAccountSignaturePrefix
|
|
237
|
+
if isHosted {
|
|
238
|
+
prefix = AdvHostedAccountSignaturePrefix
|
|
239
|
+
}
|
|
240
|
+
message := concatBytes(prefix, deviceIdentity.Details, ikp.Pub[:])
|
|
241
|
+
|
|
236
242
|
return ecc.VerifySignature(signatureKey, message, signature)
|
|
237
243
|
}
|
|
238
244
|
|
|
239
|
-
func generateDeviceSignature(deviceIdentity *waAdv.ADVSignedDeviceIdentity, ikp *keys.KeyPair
|
|
240
|
-
prefix :=
|
|
241
|
-
if isHostedAccount {
|
|
242
|
-
prefix = AdvHostedPrefixDeviceIdentityDeviceSignatureVerification
|
|
243
|
-
}
|
|
245
|
+
func generateDeviceSignature(deviceIdentity *waAdv.ADVSignedDeviceIdentity, ikp *keys.KeyPair) *[64]byte {
|
|
246
|
+
prefix := AdvDeviceSignaturePrefix
|
|
244
247
|
message := concatBytes(prefix, deviceIdentity.Details, ikp.Pub[:], deviceIdentity.AccountSignatureKey)
|
|
245
248
|
sig := ecc.CalculateSignature(ecc.NewDjbECPrivateKey(*ikp.Priv), message)
|
|
246
249
|
return &sig
|
|
@@ -93,6 +93,27 @@ func (cli *Client) uploadPreKeys(ctx context.Context) {
|
|
|
93
93
|
return
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
func (cli *Client) fetchPreKeysNoError(ctx context.Context, retryDevices []types.JID) map[types.JID]*prekey.Bundle {
|
|
97
|
+
if len(retryDevices) == 0 {
|
|
98
|
+
return nil
|
|
99
|
+
}
|
|
100
|
+
bundlesResp, err := cli.fetchPreKeys(ctx, retryDevices)
|
|
101
|
+
if err != nil {
|
|
102
|
+
cli.Log.Warnf("Failed to fetch prekeys for %v with no existing session: %v", retryDevices, err)
|
|
103
|
+
return nil
|
|
104
|
+
}
|
|
105
|
+
bundles := make(map[types.JID]*prekey.Bundle, len(retryDevices))
|
|
106
|
+
for _, jid := range retryDevices {
|
|
107
|
+
resp := bundlesResp[jid]
|
|
108
|
+
if resp.err != nil {
|
|
109
|
+
cli.Log.Warnf("Failed to fetch prekey for %s: %v", jid, resp.err)
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
bundles[jid] = resp.bundle
|
|
113
|
+
}
|
|
114
|
+
return bundles
|
|
115
|
+
}
|
|
116
|
+
|
|
96
117
|
type preKeyResp struct {
|
|
97
118
|
bundle *prekey.Bundle
|
|
98
119
|
err error
|