@iron-stack/auth
v1.0.1
Published
Full-stack authentication framework with JWT access tokens, rotating refresh tokens, and role-based access control -- built for tRPC + Fastify + Drizzle.
Readme
@iron-stack/auth
Full-stack authentication framework with JWT access tokens, rotating refresh tokens, and role-based access control -- built for tRPC + Fastify + Drizzle.
Installation
npm install @iron-stack/authQuick Start
Server
import { createAuthRouter, extractAuthContext, authRequired, requireRole, createSocketAuthMiddleware } from '@iron-stack/auth/server';
// 1. Create the auth tRPC router (register, login, refresh, logout)
const authRouter = createAuthRouter({
router: t.router,
publicProcedure,
db,
tables: { users, refreshTokens },
jwtSign: (payload, opts) => fastify.jwt.sign(payload, opts),
});
// 2. Extract auth context from requests
function createContext({ req }: CreateFastifyContextOptions) {
return { db, ...extractAuthContext(fastify, req) };
}
// 3. Protect routes
const protectedProcedure = t.procedure.use(authRequired);
const adminProcedure = t.procedure.use(requireRole(['admin']));
// 4. Authenticate Socket.IO connections
io.use(createSocketAuthMiddleware(fastify));Client
import { create } from 'zustand';
import { createAuthStore } from '@iron-stack/auth/client';
import type { AuthState } from '@iron-stack/auth/client';
export const useAuthStore = create<AuthState>((set, get) =>
createAuthStore({
apiUrl: 'http://localhost:3000',
storage: {
get: async () => { /* read refresh token from secure storage */ },
set: async (token) => { /* persist refresh token */ },
remove: async () => { /* delete refresh token */ },
},
})(set, get)
);API Reference
@iron-stack/auth (shared)
| Export | Description |
|---|---|
| RegisterSchema | Zod schema for registration input (phone, displayName, password) |
| LoginSchema | Zod schema for login input (phone, password) |
| RefreshSchema | Zod schema for token refresh input (refreshToken) |
| AuthResponseSchema | Zod schema for auth response (tokens + user) |
| RoleSchema | Zod enum schema for roles (user, admin, moderator) |
| DEFAULT_ROLE | Default role assigned to new users ("user") |
| RegisterInput | Type inferred from RegisterSchema |
| LoginInput | Type inferred from LoginSchema |
| RefreshInput | Type inferred from RefreshSchema |
| AuthResponse | Type inferred from AuthResponseSchema |
| Role | Type union: "user" \| "admin" \| "moderator" |
| RolePermissions | Interface for defining resource/action role mappings |
@iron-stack/auth/server
| Export | Description |
|---|---|
| createAuthRouter(config) | Creates a tRPC router with register, login, refresh, and logout mutations |
| authRequired | tRPC middleware that enforces authentication |
| requireRole(roles) | Factory that returns a tRPC middleware enforcing role-based access |
| extractAuthContext(fastify, req) | Extracts userId and userRole from a Fastify request's JWT |
| createSocketAuthMiddleware(fastify) | Socket.IO middleware that verifies JWT from handshake auth |
| generateRefreshToken() | Generates a cryptographically random refresh token |
| hashToken(token) | SHA-256 hashes a token for safe storage |
| AuthRouterConfig | Configuration interface for createAuthRouter |
| AuthContext | Interface: { userId: string \| null, userRole: Role \| null } |
| JwtPayload | Interface: { sub: string, role?: Role } |
| SocketAuthPayload | Interface for socket JWT payload |
@iron-stack/auth/client
| Export | Description |
|---|---|
| createAuthStore(config) | Creates platform-agnostic auth state logic for Zustand |
| AuthUser | Interface for the authenticated user object |
| AuthState | Interface for the full auth store state and actions |
| AuthStoreConfig | Configuration interface for the auth store |
Configuration
AuthRouterConfig
| Option | Type | Default | Description |
|---|---|---|---|
| router | function | required | tRPC t.router function |
| publicProcedure | object | required | tRPC public procedure builder |
| db | DrizzleDb | required | Drizzle database instance |
| tables | { users, refreshTokens } | required | Drizzle table references |
| jwtSign | function | required | JWT signing function |
| bcryptRounds | number | 12 | Bcrypt hashing rounds |
| accessTokenExpiry | string | "15m" | Access token expiration |
| refreshTokenDays | number | 30 | Refresh token validity in days |
| defaultRole | Role | "user" | Default role for new registrations |
AuthStoreConfig
| Option | Type | Default | Description |
|---|---|---|---|
| apiUrl | string | required | API base URL |
| refreshPath | string | "auth.refresh" | tRPC refresh procedure path |
| storage | { get, set, remove } | required | Secure storage adapter for refresh tokens |
License
MIT
