@tummycrypt/tinyland-auth-redis
v0.1.2
Published
Redis (Upstash) storage adapter for @tummycrypt/tinyland-auth
Downloads
1,979
Readme
@tummycrypt/tinyland-auth-redis
Redis storage adapter for @tummycrypt/tinyland-auth, backed by Upstash Redis (@upstash/redis).
Implements the full IStorageAdapter interface: users, sessions, TOTP secrets, backup codes, invitations, and audit events.
Installation
npm install @tummycrypt/tinyland-auth-redis
# or
pnpm add @tummycrypt/tinyland-auth-redisPeer dependency:
npm install @tummycrypt/tinyland-authQuick Start
import { createRedisStorageAdapter } from '@tummycrypt/tinyland-auth-redis';
const storage = createRedisStorageAdapter({
url: process.env.KV_REST_API_URL,
token: process.env.KV_REST_API_TOKEN,
prefix: 'auth', // optional, default: 'auth'
sessionMaxAge: 7 * 24 * 60 * 60 * 1000, // optional, default: 7 days
});
await storage.init(); // verifies connectivity with PINGUsing an Existing Redis Instance
import { Redis } from '@upstash/redis';
import { createRedisStorageAdapter } from '@tummycrypt/tinyland-auth-redis';
const redis = new Redis({
url: process.env.KV_REST_API_URL!,
token: process.env.KV_REST_API_TOKEN!,
});
const storage = createRedisStorageAdapter({ redis });Graceful Fallback
When Redis is unavailable (e.g., local development without Upstash credentials), fall back to an in-memory Map:
import { createRedisStorageAdapter } from '@tummycrypt/tinyland-auth-redis';
const createStorage = () => {
const url = process.env.KV_REST_API_URL;
const token = process.env.KV_REST_API_TOKEN;
if (url && token) {
return createRedisStorageAdapter({ url, token });
}
console.warn('Redis not configured, using in-memory fallback');
// Use your own in-memory adapter or the one from tinyland-auth
return createInMemoryAdapter();
};Key Namespacing
All keys are namespaced under a configurable prefix (default: auth). This allows multiple applications to share a single Redis instance without collisions.
| Pattern | Example | Purpose |
|---------|---------|---------|
| {prefix}:user:{id} | auth:user:abc-123 | User entity |
| {prefix}:user:handle:{handle} | auth:user:handle:jen | Handle lookup index |
| {prefix}:user:email:{email} | auth:user:email:[email protected] | Email lookup index |
| {prefix}:users:all | auth:users:all | Set of all user IDs |
| {prefix}:session:{id} | auth:session:sess-1 | Session entity |
| {prefix}:sessions:user:{userId} | auth:sessions:user:abc-123 | Sorted set of session IDs by expiry |
| {prefix}:totp:{handle} | auth:totp:jen | Encrypted TOTP secret |
| {prefix}:backup:{userId} | auth:backup:abc-123 | Backup codes |
| {prefix}:invite:{token} | auth:invite:tok-abc | Invitation entity |
| {prefix}:invite:id:{id} | auth:invite:id:inv-1 | Invitation ID to token index |
| {prefix}:invites:all | auth:invites:all | Set of all invitation tokens |
| {prefix}:invites:pending | auth:invites:pending | Set of pending invitation tokens |
| {prefix}:audit:{id} | auth:audit:evt_123_abc | Audit event entity |
| {prefix}:audit:log | auth:audit:log | Sorted set of audit event IDs by timestamp |
API Reference
createRedisStorageAdapter(config: RedisStorageConfig): RedisStorageAdapter
Factory function. Accepts:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| redis | Redis | - | Existing Upstash Redis instance |
| url | string | - | Upstash REST URL (used if redis not provided) |
| token | string | - | Upstash REST token (used if redis not provided) |
| prefix | string | 'auth' | Key namespace prefix |
| sessionMaxAge | number | 604800000 | Session TTL in milliseconds (7 days) |
RedisStorageAdapter (implements IStorageAdapter)
Lifecycle:
init()- Verify Redis connectivity (PING)close()- No-op (Upstash uses HTTP, no persistent connection)
Users: getUser, getUserByHandle, getUserByEmail, getAllUsers, createUser, updateUser, deleteUser, hasUsers
Sessions: getSession, getSessionsByUser, getAllSessions, createSession, updateSession, deleteSession, deleteUserSessions, cleanupExpiredSessions
TOTP: getTOTPSecret, saveTOTPSecret, deleteTOTPSecret
Backup Codes: getBackupCodes, saveBackupCodes, deleteBackupCodes
Invitations: getInvitation, getInvitationById, getAllInvitations, getPendingInvitations, createInvitation, updateInvitation, deleteInvitation, cleanupExpiredInvitations
Audit: logAuditEvent, getAuditEvents, getRecentAuditEvents
Serialization Utilities
Exported for advanced use cases:
import { serialize, deserialize, toHashFields, fromHashFields } from '@tummycrypt/tinyland-auth-redis';serialize<T>(value: T): string- Safe JSON.stringify wrapperdeserialize<T>(value: string | null): T | null- Safe JSON.parse with null handlingtoHashFields(obj: Record<string, unknown>): Record<string, string>- Convert to Redis HSET-compatible flat mapfromHashFields<T>(hash: Record<string, string> | null): T | null- Parse Redis HGETALL result back to typed object
Key Generators
import { createKeys } from '@tummycrypt/tinyland-auth-redis';
const keys = createKeys('myapp');
keys.user('abc-123'); // 'myapp:user:abc-123'
keys.session('sess-1'); // 'myapp:session:sess-1'
keys.auditLog(); // 'myapp:audit:log'Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| KV_REST_API_URL | Yes | Upstash Redis REST URL |
| KV_REST_API_TOKEN | Yes | Upstash Redis REST token |
These are the standard environment variable names used by Vercel KV (Upstash integration).
License
MIT
