summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-12-17 03:28:43 +0100
committerRory& <root@rory.gay>2025-12-17 03:28:43 +0100
commit1c05e5c97add2195c624c9c48b21c086ce0af18a (patch)
treef478a72b9343144c08645de3354049e6a6995195
parentRemove ugly hack (diff)
downloadserver-ts-1c05e5c97add2195c624c9c48b21c086ce0af18a.tar.xz
Centralise ip info logic
-rw-r--r--src/api/middlewares/Authentication.ts2
-rw-r--r--src/gateway/opcodes/Identify.ts30
-rw-r--r--src/util/entities/Session.ts26
-rw-r--r--src/util/util/Token.ts6
4 files changed, 36 insertions, 28 deletions
diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts

index ec4a808c..47f6ab37 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts
@@ -116,7 +116,7 @@ export async function Authentication(req: Request, res: Response, next: NextFunc if (!req.headers.authorization) return next(new HTTPError("Missing Authorization Header", 401)); try { - const { decoded, user } = await checkToken(req.headers.authorization, { + const { decoded, user, session, tokenVersion } = await checkToken(req.headers.authorization, { ipAddress: req.ip, fingerprint: req.fingerprint, }); diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts
index 923ff533..99a01094 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts
@@ -140,34 +140,16 @@ export async function onIdentify(this: WebSocket, data: Payload) { }); this.session.status = identify.presence?.status || "online"; + this.session.last_seen = new Date(); this.session.client_info ??= {}; this.session.client_info.platform = identify.properties?.$device ?? identify.properties?.$device; this.session.client_info.os = identify.properties?.os || identify.properties?.$os; this.session.client_status = {}; this.session.activities = identify.presence?.activities ?? []; // TODO: validation + if (this.ipAddress && this.ipAddress !== this.session.last_seen_ip) { this.session.last_seen_ip = this.ipAddress; - const ipInfo = await IpDataClient.getIpInfo(this.ipAddress); - if (ipInfo?.ip) { - this.session.last_seen_location = `${ipInfo.emoji_flag} ${ipInfo.postal} ${ipInfo.city}, ${ipInfo.region}, ${ipInfo.country_name}`; - this.session.last_seen_location_info = { - is_eu: ipInfo.is_eu, - city: ipInfo.city, - region: ipInfo.region, - region_code: ipInfo.region_code, - country_name: ipInfo.country_name, - country_code: ipInfo.country_code, - continent_name: ipInfo.continent_name, - continent_code: ipInfo.continent_code, - latitude: ipInfo.latitude, - longitude: ipInfo.longitude, - postal: ipInfo.postal, - calling_code: ipInfo.calling_code, - flag: ipInfo.flag, - emoji_flag: ipInfo.emoji_flag, - emoji_unicode: ipInfo.emoji_unicode, - }; - } + await this.session.updateIpInfo(); } const createSessionTime = taskSw.getElapsedAndReset(); @@ -179,12 +161,14 @@ export async function onIdentify(this: WebSocket, data: Payload) { // * the bot application, if it exists const [ { elapsed: sessionSaveTime }, + { elapsed: ipInfoUpdateTime }, { result: application, elapsed: applicationQueryTime }, { result: read_states, elapsed: read_statesQueryTime }, { result: members, elapsed: membersQueryTime }, { result: recipients, elapsed: recipientsQueryTime }, ] = await Promise.all([ timePromise(() => this.session!.save()), + updateIpInfoPromise ? updateIpInfoPromise : { elapsed: new ElapsedTime(0n) }, timePromise(() => Application.findOne({ @@ -505,9 +489,9 @@ export async function onIdentify(this: WebSocket, data: Payload) { // Send SESSIONS_REPLACE and PRESENCE_UPDATE const allSessions = ( await Session.find({ - where: { user_id: this.user_id } + where: { user_id: this.user_id, is_admin_session: false }, }) - ).map(x=>x.toPrivateGatewayDeviceInfo()); + ).map((x) => x.toPrivateGatewayDeviceInfo()); // ).map((x) => ({ // // TODO how is active determined? // // in our lazy request impl, we just pick the 'most relevant' session diff --git a/src/util/entities/Session.ts b/src/util/entities/Session.ts
index 3f5543fd..fa2629c0 100644 --- a/src/util/entities/Session.ts +++ b/src/util/entities/Session.ts
@@ -23,7 +23,7 @@ import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, Primary import { Activity, ClientStatus, GatewaySession, GatewaySessionClientInfo, Status } from "../interfaces"; import { randomUpperString } from "@spacebar/api"; import { IpDataIpLookupResponse } from "../util/networking/ipdata/IpDataSampleResponses"; -import { DateBuilder, TimeSpan } from "../util"; +import { DateBuilder, IpDataClient, TimeSpan } from "../util"; //TODO we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them @@ -136,6 +136,30 @@ export class Session extends BaseClassWithoutId { active: TimeSpan.fromDates(this.last_seen?.getTime() ?? 0, new Date().getTime()).totalMillis < inactiveTreshold, } } + + async updateIpInfo() { + const ipInfo = await IpDataClient.getIpInfo(this.last_seen_ip!); + if (ipInfo?.ip) { + this.last_seen_location = `${ipInfo.emoji_flag} ${ipInfo.postal} ${ipInfo.city}, ${ipInfo.region}, ${ipInfo.country_name}`; + this.last_seen_location_info = { + is_eu: ipInfo.is_eu, + city: ipInfo.city, + region: ipInfo.region, + region_code: ipInfo.region_code, + country_name: ipInfo.country_name, + country_code: ipInfo.country_code, + continent_name: ipInfo.continent_name, + continent_code: ipInfo.continent_code, + latitude: ipInfo.latitude, + longitude: ipInfo.longitude, + postal: ipInfo.postal, + calling_code: ipInfo.calling_code, + flag: ipInfo.flag, + emoji_flag: ipInfo.emoji_flag, + emoji_unicode: ipInfo.emoji_unicode, + }; + } + } } export interface ExtendedLocationInfo { diff --git a/src/util/util/Token.ts b/src/util/util/Token.ts
index a1d0ca20..91d475df 100644 --- a/src/util/util/Token.ts +++ b/src/util/util/Token.ts
@@ -122,12 +122,12 @@ export const checkToken = ( if (session && TimeSpan.fromDates(session.last_seen?.getTime() ?? 0, new Date().getTime()).totalSeconds >= 15) { session.last_seen = new Date(); + let updateIpInfoPromise; if (opts?.ipAddress && opts?.ipAddress !== session.last_seen_ip) { session.last_seen_ip = opts.ipAddress; - const ipInfo = await IpDataClient.getIpInfo(opts.ipAddress); - if (ipInfo?.ip) session.last_seen_location = `${ipInfo.emoji_flag} ${ipInfo.postal} ${ipInfo.city}, ${ipInfo.region}, ${ipInfo.country_name}`; + updateIpInfoPromise = session.updateIpInfo(); } - await session.save(); + await Promise.all([session.save(), updateIpInfoPromise]); } const result: UserTokenData = {