3 changed files with 59 additions and 0 deletions
@ -0,0 +1,37 @@ |
|||||
|
import { getRedis } from "./redis"; |
||||
|
import { sessionTtlSeconds } from "./session-ttl"; |
||||
|
|
||||
|
export type SessionPayload = { |
||||
|
userId: number; |
||||
|
sessionVersion: number; |
||||
|
createdAt: string; |
||||
|
}; |
||||
|
|
||||
|
const sessionKey = (id: string) => `sess:${id}`; |
||||
|
|
||||
|
export async function createSession( |
||||
|
sessionId: string, |
||||
|
payload: SessionPayload, |
||||
|
): Promise<void> { |
||||
|
const redis = getRedis(); |
||||
|
const ttl = sessionTtlSeconds(); |
||||
|
await redis.set(sessionKey(sessionId), JSON.stringify(payload), "EX", ttl); |
||||
|
} |
||||
|
|
||||
|
export async function readSession( |
||||
|
sessionId: string, |
||||
|
): Promise<SessionPayload | null> { |
||||
|
const redis = getRedis(); |
||||
|
const raw = await redis.get(sessionKey(sessionId)); |
||||
|
if (!raw) return null; |
||||
|
try { |
||||
|
return JSON.parse(raw) as SessionPayload; |
||||
|
} catch { |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export async function deleteSession(sessionId: string): Promise<void> { |
||||
|
const redis = getRedis(); |
||||
|
await redis.del(sessionKey(sessionId)); |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
export function sessionTtlSeconds(): number { |
||||
|
const raw = process.env.SESSION_TTL_SECONDS; |
||||
|
const n = raw ? Number(raw) : NaN; |
||||
|
return Number.isFinite(n) && n > 0 ? n : 604800; |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import { describe, expect, it, beforeEach } from "bun:test"; |
||||
|
import { sessionTtlSeconds } from "../../server/utils/session-ttl"; |
||||
|
|
||||
|
describe("sessionTtlSeconds", () => { |
||||
|
beforeEach(() => { |
||||
|
delete process.env.SESSION_TTL_SECONDS; |
||||
|
}); |
||||
|
|
||||
|
it("defaults to 7d", () => { |
||||
|
expect(sessionTtlSeconds()).toBe(604800); |
||||
|
}); |
||||
|
|
||||
|
it("respects env", () => { |
||||
|
process.env.SESSION_TTL_SECONDS = "120"; |
||||
|
expect(sessionTtlSeconds()).toBe(120); |
||||
|
}); |
||||
|
}); |
||||
Loading…
Reference in new issue