@droponair/sdk-js 0.23.1 → 0.23.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
@@ -6,6 +6,14 @@ This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [0.23.2], 2026-06-04
10
+
11
+ ### Fixed
12
+
13
+ - **Status acks (SERVER_RECEIVED / DELIVERED / PROCESSED) were mis-decoded and never reached the app.** Inbound `Ack {messageId, type}` frames were being decoded as `GroupMessageNotification` (the ack's `type` lands in the notification's `groupId`, field 2) because the group-notification / group-ack / broadcast decode guards only checked fields 1-2, which an ack satisfies. They now also require field 3 (`fromUserId` / `type` / `publisherId`), which every real group/broadcast frame carries but an ack lacks, so acks fall through to the ack decoder. This regressed in 0.22.1: making `GroupMessageNotification` decodable (the AttachmentRef fix) removed the decode-time throw that previously let acks fall through. Net effect of the bug: a sender's message never advanced past "sending" even though it was delivered. Also hardened the inbound frame handler to never drop the channel on an undecodable frame.
14
+
15
+ ---
16
+
9
17
  ## [0.23.1], 2026-06-01
10
18
 
11
19
  ### Fixed
@@ -1779,7 +1779,16 @@ class MessagingClient {
1779
1779
  }
1780
1780
  });
1781
1781
  transport.onFrame(async (bytes) => {
1782
- const frame = this.codec.decodeFrame(bytes);
1782
+ // Defensive: a single undecodable/unknown frame must not reject the
1783
+ // handler (which would silently drop it and could wedge inbound state).
1784
+ let frame;
1785
+ try {
1786
+ frame = this.codec.decodeFrame(bytes);
1787
+ }
1788
+ catch (err) {
1789
+ this.logError('frame_decode_failed', { bytes: bytes.length, error: String(err?.message ?? err) });
1790
+ return;
1791
+ }
1783
1792
  if (frame.kind === 'event') {
1784
1793
  if (frame.data.type === 'LIMIT_REACHED') {
1785
1794
  this.rateLimited = true;
@@ -419,7 +419,10 @@ class ProtobufCodec {
419
419
  tryDecodeBroadcastNotification(payload) {
420
420
  try {
421
421
  const decoded = BroadcastNotificationType.decode(payload);
422
- if (!decoded.broadcastId || !decoded.channelId) {
422
+ // Require publisherId (field 3): an Ack {messageId(1), type(2)} otherwise
423
+ // decodes as a broadcast (type lands in channelId, field 3 empty). Real
424
+ // broadcasts always carry a publisherId.
425
+ if (!decoded.broadcastId || !decoded.channelId || !decoded.publisherId) {
423
426
  return null;
424
427
  }
425
428
  return {
@@ -435,7 +438,11 @@ class ProtobufCodec {
435
438
  tryDecodeGroupMessageNotification(payload) {
436
439
  try {
437
440
  const decoded = GroupMessageNotificationType.decode(payload);
438
- if (!decoded.messageId || !decoded.groupId) {
441
+ // Require fromUserId (field 3): an Ack {messageId(1), type(2)} otherwise
442
+ // decodes as a group notification (its type lands in groupId) and steals
443
+ // status acks before the Ack probe. Real group notifications always carry
444
+ // fromUserId; acks have no field 3.
445
+ if (!decoded.messageId || !decoded.groupId || !decoded.fromUserId) {
439
446
  return null;
440
447
  }
441
448
  return {
@@ -455,7 +462,10 @@ class ProtobufCodec {
455
462
  tryDecodeGroupAck(payload) {
456
463
  try {
457
464
  const decoded = GroupAckType.decode(payload);
458
- if (!decoded.messageId || !decoded.groupId) {
465
+ // Require type (field 3): an Ack {messageId(1), type(2)} otherwise decodes
466
+ // as a GroupAck (its type lands in groupId, field 3 stays empty). Real
467
+ // GroupAcks always carry a type.
468
+ if (!decoded.messageId || !decoded.groupId || !decoded.type) {
459
469
  return null;
460
470
  }
461
471
  return decoded;
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.23.1";
10
+ export declare const SDK_VERSION = "0.23.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.23.1';
13
+ exports.SDK_VERSION = '0.23.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.23.1",
3
+ "version": "0.23.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",