stream-chat 9.43.1 → 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 +156 -7
- package/dist/cjs/index.browser.js.map +3 -3
- package/dist/cjs/index.node.js +166 -8
- package/dist/cjs/index.node.js.map +3 -3
- package/dist/esm/index.mjs +156 -7
- package/dist/esm/index.mjs.map +3 -3
- package/dist/types/client.d.ts +36 -4
- package/dist/types/messageComposer/middleware/textComposer/index.d.ts +1 -0
- package/dist/types/signing.d.ts +99 -5
- package/dist/types/types.d.ts +121 -15
- package/package.json +2 -1
- package/src/channel.ts +3 -1
- package/src/client.ts +78 -11
- package/src/messageComposer/messageComposer.ts +2 -0
- package/src/messageComposer/middleware/textComposer/index.ts +1 -0
- package/src/signing.ts +195 -7
- package/src/types.ts +133 -15
- 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 {
|
|
@@ -14301,15 +14390,17 @@ var StreamChat = class _StreamChat {
|
|
|
14301
14390
|
defaultOptions.watch = false;
|
|
14302
14391
|
}
|
|
14303
14392
|
const { predefined_filter, filter_values, sort_values, ...restOptions } = options;
|
|
14393
|
+
const normalizedSort = normalizeQuerySort(sort);
|
|
14304
14394
|
const payload = predefined_filter ? {
|
|
14305
14395
|
predefined_filter,
|
|
14306
14396
|
filter_values,
|
|
14307
14397
|
sort_values,
|
|
14398
|
+
sort: normalizedSort,
|
|
14308
14399
|
...defaultOptions,
|
|
14309
14400
|
...restOptions
|
|
14310
14401
|
} : {
|
|
14311
14402
|
filter_conditions: filterConditions,
|
|
14312
|
-
sort:
|
|
14403
|
+
sort: normalizedSort,
|
|
14313
14404
|
...defaultOptions,
|
|
14314
14405
|
...restOptions
|
|
14315
14406
|
};
|
|
@@ -15472,7 +15563,7 @@ var StreamChat = class _StreamChat {
|
|
|
15472
15563
|
if (this.userAgent) {
|
|
15473
15564
|
return this.userAgent;
|
|
15474
15565
|
}
|
|
15475
|
-
const version = "9.
|
|
15566
|
+
const version = "9.44.0";
|
|
15476
15567
|
const clientBundle = "browser-esm";
|
|
15477
15568
|
let userAgentString = "";
|
|
15478
15569
|
if (this.sdkIdentifier) {
|
|
@@ -15565,7 +15656,50 @@ var StreamChat = class _StreamChat {
|
|
|
15565
15656
|
* @returns {boolean}
|
|
15566
15657
|
*/
|
|
15567
15658
|
verifyWebhook(requestBody, xSignature) {
|
|
15568
|
-
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);
|
|
15569
15703
|
}
|
|
15570
15704
|
/** getPermission - gets the definition for a permission
|
|
15571
15705
|
*
|
|
@@ -18115,6 +18249,8 @@ export {
|
|
|
18115
18249
|
FilterBuilder,
|
|
18116
18250
|
FixedSizeQueueCache,
|
|
18117
18251
|
InsightMetrics,
|
|
18252
|
+
InvalidWebhookError,
|
|
18253
|
+
InvalidWebhookErrorMessages,
|
|
18118
18254
|
JWTServerToken,
|
|
18119
18255
|
JWTUserToken,
|
|
18120
18256
|
LinkPreviewStatus,
|
|
@@ -18201,18 +18337,24 @@ export {
|
|
|
18201
18337
|
createUploadConfigCheckMiddleware,
|
|
18202
18338
|
createUploadErrorHandlerMiddleware,
|
|
18203
18339
|
decodeBase64,
|
|
18340
|
+
decodeSnsPayload,
|
|
18341
|
+
decodeSqsPayload,
|
|
18204
18342
|
defaultPollFieldBlurEventValidators,
|
|
18205
18343
|
defaultPollFieldChangeEventValidators,
|
|
18206
18344
|
encodeBase64,
|
|
18207
18345
|
ensureIsLocalAttachment,
|
|
18346
|
+
escapeCommandRegExp,
|
|
18208
18347
|
extractPollData,
|
|
18209
18348
|
extractPollEnrichedData,
|
|
18210
18349
|
formatMessage,
|
|
18211
18350
|
generateFileName,
|
|
18212
18351
|
getAttachmentTypeFromMimeType,
|
|
18352
|
+
getCompleteCommandInString,
|
|
18213
18353
|
getExtensionFromMimeType,
|
|
18354
|
+
getRawCommandName,
|
|
18214
18355
|
getTokenizedSuggestionDisplayName,
|
|
18215
18356
|
getTriggerCharWithToken,
|
|
18357
|
+
gunzipPayload,
|
|
18216
18358
|
insertItemWithTrigger,
|
|
18217
18359
|
isAudioAttachment,
|
|
18218
18360
|
isBlobButNotFile,
|
|
@@ -18242,6 +18384,10 @@ export {
|
|
|
18242
18384
|
localMessageToNewMessagePayload,
|
|
18243
18385
|
logChatPromiseExecution,
|
|
18244
18386
|
mapPollStateToResponse,
|
|
18387
|
+
notifyCommandDisabled,
|
|
18388
|
+
parseEvent,
|
|
18389
|
+
parseSns,
|
|
18390
|
+
parseSqs,
|
|
18245
18391
|
pollCompositionStateProcessors,
|
|
18246
18392
|
pollStateChangeValidators,
|
|
18247
18393
|
postInsights,
|
|
@@ -18249,7 +18395,10 @@ export {
|
|
|
18249
18395
|
readFileAsArrayBuffer,
|
|
18250
18396
|
removeDiacritics,
|
|
18251
18397
|
replaceWordWithEntity,
|
|
18398
|
+
stripCommandFromText,
|
|
18252
18399
|
textIsEmpty,
|
|
18253
|
-
timeLeftMs
|
|
18400
|
+
timeLeftMs,
|
|
18401
|
+
verifyAndParseWebhook,
|
|
18402
|
+
verifySignature
|
|
18254
18403
|
};
|
|
18255
18404
|
//# sourceMappingURL=index.mjs.map
|