feat: get user id from namespace auth

This commit is contained in:
Rohit
2025-03-30 00:20:12 +05:30
parent 54c0a87681
commit 7a75b9d267

View File

@@ -1,6 +1,6 @@
import { Namespace, Socket } from 'socket.io';
import { IncomingMessage } from 'http';
import { verify, JwtPayload } from 'jsonwebtoken';
import { verify, JwtPayload, sign } from 'jsonwebtoken';
import logger from "../logger";
import registerInputHandlers from '../browser-management/inputHandlers';
@@ -12,48 +12,85 @@ interface AuthenticatedSocket extends Socket {
request: AuthenticatedIncomingMessage;
}
declare global {
var userContextMap: Map<string, string>;
}
if (!global.userContextMap) {
global.userContextMap = new Map<string, string>();
}
/**
* Register browser-user association in the global context map
*/
export function registerBrowserUserContext(browserId: string, userId: string) {
if (!global.userContextMap) {
global.userContextMap = new Map<string, string>();
}
global.userContextMap.set(browserId, userId);
logger.log('debug', `Registered browser-user association: ${browserId} -> ${userId}`);
}
/**
* Socket.io middleware for authentication
* This is a socket.io specific auth handler that doesn't rely on Express middleware
*/
const socketAuthMiddleware = (socket: Socket, next: (err?: Error) => void) => {
const cookies = socket.handshake.headers.cookie;
if (!cookies) {
return next(new Error('Authentication required'));
// Extract browserId from namespace
const namespace = socket.nsp.name;
const browserId = namespace.slice(1);
// Check if this browser is in our context map
if (global.userContextMap && global.userContextMap.has(browserId)) {
const userId = global.userContextMap.get(browserId);
logger.log('debug', `Found browser in context map: ${browserId} -> ${userId}`);
const authSocket = socket as AuthenticatedSocket;
authSocket.request.user = { id: userId };
return next();
}
const cookies = socket.handshake.headers.cookie;
if (!cookies) {
logger.log('debug', `No cookies found in socket handshake for ${browserId}`);
return next(new Error('Authentication required'));
}
const tokenMatch = cookies.split(';').find(c => c.trim().startsWith('token='));
if (!tokenMatch) {
logger.log('debug', `No token cookie found in socket handshake for ${browserId}`);
return next(new Error('Authentication required'));
}
const token = tokenMatch.split('=')[1];
if (!token) {
logger.log('debug', `Empty token value in cookie for ${browserId}`);
return next(new Error('Authentication required'));
}
const secret = process.env.JWT_SECRET;
if (!secret) {
logger.error('JWT_SECRET environment variable is not defined');
return next(new Error('Server configuration error'));
}
verify(token, secret, (err: any, user: any) => {
if (err) {
logger.log('warn', `JWT verification error: ${err.message}`);
return next(new Error('Authentication failed'));
}
const tokenMatch = cookies.split(';').find(c => c.trim().startsWith('token='));
if (!tokenMatch) {
return next(new Error('Authentication required'));
// Normalize payload key
if (user.userId && !user.id) {
user.id = user.userId;
delete user.userId;
}
const token = tokenMatch.split('=')[1];
if (!token) {
return next(new Error('Authentication required'));
}
const secret = process.env.JWT_SECRET;
if (!secret) {
return next(new Error('Server configuration error'));
}
verify(token, secret, (err: any, user: any) => {
if (err) {
logger.log('warn', 'JWT verification error:', err);
return next(new Error('Authentication failed'));
}
// Normalize payload key
if (user.userId && !user.id) {
user.id = user.userId;
delete user.userId; // temporary: del the old key for clarity
}
// Attach user to socket request
const authSocket = socket as AuthenticatedSocket;
authSocket.request.user = user;
next();
});
// Attach user to socket request
const authSocket = socket as AuthenticatedSocket;
authSocket.request.user = user;
next();
});
};
/**