UNPKG

codalware-auth

Version:

Complete authentication system with enterprise security, attack protection, team workspaces, waitlist, billing, UI components, 2FA, and account recovery - production-ready in 5 minutes. Enhanced CLI with verification, rollback, and App Router scaffolding.

71 lines (67 loc) 2.37 kB
import { Adapter, User, Session, MagicToken } from './types'; import crypto from 'crypto'; function id() { return crypto.randomUUID(); } export function createMemoryAdapter(): Adapter { const users = new Map<string, User>(); const sessions = new Map<string, Session>(); const tokens = new Map<string, MagicToken>(); return { async createUser({ email, name, metadata }) { const now = new Date(); const u: User = { id: id(), email, name: name ?? null, metadata: metadata ?? null, createdAt: now, updatedAt: now }; users.set(u.id, u); return u; }, async getUserById(id) { return users.get(id) ?? null; }, async getUserByEmail(email) { for (const u of Array.from(users.values())) { if (u.email === email) return u; } return null; }, async updateUser(id, patch) { const u = users.get(id); if (!u) throw new Error('user not found'); const nu = { ...u, ...patch, updatedAt: new Date() } as User; users.set(id, nu); return nu; }, async createSession(session) { const s: Session = { id: id(), userId: session.userId, createdAt: new Date(), expiresAt: session.expiresAt, handle: session.handle ?? null, metadata: session.metadata ?? null }; sessions.set(s.id, s); return s; }, async getSessionById(id) { return sessions.get(id) ?? null; }, async deleteSession(id) { sessions.delete(id); }, async deleteSessionsByUserId(userId) { for (const [k, s] of Array.from(sessions.entries())) { if (s.userId === userId) sessions.delete(k); } }, async storeMagicToken({ tokenHash, userId = null, expiresAt, ip = null, userAgent = null }) { const t: MagicToken = { id: id(), tokenHash, userId, createdAt: new Date(), expiresAt, consumedAt: null, ip, userAgent }; tokens.set(t.id, t); return t; }, async findValidMagicToken(tokenHash) { for (const t of Array.from(tokens.values())) { if (t.tokenHash === tokenHash && !t.consumedAt && t.expiresAt > new Date()) return t; } return null; }, async consumeMagicToken(id) { const t = tokens.get(id); if (!t) return; t.consumedAt = new Date(); tokens.set(id, t); }, }; }