summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-04-13 22:41:57 +0200
committerRory& <root@rory.gay>2026-04-13 22:41:57 +0200
commite0204f76cf5427eeb529d03fde988522923ecf2b (patch)
tree88a0ffd543804fa6378e118f97fc0ae7ec77b33a
parentPresence disconnect works! (diff)
downloadserver-ts-e0204f76cf5427eeb529d03fde988522923ecf2b.tar.xz
Make presence clear async, clean up temp session code
-rw-r--r--src/api/util/utility/EmbedHandlers.ts6
-rw-r--r--src/gateway/util/Utils.ts17
-rw-r--r--src/util/util/Token.ts17
-rw-r--r--src/util/util/extensions/index.ts5
4 files changed, 23 insertions, 22 deletions
diff --git a/src/api/util/utility/EmbedHandlers.ts b/src/api/util/utility/EmbedHandlers.ts

index 679424f3..25a33f06 100644 --- a/src/api/util/utility/EmbedHandlers.ts +++ b/src/api/util/utility/EmbedHandlers.ts
@@ -16,7 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { arrayDistinctBy, arrayGroupBy, Config, EmbedCache, emitEvent, Message, MessageUpdateEvent, normalizeUrl, OrmUtils } from "@spacebar/util"; +import { arrayDistinctBy, arrayGroupBy, Config, EmbedCache, emitEvent, Message, MessageUpdateEvent, normalizeUrl, OrmUtils, sleep } from "@spacebar/util"; import { Embed, EmbedImage, EmbedType } from "@spacebar/schemas"; import * as cheerio from "cheerio"; import crypto from "crypto"; @@ -572,10 +572,6 @@ export async function dropDuplicateCacheEntries(entries: EmbedCache[]): Promise< ); } -async function sleep(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - // hack to make nodejs not die function getSlowdownFactor(off: number) { if (off < 10) return off; diff --git a/src/gateway/util/Utils.ts b/src/gateway/util/Utils.ts
index c54c4980..ebf7ae02 100644 --- a/src/gateway/util/Utils.ts +++ b/src/gateway/util/Utils.ts
@@ -1,4 +1,4 @@ -import { Event, VoiceState } from "@spacebar/util"; +import { Event, Session, sleep, TimeSpan, VoiceState } from "@spacebar/util"; import { WebSocket } from "./WebSocket"; import { OPCODES } from "./Constants"; import { Send } from "./Send"; @@ -60,6 +60,21 @@ export async function cleanupOnStartup(): Promise<void> { VoiceState.clear() .then(() => console.log("[Gateway] Successfully cleaned voice states")) .catch((e) => console.error("[Gateway] Error cleaning voice states on startup:", e)); + + console.log("[Gateway] Starting async presence expiry..."); + expireOldPresenceStates() + .then(() => console.log("[Gateway] Successfully cleaned expired presence states")) + .catch((e) => console.error("[Gateway] Error cleaning expired presence states on startup:", e)); +} + +async function expireOldPresenceStates() { + for await (const session of await Session.createQueryBuilder("session").where("last_seen >= '2000/01/01' AND status != 'offline'").select().stream()) { + // session object has all fields prefixed with `session_`... thanks typeorm + if (TimeSpan.fromDates((session.session_last_seen as Date).getTime(), new Date().getTime()).totalMinutes > 30) { + console.log(`[Gateway/util/Utils.ts] Expiring presence for session ${session.session_session_id} last seen at ${session.session_last_seen}`); + await Session.update({ session_id: session.session_session_id }, { status: "offline" }); + } + } } export async function handleOffloadedGatewayRequest(socket: WebSocket, url: string, body: unknown) { diff --git a/src/util/util/Token.ts b/src/util/util/Token.ts
index 8bd45bcb..601fb275 100644 --- a/src/util/util/Token.ts +++ b/src/util/util/Token.ts
@@ -96,21 +96,6 @@ export const checkToken = ( return rejectAndLog(reject, 401, "User not found"); } - if (decoded.did && !session) { - // temporary hack: create new session - session = Session.create({ - session_id: decoded.did, - user_id: user.id, - is_admin_session: false, - client_status: {}, - status: "online", - client_info: {}, - }); - await session.save(); - logAuth("validateUser rejected: Session not found"); - return rejectAndLog(reject, 401, "Invalid Token"); - } - // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) { logAuth("validateUser rejected: Token not yet valid"); @@ -183,7 +168,7 @@ export async function generateToken(id: string, isAdminSession: boolean = false) user_id: id, is_admin_session: isAdminSession, client_status: {}, - status: "online", + status: "offline", // will be set to online upon IDENTIFY client_info: {}, }); } while (await Session.findOne({ where: { session_id: newSession.session_id } })); diff --git a/src/util/util/extensions/index.ts b/src/util/util/extensions/index.ts
index e1946bb3..0ec969f4 100644 --- a/src/util/util/extensions/index.ts +++ b/src/util/util/extensions/index.ts
@@ -1 +1,6 @@ export * from "./Array"; + +// TODO: move to a separate file +export async function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +}