@droponair/sdk-js 0.24.0 → 0.24.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.2
4
+
5
+ - Fix: E2EE group message decryption failed because the decrypt AAD bound `recipientId` to the group id instead of the receiving user's own id (which is what the sender encrypts against). Now matches the sender and the other SDKs. Requires sdk-be that preserves the sender timestamp on group notifications.
6
+
7
+ ## 0.24.1
8
+
9
+ - Fix: incoming frame classifier misrouted server-pushed Event and Broadcast frames as group messages (protobuf field overlap), so `onBroadcast` never fired and events like `LIMIT_REACHED` were swallowed. Event is now probed with a strict type check before group/broadcast/ack, and group notifications additionally require `senderDeviceId`.
10
+
3
11
  All notable changes to the DropOnAir JS SDK will be documented in this file.
4
12
 
5
13
  This project follows [Semantic Versioning](https://semver.org/).
@@ -1580,7 +1580,12 @@ class MessagingClient {
1580
1580
  plaintext = await this.cryptoService.decrypt(myPayload.encryptedPayload, sharedKey, {
1581
1581
  messageId: notif.messageId,
1582
1582
  senderId: notif.fromUserId,
1583
- recipientId: notif.groupId,
1583
+ // AAD recipientId is the receiving user's own id — this MUST match the
1584
+ // sender's encrypt AAD, which binds recipientId to the target member's
1585
+ // userId (memberId). Using notif.groupId here (the previous value) never
1586
+ // matched, so E2EE group messages failed GCM auth on decrypt. android /
1587
+ // ios / unity already bind this to the recipient's own id.
1588
+ recipientId: this.currentUserId,
1584
1589
  timestamp: notif.timestamp,
1585
1590
  });
1586
1591
  }
@@ -307,6 +307,14 @@ class ProtobufCodec {
307
307
  if (asGroupCall) {
308
308
  return { kind: 'groupCall', data: asGroupCall };
309
309
  }
310
+ // Event (LIMIT_REACHED, ERROR, CONNECTED, ...). Probed before groupMessage /
311
+ // broadcast / ack: an event carrying metadata (field 3) otherwise satisfies
312
+ // their messageId+groupId+fromUserId / broadcastId shape and gets misrouted.
313
+ // The strict type check keeps real UUID-bearing frames out of this branch.
314
+ const asEvent = this.tryDecodeEvent(payload);
315
+ if (asEvent) {
316
+ return { kind: 'event', data: asEvent };
317
+ }
310
318
  // Group message notification (per-member stripped payload from server)
311
319
  const asGroupMsg = this.tryDecodeGroupMessageNotification(payload);
312
320
  if (asGroupMsg) {
@@ -325,10 +333,6 @@ class ProtobufCodec {
325
333
  if (asAck) {
326
334
  return { kind: 'ack', data: asAck };
327
335
  }
328
- const asEvent = this.tryDecodeEvent(payload);
329
- if (asEvent) {
330
- return { kind: 'event', data: asEvent };
331
- }
332
336
  throw new Error('Unsupported inbound protobuf frame');
333
337
  }
334
338
  tryDecodeEnvelope(payload) {
@@ -395,7 +399,12 @@ class ProtobufCodec {
395
399
  tryDecodeEvent(payload) {
396
400
  try {
397
401
  const decoded = EventType.decode(payload);
398
- if (!decoded.type) {
402
+ // Event.type is a SCREAMING_SNAKE_CASE enum string (e.g. LIMIT_REACHED).
403
+ // A GroupMessageNotification, BroadcastNotification, or Ack decoded here
404
+ // carries a UUID (messageId / broadcastId) in field 1, which never matches
405
+ // this shape — so this reliably rejects those overlapping frame types and
406
+ // lets Event be probed before them.
407
+ if (!decoded.type || !/^[A-Z][A-Z0-9_]*$/.test(decoded.type)) {
399
408
  return null;
400
409
  }
401
410
  return decoded;
@@ -442,7 +451,11 @@ class ProtobufCodec {
442
451
  // decodes as a group notification (its type lands in groupId) and steals
443
452
  // status acks before the Ack probe. Real group notifications always carry
444
453
  // fromUserId; acks have no field 3.
445
- if (!decoded.messageId || !decoded.groupId || !decoded.fromUserId) {
454
+ // Require senderDeviceId (field 8, string). A BroadcastNotification (field 8 =
455
+ // sequenceNumber, int32) or an Event (no field 8) otherwise satisfies the
456
+ // messageId+groupId+fromUserId shape and is misrouted here. The server always
457
+ // sets senderDeviceId on group notifications.
458
+ if (!decoded.messageId || !decoded.groupId || !decoded.fromUserId || !decoded.senderDeviceId) {
446
459
  return null;
447
460
  }
448
461
  return {
package/dist/version.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * MINOR, additive feature (e.g. multi-device payloads, new call event type)
8
8
  * PATCH, bug-fix / perf improvement with no wire or API change
9
9
  */
10
- export declare const SDK_VERSION = "0.24.0";
10
+ export declare const SDK_VERSION = "0.24.2";
11
11
  /**
12
12
  * Binary encrypted-payload format version.
13
13
  * Included as the first byte of every encrypted payload so receivers can
package/dist/version.js CHANGED
@@ -10,7 +10,7 @@ exports.PROTOCOL_VERSION = exports.PAYLOAD_FORMAT_VERSION = exports.SDK_VERSION
10
10
  * MINOR, additive feature (e.g. multi-device payloads, new call event type)
11
11
  * PATCH, bug-fix / perf improvement with no wire or API change
12
12
  */
13
- exports.SDK_VERSION = '0.24.0';
13
+ exports.SDK_VERSION = '0.24.2';
14
14
  /**
15
15
  * Binary encrypted-payload format version.
16
16
  * Included as the first byte of every encrypted payload so receivers can
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droponair/sdk-js",
3
- "version": "0.24.0",
3
+ "version": "0.24.2",
4
4
  "description": "DropOnAir SDK for end-to-end encrypted messaging",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",