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/cjs/index.node.js
CHANGED
|
@@ -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,18 +159,24 @@ __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,
|
|
163
167
|
ensureIsLocalAttachment: () => ensureIsLocalAttachment,
|
|
168
|
+
escapeCommandRegExp: () => escapeCommandRegExp,
|
|
164
169
|
extractPollData: () => extractPollData,
|
|
165
170
|
extractPollEnrichedData: () => extractPollEnrichedData,
|
|
166
171
|
formatMessage: () => formatMessage,
|
|
167
172
|
generateFileName: () => generateFileName,
|
|
168
173
|
getAttachmentTypeFromMimeType: () => getAttachmentTypeFromMimeType,
|
|
174
|
+
getCompleteCommandInString: () => getCompleteCommandInString,
|
|
169
175
|
getExtensionFromMimeType: () => getExtensionFromMimeType,
|
|
176
|
+
getRawCommandName: () => getRawCommandName,
|
|
170
177
|
getTokenizedSuggestionDisplayName: () => getTokenizedSuggestionDisplayName,
|
|
171
178
|
getTriggerCharWithToken: () => getTriggerCharWithToken,
|
|
179
|
+
gunzipPayload: () => gunzipPayload,
|
|
172
180
|
insertItemWithTrigger: () => insertItemWithTrigger,
|
|
173
181
|
isAudioAttachment: () => isAudioAttachment,
|
|
174
182
|
isBlobButNotFile: () => isBlobButNotFile,
|
|
@@ -198,6 +206,10 @@ __export(index_exports, {
|
|
|
198
206
|
localMessageToNewMessagePayload: () => localMessageToNewMessagePayload,
|
|
199
207
|
logChatPromiseExecution: () => logChatPromiseExecution,
|
|
200
208
|
mapPollStateToResponse: () => mapPollStateToResponse,
|
|
209
|
+
notifyCommandDisabled: () => notifyCommandDisabled,
|
|
210
|
+
parseEvent: () => parseEvent,
|
|
211
|
+
parseSns: () => parseSns,
|
|
212
|
+
parseSqs: () => parseSqs,
|
|
201
213
|
pollCompositionStateProcessors: () => pollCompositionStateProcessors,
|
|
202
214
|
pollStateChangeValidators: () => pollStateChangeValidators,
|
|
203
215
|
postInsights: () => postInsights,
|
|
@@ -205,8 +217,11 @@ __export(index_exports, {
|
|
|
205
217
|
readFileAsArrayBuffer: () => readFileAsArrayBuffer,
|
|
206
218
|
removeDiacritics: () => removeDiacritics,
|
|
207
219
|
replaceWordWithEntity: () => replaceWordWithEntity,
|
|
220
|
+
stripCommandFromText: () => stripCommandFromText,
|
|
208
221
|
textIsEmpty: () => textIsEmpty,
|
|
209
|
-
timeLeftMs: () => timeLeftMs
|
|
222
|
+
timeLeftMs: () => timeLeftMs,
|
|
223
|
+
verifyAndParseWebhook: () => verifyAndParseWebhook,
|
|
224
|
+
verifySignature: () => verifySignature
|
|
210
225
|
});
|
|
211
226
|
module.exports = __toCommonJS(index_exports);
|
|
212
227
|
|
|
@@ -818,7 +833,7 @@ var deleteUserMessages = ({
|
|
|
818
833
|
if (message.user?.id === user.id) {
|
|
819
834
|
messages[i] = message.type === "deleted" ? message : toDeletedMessage({ message, hardDelete, deletedAt });
|
|
820
835
|
}
|
|
821
|
-
if (message.quoted_message?.user?.id === user.id) {
|
|
836
|
+
if (messages[i].quoted_message && message.quoted_message?.user?.id === user.id) {
|
|
822
837
|
messages[i].quoted_message = message.quoted_message.type === "deleted" ? message.quoted_message : toDeletedMessage({
|
|
823
838
|
message: messages[i].quoted_message,
|
|
824
839
|
hardDelete,
|
|
@@ -7418,6 +7433,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7418
7433
|
const draft = event.draft;
|
|
7419
7434
|
if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid)
|
|
7420
7435
|
return;
|
|
7436
|
+
if (this.editedMessage) return;
|
|
7421
7437
|
this.initState({ composition: draft });
|
|
7422
7438
|
}).unsubscribe;
|
|
7423
7439
|
this.subscribeDraftDeleted = () => this.client.on("draft.deleted", (event) => {
|
|
@@ -7425,6 +7441,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7425
7441
|
if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid) {
|
|
7426
7442
|
return;
|
|
7427
7443
|
}
|
|
7444
|
+
if (this.editedMessage) return;
|
|
7428
7445
|
this.logDraftUpdateTimestamp();
|
|
7429
7446
|
if (this.compositionIsEmpty) {
|
|
7430
7447
|
return;
|
|
@@ -9468,7 +9485,7 @@ var Channel = class {
|
|
|
9468
9485
|
if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes("read-events")) {
|
|
9469
9486
|
return false;
|
|
9470
9487
|
}
|
|
9471
|
-
if (this.
|
|
9488
|
+
if (this.getClient()._muteStatus(this.cid).muted) return false;
|
|
9472
9489
|
return true;
|
|
9473
9490
|
}
|
|
9474
9491
|
/**
|
|
@@ -10979,6 +10996,7 @@ var UploadManager = class {
|
|
|
10979
10996
|
// src/signing.ts
|
|
10980
10997
|
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
10981
10998
|
var import_crypto = __toESM(require("crypto"));
|
|
10999
|
+
var import_zlib = __toESM(require("zlib"));
|
|
10982
11000
|
function JWTUserToken(apiSecret, userId, extraData = {}, jwtOptions = {}) {
|
|
10983
11001
|
if (typeof userId !== "string") {
|
|
10984
11002
|
throw new TypeError("userId should be a string");
|
|
@@ -11030,7 +11048,7 @@ function DevToken(userId) {
|
|
|
11030
11048
|
// hardcoded signature
|
|
11031
11049
|
].join(".");
|
|
11032
11050
|
}
|
|
11033
|
-
function
|
|
11051
|
+
function verifySignature(body, signature, secret) {
|
|
11034
11052
|
const key = Buffer.from(secret, "utf8");
|
|
11035
11053
|
const hash = import_crypto.default.createHmac("sha256", key).update(body).digest("hex");
|
|
11036
11054
|
try {
|
|
@@ -11039,6 +11057,86 @@ function CheckSignature(body, secret, signature) {
|
|
|
11039
11057
|
return false;
|
|
11040
11058
|
}
|
|
11041
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
|
+
}
|
|
11042
11140
|
|
|
11043
11141
|
// src/token_manager.ts
|
|
11044
11142
|
var TokenManager = class {
|
|
@@ -14469,15 +14567,17 @@ var StreamChat = class _StreamChat {
|
|
|
14469
14567
|
defaultOptions.watch = false;
|
|
14470
14568
|
}
|
|
14471
14569
|
const { predefined_filter, filter_values, sort_values, ...restOptions } = options;
|
|
14570
|
+
const normalizedSort = normalizeQuerySort(sort);
|
|
14472
14571
|
const payload = predefined_filter ? {
|
|
14473
14572
|
predefined_filter,
|
|
14474
14573
|
filter_values,
|
|
14475
14574
|
sort_values,
|
|
14575
|
+
sort: normalizedSort,
|
|
14476
14576
|
...defaultOptions,
|
|
14477
14577
|
...restOptions
|
|
14478
14578
|
} : {
|
|
14479
14579
|
filter_conditions: filterConditions,
|
|
14480
|
-
sort:
|
|
14580
|
+
sort: normalizedSort,
|
|
14481
14581
|
...defaultOptions,
|
|
14482
14582
|
...restOptions
|
|
14483
14583
|
};
|
|
@@ -15640,7 +15740,7 @@ var StreamChat = class _StreamChat {
|
|
|
15640
15740
|
if (this.userAgent) {
|
|
15641
15741
|
return this.userAgent;
|
|
15642
15742
|
}
|
|
15643
|
-
const version = "9.
|
|
15743
|
+
const version = "9.44.0";
|
|
15644
15744
|
const clientBundle = "node-cjs";
|
|
15645
15745
|
let userAgentString = "";
|
|
15646
15746
|
if (this.sdkIdentifier) {
|
|
@@ -15733,7 +15833,50 @@ var StreamChat = class _StreamChat {
|
|
|
15733
15833
|
* @returns {boolean}
|
|
15734
15834
|
*/
|
|
15735
15835
|
verifyWebhook(requestBody, xSignature) {
|
|
15736
|
-
return !!this.secret &&
|
|
15836
|
+
return !!this.secret && verifySignature(requestBody, xSignature, this.secret);
|
|
15837
|
+
}
|
|
15838
|
+
/**
|
|
15839
|
+
* Verify and parse an HTTP webhook event.
|
|
15840
|
+
*
|
|
15841
|
+
* Decompresses `rawBody` when gzipped (detected from the body bytes),
|
|
15842
|
+
* verifies the `X-Signature` header against the app's API secret, and
|
|
15843
|
+
* returns the parsed `Event`. Works whether or not Stream is currently
|
|
15844
|
+
* compressing payloads for this app, and stays correct behind
|
|
15845
|
+
* middleware that auto-decompresses the request.
|
|
15846
|
+
*
|
|
15847
|
+
* @param rawBody Raw HTTP request body bytes Stream signed
|
|
15848
|
+
* @param signature Value of the `X-Signature` header
|
|
15849
|
+
* @throws {InvalidWebhookError} When the signature does not match or
|
|
15850
|
+
* the gzip envelope is malformed.
|
|
15851
|
+
*/
|
|
15852
|
+
verifyAndParseWebhook(rawBody, signature) {
|
|
15853
|
+
if (!this.secret) {
|
|
15854
|
+
throw new InvalidWebhookError(
|
|
15855
|
+
"cannot verify webhook signature without an API secret on the client"
|
|
15856
|
+
);
|
|
15857
|
+
}
|
|
15858
|
+
return verifyAndParseWebhook(rawBody, signature, this.secret);
|
|
15859
|
+
}
|
|
15860
|
+
/**
|
|
15861
|
+
* Parse an SQS firehose event: decodes the message `Body` (base64 +
|
|
15862
|
+
* optional gzip) and returns the parsed `Event`. No HMAC verification
|
|
15863
|
+
* (Stream does not sign SQS bodies).
|
|
15864
|
+
*
|
|
15865
|
+
* @param messageBody SQS message `Body` string
|
|
15866
|
+
* @throws {InvalidWebhookError} When the base64 / gzip envelope is malformed.
|
|
15867
|
+
*/
|
|
15868
|
+
parseSqs(messageBody) {
|
|
15869
|
+
return parseSqs(messageBody);
|
|
15870
|
+
}
|
|
15871
|
+
/**
|
|
15872
|
+
* Parse an SNS-delivered event (unwraps envelope JSON when needed, then
|
|
15873
|
+
* same decode path as SQS). No HMAC verification.
|
|
15874
|
+
*
|
|
15875
|
+
* @param notificationBody Raw SNS POST body or pre-extracted `Message` string
|
|
15876
|
+
* @throws {InvalidWebhookError} When the envelope cannot be decoded.
|
|
15877
|
+
*/
|
|
15878
|
+
parseSns(notificationBody) {
|
|
15879
|
+
return parseSns(notificationBody);
|
|
15737
15880
|
}
|
|
15738
15881
|
/** getPermission - gets the definition for a permission
|
|
15739
15882
|
*
|
|
@@ -18284,6 +18427,8 @@ var FixedSizeQueueCache = class {
|
|
|
18284
18427
|
FilterBuilder,
|
|
18285
18428
|
FixedSizeQueueCache,
|
|
18286
18429
|
InsightMetrics,
|
|
18430
|
+
InvalidWebhookError,
|
|
18431
|
+
InvalidWebhookErrorMessages,
|
|
18287
18432
|
JWTServerToken,
|
|
18288
18433
|
JWTUserToken,
|
|
18289
18434
|
LinkPreviewStatus,
|
|
@@ -18370,18 +18515,24 @@ var FixedSizeQueueCache = class {
|
|
|
18370
18515
|
createUploadConfigCheckMiddleware,
|
|
18371
18516
|
createUploadErrorHandlerMiddleware,
|
|
18372
18517
|
decodeBase64,
|
|
18518
|
+
decodeSnsPayload,
|
|
18519
|
+
decodeSqsPayload,
|
|
18373
18520
|
defaultPollFieldBlurEventValidators,
|
|
18374
18521
|
defaultPollFieldChangeEventValidators,
|
|
18375
18522
|
encodeBase64,
|
|
18376
18523
|
ensureIsLocalAttachment,
|
|
18524
|
+
escapeCommandRegExp,
|
|
18377
18525
|
extractPollData,
|
|
18378
18526
|
extractPollEnrichedData,
|
|
18379
18527
|
formatMessage,
|
|
18380
18528
|
generateFileName,
|
|
18381
18529
|
getAttachmentTypeFromMimeType,
|
|
18530
|
+
getCompleteCommandInString,
|
|
18382
18531
|
getExtensionFromMimeType,
|
|
18532
|
+
getRawCommandName,
|
|
18383
18533
|
getTokenizedSuggestionDisplayName,
|
|
18384
18534
|
getTriggerCharWithToken,
|
|
18535
|
+
gunzipPayload,
|
|
18385
18536
|
insertItemWithTrigger,
|
|
18386
18537
|
isAudioAttachment,
|
|
18387
18538
|
isBlobButNotFile,
|
|
@@ -18411,6 +18562,10 @@ var FixedSizeQueueCache = class {
|
|
|
18411
18562
|
localMessageToNewMessagePayload,
|
|
18412
18563
|
logChatPromiseExecution,
|
|
18413
18564
|
mapPollStateToResponse,
|
|
18565
|
+
notifyCommandDisabled,
|
|
18566
|
+
parseEvent,
|
|
18567
|
+
parseSns,
|
|
18568
|
+
parseSqs,
|
|
18414
18569
|
pollCompositionStateProcessors,
|
|
18415
18570
|
pollStateChangeValidators,
|
|
18416
18571
|
postInsights,
|
|
@@ -18418,7 +18573,10 @@ var FixedSizeQueueCache = class {
|
|
|
18418
18573
|
readFileAsArrayBuffer,
|
|
18419
18574
|
removeDiacritics,
|
|
18420
18575
|
replaceWordWithEntity,
|
|
18576
|
+
stripCommandFromText,
|
|
18421
18577
|
textIsEmpty,
|
|
18422
|
-
timeLeftMs
|
|
18578
|
+
timeLeftMs,
|
|
18579
|
+
verifyAndParseWebhook,
|
|
18580
|
+
verifySignature
|
|
18423
18581
|
});
|
|
18424
18582
|
//# sourceMappingURL=index.node.js.map
|