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

secure-server-fetch

v1.0.3

Published

A secure, server-side HTTP client with built-in API key validation, rate limiting, and security features

Readme

Secure Server Fetch

A secure, server-side HTTP client with built-in API key validation, rate limiting, and security features.

Features

  • 🔒 Server-side only execution
  • 🔑 API key validation and requirement
  • ⏱️ Rate limiting with Redis
  • 🔐 HTTPS enforcement
  • ⚡ Request timeout handling
  • 🛡️ Comprehensive error handling

Installation

npm install secure-server-fetch
# or
yarn add secure-server-fetch

Environment Variables Setup

Create a .env file in your project root:

UPSTASH_REDIS_REST_URL=your_redis_url
UPSTASH_REDIS_REST_TOKEN=your_redis_token

Both variables are required for rate limiting functionality. The Redis URL must be a valid HTTPS URL.

Usage Examples

Basic Fetch with API Key

import { secureServerFetch } from 'secure-server-fetch';

async function fetchData() {
  try {
    const data = await secureServerFetch('https://api.example.com/data', {
      apiKey: 'your-api-key',
      timeout: 5000, // 5 seconds
    });
    return data;
  } catch (error) {
    console.error('Fetch failed:', error);
  }
}

API Key Validation

import { requireApiKey } from 'secure-server-fetch';

// In your API route handler
export async function handler(request: Request) {
  const apiKeyCheck = requireApiKey(request, 'your-expected-api-key');
  if (apiKeyCheck) {
    return apiKeyCheck; // Returns 401 response if validation fails
  }
  
  // Continue with your API logic
}

API Key Requirements

The API key validation enforces the following requirements:

  • Length: Must be at least 32 characters long
  • Character Set: Can only contain:
    • Uppercase letters (A-Z)
    • Lowercase letters (a-z)
    • Numbers (0-9)
    • Underscores (_)
    • Hyphens (-)
  • Character Mix: Must contain at least:
    • One uppercase letter
    • One lowercase letter
    • One number

Error Responses

All error responses are returned in JSON format with appropriate HTTP status codes:

  1. Missing API Key (Status: 401)
{
  "error": "API key is missing",
  "message": "Please provide 'x-api-key' header with a valid API key",
  "requirements": {
    "format": "Must be at least 32 characters long",
    "characters": "Can only contain letters, numbers, underscores, and hyphens",
    "complexity": "Must contain at least one uppercase letter, one lowercase letter, and one number"
  }
}
  1. Empty API Key (Status: 401)
{
  "error": "Empty API key",
  "message": "API key cannot be empty",
  "requirements": {
    "format": "Must be at least 32 characters long",
    "characters": "Can only contain letters, numbers, underscores, and hyphens",
    "complexity": "Must contain at least one uppercase letter, one lowercase letter, and one number"
  }
}
  1. Invalid Format (Status: 401)
{
  "error": "Invalid API key format",
  "message": "[Specific validation error message]",
  "requirements": {
    "format": "Must be at least 32 characters long",
    "characters": "Can only contain letters, numbers, underscores, and hyphens",
    "complexity": "Must contain at least one uppercase letter, one lowercase letter, and one number"
  }
}
  1. Invalid API Key (Status: 401)
{
  "error": "Invalid API key",
  "message": "The provided API key is not valid"
}

Rate Limiting

import { rateLimit } from 'secure-server-fetch';

async function handleRequest(request: Request) {
  try {
    const rateLimitResult = await rateLimit(request, 'unique-identifier', {
      maxRequests: 100,
      timeframeMs: 60000, // 1 minute
    });

    // Rate limit headers will be automatically included in rateLimitResult.headers
    
    // Your API logic here
    
  } catch (error) {
    if (error.name === 'RateLimitError') {
      return new Response('Rate limit exceeded', { status: 429 });
    }
  }
}

API Reference

secureServerFetch(url, options)

Makes a secure server-side HTTP request.

Options

  • apiKey?: string - API key for authentication
  • requireHttps?: boolean - Enforce HTTPS (default: true)
  • timeout?: number - Request timeout in ms (default: 30000)
  • ...RequestInit - All standard fetch options

requireApiKey(request, expectedKey)

Validates API key from request headers.

  • request: Request - Incoming request object
  • expectedKey: string - The API key to validate against

rateLimit(request, identifier, options)

Implements rate limiting for requests.

Options

  • maxRequests: number - Maximum requests allowed
  • timeframeMs: number - Time window in milliseconds
  • prefix?: string - Redis key prefix

Security Best Practices

  1. API Keys

    • Use keys at least 32 characters long
    • Include mix of uppercase, lowercase, and numbers
    • Rotate keys periodically
    • Store keys securely in environment variables
  2. Rate Limiting

    • Implement rate limiting on all public endpoints
    • Use unique identifiers (e.g., IP, user ID)
    • Set appropriate limits based on endpoint sensitivity
  3. HTTPS

    • Always use HTTPS in production
    • Only disable HTTPS requirement in development
  4. Error Handling

    • Never expose internal errors to clients
    • Use provided error classes for consistent handling
    • Log errors securely

Error Handling

The library provides specific error classes:

  • ServerSideError: For client-side execution attempts
  • NetworkError: For network and HTTP errors
  • ValidationError: For input validation failures
  • RateLimitError: For rate limit violations

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests.

License

MIT