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

@roastery-capsules/auth

v0.1.0

Published

Authentication and session management capsule for the Roastery CMS ecosystem, featuring JWT tokens, rate-limited login, and route protection guards.

Readme

@roastery-capsules/auth

Authentication and session management capsule for the Roastery CMS ecosystem.

Checked with Biome

Overview

auth provides a single-credential login endpoint, revocable session access keys, and a route-protection guard, packaged as a Blend capsule for Barista (Elysia-based) apps:

  • Login endpointPOST /auth/login, rate-limited, issues a secure HTTP-only session cookie.
  • Auth guard — protects routes by verifying the session cookie against a revocable, cached access key.
  • Rate limiting — progressive login attempt tracking with lazy, automatic recovery.
  • No bundled infrastructure — JWT signing/verification and cache persistence are entirely delegated to injected capsules; this package ships no implementation of either.

Technologies

| Tool | Purpose | |------|---------| | @roastery-capsules/jwt | Injected JWT signing and verification | | @roastery-adapters/cache | Injected cache abstraction for access keys and attempt tracking | | @roastery/barista | Web framework (Elysia-based) for controllers and guards | | @roastery/blend | Capsule packaging and dependency manifest | | @roastery/terroir | Exception hierarchy and runtime schema validation | | @roastery/pantry | Shared constants and OpenAPI response helpers | | tsup | Bundling to ESM + CJS with .d.ts generation | | Bun | Runtime, test runner, and package manager | | Knip | Unused exports and dependency detection | | Husky + commitlint | Git hooks and conventional commit enforcement |

Installation

bun add @roastery-capsules/auth

Consumption modes

This package can be consumed in two ways:

As a Blend capsule — register the Auth manifest and let the platform validate its environment and dependencies before mounting it:

import { Auth } from '@roastery-capsules/auth';

const capsule = new Auth();
app.use(capsule.plugin);

As granular subpaths — import only what you need:

import { authController } from '@roastery-capsules/auth/plugins/controllers';
import { auth } from '@roastery-capsules/auth/plugins/guards';
import { AccessKey, LoginAttempt, verifyCredentials } from '@roastery-capsules/auth/utils';
import { AuthEnvDependenciesDTO, VerifyCredentialsDTO } from '@roastery-capsules/auth/dtos';

Dependency-injection contract

Neither authController nor the auth guard construct their own collaborators — they read them off the Barista instance's decorators:

| Decorator | Type | Source | |---|---|---| | env | AuthEnvDependenciesDTO | Validated environment (AUTH_EMAIL, AUTH_PASSWORD, optional IGNORE_AUTH) | | cache | BaristaCacheInstance | @roastery-adapters/cache | | jwt | JsonWebToken | @roastery-capsules/jwt |

The host application must decorate all three before mounting this capsule's plugin or guard:

app
  .decorate('env', validatedEnv)
  .decorate('cache', cacheInstance)
  .decorate('jwt', jwtInstance)
  .use(authController)
  .use(auth);

Missing pieces throw at registration time: MissingPluginDependencyException when cache/jwt are absent, InvalidEnvironmentException when AUTH_EMAIL/AUTH_PASSWORD are missing from env.


Login Controller

authController exposes a POST /auth/login endpoint that handles the full authentication flow.

import { authController } from '@roastery-capsules/auth/plugins/controllers';

app.use(authController);

Flow:

  1. Checks the rate limit (max 5 attempts, lazy recovery of 1 attempt/hour)
  2. Validates the request body against the configured AUTH_EMAIL/AUTH_PASSWORD
  3. On failure, consumes one attempt and throws a BadRequestException
  4. On success, resets the rate limit, mints a UUID access key and stores it in cache
  5. Signs a JWT containing { ACCESS_KEY, EMAIL } and returns it in a secure, HTTP-only ACCESS_TOKEN cookie

Response codes:

| Status | Meaning | |--------|---------| | 200 | Login successful | | 400 | Invalid credentials | | 429 | Too many attempts | | 503 | Cache unavailable |


Auth Guard

auth protects routes by verifying the ACCESS_TOKEN cookie against the cached session access key.

import { auth } from '@roastery-capsules/auth/plugins/guards';

app.use(auth);

On each request:

  1. Reads and jwt.verifys the ACCESS_TOKEN cookie
  2. Compares the token's ACCESS_KEY against the cached value for that EMAIL
  3. Throws UnauthorizedException (missing/invalid cookie or key mismatch) or ResourceNotFoundException (missing EMAIL in the token payload) on failure

Sessions are revocable: deleting the cache entry — or simply logging in again, which overwrites it — invalidates any previously issued token. Setting IGNORE_AUTH truthy in the environment turns the guard into a no-op, for local development only.


Utils

| Export | Purpose | |---|---| | AccessKey | Cache wrapper for the session access key of an e-mail (access-key:<email>, TTL CACHE_EXPIRATION_TIME.SAFE) | | LoginAttempt | Rate limiter (login-attempts:<email>), max 5 attempts with lazy recovery of 1/hour | | verifyCredentials | Validates a login payload's shape and compares it against the configured credential pair |


Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | AUTH_EMAIL | Yes | Configured authentication email | | AUTH_PASSWORD | Yes | Configured authentication password | | IGNORE_AUTH | No | When truthy, disables the auth guard entirely (development only). Default false |

CACHE_PROVIDER/REDIS_URL and any JWT signing secret are required by the injected @roastery-adapters/cache and @roastery-capsules/jwt dependencies, not by this capsule directly.


Exports Reference

import { Auth } from '@roastery-capsules/auth';                              // Blend capsule manifest
import { authController } from '@roastery-capsules/auth/plugins/controllers'; // POST /auth/login
import { auth } from '@roastery-capsules/auth/plugins/guards';                // Route-protection guard
import AuthTags from '@roastery-capsules/auth/plugins/tags';                  // OpenAPI tag metadata
import { AccessKey, LoginAttempt, verifyCredentials } from '@roastery-capsules/auth/utils';
import { AuthEnvDependenciesDTO, VerifyCredentialsDTO } from '@roastery-capsules/auth/dtos';

Development

# Run tests
bun run test:unit

# Run tests with coverage
bun run test:coverage

# Build for distribution
bun run build

# Check for unused exports and dependencies
bun run knip

# Full setup (build + bun link)
bun run setup

License

MIT