npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@xyz/webhook-verifier

v1.3.1

Published

A lightweight library for verifying webhook signatures

Readme

Webhook Verifier

A lightweight library for verifying webhook signatures.

Installation

npm install @xyz/webhook-verifier

Usage

import { WebhookVerifier } from '@xyz/webhook-verifier';

// Create a verifier with your configuration
const verifier = new WebhookVerifier({
  secretKey: process.env.SECRET_KEY,
  signatureHeader: 'x-signature', // The name of the header containing the signature
  encoding: 'base64'
});

// In your webhook handler (e.g., in an Express route)
app.post('/webhook', (req, res) => {
  // Pass request headers directly - signature will be automatically extracted
  const result = verifier.verify(req.body, req.headers);
  
  if (!result.isValid) {
    console.error('Invalid webhook signature:', result.error);
    return res.status(401).json({ status: 'error', message: 'Invalid signature' });
  }
  
  // Process the verified webhook data
  console.log('Verified webhook payload:', result.data);
  return res.status(200).json({ status: 'success' });
});

// You can also verify with a signature string directly
app.post('/webhook/manual', (req, res) => {
  const signature = req.headers['x-signature'] as string;
  const result = verifier.verify(req.body, signature);
  
  // Rest of handler...
});

Configuration Options

The WebhookVerifier accepts the following configuration options:

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | secretKey | string | Yes | - | The secret key used to verify the signature | | signatureHeader | string | Yes | - | The name of the header that contains the signature | | signaturePrefix | string | No | - | A prefix for the signature (e.g., "sha256=") | | hashAlgorithm | string | No | "sha256" | The hashing algorithm to use | | encoding | "hex" | "base64" | No | "hex" | The encoding format for the signature | | payloadFormatter | function | No | JSON.stringify | A function to format the payload before hashing |

Verification Method

The WebhookVerifier provides an intelligent verify method that can handle both signature strings and header objects:

verify(payload: WebhookPayload, signatureOrHeaders: string | Record<string, any>): VerificationResult

This method intelligently detects whether the second argument is:

  • A string: treated as the signature directly
  • An object: treated as headers from which it extracts the signature using signatureHeader

When using headers, the method:

  • Handles case-insensitive header lookups
  • Works with headers that are strings or arrays of strings (for different HTTP libraries)
  • Returns a clear error message if the signature is missing

Predefined Configurations

The library includes predefined configuration templates for common webhook providers. Note: These templates do not include a secret key - you must provide your own.

import { WebhookVerifier } from '@xyz/webhook-verifier';
import { tap, invoiless } from '@xyz/webhook-verifier/configs';

// Using a predefined config template (you must add your secret key)
const tapVerifier = new WebhookVerifier({
  ...tap,
  secretKey: process.env.TAP_SECRET_KEY // Add your own secret key
});

// In your request handler
app.post('/webhook/tap', (req, res) => {
  // Automatically use the correct header name from the config
  const result = tapVerifier.verify(req.body, req.headers);
  
  if (result.isValid) {
    // Process the webhook...
  }
});

// You can also customize other options while using the predefined config
const customVerifier = new WebhookVerifier({
  ...invoiless,
  secretKey: process.env.MY_SECRET_KEY,
  hashAlgorithm: 'sha512' // Override specific options as needed
});

Custom Formatters

The library provides specialized formatters for common webhook providers, which can be imported directly:

import { WebhookVerifier } from '@xyz/webhook-verifier';
import { tap, invoiless } from '@xyz/webhook-verifier/formatters';

// Using a pre-defined formatter
const verifier = new WebhookVerifier({
  secretKey: process.env.SECRET_KEY,
  signatureHeader: 'x-signature',
  payloadFormatter: tap
});

Creating Custom Formatters

You can create your own custom formatters by defining a function that takes a webhook payload and returns a string:

import { WebhookVerifier, WebhookPayload } from '@xyz/webhook-verifier';

// Define a custom formatter
const myCustomFormatter = (payload: WebhookPayload): string => {
  return `${payload.eventType}|${payload.id}|${JSON.stringify(payload.data)}`;
};

// Use the custom formatter
const verifier = new WebhookVerifier({
  secretKey: process.env.SECRET_KEY,
  signatureHeader: 'x-signature',
  payloadFormatter: myCustomFormatter
});

License

MIT