diff --git a/mvp/b2c/src/lib/auth/tokens.ts b/mvp/b2c/src/lib/auth/tokens.ts new file mode 100644 index 0000000..8cc3266 --- /dev/null +++ b/mvp/b2c/src/lib/auth/tokens.ts @@ -0,0 +1,19 @@ +import { randomBytes, createHash } from 'node:crypto'; + +export const SESSION_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 días + +export function generateSessionToken(): string { + return randomBytes(32).toString('hex'); +} + +export function hashSessionToken(token: string): string { + return createHash('sha256').update(token).digest('hex'); +} + +export function isSessionExpired(expiresAt: Date, now: Date = new Date()): boolean { + return expiresAt.getTime() <= now.getTime(); +} + +export function sessionExpiry(now: Date = new Date()): Date { + return new Date(now.getTime() + SESSION_TTL_MS); +} diff --git a/mvp/b2c/tests/auth/tokens.test.ts b/mvp/b2c/tests/auth/tokens.test.ts new file mode 100644 index 0000000..fc6ca15 --- /dev/null +++ b/mvp/b2c/tests/auth/tokens.test.ts @@ -0,0 +1,34 @@ +import { describe, it, expect } from 'vitest'; +import { + generateSessionToken, + hashSessionToken, + isSessionExpired, + sessionExpiry, + SESSION_TTL_MS, +} from '@/lib/auth/tokens'; + +describe('tokens', () => { + it('genera tokens distintos en hex de 64 chars', () => { + const a = generateSessionToken(); + const b = generateSessionToken(); + expect(a).toMatch(/^[0-9a-f]{64}$/); + expect(a).not.toBe(b); + }); + + it('hashea el token de forma determinista y distinta al token', () => { + const t = generateSessionToken(); + expect(hashSessionToken(t)).toBe(hashSessionToken(t)); + expect(hashSessionToken(t)).not.toBe(t); + }); + + it('marca expirada una sesión pasada y válida una futura', () => { + const now = new Date('2026-05-30T12:00:00Z'); + expect(isSessionExpired(new Date('2026-05-29T12:00:00Z'), now)).toBe(true); + expect(isSessionExpired(new Date('2026-05-31T12:00:00Z'), now)).toBe(false); + }); + + it('sessionExpiry suma el TTL al instante dado', () => { + const now = new Date('2026-05-30T12:00:00Z'); + expect(sessionExpiry(now).getTime()).toBe(now.getTime() + SESSION_TTL_MS); + }); +});