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

@jezweb/oauth-token-manager

v0.1.3

Published

OAuth token management for Cloudflare Workers - store, refresh, and retrieve tokens for downstream API access

Readme

@jezweb/oauth-token-manager

OAuth token management for Cloudflare Workers. Store, refresh, and retrieve tokens for downstream API access.

The Problem

When your application needs to call APIs on behalf of users (Google Calendar, GitHub, Xero, etc.), you need to:

  1. Store OAuth tokens securely (encrypted at rest)
  2. Refresh expired tokens automatically
  3. Retrieve valid tokens for API calls
  4. Handle errors gracefully (expired, revoked, insufficient scopes)

Most auth libraries focus on identity ("who is this user?") not API access ("act on their behalf"). This package fills that gap.

Installation

npm install @jezweb/oauth-token-manager

Quick Start

import { TokenManager, KVStorage } from '@jezweb/oauth-token-manager';

// Initialize
const tokens = new TokenManager({
  storage: new KVStorage({
    namespace: env.TOKEN_KV,
    encryptionKey: env.TOKEN_ENCRYPTION_KEY,
  }),
  providers: {
    google: {
      clientId: env.GOOGLE_CLIENT_ID,
      clientSecret: env.GOOGLE_CLIENT_SECRET,
    },
  },
});

// Store token after OAuth callback
await tokens.store({
  userId: 'user-123',
  provider: 'google',
  accessToken: 'ya29.xxx',
  refreshToken: '1//xxx',
  expiresAt: Date.now() + 3600000,
  scopes: ['https://www.googleapis.com/auth/calendar'],
});

// Get valid token (auto-refreshes if expired)
const { accessToken } = await tokens.get({
  userId: 'user-123',
  provider: 'google',
});

// Use token for API call
const response = await fetch('https://www.googleapis.com/calendar/v3/calendars', {
  headers: { Authorization: `Bearer ${accessToken}` },
});

Features

  • Encrypted storage - Tokens encrypted at rest using AES-256-GCM
  • Automatic refresh - Tokens refreshed before expiry (5 min buffer by default)
  • Scope validation - Verify required scopes before returning tokens
  • Built-in providers - Google, Microsoft, GitHub out of the box
  • Cloudflare-native - Built specifically for Workers + KV
  • Clear errors - Typed errors guide recovery actions

API

TokenManager

Main class for token management.

const tokens = new TokenManager({
  storage: TokenStorage,        // KVStorage or custom (handles encryption)
  providers: {                  // Provider configs for refresh
    google?: ProviderConfig,
    microsoft?: ProviderConfig,
    github?: ProviderConfig,
  },
  defaultRefreshBuffer?: number, // ms before expiry to refresh (default: 5 min)
});

Methods

| Method | Description | |--------|-------------| | store(options) | Store a new token or update existing | | get(options) | Get valid token (auto-refreshes) | | list(options) | List connected providers for a user | | revoke(options) | Delete a token | | has(userId, provider) | Check if token exists |

Error Types

| Error | Meaning | Recovery | |-------|---------|----------| | TokenNotFoundError | No token for user/provider | Redirect to OAuth | | TokenExpiredError | Token expired, refresh failed | Redirect to OAuth | | InsufficientScopesError | Missing required scopes | Redirect to OAuth with incremental consent | | ProviderNotConfiguredError | Provider not in config | Add provider config |

Supported Providers

| Provider | Refresh Support | Token Lifetime | Notes | |----------|-----------------|----------------|-------| | Google | ✅ Yes | ~1 hour | Requires access_type=offline | | Microsoft | ✅ Yes | ~1 hour | Token rotation by default | | GitHub | ❌ No | Never expires | Tokens valid until revoked |

Storage Adapters

KV Storage (Recommended)

import { KVStorage } from '@jezweb/oauth-token-manager/storage/kv';

const storage = new KVStorage({
  namespace: env.TOKEN_KV,
  encryptionKey: env.TOKEN_ENCRYPTION_KEY,
  keyPrefix: 'tokens', // optional, default: 'tokens'
});

D1 Storage (Coming Soon)

D1 adapter for stronger consistency and complex queries.

Wrangler Setup

# wrangler.toml
kv_namespaces = [
  { binding = "TOKEN_KV", id = "your-kv-id" }
]

[vars]
# Store encryption key as secret, not here!
# Set encryption key (generate with: openssl rand -base64 32)
echo "your-32-byte-key" | wrangler secret put TOKEN_ENCRYPTION_KEY

Use Cases

  • MCP Servers - Call Google Calendar, GitHub, etc. on behalf of users
  • CRM integrations - Sync with external calendars, email
  • Social media tools - Post to Twitter, LinkedIn
  • Accounting apps - Connect to Xero, QuickBooks

Architecture

This package handles outbound OAuth (your app calling external APIs).

For inbound OAuth (clients authenticating to your app), use:

┌─────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ MCP Client  │────▶│   Your App      │────▶│  External API   │
│ (Claude.ai) │     │                 │     │ (Google, etc)   │
└─────────────┘     └─────────────────┘     └─────────────────┘
       │                    │                       │
       ▼                    ▼                       ▼
  Inbound auth         Token Manager           External OAuth
  (who is client?)     (this package)          (act on behalf)

Security

See SECURITY.md for security considerations.

License

MIT © Jezweb