stream-chat 9.43.2 → 9.44.1

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.
@@ -71,6 +71,8 @@ __export(index_exports, {
71
71
  FilterBuilder: () => FilterBuilder,
72
72
  FixedSizeQueueCache: () => FixedSizeQueueCache,
73
73
  InsightMetrics: () => InsightMetrics,
74
+ InvalidWebhookError: () => InvalidWebhookError,
75
+ InvalidWebhookErrorMessages: () => InvalidWebhookErrorMessages,
74
76
  JWTServerToken: () => JWTServerToken,
75
77
  JWTUserToken: () => JWTUserToken,
76
78
  LinkPreviewStatus: () => LinkPreviewStatus,
@@ -157,6 +159,8 @@ __export(index_exports, {
157
159
  createUploadConfigCheckMiddleware: () => createUploadConfigCheckMiddleware,
158
160
  createUploadErrorHandlerMiddleware: () => createUploadErrorHandlerMiddleware,
159
161
  decodeBase64: () => decodeBase64,
162
+ decodeSnsPayload: () => decodeSnsPayload,
163
+ decodeSqsPayload: () => decodeSqsPayload,
160
164
  defaultPollFieldBlurEventValidators: () => defaultPollFieldBlurEventValidators,
161
165
  defaultPollFieldChangeEventValidators: () => defaultPollFieldChangeEventValidators,
162
166
  encodeBase64: () => encodeBase64,
@@ -172,6 +176,7 @@ __export(index_exports, {
172
176
  getRawCommandName: () => getRawCommandName,
173
177
  getTokenizedSuggestionDisplayName: () => getTokenizedSuggestionDisplayName,
174
178
  getTriggerCharWithToken: () => getTriggerCharWithToken,
179
+ gunzipPayload: () => gunzipPayload,
175
180
  insertItemWithTrigger: () => insertItemWithTrigger,
176
181
  isAudioAttachment: () => isAudioAttachment,
177
182
  isBlobButNotFile: () => isBlobButNotFile,
@@ -202,6 +207,9 @@ __export(index_exports, {
202
207
  logChatPromiseExecution: () => logChatPromiseExecution,
203
208
  mapPollStateToResponse: () => mapPollStateToResponse,
204
209
  notifyCommandDisabled: () => notifyCommandDisabled,
210
+ parseEvent: () => parseEvent,
211
+ parseSns: () => parseSns,
212
+ parseSqs: () => parseSqs,
205
213
  pollCompositionStateProcessors: () => pollCompositionStateProcessors,
206
214
  pollStateChangeValidators: () => pollStateChangeValidators,
207
215
  postInsights: () => postInsights,
@@ -211,7 +219,9 @@ __export(index_exports, {
211
219
  replaceWordWithEntity: () => replaceWordWithEntity,
212
220
  stripCommandFromText: () => stripCommandFromText,
213
221
  textIsEmpty: () => textIsEmpty,
214
- timeLeftMs: () => timeLeftMs
222
+ timeLeftMs: () => timeLeftMs,
223
+ verifyAndParseWebhook: () => verifyAndParseWebhook,
224
+ verifySignature: () => verifySignature
215
225
  });
216
226
  module.exports = __toCommonJS(index_exports);
217
227
 
@@ -823,7 +833,7 @@ var deleteUserMessages = ({
823
833
  if (message.user?.id === user.id) {
824
834
  messages[i] = message.type === "deleted" ? message : toDeletedMessage({ message, hardDelete, deletedAt });
825
835
  }
826
- if (message.quoted_message?.user?.id === user.id) {
836
+ if (messages[i].quoted_message && message.quoted_message?.user?.id === user.id) {
827
837
  messages[i].quoted_message = message.quoted_message.type === "deleted" ? message.quoted_message : toDeletedMessage({
828
838
  message: messages[i].quoted_message,
829
839
  hardDelete,
@@ -7423,6 +7433,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7423
7433
  const draft = event.draft;
7424
7434
  if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid)
7425
7435
  return;
7436
+ if (this.editedMessage) return;
7426
7437
  this.initState({ composition: draft });
7427
7438
  }).unsubscribe;
7428
7439
  this.subscribeDraftDeleted = () => this.client.on("draft.deleted", (event) => {
@@ -7430,6 +7441,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7430
7441
  if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid) {
7431
7442
  return;
7432
7443
  }
7444
+ if (this.editedMessage) return;
7433
7445
  this.logDraftUpdateTimestamp();
7434
7446
  if (this.compositionIsEmpty) {
7435
7447
  return;
@@ -9473,7 +9485,7 @@ var Channel = class {
9473
9485
  if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes("read-events")) {
9474
9486
  return false;
9475
9487
  }
9476
- if (this.muteStatus().muted) return false;
9488
+ if (this.getClient()._muteStatus(this.cid).muted) return false;
9477
9489
  return true;
9478
9490
  }
9479
9491
  /**
@@ -10984,6 +10996,7 @@ var UploadManager = class {
10984
10996
  // src/signing.ts
10985
10997
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
10986
10998
  var import_crypto = __toESM(require("crypto"));
10999
+ var import_zlib = __toESM(require("zlib"));
10987
11000
  function JWTUserToken(apiSecret, userId, extraData = {}, jwtOptions = {}) {
10988
11001
  if (typeof userId !== "string") {
10989
11002
  throw new TypeError("userId should be a string");
@@ -11035,7 +11048,7 @@ function DevToken(userId) {
11035
11048
  // hardcoded signature
11036
11049
  ].join(".");
11037
11050
  }
11038
- function CheckSignature(body, secret, signature) {
11051
+ function verifySignature(body, signature, secret) {
11039
11052
  const key = Buffer.from(secret, "utf8");
11040
11053
  const hash = import_crypto.default.createHmac("sha256", key).update(body).digest("hex");
11041
11054
  try {
@@ -11044,6 +11057,86 @@ function CheckSignature(body, secret, signature) {
11044
11057
  return false;
11045
11058
  }
11046
11059
  }
11060
+ function CheckSignature(body, secret, signature) {
11061
+ return verifySignature(body, signature, secret);
11062
+ }
11063
+ var InvalidWebhookErrorMessages = {
11064
+ signatureMismatch: "signature mismatch",
11065
+ invalidBase64: "invalid base64 encoding",
11066
+ gzipFailed: "gzip decompression failed",
11067
+ invalidJson: "invalid JSON payload"
11068
+ };
11069
+ var InvalidWebhookError = class extends Error {
11070
+ constructor(message = InvalidWebhookErrorMessages.signatureMismatch) {
11071
+ super(message);
11072
+ this.name = "InvalidWebhookError";
11073
+ }
11074
+ };
11075
+ function gunzipPayload(rawBody) {
11076
+ const GZIP_MAGIC = Buffer.from([31, 139]);
11077
+ const body = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody);
11078
+ if (body.length >= 2 && body.subarray(0, 2).equals(GZIP_MAGIC)) {
11079
+ try {
11080
+ return import_zlib.default.gunzipSync(body);
11081
+ } catch {
11082
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.gzipFailed);
11083
+ }
11084
+ }
11085
+ return body;
11086
+ }
11087
+ function decodeSqsPayload(body) {
11088
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(body) || body.length % 4 !== 0) {
11089
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidBase64);
11090
+ }
11091
+ const decoded = Buffer.from(body, "base64");
11092
+ if (decoded.toString("base64").length !== body.length) {
11093
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidBase64);
11094
+ }
11095
+ return gunzipPayload(decoded);
11096
+ }
11097
+ function decodeSnsPayload(notificationBody) {
11098
+ const inner = extractSnsMessage(notificationBody);
11099
+ return decodeSqsPayload(inner ?? notificationBody);
11100
+ }
11101
+ function extractSnsMessage(notificationBody) {
11102
+ const trimmed = notificationBody.replace(/^[\s\uFEFF]+/, "");
11103
+ if (!trimmed.startsWith("{")) {
11104
+ return null;
11105
+ }
11106
+ let parsed;
11107
+ try {
11108
+ parsed = JSON.parse(trimmed);
11109
+ } catch {
11110
+ return null;
11111
+ }
11112
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.Message !== "string") {
11113
+ return null;
11114
+ }
11115
+ return parsed.Message;
11116
+ }
11117
+ function parseEvent(payload) {
11118
+ const text = Buffer.isBuffer(payload) ? payload.toString("utf8") : payload;
11119
+ try {
11120
+ return JSON.parse(text);
11121
+ } catch {
11122
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidJson);
11123
+ }
11124
+ }
11125
+ function verifyAndParse(payload, signature, secret) {
11126
+ if (!verifySignature(payload, signature, secret)) {
11127
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.signatureMismatch);
11128
+ }
11129
+ return parseEvent(payload);
11130
+ }
11131
+ function verifyAndParseWebhook(rawBody, signature, secret) {
11132
+ return verifyAndParse(gunzipPayload(rawBody), signature, secret);
11133
+ }
11134
+ function parseSqs(messageBody) {
11135
+ return parseEvent(decodeSqsPayload(messageBody));
11136
+ }
11137
+ function parseSns(notificationBody) {
11138
+ return parseEvent(decodeSnsPayload(notificationBody));
11139
+ }
11047
11140
 
11048
11141
  // src/token_manager.ts
11049
11142
  var TokenManager = class {
@@ -12387,12 +12480,13 @@ var ChannelManager = class extends WithSubscriptions {
12387
12480
  });
12388
12481
  const {
12389
12482
  channels,
12390
- pagination: { filters, sort }
12483
+ pagination: { filters, options, sort }
12391
12484
  } = this.state.getLatestValue();
12392
12485
  this.client.offlineDb?.executeQuerySafely(
12393
12486
  (db) => db.upsertCidsForQuery({
12394
12487
  cids: channels.map((channel) => channel.cid),
12395
12488
  filters,
12489
+ options,
12396
12490
  sort
12397
12491
  }),
12398
12492
  { method: "upsertCidsForQuery" }
@@ -12446,6 +12540,7 @@ var ChannelManager = class extends WithSubscriptions {
12446
12540
  (db) => db.upsertCidsForQuery({
12447
12541
  cids: channels.map((channel) => channel.cid),
12448
12542
  filters: pagination.filters,
12543
+ options,
12449
12544
  sort: pagination.sort
12450
12545
  }),
12451
12546
  { method: "upsertCidsForQuery" }
@@ -12502,6 +12597,7 @@ var ChannelManager = class extends WithSubscriptions {
12502
12597
  const channelsFromDB = await this.client.offlineDb.getChannelsForQuery({
12503
12598
  userId: this.client.user.id,
12504
12599
  filters,
12600
+ options,
12505
12601
  sort
12506
12602
  });
12507
12603
  if (channelsFromDB) {
@@ -15647,7 +15743,7 @@ var StreamChat = class _StreamChat {
15647
15743
  if (this.userAgent) {
15648
15744
  return this.userAgent;
15649
15745
  }
15650
- const version = "9.43.2";
15746
+ const version = "9.44.1";
15651
15747
  const clientBundle = "node-cjs";
15652
15748
  let userAgentString = "";
15653
15749
  if (this.sdkIdentifier) {
@@ -15740,7 +15836,50 @@ var StreamChat = class _StreamChat {
15740
15836
  * @returns {boolean}
15741
15837
  */
15742
15838
  verifyWebhook(requestBody, xSignature) {
15743
- return !!this.secret && CheckSignature(requestBody, this.secret, xSignature);
15839
+ return !!this.secret && verifySignature(requestBody, xSignature, this.secret);
15840
+ }
15841
+ /**
15842
+ * Verify and parse an HTTP webhook event.
15843
+ *
15844
+ * Decompresses `rawBody` when gzipped (detected from the body bytes),
15845
+ * verifies the `X-Signature` header against the app's API secret, and
15846
+ * returns the parsed `Event`. Works whether or not Stream is currently
15847
+ * compressing payloads for this app, and stays correct behind
15848
+ * middleware that auto-decompresses the request.
15849
+ *
15850
+ * @param rawBody Raw HTTP request body bytes Stream signed
15851
+ * @param signature Value of the `X-Signature` header
15852
+ * @throws {InvalidWebhookError} When the signature does not match or
15853
+ * the gzip envelope is malformed.
15854
+ */
15855
+ verifyAndParseWebhook(rawBody, signature) {
15856
+ if (!this.secret) {
15857
+ throw new InvalidWebhookError(
15858
+ "cannot verify webhook signature without an API secret on the client"
15859
+ );
15860
+ }
15861
+ return verifyAndParseWebhook(rawBody, signature, this.secret);
15862
+ }
15863
+ /**
15864
+ * Parse an SQS firehose event: decodes the message `Body` (base64 +
15865
+ * optional gzip) and returns the parsed `Event`. No HMAC verification
15866
+ * (Stream does not sign SQS bodies).
15867
+ *
15868
+ * @param messageBody SQS message `Body` string
15869
+ * @throws {InvalidWebhookError} When the base64 / gzip envelope is malformed.
15870
+ */
15871
+ parseSqs(messageBody) {
15872
+ return parseSqs(messageBody);
15873
+ }
15874
+ /**
15875
+ * Parse an SNS-delivered event (unwraps envelope JSON when needed, then
15876
+ * same decode path as SQS). No HMAC verification.
15877
+ *
15878
+ * @param notificationBody Raw SNS POST body or pre-extracted `Message` string
15879
+ * @throws {InvalidWebhookError} When the envelope cannot be decoded.
15880
+ */
15881
+ parseSns(notificationBody) {
15882
+ return parseSns(notificationBody);
15744
15883
  }
15745
15884
  /** getPermission - gets the definition for a permission
15746
15885
  *
@@ -18291,6 +18430,8 @@ var FixedSizeQueueCache = class {
18291
18430
  FilterBuilder,
18292
18431
  FixedSizeQueueCache,
18293
18432
  InsightMetrics,
18433
+ InvalidWebhookError,
18434
+ InvalidWebhookErrorMessages,
18294
18435
  JWTServerToken,
18295
18436
  JWTUserToken,
18296
18437
  LinkPreviewStatus,
@@ -18377,6 +18518,8 @@ var FixedSizeQueueCache = class {
18377
18518
  createUploadConfigCheckMiddleware,
18378
18519
  createUploadErrorHandlerMiddleware,
18379
18520
  decodeBase64,
18521
+ decodeSnsPayload,
18522
+ decodeSqsPayload,
18380
18523
  defaultPollFieldBlurEventValidators,
18381
18524
  defaultPollFieldChangeEventValidators,
18382
18525
  encodeBase64,
@@ -18392,6 +18535,7 @@ var FixedSizeQueueCache = class {
18392
18535
  getRawCommandName,
18393
18536
  getTokenizedSuggestionDisplayName,
18394
18537
  getTriggerCharWithToken,
18538
+ gunzipPayload,
18395
18539
  insertItemWithTrigger,
18396
18540
  isAudioAttachment,
18397
18541
  isBlobButNotFile,
@@ -18422,6 +18566,9 @@ var FixedSizeQueueCache = class {
18422
18566
  logChatPromiseExecution,
18423
18567
  mapPollStateToResponse,
18424
18568
  notifyCommandDisabled,
18569
+ parseEvent,
18570
+ parseSns,
18571
+ parseSqs,
18425
18572
  pollCompositionStateProcessors,
18426
18573
  pollStateChangeValidators,
18427
18574
  postInsights,
@@ -18431,6 +18578,8 @@ var FixedSizeQueueCache = class {
18431
18578
  replaceWordWithEntity,
18432
18579
  stripCommandFromText,
18433
18580
  textIsEmpty,
18434
- timeLeftMs
18581
+ timeLeftMs,
18582
+ verifyAndParseWebhook,
18583
+ verifySignature
18435
18584
  });
18436
18585
  //# sourceMappingURL=index.node.js.map