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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@trustsig/server

v2.3.0

Published

Node.js and Edge SDK for TrustSig — token verification and local decryption

Readme

@trustsig/server

Node.js and Edge SDK for TrustSig bot protection. Handles token verification and local decryption. Requires Node.js 18+.

Installation

npm install @trustsig/server

Usage

import { TrustSig } from '@trustsig/server';

const ts = new TrustSig({ secretKey: process.env.TRUSTSIG_SECRET_KEY });

const token = request.headers.get('X-TrustSig-Response'); // string | null

const result = await ts.verifyRemote(token);

// Allow-list check: fail-closed. Every failure mode resolves to BLOCK.
if (result.action !== 'ALLOW') {
  throw new Error(`Access denied (${result.error ?? result.action})`);
}

The result contract

verifyLocal and verifyRemote return the same shape and never throw — they always resolve to a decision:

| Field | Type | Notes | | --- | --- | --- | | action | 'ALLOW' \| 'CHALLENGE' \| 'BLOCK' | All failures normalise to BLOCK. | | blocked | boolean | Equals action !== 'ALLOW'. | | error | TrustSigErrorCode \| null | null on success; otherwise TOKEN_MISSING, TOKEN_EXPIRED, TOKEN_REUSED, CRYPTO_FAIL, API_FAIL, or MALFORMED_RESPONSE. | | is_bot | boolean | | | score | number | 0–100, higher = more suspicious. | | request_id | string | Correlation id; usable for an app-side replay cache. | | factors | string[] | Contributing signals. | | evidence | Record<string, unknown> | Raw signal detail. | | site_key | string | |

Gate access with action !== 'ALLOW' or blocked. Never match the old BLOCK_CRYPTO_FAIL / BLOCK_API_FAIL strings — they no longer exist.

Verification Methods

  • verifyLocal(token) — decrypts locally with ChaCha20-Poly1305. Zero latency, no network. Checks decryptability, age, and (by default) per-token reuse via an in-process cache. See Replay protection below for the cap and how to tune or disable it.
  • verifyRemote(token) — validates against the TrustSig Edge API. Replay-resistant via the server-side nonce, full telemetry, configurable timeout. Recommended for authentication, payments, and account changes.

Replay protection

verifyLocal ships with a small in-process cache that hashes every accepted token (SHA-256) and caps how many times the same token may be verified. By default the same token is accepted up to 4 times; the 5th call resolves to action: 'BLOCK' with error: 'TOKEN_REUSED'. Entries auto-evict at the token's own expiry (issued_at + maxTokenAgeSeconds, default 300s / 5 minutes), so memory growth is bounded by the in-flight token set.

// Defaults: replayProtection on, 4 uses per token.
const ts = new TrustSig({ secretKey });

// Tighter — single-use tokens (server-rendered checkout, OTP confirmation, …).
const oneShot = new TrustSig({ secretKey, maxUsesPerToken: 1 });

// Looser — keep tracking but raise the cap.
const generous = new TrustSig({ secretKey, maxUsesPerToken: 50 });

// Off — accept the same token unlimited times within its age window.
const noReplay = new TrustSig({ secretKey, replayProtection: false });

// Tests / manual operator reset.
ts.clearReplayCache();

Runtime requirement. The cache lives in process memory, so it only enforces the cap inside a long-lived server: a Node process, a container, a fly.io machine, a Cloud Run instance with min-instances >= 1, a worker on a queue. It is not preserved across cold starts or shared between horizontally scaled instances. In per-request serverless runtimes (each invocation spawns a fresh process) the cache always starts empty and the cap cannot be enforced — set replayProtection: false to drop the overhead, or call verifyRemote() which validates the nonce server-side.

Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | secretKey | string | required | Secret key. Server-side only — never expose to the browser. | | env | PROD \| DEMO \| DEV | PROD | Selects the default endpoint host. | | endpoint | string | env-derived | Override the verification endpoint. | | timeoutMs | number | 5000 | verifyRemote network timeout; abort fails closed. | | maxTokenAgeSeconds | number | 300 | Max accepted token age for verifyLocal. Also the eviction TTL for replay-cache entries. | | clockSkewSeconds | number | 30 | Tolerance for future-dated tokens. | | replayProtection | boolean | true | Track token hashes in process memory and cap reuse via verifyLocal. Set false in serverless runtimes. | | maxUsesPerToken | number | 4 | Maximum times the same token may pass verifyLocal before TOKEN_REUSED. Ignored when replayProtection is false. |