diff --git a/lib/server/auth/connectionWatchdog.ts b/lib/server/auth/connectionWatchdog.ts index c66ae7b10..ba7dfed34 100644 --- a/lib/server/auth/connectionWatchdog.ts +++ b/lib/server/auth/connectionWatchdog.ts @@ -15,7 +15,7 @@ export const disconnectConnectionsWithStaleCreds = async () => { }, 'Cutting off connection.', ); - client.socket!.end(); + client.socket?.end(); } }); } diff --git a/lib/server/routesHandlers/connectionStatusHandler.ts b/lib/server/routesHandlers/connectionStatusHandler.ts index c6bb181e6..9fd96368d 100644 --- a/lib/server/routesHandlers/connectionStatusHandler.ts +++ b/lib/server/routesHandlers/connectionStatusHandler.ts @@ -20,6 +20,7 @@ export const connectionStatusHandler = async (req: Request, res: Response) => { const localHostname = hostname(); const regex = new RegExp(/-[0-9]{1,2}-[0-1]/); if ( + !process.env.BROKER_SERVER_MANDATORY_AUTH_ENABLED && localHostname && localHostname.endsWith('-1') && localHostname.match(regex) diff --git a/lib/server/routesHandlers/httpRequestHandler.ts b/lib/server/routesHandlers/httpRequestHandler.ts index 257a8d20d..d62c6c954 100644 --- a/lib/server/routesHandlers/httpRequestHandler.ts +++ b/lib/server/routesHandlers/httpRequestHandler.ts @@ -24,6 +24,7 @@ export const overloadHttpRequestWithConnectionDetailsMiddleware = async ( const localHostname = hostname(); const regex = new RegExp(/-[0-9]{1,2}-[0-1]/); if ( + !process.env.BROKER_SERVER_MANDATORY_AUTH_ENABLED && localHostname && localHostname.endsWith('-1') && localHostname.match(regex) @@ -63,7 +64,6 @@ export const overloadHttpRequestWithConnectionDetailsMiddleware = async ( return res.status(404).json({ ok: false }); } } - // Grab a first (newest) client from the pool // This is really silly... res.locals.websocket = connections.get(token)![0].socket; diff --git a/lib/server/socket.ts b/lib/server/socket.ts index 914dd2f40..89f79c9b4 100644 --- a/lib/server/socket.ts +++ b/lib/server/socket.ts @@ -96,13 +96,23 @@ const socket = ({ server, loadedServerOpts }): SocketHandler => { connectionIdentifier, ); if (!credsCheckResponse) { + logger.debug( + { maskedToken: maskToken(connectionIdentifier), brokerClientId }, + `Denied auth for Connection ${connectionIdentifier} client Id ${brokerClientId}, role ${role}`, + ); done({ statusCode: 401, authenticate: 'Bearer', message: 'Invalid credentials.', }); + return; } + logger.debug( + { maskedToken: maskToken(connectionIdentifier), brokerClientId }, + `Successful auth for Connection ${connectionIdentifier} client Id ${brokerClientId}, role ${role}`, + ); + const decodedJwt = decode(jwt, { complete: true }); const brokerAppClientId = decodedJwt?.payload['azp'] ?? ''; const nowDate = new Date().toISOString(); diff --git a/test/unit/old-client-redirect-disabled-in-universal-broker-stack.test.ts b/test/unit/old-client-redirect-disabled-in-universal-broker-stack.test.ts new file mode 100644 index 000000000..37a4cdd77 --- /dev/null +++ b/test/unit/old-client-redirect-disabled-in-universal-broker-stack.test.ts @@ -0,0 +1,130 @@ +import bodyParser from 'body-parser'; +import { overloadHttpRequestWithConnectionDetailsMiddleware } from '../../lib/server/routesHandlers/httpRequestHandler'; +import express from 'express'; +import request from 'supertest'; +import { connectionStatusHandler } from '../../lib/server/routesHandlers/connectionStatusHandler'; + +jest.mock('../../lib/server/socket', () => { + const originalModule = jest.requireActual('../../lib/server/socket'); + + return { + __esModule: true, + ...originalModule, + getSocketConnections: () => { + const map = new Map(); + + map.set('7fe7a57b-aa0d-416a-97fc-472061737e24', [ + { socket: {}, socketVersion: '1', metadata: { capabilities: {} } }, + ]); + // map.set('7fe7a57b-aa0d-416a-97fc-472061737e26', [ + // { metadata: {version: '123', filter: {}} }, + // ]); + return map; + }, + }; +}); + +jest.mock('node:os', () => { + const originalModule = jest.requireActual('node:os'); + + return { + __esModule: true, + ...originalModule, + hostname: () => { + return 'my-server-name-10-1'; + }, + }; +}); + +describe('Testing older clients specific logic', () => { + beforeAll(() => { + process.env.BROKER_SERVER_MANDATORY_AUTH_ENABLED = 'true'; + }); + afterAll(() => { + delete process.env.BROKER_SERVER_MANDATORY_AUTH_ENABLED; + }); + + it('Testing the old client redirected to primary from secondary pods', async () => { + const app = express(); + app.use( + bodyParser.raw({ + type: (req) => + req.headers['content-type'] !== + 'application/vnd.broker.stream+octet-stream', + limit: '10mb', + }), + ); + app.all( + '/broker/:token/*', + overloadHttpRequestWithConnectionDetailsMiddleware, + ); + + const response = await request(app) + .get('/broker/7fe7a57b-aa0d-416a-97fc-472061737e25/path') + .set('Host', 'my-server-name-1.default.svc.cluster'); + + expect(response.status).toEqual(404); + }); + it('Testing the old client redirected to primary from secondary pods - POST request', async () => { + const app = express(); + app.use( + bodyParser.raw({ + type: (req) => + req.headers['content-type'] !== + 'application/vnd.broker.stream+octet-stream', + limit: '10mb', + }), + ); + app.all( + '/broker/:token/*', + overloadHttpRequestWithConnectionDetailsMiddleware, + ); + + const response = await request(app) + .post('/broker/7fe7a57b-aa0d-416a-97fc-472061737e25/path') + .set('Host', 'my-server-name-1.default.svc.cluster') + .send({ test: 'value2' }); + + expect(response.status).toEqual(404); + }); + it('Testing the old client redirected to primary from secondary pods - get request', async () => { + const app = express(); + app.use( + bodyParser.raw({ + type: (req) => + req.headers['content-type'] !== + 'application/vnd.broker.stream+octet-stream', + limit: '10mb', + }), + ); + app.all( + '/broker/:token/*', + overloadHttpRequestWithConnectionDetailsMiddleware, + ); + + const response = await request(app) + .get('/broker/7fe7a57b-aa0d-416a-97fc-472061737e25/file') + .set('Host', 'my-server-name-1.default.svc.cluster'); + + expect(response.status).toEqual(404); + }); + + it('Testing the connection-status old client redirected to primary from secondary pods', async () => { + const app = express(); + app.use( + bodyParser.raw({ + type: (req) => + req.headers['content-type'] !== + 'application/vnd.broker.stream+octet-stream', + limit: '10mb', + }), + ); + app.all('/connection-status/:token', connectionStatusHandler); + + const response = await request(app) + .get('/connection-status/7fe7a57b-aa0d-416a-97fc-472061737e26') + .set('Host', 'my-server-name-1.default.svc.cluster'); + + expect(response.status).toEqual(404); + }); +});