stream-chat
Version:
JS SDK for the Stream Chat API
125 lines (124 loc) • 5.61 kB
TypeScript
import jwt from 'jsonwebtoken';
import type { Event, UR } from './types';
/**
* Creates the JWT token that can be used for a UserSession
* @method JWTUserToken
* @memberof signing
* @private
* @param {Secret} apiSecret - API Secret key
* @param {string} userId - The user_id key in the JWT payload
* @param {UR} [extraData] - Extra that should be part of the JWT token
* @param {SignOptions} [jwtOptions] - Options that can be past to jwt.sign
* @return {string} JWT Token
*/
export declare function JWTUserToken(apiSecret: jwt.Secret, userId: string, extraData?: UR, jwtOptions?: jwt.SignOptions): string;
export declare function JWTServerToken(apiSecret: jwt.Secret, jwtOptions?: jwt.SignOptions): string;
export declare function UserFromToken(token: string): string;
/**
*
* @param {string} userId the id of the user
* @return {string}
*/
export declare function DevToken(userId: string): string;
/**
* Constant-time HMAC-SHA256 verification of `signature` against the
* digest of `body` using `secret` as the key. The signature is always
* computed over the **uncompressed** JSON bytes, so callers that
* decoded a gzipped or base64-wrapped payload must pass the inflated
* bytes here.
*
* The legacy `client.verifyWebhook` helper wraps this function, so
* callers that have already migrated to `verifyAndParseWebhook`,
* `parseSqs`, or `parseSns` rarely need to invoke this
* directly.
*/
export declare function verifySignature(body: string | Buffer, signature: string, secret: string): boolean;
/**
* @deprecated Use {@link verifySignature} - same logic, parameters
* reordered to match the cross-SDK contract
* (`verifySignature(body, signature, secret)`).
*/
export declare function CheckSignature(body: string | Buffer, secret: string, signature: string): boolean;
/**
* Canonical failure-mode messages for {@link InvalidWebhookError}.
*
* Customers that prefer exact-match filtering (security logging, retry
* policy) over substring matches can compare `err.message` to these
* constants instead of pattern-matching free-form text.
*/
export declare const InvalidWebhookErrorMessages: {
readonly signatureMismatch: "signature mismatch";
readonly invalidBase64: "invalid base64 encoding";
readonly gzipFailed: "gzip decompression failed";
readonly invalidJson: "invalid JSON payload";
};
/**
* Thrown by {@link verifyAndParseWebhook} when the supplied `x-signature` does not
* match the HMAC of the uncompressed payload, and by all webhook helpers (including
* {@link parseSqs} / {@link parseSns}) when a gzip / base64 / JSON envelope is malformed.
*
* The message identifies which failure mode fired. See
* {@link InvalidWebhookErrorMessages} for the canonical strings.
*/
export declare class InvalidWebhookError extends Error {
name: string;
constructor(message?: string);
}
/**
* Returns `body` as a `Buffer`, gzip-decompressed when its first two
* bytes match the gzip magic (`1f 8b`, per RFC 1952). When the body is
* plain JSON (no compression, or middleware already decompressed), the
* bytes are returned unchanged.
*
* Magic-byte detection (rather than relying on a header) keeps the
* same handler correct when middleware - Express, Next.js, AWS Lambda
* - auto-decompresses the request before your code sees it.
*/
export declare function gunzipPayload(rawBody: string | Buffer): Buffer;
/**
* Reverses the SQS firehose envelope: the message `Body` is
* base64-decoded, then the result is gzip-decompressed when it begins
* with the gzip magic. Returns the raw JSON `Buffer` Stream signed.
*
* SQS bodies are always base64-encoded so they remain valid UTF-8 over
* the queue. The same call works whether or not Stream is currently
* compressing payloads for this app.
*/
export declare function decodeSqsPayload(body: string): Buffer;
/**
* Reverses an SNS HTTP notification envelope. When `notificationBody`
* is a JSON envelope (`{"Type":"Notification","Message":"..."}`), the
* inner `Message` field is extracted and run through the SQS pipeline
* (base64-decode, then gzip-if-magic). When the input is not a JSON
* envelope it is treated as the already-extracted `Message` string,
* so call sites that pre-unwrap continue to work.
*/
export declare function decodeSnsPayload(notificationBody: string): Buffer;
/**
* Parse a JSON-encoded webhook event into a typed {@link Event}. New
* event types Stream introduces still parse successfully - the runtime
* shape is the JSON Stream sent and the `type` field stays preserved.
*/
export declare function parseEvent(payload: Buffer | string): Event;
/**
* Decompress (when gzipped), verify the HMAC `signature`, and return
* the parsed {@link Event}.
*
* @param rawBody Raw HTTP request body bytes Stream signed
* @param signature Value of the `X-Signature` header
* @param secret Your app's API secret
* @throws {InvalidWebhookError} When the signature does not match or
* the gzip envelope is malformed.
*/
export declare function verifyAndParseWebhook(rawBody: string | Buffer, signature: string, secret: string): Event;
/**
* Decode the SQS message `Body` (base64, then gzip-if-magic) and return
* the parsed {@link Event}. Stream does not attach an application-level HMAC
* to SQS deliveries — use {@link verifyAndParseWebhook} for HTTP webhooks.
*/
export declare function parseSqs(messageBody: string): Event;
/**
* Decode an SNS notification (unwrap the JSON envelope when needed; same
* inner format as SQS). No application-level HMAC verification.
*/
export declare function parseSns(notificationBody: string): Event;