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

@auth-craft/pages-auth-proxy

v1.1.0

Published

Thin Cloudflare Pages reverse-proxy for Auth Craft — serves /{scope}/auth/* same-origin (first-party cookies) and forwards to the gateway worker (Service Binding or HTTP + X-Edge-Gate). Keeps all trust-critical logic in the gateway.

Readme

@auth-craft/pages-auth-proxy

Thin reverse-proxy so an app on Cloudflare Pages can serve /{scope}/auth/* on its own origin, then forward to the Auth Craft gateway worker.

Why: when the browser only ever sees the app's own origin, the refresh cookie the backend sets is first-party (same-site) — SameSite=Lax/Strict works, there is no cross-site CORS, and it is immune to Safari ITP. This proxy is intentionally thin: it never holds backend secrets. All trust-critical logic (X-Gateway-Secret, JWT verify, rate-limit, stealth 404) stays in the gateway.

The one thing it can enforce is scope: lock the proxy to a single scope (scope: 'customer') and the frontend calls scope-less /auth/... while the proxy prepends the scope segment. The client never picks the scope, so a customer app cannot reach system/tenant context through it — the lock holds even against a single shared gateway worker that derives scope from the path. (Leave scope unset for the legacy behaviour where the client carries its own /{scope}/... segment.)

Optional: use this only for apps you deploy on Cloudflare Pages. Apps that can't (e.g. a store you don't host) keep calling the gateway cross-origin and use body token transport instead — both models work against the same gateway + backend.

Install

pnpm add @auth-craft/pages-auth-proxy

Cloudflare Pages usage

Add a catch-all Pages Function under /auth and lock it to this app's scope:

// functions/auth/[[path]].ts
import { createPagesAuthProxy } from '@auth-craft/pages-auth-proxy/pages';

export const onRequest = createPagesAuthProxy({ scope: 'customer' });

Configure the Pages project bindings:

| Binding | Purpose | |---------|---------| | AUTH_GATEWAY | Service Binding to the gateway worker (preferred — in-network, lowest latency) | | AUTH_GATEWAY_URL | Gateway public URL (fallback when no Service Binding) | | EDGE_GATE_SECRET | Client→gateway gate, sent as X-Edge-Gate (Pages secret) |

The frontend then calls auth on its own origin, scope-less, e.g. fetch('/auth/authenticate', { method: 'POST', credentials: 'include', ... }). The proxy stamps the scope; the cookie set by the backend is first-party to the app.

Pairs with @auth-craft/client cookie mode

Because cookies are first-party, use the cookie provider — no IndexedDB, refresh handled by the HttpOnly cookie:

import { createCookieProvider } from '@auth-craft/client';

const provider = createCookieProvider({
  loginUrl: '/auth/authenticate',
  refreshUrl: '/auth/refresh',
  logoutUrl: '/auth/logout',
});

Framework-agnostic core

import { createAuthProxy } from '@auth-craft/pages-auth-proxy';

const proxy = createAuthProxy({
  scope: 'customer',
  gatewayUrl: 'https://auth-craft-prod-customer.acme.workers.dev',
  edgeGateSecret: env.EDGE_GATE_SECRET,
});

export default { fetch: (req: Request) => proxy(req) };

Security notes

  • Not a CORS replacement — better. Same-origin requests have no CORS at all. Site isolation comes from first-party SameSite cookies + HttpOnly + the backend's CSRF Origin check (trustedOrigins), not from CORS.
  • Scope is enforced, not trusted. With scope set, the prepended segment is the lock's value; the client's path is normalized (.. collapsed) before matching, so it can't smuggle another scope. A customer app physically cannot reach system/tenant — even against one shared gateway worker. Use one locked proxy per app/scope.
  • Keep EDGE_GATE_SECRET in a Pages secret. With a Service Binding you can configure the gateway to trust the binding and avoid exposing the gate entirely.
  • The proxy preserves method, body, headers and cookies; it adds only X-Edge-Gate.