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

@bambsdev/auth

v1.4.13

Published

> πŸ” **The Complete Authentication Solution** for Hono, Cloudflare Workers (Edge Runtime), and Drizzle ORM.

Readme

@bambsdev/auth

πŸ” The Complete Authentication Solution for Hono, Cloudflare Workers (Edge Runtime), and Drizzle ORM.

@bambsdev/auth (v1.4.0) is a production-ready, type-safe, multi-database authentication library designed specifically for the Cloudflare Workers ecosystem. It provides everything from standard JWT auth and family-based refresh token rotation to Google OAuth, AI-moderated avatar uploads (Cloudflare R2 + Workers AI), customizable verification flows (OTP / Link), and automated OpenAPI/Swagger documentation.


πŸ— Architecture & Tech Stack

This package follows a Clean Service Layer Architecture. Business logic is strictly decoupled from routing and infrastructure, ensuring high testability, modularity, and edge runtime compatibility.

Core Technologies

  • Framework: Hono (powered by @hono/zod-openapi for automatic OpenAPI/Swagger documentation)
  • Runtime: Cloudflare Workers (Edge Serverless)
  • Multi-Database Support:
    • PostgreSQL: Subpath @bambsdev/auth/pg via Cloudflare Hyperdrive / node-postgres
    • Cloudflare D1 (SQLite): Subpath @bambsdev/auth/d1 via Cloudflare native D1 Edge Database
    • Shared Core: Root @bambsdev/auth for shared types, utilities, and schemas
  • ORM: Drizzle ORM
  • Storage: Cloudflare R2 (for avatar storage & orphan cleanup)
  • State & Caching: Two-tier caching (Cloudflare Cache API L1 + Cloudflare KV L2) for rate limiting, blacklisting, and OAuth CSRF states
  • AI Moderation: Cloudflare Workers AI (@cf/microsoft/resnet-50 for image safety classification)
  • Observability: Cloudflare Analytics Engine (for non-blocking audit logging)
  • Email Service: Resend API via native fetch (for OTP codes, verification links, and password resets)

✨ Key Features

πŸ›‘οΈ Core Authentication & Session Management

  • Token Rotation & Grace Period (Leeway Window): Refresh token rotation with family-based tracking and a 30-second leeway window (RFC 6749 / Auth0 standard) to handle spam reloads and concurrent requests seamlessly. If an old token is reused outside the grace period, all tokens in the family are automatically revoked.
  • Strict Session Limits (Max 10): Prevents session hoarding by automatically revoking the oldest session (FIFO) when a user exceeds 10 active devices/sessions.
  • Session Control: List active devices, revoke individual sessions, or execute a global "Logout from all devices" command.
  • Ultra-Low Cost Rate Limiting (CF Cache API L1 + Lazy KV): Failed attempts are tracked in free L1 Cache API; KV is only written when brute-force threshold is breached, eliminating up to 95% of KV write operations.
  • Adaptive Cookie Management: Configurable cookie name (COOKIE_NAME) and domain (COOKIE_DOMAIN) with HttpOnly, Secure, and adaptive SameSite (Lax for first-party root sharing, None for cross-site dev/preview environments).
  • Two-Tier Edge Cache: L1 Cache API + L2 KV caching with negative caching ("0") reducing KV read costs by up to 99%.

πŸ“² Cross-Client Session Handoff (Mobile-to-Web SSO)

  • One-Time Magic Ticket: Enables seamless session transfer from mobile applications to mobile browsers / web checkout without forcing users to re-enter credentials.
  • Zero Replay Attacks: Tokens are cryptographically secure 64-character hex strings stored temporarily in Cloudflare KV with a short TTL (default 180s / 3 minutes) and destroyed immediately upon exchange.
  • Target Redirection: Supports optional redirectUrl parameter to route users directly to specific destinations (e.g. checkout, invoice, or library) with active session state.

πŸ“¨ Flexible Email Verification & Password Reset

  • Verification Modes: Choose between 6-digit numeric OTP codes or URL verification links (verificationMethod: "code" | "link").
  • Customizable Templates: Fully customizable email templates and configurable OTP TTL.
  • Secure Password Reset: Transactional password reset with 64-character hex tokens and automatic invalidation of old unused tokens.
  • Password Reuse Prevention: Rejects password changes if the new password is identical to the current one.

🌐 Google OAuth 2.0 & RFC 7636 PKCE

  • Zero-KV OAuth Flow & PKCE Defense: Full RFC 7636 PKCE (code_challenge S256 + code_verifier) with signed HttpOnly cookie storage (oauth_session), eliminating 100% of KV reads/writes during Google login.
  • Web Flow: Standard redirect flow with RFC 6750 compliant URL Fragment delivery (#accessToken=...) preventing token leakage in logs and referrers.
  • Mobile Flow: Direct Google ID token verification via Native SDKs (Android/iOS).
  • Smart Account Linking: Atomically links Google logins to existing accounts with matching email addresses.
  • Open Redirect Protection: Strict fail-closed validation of redirect URLs against ALLOWED_ORIGINS (supports wildcard subdomains like *.example.pages.dev or https://*.pages.dev) and APP_URL.

πŸ‘€ Avatar Uploads (Cloudflare R2 + Workers AI Moderation)

  • Built-in AI Moderation: Uses @cf/microsoft/resnet-50 to classify uploaded avatars.
  • SSRF Protection: Strict URL validation blocking private IPs, metadata endpoints (169.254.169.254), and localhost before fetching images.
  • Automatic Storage Cleanup: Deletes old avatar files from R2 automatically upon new upload or deletion.
  • R2 Proxy Endpoint: Built-in streaming proxy route for R2 files when custom domains are not configured.

πŸ“¦ Subpath Package Exports

| Subpath | Dialect / Target | Database Middleware | Primary Use Case | | :--- | :--- | :--- | :--- | | @bambsdev/auth/pg | PostgreSQL | dbMiddleware | Cloudflare Workers using Hyperdrive / PostgreSQL | | @bambsdev/auth/d1 | Cloudflare D1 | dbMiddleware | Cloudflare Workers using native Cloudflare D1 (SQLite) | | @bambsdev/auth | Core Agnostic | N/A | Shared schemas, types, error utilities, and helpers |


πŸš€ Installation & Setup

1. Install the Package

bun add @bambsdev/auth

2. Peer Dependencies

Install the peer dependencies required for your database choice:

# For PostgreSQL Workers:
bun add hono @hono/zod-openapi drizzle-orm pg zod

# For Cloudflare D1 Workers (zero pg dependencies needed):
bun add hono @hono/zod-openapi drizzle-orm zod

⚑ Quick Start Examples

Option A: PostgreSQL Worker (@bambsdev/auth/pg)

import { Hono } from "hono";
import { authRoutes, settingRoutes, dbMiddleware } from "@bambsdev/auth/pg";
import type { PgBindings, PgVariables } from "@bambsdev/auth/pg";
import type { EmailConfig } from "@bambsdev/auth";

const app = new Hono<{ Bindings: PgBindings; Variables: PgVariables }>();

// Injects Drizzle PostgreSQL client into context
app.use("*", dbMiddleware);

// Optional Email Configuration
const emailConfig: EmailConfig = {
  from: "No-Reply <[email protected]>",
  verificationMethod: "code", // "code" (OTP) | "link" (URL)
  verificationCodeTtlMinutes: 10,
  resetPasswordBaseUrl: "https://myapp.com",
};

app.use("*", async (c, next) => {
  c.set("emailConfig", emailConfig);
  // Optional Image Filter Configuration (AI Moderation)
  c.set("imageFilterConfig", {
    enabled: true, // set to false to bypass AI moderation
    failOpenOnAiError: true, // allow upload if Workers AI service errors or is unreachable
    confidenceThreshold: 0.50, // detection threshold (default: 0.15)
    allowAvatarUpload: true, // Optional: set to false to disable avatar uploads (default: true)
  });
  await next();
});

// Mount routes
app.route("/auth", authRoutes);
app.route("/api/settings", settingRoutes);

export default app;

Option B: Cloudflare D1 Worker (@bambsdev/auth/d1)

import { Hono } from "hono";
import { authRoutes, settingRoutes, dbMiddleware } from "@bambsdev/auth/d1";
import type { D1Bindings, D1Variables } from "@bambsdev/auth/d1";
import type { EmailConfig } from "@bambsdev/auth";

const app = new Hono<{ Bindings: D1Bindings; Variables: D1Variables }>();

// Injects Drizzle D1 client into context
app.use("*", dbMiddleware);

// Mount routes
app.route("/auth", authRoutes);
app.route("/api/settings", settingRoutes);

export default app;

βš™οΈ Wrangler Configuration

Example wrangler.jsonc configuration:

{
  "name": "my-auth-worker",
  "main": "src/index.ts",
  "compatibility_date": "2024-09-23",
  "vars": {
    "APP_URL": "https://myapp.com",
    "ALLOWED_ORIGINS": "https://myapp.com,https://admin.myapp.com,https://*.pages.dev",
    "COOKIE_NAME": "my_auth_rf", // Optional, defaults to "refresh_token"
    "COOKIE_DOMAIN": ".myapp.com", // Optional, enables first-party root cookie sharing
    "COOKIE_SAME_SITE": "Lax", // Optional, "Lax" | "Strict" | "None"
    "REFRESH_TOKEN_GRACE_PERIOD_SECONDS": "30", // Optional, grace period in seconds (default: 30)
    "ALLOW_AVATAR_UPLOAD": "true", // Optional: "true" (default) or "false" to disable avatar uploads
    "EMAIL_FROM": "No-Reply <[email protected]>",
    "BUCKET_PUBLIC_URL": "https://pub-xxx.r2.dev",
    "GOOGLE_CLIENT_ID": "xxx.apps.googleusercontent.com",
    "GOOGLE_CLIENT_SECRET": "GOCSPX-xxx",
    "GOOGLE_ALLOWED_CLIENT_IDS": "android-client-id,ios-client-id",
    "JWT_SECRET": "your-jwt-access-secret-min-32-chars",
    "JWT_REFRESH_SECRET": "your-jwt-refresh-secret-min-32-chars",
    "RESEND_API_KEY": "re_xxx"
  },
  // For PostgreSQL:
  "hyperdrive": [
    { "binding": "HYPERDRIVE", "id": "<your-hyperdrive-id>" }
  ],
  // For Cloudflare D1:
  "d1_databases": [
    { "binding": "DB", "database_name": "my-auth-db", "database_id": "<your-d1-id>" }
  ],
  "kv_namespaces": [
    { "binding": "KV", "id": "<your-kv-id>" }
  ],
  "r2_buckets": [
    { "binding": "R2_PUBLIC", "bucket_name": "my-avatars" }
  ],
  "ai": { "binding": "AI" },
  "analytics_engine_datasets": [
    { "binding": "ANALYTICS" }
  ]
}

🧹 Scheduled Token Cleanups (Cron Trigger)

Clean up expired refresh tokens, verification tokens, and password reset records periodically:

PostgreSQL:

import {
  cleanupExpiredTokens,
  cleanupExpiredPasswordResets,
  cleanupExpiredEmailVerifications,
} from "@bambsdev/auth/pg";

export default {
  async scheduled(event, env, ctx) {
    const conn = env.LOCAL_DATABASE_URL || env.HYPERDRIVE?.connectionString;
    ctx.waitUntil(cleanupExpiredTokens(conn));
    ctx.waitUntil(cleanupExpiredPasswordResets(conn));
    ctx.waitUntil(cleanupExpiredEmailVerifications(conn));
  },
};

Cloudflare D1:

import {
  cleanupExpiredTokensD1,
  cleanupExpiredPasswordResetsD1,
  cleanupExpiredEmailVerificationsD1,
} from "@bambsdev/auth/d1";

export default {
  async scheduled(event, env, ctx) {
    ctx.waitUntil(cleanupExpiredTokensD1(env.DB));
    ctx.waitUntil(cleanupExpiredPasswordResetsD1(env.DB));
    ctx.waitUntil(cleanupExpiredEmailVerificationsD1(env.DB));
  },
};

πŸ—ΊοΈ API Reference

πŸ” Auth Endpoints (/auth)

| Method | Path | Access | Rate Limit | Description | | :------- | :-------------------------- | :--------- | :--------- | :----------------------------------------------------- | | POST | /auth/register | Public | - | Register new user with email, password, and username | | POST | /auth/login | Public | 5 / 5 min | Login with email & password, returns JWT token pair | | POST | /auth/refresh | Public | 5 / 5 min | Rotate refresh token (supports JSON body or HttpOnly Cookie) | | POST | /auth/logout | πŸ”’ Private | - | Logout current device session (supports JSON body or Cookie) | | POST | /auth/logout-all | πŸ”’ Private | - | Revoke all active sessions across all devices | | GET | /auth/sessions | πŸ”’ Private | - | List all active sessions with device info | | DELETE | /auth/sessions/:id | πŸ”’ Private | - | Revoke a specific session ID | | GET | /auth/verify-email | Public | - | Verify email via 64-character hex link token | | POST | /auth/verify-email-code | Public | 5 / 5 min | Verify email via 6-digit numeric OTP code | | POST | /auth/resend-verification | Public | 3 / 5 min | Resend verification code or link | | GET | /auth/google/login | Public | - | Redirect to Google OAuth consent screen (Web flow) | | GET | /auth/google/callback | Public | - | Handle Google redirect, returns token in URL fragment | | POST | /auth/google/token | Public | 5 / 5 min | Verify Google ID token from Native Mobile SDK | | POST | /auth/forgot-password | Public | 3 / 5 min | Request password reset link email | | POST | /auth/reset-password | Public | 10 / 5 min | Reset password using 64-character hex token | | POST | /auth/handoff/token | πŸ”’ Private | - | Generate short-lived one-time handoff token for Web SSO (alias: /auth/handoff-token) | | POST | /auth/handoff/exchange | Public | 5 / 5 min | Exchange one-time handoff token for Web session (accessToken + HttpOnly cookie) |

πŸ‘€ Settings Endpoints (/api/settings)

| Method | Path | Access | Description | | :------- | :------------------------------ | :--------- | :-------------------------------------------------- | | GET | /api/settings/profile | πŸ”’ Private | Get authenticated user profile | | PUT | /api/settings/profile | πŸ”’ Private | Update username (case-insensitive) or full name | | PUT | /api/settings/password | πŸ”’ Private | Change password (revokes old device sessions) | | PUT | /api/settings/avatar | πŸ”’ Private | Upload avatar file (Multipart, AI safety check, R2). Returns 403 if disabled via ALLOW_AVATAR_UPLOAD. | | DELETE | /api/settings/avatar | πŸ”’ Private | Delete avatar and clean up physical file from R2 | | GET | /api/settings/avatar-file/* | Public | Streaming proxy for avatar images from R2 |


πŸ“œ Documentation Guides

  • MIGRATION.md: Comprehensive multi-database migration and configuration guide.
  • CHANGELOG.md: Detailed release notes and breaking changes history.

πŸ“œ License

ISC License