Files
drop/server/internal/session/memory.ts
Paco d8db5b5b85 Adds new tile on the admin home page with system data. (#301)
* Adds new tile on the admin home page with system data. Also fixes the active users bug in the pie chart

* Fixes missing parentheses

* Updates user stats cache when signing in

* Reads active number of users from session provider

* Removes unused variable

* Small improvements

* Removes acl properties from system data websocket and performs initial push of data

* fix: remove acl fetch

---------

Co-authored-by: DecDuck <declanahofmeyr@gmail.com>
2026-01-22 10:58:21 +11:00

83 lines
2.4 KiB
TypeScript

import type { SessionProvider, SessionWithToken } from "./types";
export default function createMemorySessionHandler() {
const sessions = new Map<string, SessionWithToken>();
const memoryProvider: SessionProvider = {
async setSession(token, data) {
const session = { ...data, token };
sessions.set(token, session);
return session;
},
async getSession<T extends SessionWithToken>(
token: string,
): Promise<T | undefined> {
const session = sessions.get(token);
return session ? (session as T) : undefined; // Ensure undefined is returned if session is not found
},
async updateSession(token, data) {
return (await this.setSession(token, data)) !== undefined;
},
async removeSession(token) {
sessions.delete(token);
return true;
},
async getNumberActiveSessions() {
let activeSessions = 0;
for (const [_key, session] of sessions) {
if (session.expiresAt.getDate() > Date.now()) {
activeSessions += 1;
}
}
return activeSessions;
},
async cleanupSessions() {
const now = new Date();
for (const [token, session] of sessions) {
// if expires at time is before now, the session is expired
if (session.expiresAt < now) await this.removeSession(token);
}
},
async findSessions(options) {
const results: SessionWithToken[] = [];
for (const session of sessions.values()) {
let match = true;
if (
options.userId &&
session.authenticated &&
session.authenticated.userId !== options.userId
) {
match = false;
}
if (options.oidc && session.oidc) {
for (const [key, value] of Object.entries(options.oidc)) {
// stringify to do deep comparison
if (
JSON.stringify(
(session.oidc as unknown as Record<string, unknown>)[key],
) !== JSON.stringify(value)
) {
match = false;
break;
}
}
}
for (const [key, value] of Object.entries(options.data || {})) {
// stringify to do deep comparison
if (JSON.stringify(session.data[key]) !== JSON.stringify(value)) {
match = false;
break;
}
}
if (match) {
results.push(session);
}
}
return results;
},
};
return memoryProvider;
}