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.
- package/README.md +1 -1
- package/dist/cjs/index.browser.js +148 -6
- package/dist/cjs/index.browser.js.map +3 -3
- package/dist/cjs/index.node.js +153 -7
- package/dist/cjs/index.node.js.map +3 -3
- package/dist/esm/index.mjs +148 -6
- package/dist/esm/index.mjs.map +3 -3
- package/dist/types/client.d.ts +32 -0
- package/dist/types/signing.d.ts +99 -5
- package/package.json +2 -1
- package/src/channel.ts +3 -1
- package/src/client.ts +56 -2
- package/src/messageComposer/messageComposer.ts +2 -0
- package/src/signing.ts +195 -7
- package/src/utils.ts +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -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.
|
|
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
|
|
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.
|
|
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 &&
|
|
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
|