UNPKG

@sanity/webhook

Version:

Toolkit for dealing with GROQ-powered webhooks delivered by Sanity.io

208 lines (191 loc) 6.2 kB
import type {RequestHandler} from 'express' /** * Asserts that the given request is valid. * Throws an error if the request is invalid. * * @param request - The Connect/Express-like request to verify * @param secret - The secret to use for verifying the signature * @public */ export declare function assertValidRequest( request: ConnectLikeRequest, secret: string, ): Promise<void> /** * Asserts that the given signature is valid. * Throws an error if the signature is invalid. * * @param stringifiedPayload - The stringified payload to verify - should be straight from the request, not a re-encoded JSON string, as this in certain cases will yield mismatches due to inconsistent encoding. * @param signature - The signature to verify against * @param secret - The secret to use for verifying the signature * @public */ export declare function assertValidSignature( stringifiedPayload: string, signature: string, secret: string, ): Promise<void> /** * A Connect/Express-like request object, containing a `headers` object and a `body` property. * * @public */ export declare interface ConnectLikeRequest<B = unknown> { headers: Record<string, string | string[] | undefined> body: B } /** * A decoded signature header * * @public */ export declare interface DecodedSignature { /** * The timestamp the signature was created */ timestamp: number /** * The hashed payload (base64url encoded) */ hashedPayload: string } /** * Decode a signature header into a timestamp and hashed payload. * * @param signaturePayload - The signature header to decode * @returns An object with the decoded timestamp and hashed payload * @public */ export declare function decodeSignatureHeader(signaturePayload: string): DecodedSignature /** * Encodes a signature header for the given payload and timestamp. * * @param stringifiedPayload - The stringified payload to verify - should be straight from the request, not a re-encoded JSON string, as this in certain cases will yield mismatches due to inconsistent encoding. * @param timestamp - The timestamp to use for the signature * @param secret - The secret to use for verifying the signature * @returns A promise that resolves to the encoded signature header * @public */ export declare function encodeSignatureHeader( stringifiedPayload: string, timestamp: number, secret: string, ): Promise<string> /** * Checks whether or not the given error is a signature error. * * @param error - The error to check. * @returns `true` if the error is a signature error, otherwise `false`. * @public */ export declare function isSignatureError(error: unknown): error is WebhookSignatureError /** * Checks if the given request is valid. * * @param request - The Connect/Express-like request to verify * @param secret - The secret to use for verifying the signature * @returns Promise that resolves to `true` if the request is valid, `false` otherwise. * @public */ export declare function isValidRequest( request: ConnectLikeRequest, secret: string, ): Promise<boolean> /** * Checks if the given signature is valid. * * @param stringifiedPayload - The stringified payload to verify - should be straight from the request, not a re-encoded JSON string, as this in certain cases will yield mismatches due to inconsistent encoding. * @param signature - The signature to verify against * @param secret - The secret to use for verifying the signature * @returns A promise that resolves to `true` if the signature is valid, `false` otherwise. * @public */ export declare function isValidSignature( stringifiedPayload: string, signature: string, secret: string, ): Promise<boolean> /** * Express/Connect style middleware that verifies the signature of a request. * Should be added _after_ a body parser that parses the request body to _text_, not parsed JSON. * * @example * ```ts * import express from 'express' * import bodyParser from 'body-parser' * import {requireSignedRequest} from '@sanity/webhook' * * express() * .use(bodyParser.text({type: 'application/json'})) * .post( * '/hook', * requireSignedRequest({secret: process.env.MY_WEBHOOK_SECRET, parseBody: true}), * function myRequestHandler(req, res) { * // Note that `req.body` is now a parsed version, set `parseBody` to `false` * // if you want the raw text version of the request body * }, * ) * .listen(1337) * ``` * * @param options - Options for the middleware * @returns A middleware function * @public */ export declare function requireSignedRequest(options: SignatureMiddlewareOptions): RequestHandler /** * The name of the header that contains the signature. * * @public */ export declare const SIGNATURE_HEADER_NAME = 'sanity-webhook-signature' /** * Options for the `requireSignedRequest` middleware * * @public */ export declare interface SignatureMiddlewareOptions { /** * The secret to use for verifying the signature */ secret: string /** * Whether or not to parse the request body as JSON on success (assigns it to `request.body`). * Default: `true` */ parseBody?: boolean /** * Whether or not to respond with an error when the signature is invalid. * If `false`, it will call the `next` function with the error instead. * Default: `true` */ respondOnError?: boolean } /** * Error types used on signature errors. * Includes `type` and `statusCode` properties. * * @public */ export declare type WebhookSignatureError = WebhookSignatureValueError | WebhookSignatureFormatError /** * Error thrown when the signature format is invalid. * This can happen when the signature is not a string or is not in the format of `t=<timestamp>,v=<signature>`. * This error is also thrown when the timestamp is not a number or is not within the tolerance time. * * @public */ export declare class WebhookSignatureFormatError extends Error { type: string statusCode: number } /** * Error thrown when the signature value does not match the expected value. * * @public */ export declare class WebhookSignatureValueError extends Error { type: string statusCode: number } export {}