Registry / auth-security / velvet-auth

velvet-auth

JSON →
library0.1.9jsnpmunverified

velvet-auth is a production-ready authentication plugin specifically designed for Elysia.js applications running on Bun. It provides a comprehensive solution for common authentication patterns, including JWT rotation, secure password hashing using native Argon2id (via `Bun.password`), and session management with RESP-compatible stores like Redis for refresh token invalidation and JTI blacklisting. The current stable version is 0.1.9, with frequent minor releases addressing bug fixes and introducing improvements. Key differentiators include its tight integration with Bun's native features, an adapter pattern for database and email provider flexibility, and a focus on type safety with Zod validation. It aims to reduce boilerplate for setting up robust auth stacks in the Bun/Elysia ecosystem.

npm install velvet-auth
INSTALL
IMPORT
SIG · VELVET-AUTH
V
velvet-auth
auth-securityjavascriptv0.1.9
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

velvetAuth
import { velvetAuth } from 'velvet-auth'
const velvetAuth = require('velvet-auth')
Main plugin export for Elysia. Primarily used with ESM. Types are included.
createAuthGuard
import { createAuthGuard } from 'velvet-auth'
import createAuthGuard from 'velvet-auth/guard'
Used to protect routes and inject `ctx.user`. Imported as a named export.
UserStoreAdapter
import type { UserStoreAdapter } from 'velvet-auth'
import { UserStoreAdapter } from 'velvet-auth'
TypeScript type definition for the database adapter interface. Should be imported as a type.

This quickstart demonstrates how to integrate `velvet-auth` into an Elysia application, showing the setup of `UserStoreAdapter` and `EmailAdapter` mocks, and mounting the `velvetAuth` plugin with essential JWT and Redis configuration. It also includes a basic Elysia route to confirm server operation.

import { Elysia } from "elysia"; import { velvetAuth } from "velvet-auth"; import { BunFileRouter } from 'bun-file-router'; // Assuming a simple db mock for demonstration const db = { users: { data: [] as any[], // In-memory mock for demonstration findOne: async ({ id, username, email }: { id?: string; username?: string; email?: string }) => { if (id) return db.users.data.find(u => u.id === id); if (username) return db.users.data.find(u => u.username === username); if (email) return db.users.data.find(u => u.email === email); return undefined; }, insert: async (data: any) => { db.users.data.push({ ...data, id: Date.now().toString() }); return data; }, update: async ({ id }: { id: string }, updates: any) => { const userIndex = db.users.data.findIndex(u => u.id === id); if (userIndex !== -1) { db.users.data[userIndex] = { ...db.users.data[userIndex], ...updates }; } }, }, }; // 1. Implement the UserStoreAdapter for your database const userStore = { findById: async (id) => db.users.findOne({ id }), findByUsername: async (username) => db.users.findOne({ username }), findByEmail: async (email) => db.users.findOne({ email }), create: async (data) => db.users.insert(data), updatePassword: async (id, hash) => db.users.update({ id }, { password: hash }), setEmailVerified: async (id) => db.users.update({ id }, { emailVerified: true }), }; // 2. Implement the EmailAdapter for your email provider const emailAdapter = { sendOtp: async (to, otp) => { console.log(`Sending OTP to ${to}: ${otp}`); return true; }, sendVerification: async (to, url) => { console.log(`Sending verification to ${to}: ${url}`); return true; }, checkStatus: async () => true, }; // 3. Mount the plugin const app = new Elysia() .use( velvetAuth(userStore, emailAdapter, { jwt: { secret: process.env.JWT_SECRET ?? 'super-secret-jwt-key-that-is-at-least-32-chars-long', }, redis: { url: process.env.REDIS_URL ?? 'redis://localhost:6379' }, password: { minLength: 8, // Example: enforce min length } }), ) .get('/', () => 'Welcome to velvet-auth example!') .listen(3000); console.log( `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}` );
Debug
Known issues
gotchaThe `createAuthGuard` function in v0.1.9 changed its internal `.derive()` call from `{ as: "global" }` to `{ as: "scoped" }`. This change prevents the user context from unintentionally leaking into unrelated routes when the guard is composed into a larger Elysia app. While a fix for context isolation, it might affect assumptions in existing applications that relied on the global derivation behavior.
fix
Ensure that `createAuthGuard` is composed only where the `user` context is explicitly intended to be available. Review any complex app compositions to verify the correct scope of `ctx.user`.
affects: >=0.1.9
gotchaThe `jwt.secret` configuration option is critical for security and must be a string with a minimum length of 32 characters. Using a shorter or easily guessable secret makes JWTs vulnerable to brute-force attacks.
fix
Generate a strong, long (>=32 characters) cryptographic secret for `jwt.secret`. Use environment variables (e.g., `process.env.JWT_SECRET!`) to manage it securely, especially in production environments.
affects: >=0.1.0
breakingEarlier versions (before v0.1.8) might have silently ignored password policy rules defined in `config.password` (e.g., `minLength`, `requireUppercase`). Since v0.1.8, these rules are actively enforced during registration and will return a `400` error if violated.
fix
Ensure client-side password validation logic aligns with the server-side `config.password` rules to prevent registration failures due to policy violations. Inform users about password requirements during registration.
affects: >=0.1.8
gotchavelvet-auth relies heavily on Bun's native features, specifically `Bun.password` for Argon2id hashing and `Bun.RedisClient`. This means it is strictly a Bun-only package and will not work with Node.js or Deno runtimes.
fix
Ensure your project is running on Bun version >= 1.0. This package is not compatible with other JavaScript runtimes.
affects: >=0.1.0
Errors
Common errors & fixes
Error: The provided secret must be at least 32 characters long.
The `jwt.secret` configuration option is too short, leading to an insecure JWT setup.
fix
Update your `velvetAuth` configuration to provide a `jwt.secret` that is at least 32 characters long. Example: `{ jwt: { secret: process.env.JWT_SECRET || 'your-long-and-secure-secret-key-here' } }`
TypeError: Bun.password is not a function
The application is likely being run in a Node.js environment instead of Bun, or Bun is an outdated version.
fix
Ensure your project is executed using Bun (e.g., `bun run start`) and that your Bun version is >= 1.0.
Error: Redis connection failed: connect ECONNREFUSED 127.0.0.1:6379
The application cannot establish a connection to the Redis server, which might be offline, misconfigured, or running on a different port/host.
fix
Verify that your Redis server is running and accessible at the configured `redis.url` (default `redis://localhost:6379`). Check firewall rules and Redis server status. You can configure the URL via `velvetAuth({ redis: { url: 'your_redis_url' } })` or `process.env.REDIS_URL`.
Property 'user' does not exist on type 'Context'.
The `ctx.user` object is not correctly typed or available in the handler, likely because the `createAuthGuard` was not applied, or applied incorrectly to the route.
fix
Ensure you are using `createAuthGuard()` on the routes where `ctx.user` is expected. Example: `app.group('/protected', (app) => app.use(createAuthGuard()).get('/', (ctx) => ctx.user))`.
Upgrade
Version history
0.1.9latest on npm
Audit
Dependencies
elysiarequiredPeer dependency, velvet-auth is an Elysia plugin.
bunrequiredRuntime dependency for native features like Bun.password and Bun.RedisClient.
redisrequiredRuntime dependency for session management (refresh tokens, JTI blacklist), can be any RESP-compatible server like Valkey, KeyDB, Dragonfly, Garnet.
Agent activity
30 hits · last 30 days
node
24
Amazon
1
OpenAI (training)
1
Resources
velvet-auth — npm install velvet-auth · libregistry