Files
kycnotme/web/src/lib/redis/redisSessions.ts
2025-06-09 10:00:55 +00:00

77 lines
2.4 KiB
TypeScript

import { randomBytes } from 'crypto'
import { RedisGenericManager } from './redisGenericManager'
class RedisSessions extends RedisGenericManager {
/**
* Generates a random session ID
*/
private generateSessionId(): string {
return randomBytes(32).toString('hex')
}
/**
* Creates a new session for a user
* @param userSecretTokenHash The ID of the user
* @returns The generated session ID
*/
async createSession(userSecretTokenHash: string): Promise<string> {
const sessionId = this.generateSessionId()
// Store the session with user ID
await this.redisClient.set(`session:${sessionId}`, userSecretTokenHash, {
EX: this.expirationTime,
})
// Store session ID in user's sessions set
await this.redisClient.sAdd(`user:${userSecretTokenHash}:sessions`, sessionId)
return sessionId
}
/**
* Gets the user ID associated with a session
* @param sessionId The session ID to look up
* @returns The user ID or null if session not found
*/
async getUserBySessionId(sessionId: string): Promise<string | null> {
const userSecretTokenHash = await this.redisClient.get(`session:${sessionId}`)
return userSecretTokenHash
}
/**
* Deletes all sessions for a user
* @param userSecretTokenHash The ID of the user whose sessions should be deleted
*/
async deleteUserSessions(userSecretTokenHash: string): Promise<void> {
// Get all session IDs for the user
const sessionIds = await this.redisClient.sMembers(`user:${userSecretTokenHash}:sessions`)
if (sessionIds.length > 0) {
// Delete each session
// Delete sessions one by one to avoid type issues with spread operator
for (const sessionId of sessionIds) {
await this.redisClient.del(`session:${sessionId}`)
}
// Delete the set of user's sessions
await this.redisClient.del(`user:${userSecretTokenHash}:sessions`)
}
}
/**
* Deletes a specific session
* @param sessionId The session ID to delete
*/
async deleteSession(sessionId: string): Promise<void> {
const userSecretTokenHash = await this.getUserBySessionId(sessionId)
if (userSecretTokenHash) {
await this.redisClient.del(`session:${sessionId}`)
await this.redisClient.sRem(`user:${userSecretTokenHash}:sessions`, sessionId)
}
}
}
export const redisSessions = await RedisSessions.createAndConnect({
expirationTime: 60 * 60 * 24, // 24 hours in seconds
})