diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 26af17ea..756f982e 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -88,6 +88,13 @@ export default ({ app }: { app: Application }) => { return next(); } + // If JWT has been successfully verified by expressjwt middleware, allow the request + // This handles regular users whose tokens are not stored in authInfo + if (req.auth) { + return next(); + } + + // For system admin, also check against stored token const authInfo = await shareStore.getAuthInfo(); if (authInfo && headerToken) { const { token = '', tokens = {} } = authInfo; diff --git a/back/loaders/sock.ts b/back/loaders/sock.ts index d7db3d97..0568cfb7 100644 --- a/back/loaders/sock.ts +++ b/back/loaders/sock.ts @@ -4,6 +4,8 @@ import { Container } from 'typedi'; import SockService from '../services/sock'; import { getPlatform } from '../config/util'; import { shareStore } from '../shared/store'; +import jwt from 'jsonwebtoken'; +import config from '../config'; export default async ({ server }: { server: Server }) => { const echo = sockJs.createServer({ prefix: '/api/ws', log: () => {} }); @@ -14,26 +16,46 @@ export default async ({ server }: { server: Server }) => { conn.close('404'); } - const authInfo = await shareStore.getAuthInfo(); const platform = getPlatform(conn.headers['user-agent'] || '') || 'desktop'; const headerToken = conn.url.replace(`${conn.pathname}?token=`, ''); - if (authInfo) { - const { token = '', tokens = {} } = authInfo; - if (headerToken === token || tokens[platform] === headerToken) { - sockService.addClient(conn); + + let isAuthenticated = false; - conn.on('data', (message) => { - conn.write(message); - }); - - conn.on('close', function () { - sockService.removeClient(conn); - }); - - return; + // First try to verify JWT token (for regular users) + if (headerToken) { + try { + jwt.verify(headerToken, config.jwt.secret, { algorithms: ['HS384'] }); + isAuthenticated = true; + } catch (error) { + // JWT verification failed, will try authInfo check next } } + // Also check against stored token for system admin + if (!isAuthenticated) { + const authInfo = await shareStore.getAuthInfo(); + if (authInfo) { + const { token = '', tokens = {} } = authInfo; + if (headerToken === token || tokens[platform] === headerToken) { + isAuthenticated = true; + } + } + } + + if (isAuthenticated) { + sockService.addClient(conn); + + conn.on('data', (message) => { + conn.write(message); + }); + + conn.on('close', function () { + sockService.removeClient(conn); + }); + + return; + } + conn.close('404'); });