stream-chat 9.43.2 → 9.44.0

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.
@@ -42,6 +42,12 @@ var require_crypto = __commonJS({
42
42
  }
43
43
  });
44
44
 
45
+ // (disabled):zlib
46
+ var require_zlib = __commonJS({
47
+ "(disabled):zlib"() {
48
+ }
49
+ });
50
+
45
51
  // src/base64.ts
46
52
  import { fromByteArray } from "base64-js";
47
53
  function isString(arrayOrString) {
@@ -650,7 +656,7 @@ var deleteUserMessages = ({
650
656
  if (message.user?.id === user.id) {
651
657
  messages[i] = message.type === "deleted" ? message : toDeletedMessage({ message, hardDelete, deletedAt });
652
658
  }
653
- if (message.quoted_message?.user?.id === user.id) {
659
+ if (messages[i].quoted_message && message.quoted_message?.user?.id === user.id) {
654
660
  messages[i].quoted_message = message.quoted_message.type === "deleted" ? message.quoted_message : toDeletedMessage({
655
661
  message: messages[i].quoted_message,
656
662
  hardDelete,
@@ -7250,6 +7256,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7250
7256
  const draft = event.draft;
7251
7257
  if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid)
7252
7258
  return;
7259
+ if (this.editedMessage) return;
7253
7260
  this.initState({ composition: draft });
7254
7261
  }).unsubscribe;
7255
7262
  this.subscribeDraftDeleted = () => this.client.on("draft.deleted", (event) => {
@@ -7257,6 +7264,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7257
7264
  if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid) {
7258
7265
  return;
7259
7266
  }
7267
+ if (this.editedMessage) return;
7260
7268
  this.logDraftUpdateTimestamp();
7261
7269
  if (this.compositionIsEmpty) {
7262
7270
  return;
@@ -9300,7 +9308,7 @@ var Channel = class {
9300
9308
  if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes("read-events")) {
9301
9309
  return false;
9302
9310
  }
9303
- if (this.muteStatus().muted) return false;
9311
+ if (this.getClient()._muteStatus(this.cid).muted) return false;
9304
9312
  return true;
9305
9313
  }
9306
9314
  /**
@@ -10811,6 +10819,7 @@ var UploadManager = class {
10811
10819
  // src/signing.ts
10812
10820
  var import_jsonwebtoken = __toESM(require_jsonwebtoken());
10813
10821
  var import_crypto = __toESM(require_crypto());
10822
+ var import_zlib = __toESM(require_zlib());
10814
10823
  function JWTUserToken(apiSecret, userId, extraData = {}, jwtOptions = {}) {
10815
10824
  if (typeof userId !== "string") {
10816
10825
  throw new TypeError("userId should be a string");
@@ -10862,7 +10871,7 @@ function DevToken(userId) {
10862
10871
  // hardcoded signature
10863
10872
  ].join(".");
10864
10873
  }
10865
- function CheckSignature(body, secret, signature) {
10874
+ function verifySignature(body, signature, secret) {
10866
10875
  const key = Buffer.from(secret, "utf8");
10867
10876
  const hash = import_crypto.default.createHmac("sha256", key).update(body).digest("hex");
10868
10877
  try {
@@ -10871,6 +10880,86 @@ function CheckSignature(body, secret, signature) {
10871
10880
  return false;
10872
10881
  }
10873
10882
  }
10883
+ function CheckSignature(body, secret, signature) {
10884
+ return verifySignature(body, signature, secret);
10885
+ }
10886
+ var InvalidWebhookErrorMessages = {
10887
+ signatureMismatch: "signature mismatch",
10888
+ invalidBase64: "invalid base64 encoding",
10889
+ gzipFailed: "gzip decompression failed",
10890
+ invalidJson: "invalid JSON payload"
10891
+ };
10892
+ var InvalidWebhookError = class extends Error {
10893
+ constructor(message = InvalidWebhookErrorMessages.signatureMismatch) {
10894
+ super(message);
10895
+ this.name = "InvalidWebhookError";
10896
+ }
10897
+ };
10898
+ function gunzipPayload(rawBody) {
10899
+ const GZIP_MAGIC = Buffer.from([31, 139]);
10900
+ const body = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody);
10901
+ if (body.length >= 2 && body.subarray(0, 2).equals(GZIP_MAGIC)) {
10902
+ try {
10903
+ return import_zlib.default.gunzipSync(body);
10904
+ } catch {
10905
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.gzipFailed);
10906
+ }
10907
+ }
10908
+ return body;
10909
+ }
10910
+ function decodeSqsPayload(body) {
10911
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(body) || body.length % 4 !== 0) {
10912
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidBase64);
10913
+ }
10914
+ const decoded = Buffer.from(body, "base64");
10915
+ if (decoded.toString("base64").length !== body.length) {
10916
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidBase64);
10917
+ }
10918
+ return gunzipPayload(decoded);
10919
+ }
10920
+ function decodeSnsPayload(notificationBody) {
10921
+ const inner = extractSnsMessage(notificationBody);
10922
+ return decodeSqsPayload(inner ?? notificationBody);
10923
+ }
10924
+ function extractSnsMessage(notificationBody) {
10925
+ const trimmed = notificationBody.replace(/^[\s\uFEFF]+/, "");
10926
+ if (!trimmed.startsWith("{")) {
10927
+ return null;
10928
+ }
10929
+ let parsed;
10930
+ try {
10931
+ parsed = JSON.parse(trimmed);
10932
+ } catch {
10933
+ return null;
10934
+ }
10935
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.Message !== "string") {
10936
+ return null;
10937
+ }
10938
+ return parsed.Message;
10939
+ }
10940
+ function parseEvent(payload) {
10941
+ const text = Buffer.isBuffer(payload) ? payload.toString("utf8") : payload;
10942
+ try {
10943
+ return JSON.parse(text);
10944
+ } catch {
10945
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.invalidJson);
10946
+ }
10947
+ }
10948
+ function verifyAndParse(payload, signature, secret) {
10949
+ if (!verifySignature(payload, signature, secret)) {
10950
+ throw new InvalidWebhookError(InvalidWebhookErrorMessages.signatureMismatch);
10951
+ }
10952
+ return parseEvent(payload);
10953
+ }
10954
+ function verifyAndParseWebhook(rawBody, signature, secret) {
10955
+ return verifyAndParse(gunzipPayload(rawBody), signature, secret);
10956
+ }
10957
+ function parseSqs(messageBody) {
10958
+ return parseEvent(decodeSqsPayload(messageBody));
10959
+ }
10960
+ function parseSns(notificationBody) {
10961
+ return parseEvent(decodeSnsPayload(notificationBody));
10962
+ }
10874
10963
 
10875
10964
  // src/token_manager.ts
10876
10965
  var TokenManager = class {
@@ -15474,7 +15563,7 @@ var StreamChat = class _StreamChat {
15474
15563
  if (this.userAgent) {
15475
15564
  return this.userAgent;
15476
15565
  }
15477
- const version = "9.43.2";
15566
+ const version = "9.44.0";
15478
15567
  const clientBundle = "browser-esm";
15479
15568
  let userAgentString = "";
15480
15569
  if (this.sdkIdentifier) {
@@ -15567,7 +15656,50 @@ var StreamChat = class _StreamChat {
15567
15656
  * @returns {boolean}
15568
15657
  */
15569
15658
  verifyWebhook(requestBody, xSignature) {
15570
- return !!this.secret && CheckSignature(requestBody, this.secret, xSignature);
15659
+ return !!this.secret && verifySignature(requestBody, xSignature, this.secret);
15660
+ }
15661
+ /**
15662
+ * Verify and parse an HTTP webhook event.
15663
+ *
15664
+ * Decompresses `rawBody` when gzipped (detected from the body bytes),
15665
+ * verifies the `X-Signature` header against the app's API secret, and
15666
+ * returns the parsed `Event`. Works whether or not Stream is currently
15667
+ * compressing payloads for this app, and stays correct behind
15668
+ * middleware that auto-decompresses the request.
15669
+ *
15670
+ * @param rawBody Raw HTTP request body bytes Stream signed
15671
+ * @param signature Value of the `X-Signature` header
15672
+ * @throws {InvalidWebhookError} When the signature does not match or
15673
+ * the gzip envelope is malformed.
15674
+ */
15675
+ verifyAndParseWebhook(rawBody, signature) {
15676
+ if (!this.secret) {
15677
+ throw new InvalidWebhookError(
15678
+ "cannot verify webhook signature without an API secret on the client"
15679
+ );
15680
+ }
15681
+ return verifyAndParseWebhook(rawBody, signature, this.secret);
15682
+ }
15683
+ /**
15684
+ * Parse an SQS firehose event: decodes the message `Body` (base64 +
15685
+ * optional gzip) and returns the parsed `Event`. No HMAC verification
15686
+ * (Stream does not sign SQS bodies).
15687
+ *
15688
+ * @param messageBody SQS message `Body` string
15689
+ * @throws {InvalidWebhookError} When the base64 / gzip envelope is malformed.
15690
+ */
15691
+ parseSqs(messageBody) {
15692
+ return parseSqs(messageBody);
15693
+ }
15694
+ /**
15695
+ * Parse an SNS-delivered event (unwraps envelope JSON when needed, then
15696
+ * same decode path as SQS). No HMAC verification.
15697
+ *
15698
+ * @param notificationBody Raw SNS POST body or pre-extracted `Message` string
15699
+ * @throws {InvalidWebhookError} When the envelope cannot be decoded.
15700
+ */
15701
+ parseSns(notificationBody) {
15702
+ return parseSns(notificationBody);
15571
15703
  }
15572
15704
  /** getPermission - gets the definition for a permission
15573
15705
  *
@@ -18117,6 +18249,8 @@ export {
18117
18249
  FilterBuilder,
18118
18250
  FixedSizeQueueCache,
18119
18251
  InsightMetrics,
18252
+ InvalidWebhookError,
18253
+ InvalidWebhookErrorMessages,
18120
18254
  JWTServerToken,
18121
18255
  JWTUserToken,
18122
18256
  LinkPreviewStatus,
@@ -18203,6 +18337,8 @@ export {
18203
18337
  createUploadConfigCheckMiddleware,
18204
18338
  createUploadErrorHandlerMiddleware,
18205
18339
  decodeBase64,
18340
+ decodeSnsPayload,
18341
+ decodeSqsPayload,
18206
18342
  defaultPollFieldBlurEventValidators,
18207
18343
  defaultPollFieldChangeEventValidators,
18208
18344
  encodeBase64,
@@ -18218,6 +18354,7 @@ export {
18218
18354
  getRawCommandName,
18219
18355
  getTokenizedSuggestionDisplayName,
18220
18356
  getTriggerCharWithToken,
18357
+ gunzipPayload,
18221
18358
  insertItemWithTrigger,
18222
18359
  isAudioAttachment,
18223
18360
  isBlobButNotFile,
@@ -18248,6 +18385,9 @@ export {
18248
18385
  logChatPromiseExecution,
18249
18386
  mapPollStateToResponse,
18250
18387
  notifyCommandDisabled,
18388
+ parseEvent,
18389
+ parseSns,
18390
+ parseSqs,
18251
18391
  pollCompositionStateProcessors,
18252
18392
  pollStateChangeValidators,
18253
18393
  postInsights,
@@ -18257,6 +18397,8 @@ export {
18257
18397
  replaceWordWithEntity,
18258
18398
  stripCommandFromText,
18259
18399
  textIsEmpty,
18260
- timeLeftMs
18400
+ timeLeftMs,
18401
+ verifyAndParseWebhook,
18402
+ verifySignature
18261
18403
  };
18262
18404
  //# sourceMappingURL=index.mjs.map