diff --git a/app/server/src/modules/api/v2/account/ping.request.ts b/app/server/src/modules/api/v2/account/ping.request.ts index 2f99a34..7a075b8 100644 --- a/app/server/src/modules/api/v2/account/ping.request.ts +++ b/app/server/src/modules/api/v2/account/ping.request.ts @@ -19,12 +19,12 @@ export const pingRequest: RequestType = { ); // const account = await getAccountFromRequest(request); - const serverSessionByAccount = await System.db.get([ + const { value: serverSession } = await System.db.get([ "serverSessionByAccount", accountId, ]); - if (!serverSessionByAccount) + if (!serverSession) return Response.json( { status: 403 }, { @@ -34,12 +34,10 @@ export const pingRequest: RequestType = { const ip = getIpFromRequest(request); - const serverSession = serverSessionByAccount.value; - if ( - serverSession.ip !== ip || - serverSession.server !== server || - serverSession.ticketId !== ticketId + serverSession?.ip !== ip || + serverSession?.server !== server || + serverSession?.ticketId !== ticketId ) return Response.json( { status: 403 }, diff --git a/app/server/src/modules/api/v2/server/claim-session.request.ts b/app/server/src/modules/api/v2/server/claim-session.request.ts index 7baf197..e213f26 100644 --- a/app/server/src/modules/api/v2/server/claim-session.request.ts +++ b/app/server/src/modules/api/v2/server/claim-session.request.ts @@ -114,6 +114,7 @@ export const claimSessionRequest: RequestType = { expireIn: SERVER_SESSION_EXPIRE_TIME, }, ); + await System.sessions.checkAccountSession(account.accountId); return Response.json( { diff --git a/app/server/src/system/main.ts b/app/server/src/system/main.ts index b91389e..0bcc9d5 100644 --- a/app/server/src/system/main.ts +++ b/app/server/src/system/main.ts @@ -49,5 +49,6 @@ export const System = (() => { email: $email, otp: $otp, tasks: $tasks, + sessions: $sessions, }; })(); diff --git a/app/server/src/system/sessions.ts b/app/server/src/system/sessions.ts index 250dee2..4490ecd 100644 --- a/app/server/src/system/sessions.ts +++ b/app/server/src/system/sessions.ts @@ -5,51 +5,46 @@ import { getServerSessionList } from "shared/utils/main.ts"; export const sessions = () => { const sessionMap: Record = {}; - const $checkSessions = async () => { - const sessionList = await getServerSessionList(); - console.log(`Checking sessions... (${sessionList.length})`); + const $disconnectFromLastServer = (accountId: string, server: string) => { + const headers = new Headers(); + headers.append("auth-server", performance.now() + ""); - //check disconnected accounts - for (const accountId of Object.keys(sessionMap)) { - const foundSession = sessionList.find(({ key }) => key[1] === accountId); + console.error(`${server}/auth/user-disconnected?accountId=${accountId}`); + fetch(`${server}/auth/user-disconnected?accountId=${accountId}`, { + headers, + }) + .then(async (response) => console.error(await response.json())) + .catch((e) => { + console.error(e); + //we don't really care if server receives our petition, the session is being invalidated anyway + }); + }; - const session = sessionMap[accountId]; - const $disconnectFromLastServer = () => { - const headers = new Headers(); - headers.append("auth-server", performance.now() + ""); + const $checkSessions = async () => { + const currentSessions = Object.keys(sessionMap); + const targetSessions = (await getServerSessionList()).map( + ({ key: [, accountId] }) => accountId, + ); + console.log( + `Checking sessions... (${currentSessions.length}..${targetSessions.length})`, + ); - fetch( - `${session.server}/auth/user-disconnected?accountId=${accountId}`, - { - headers, - }, - ).catch(() => { - //we don't really care if server receives our petition, the session is being invalidated anyway - }); - delete sessionMap[accountId]; - }; + const toDeleteSessions = currentSessions.filter( + (accountId) => !targetSessions.includes(accountId), + ); - if (foundSession) { - const { sessionId, ticketId, server } = foundSession.value; - //check if session/server/ticket is still the same - if ( - session.sessionId !== sessionId || - session.ticketId !== ticketId || - session.server !== server - ) - $disconnectFromLastServer(); - continue; - } - //account is disconnected - $disconnectFromLastServer(); + //remove not active sessions + for (const accountId of toDeleteSessions) { + $disconnectFromLastServer(accountId, sessionMap[accountId].server); + delete sessionMap[accountId]; } - //update sessions - for (const { - key: [, accountId], - value: session, - } of sessionList) - sessionMap[accountId] = session; + const accountCheckList = [ + ...new Set([...currentSessions, ...targetSessions]), + ].filter((accountId) => toDeleteSessions.includes(accountId)); + + //check accounts + for (const accountId of accountCheckList) checkAccountSession(accountId); }; const load = () => { @@ -61,7 +56,39 @@ export const sessions = () => { $checkSessions(); }; + const checkAccountSession = async (accountId: string) => { + const foundSession = await System.db.get([ + "serverSessionByAccount", + accountId, + ]); + const session = sessionMap[accountId]; + + console.warn( + accountId, + "->", + session?.server, + "->", + foundSession?.value?.server, + "<<<<", + ); + + const currentSession = foundSession.value; + + //check if session server exists and changed if so disconnect from last server + if ( + session && + (session.sessionId !== currentSession.sessionId || + session.ticketId !== currentSession.ticketId || + session.server !== currentSession.server) + ) { + $disconnectFromLastServer(accountId, session.server); + } + //reassign server session + sessionMap[accountId] = currentSession; + }; + return { load, + checkAccountSession, }; };