/**
* QR Code storage and management utility.
* Stores QR codes in memory with automatic expiration (default: 5 minutes).
*/
import { QRCode } from '../types/index.js';
import { logger } from './logger.js';
class QRStorage {
private qrMap: Map<string, QRCode> = new Map();
private expiryMs: number = 5 * 60 * 1000; // 5 minutes default
/**
* Store a QR code for a session.
*/
store(sessionId: string, qrData: string): void {
try {
const now = new Date();
const expiresAt = new Date(now.getTime() + this.expiryMs);
const qrCode: QRCode = {
sessionId,
data: qrData,
createdAt: now,
expiresAt,
};
this.qrMap.set(sessionId, qrCode);
logger.info('QRStorage', `QR code stored for session ${sessionId}, expires at ${expiresAt.toISOString()}`);
} catch (error) {
logger.error('QRStorage.store', error);
throw error;
}
}
/**
* Retrieve a QR code for a session.
* Returns null if expired or not found.
*/
get(sessionId: string): QRCode | null {
try {
const qr = this.qrMap.get(sessionId);
if (!qr) {
return null;
}
// Check if expired
if (new Date() > qr.expiresAt) {
this.qrMap.delete(sessionId);
logger.info('QRStorage', `QR code for session ${sessionId} has expired`);
return null;
}
return qr;
} catch (error) {
logger.error('QRStorage.get', error);
throw error;
}
}
/**
* Check if a QR code exists and is not expired.
*/
exists(sessionId: string): boolean {
const qr = this.qrMap.get(sessionId);
if (!qr) return false;
if (new Date() > qr.expiresAt) {
this.qrMap.delete(sessionId);
return false;
}
return true;
}
/**
* Clear a QR code for a session.
*/
clear(sessionId: string): void {
try {
if (this.qrMap.has(sessionId)) {
this.qrMap.delete(sessionId);
logger.info('QRStorage', `QR code cleared for session ${sessionId}`);
}
} catch (error) {
logger.error('QRStorage.clear', error);
throw error;
}
}
/**
* Clear all expired QR codes.
*/
clearExpired(): void {
try {
const now = new Date();
let cleared = 0;
for (const [sessionId, qr] of this.qrMap.entries()) {
if (now > qr.expiresAt) {
this.qrMap.delete(sessionId);
cleared++;
}
}
if (cleared > 0) {
logger.info('QRStorage', `Cleared ${cleared} expired QR codes`);
}
} catch (error) {
logger.error('QRStorage.clearExpired', error);
}
}
/**
* Get the number of stored QR codes.
*/
size(): number {
return this.qrMap.size;
}
/**
* Set the expiry time for new QR codes.
*/
setExpiry(ms: number): void {
this.expiryMs = ms;
logger.info('QRStorage', `QR expiry time set to ${ms}ms`);
}
}
export const qrStorage = new QRStorage();