import { Collection, Db } from "mongodb"; import OidcSession from "../schemas/OidcSession"; /** * Repository for OIDC sessions * * Manages temporary sessions during the OIDC authorization flow. * Sessions are automatically deleted by MongoDB TTL index after expiration. */ export default class OidcSessionRepo { private collection: Collection; constructor(collectionName: string, db: Db) { this.collection = db.collection(collectionName); } /** * Create a new OIDC session * * @param session - Session data * @returns Created session with _id */ async create(session: Omit): Promise { const result = await this.collection.insertOne(session as any); return { ...session, _id: result.insertedId.toString(), }; } /** * Find session by state parameter * * Used during callback to validate the state and retrieve session data. * * @param state - State parameter from callback * @returns Session or null if not found */ async getByState(state: string): Promise { const session = await this.collection.findOne({ state }); if (!session) { return null; } return { ...session, _id: session._id?.toString(), }; } /** * Find one session by query * * @param query - MongoDB query * @returns Session or null if not found */ async getOne(query: Partial): Promise { const session = await this.collection.findOne(query as any); if (!session) { return null; } return { ...session, _id: session._id?.toString(), }; } /** * Delete session by session ID * * Sessions are one-time use - delete after successful validation. * * @param sessionId - Session identifier */ async deleteBySessionId(sessionId: string): Promise { await this.collection.deleteOne({ sessionId }); } /** * Delete session by state * * @param state - State parameter */ async deleteByState(state: string): Promise { await this.collection.deleteOne({ state }); } /** * Delete all expired sessions * * This is handled automatically by MongoDB TTL index, * but can be called manually for testing or cleanup. */ async deleteExpired(): Promise { const result = await this.collection.deleteMany({ createdAt: { $lt: new Date(Date.now() - 600000) }, // 10 minutes }); return result.deletedCount; } }