Release 2025-05-19
This commit is contained in:
@@ -1,78 +0,0 @@
|
||||
import { randomBytes } from 'crypto'
|
||||
|
||||
import { REDIS_USER_SESSION_EXPIRY_SECONDS } from 'astro:env/server'
|
||||
|
||||
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: REDIS_USER_SESSION_EXPIRY_SECONDS,
|
||||
})
|
||||
Reference in New Issue
Block a user