Skip to content

Commit 37b3bd4

Browse files
author
Antigravity Assistant
committed
small fixes
1 parent 0f196cc commit 37b3bd4

2 files changed

Lines changed: 139 additions & 133 deletions

File tree

server/test/integration/socket-auth.test.ts

Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -7,132 +7,132 @@ import jwt from 'jsonwebtoken';
77
import { createTestServer } from './utils/socket-test-utils.js';
88

99
describe('Socket.IO Authentication Integration', () => {
10-
let io: Server;
11-
let httpServer: HTTPServer;
12-
let port: number;
13-
14-
const validUser = { id: 'user-auth-123', username: 'TestUser' };
15-
16-
beforeAll(async () => {
17-
const testServerParams = await createTestServer();
18-
io = testServerParams.io;
19-
httpServer = testServerParams.httpServer;
20-
port = testServerParams.port;
10+
let io: Server;
11+
let httpServer: HTTPServer;
12+
let port: number;
13+
14+
const validUser = { id: 'user-auth-123', username: 'TestUser' };
15+
16+
beforeAll(async () => {
17+
const testServerParams = await createTestServer();
18+
io = testServerParams.io;
19+
httpServer = testServerParams.httpServer;
20+
port = testServerParams.port;
21+
});
22+
23+
afterAll(() => {
24+
io.close();
25+
httpServer.close();
26+
});
27+
28+
it('should reject connection when no token is provided', () => {
29+
return new Promise<void>((resolve, reject) => {
30+
const clientSocket = Client(`http://localhost:${port}`, {
31+
reconnection: false,
32+
});
33+
34+
clientSocket.on('connect_error', (err) => {
35+
try {
36+
expect(err.message).toBe('Authentication error: No token provided');
37+
clientSocket.disconnect();
38+
resolve();
39+
} catch (e) {
40+
clientSocket.disconnect();
41+
reject(e);
42+
}
43+
});
44+
45+
clientSocket.on('connect', () => {
46+
clientSocket.disconnect();
47+
reject(new Error('Should not connect successfully without a token'));
48+
});
2149
});
22-
23-
afterAll(() => {
24-
io.close();
25-
httpServer.close();
50+
});
51+
52+
it('should reject connection when an invalid/tampered token is provided', () => {
53+
return new Promise<void>((resolve, reject) => {
54+
const clientSocket = Client(`http://localhost:${port}`, {
55+
auth: {
56+
token: 'invalid.tampered.token'
57+
},
58+
reconnection: false,
59+
});
60+
61+
clientSocket.on('connect_error', (err) => {
62+
try {
63+
expect(err.message).toBe('Authentication error: Invalid token');
64+
clientSocket.disconnect();
65+
resolve();
66+
} catch (e) {
67+
clientSocket.disconnect();
68+
reject(e);
69+
}
70+
});
71+
72+
clientSocket.on('connect', () => {
73+
clientSocket.disconnect();
74+
reject(new Error('Should not connect successfully with an invalid token'));
75+
});
2676
});
27-
28-
it("should reject connection when no token is provided", () => {
29-
return new Promise<void>((resolve, reject) => {
30-
const clientSocket = Client(`http://localhost:${port}`, {
31-
reconnection: false,
32-
});
33-
34-
clientSocket.on("connect_error", (err) => {
35-
try {
36-
expect(err.message).toBe("Authentication error: No token provided");
37-
clientSocket.disconnect();
38-
resolve();
39-
} catch (e) {
40-
clientSocket.disconnect();
41-
reject(e);
42-
}
43-
});
44-
45-
clientSocket.on("connect", () => {
46-
clientSocket.disconnect();
47-
reject(new Error("Should not connect successfully without a token"));
48-
});
49-
});
77+
});
78+
79+
it('should reject connection when an expired token is provided', () => {
80+
return new Promise<void>((resolve, reject) => {
81+
const expiredToken = jwt.sign(
82+
validUser,
83+
CONFIG.JWT.SECRET,
84+
{ expiresIn: '-1h' }
85+
);
86+
87+
const clientSocket = Client(`http://localhost:${port}`, {
88+
auth: {
89+
token: expiredToken
90+
},
91+
reconnection: false,
92+
});
93+
94+
clientSocket.on('connect_error', (err) => {
95+
try {
96+
expect(err.message).toBe('Authentication error: Invalid token');
97+
clientSocket.disconnect();
98+
resolve();
99+
} catch (e) {
100+
clientSocket.disconnect();
101+
reject(e);
102+
}
103+
});
104+
105+
clientSocket.on('connect', () => {
106+
clientSocket.disconnect();
107+
reject(new Error('Should not connect successfully with an expired token'));
108+
});
50109
});
51-
52-
it("should reject connection when an invalid/tampered token is provided", () => {
53-
return new Promise<void>((resolve, reject) => {
54-
const clientSocket = Client(`http://localhost:${port}`, {
55-
auth: {
56-
token: "invalid.tampered.token"
57-
},
58-
reconnection: false,
59-
});
60-
61-
clientSocket.on("connect_error", (err) => {
62-
try {
63-
expect(err.message).toBe("Authentication error: Invalid token");
64-
clientSocket.disconnect();
65-
resolve();
66-
} catch (e) {
67-
clientSocket.disconnect();
68-
reject(e);
69-
}
70-
});
71-
72-
clientSocket.on("connect", () => {
73-
clientSocket.disconnect();
74-
reject(new Error("Should not connect successfully with an invalid token"));
75-
});
76-
});
77-
});
78-
79-
it("should reject connection when an expired token is provided", () => {
80-
return new Promise<void>((resolve, reject) => {
81-
const expiredToken = jwt.sign(
82-
validUser,
83-
CONFIG.JWT.SECRET,
84-
{ expiresIn: "-1h" }
85-
);
86-
87-
const clientSocket = Client(`http://localhost:${port}`, {
88-
auth: {
89-
token: expiredToken
90-
},
91-
reconnection: false,
92-
});
93-
94-
clientSocket.on("connect_error", (err) => {
95-
try {
96-
expect(err.message).toBe("Authentication error: Invalid token");
97-
clientSocket.disconnect();
98-
resolve();
99-
} catch (e) {
100-
clientSocket.disconnect();
101-
reject(e);
102-
}
103-
});
104-
105-
clientSocket.on("connect", () => {
106-
clientSocket.disconnect();
107-
reject(new Error("Should not connect successfully with an expired token"));
108-
});
109-
});
110-
});
111-
112-
it("should successfully connect when a valid token is provided", () => {
113-
return new Promise<void>((resolve, reject) => {
114-
const validToken = jwt.sign(
115-
validUser,
116-
CONFIG.JWT.SECRET,
117-
{ expiresIn: "1h" }
118-
);
119-
120-
const clientSocket = Client(`http://localhost:${port}`, {
121-
auth: {
122-
token: validToken
123-
},
124-
reconnection: false,
125-
});
126-
127-
clientSocket.on("connect", () => {
128-
clientSocket.disconnect();
129-
resolve();
130-
});
131-
132-
clientSocket.on("connect_error", (err) => {
133-
clientSocket.disconnect();
134-
reject(new Error(`Should connect successfully, but got error: ${err.message}`));
135-
});
136-
});
110+
});
111+
112+
it('should successfully connect when a valid token is provided', () => {
113+
return new Promise<void>((resolve, reject) => {
114+
const validToken = jwt.sign(
115+
validUser,
116+
CONFIG.JWT.SECRET,
117+
{ expiresIn: '1h' }
118+
);
119+
120+
const clientSocket = Client(`http://localhost:${port}`, {
121+
auth: {
122+
token: validToken
123+
},
124+
reconnection: false,
125+
});
126+
127+
clientSocket.on('connect', () => {
128+
clientSocket.disconnect();
129+
resolve();
130+
});
131+
132+
clientSocket.on('connect_error', (err) => {
133+
clientSocket.disconnect();
134+
reject(new Error(`Should connect successfully, but got error: ${err.message}`));
135+
});
137136
});
137+
});
138138
});

server/test/integration/utils/socket-test-utils.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createServer, Server as HTTPServer } from 'http';
22
import { Server } from 'socket.io';
33
import { io as Client, Socket as ClientSocket } from 'socket.io-client';
44
import { vi } from 'vitest';
5-
import jwt from 'jsonwebtoken';
5+
import jwt, { Secret, VerifyCallback, JsonWebTokenError } from 'jsonwebtoken';
66
import { setupSocket } from '../../../src/sockets/index.js';
77
import { CONFIG } from '../../../src/config.js';
88
import { LobbyService } from '../../../src/services/lobby.service.js';
@@ -16,16 +16,20 @@ export const tokenB = 'token-b';
1616

1717
export const setupTestMocks = () => {
1818
// Mock JWT verification
19-
vi.spyOn(jwt, 'verify').mockImplementation((token: any, secret: any, callback: any) => {
19+
vi.spyOn(jwt, 'verify').mockImplementation(((
20+
token: string,
21+
secretOrPublicKey: Secret,
22+
callback: VerifyCallback
23+
) => {
2024
if (token === tokenA) callback(null, userA);
2125
else if (token === tokenB) callback(null, userB);
22-
else callback(new Error('Invalid token'));
23-
});
26+
else callback(new JsonWebTokenError('Invalid token'), undefined);
27+
}) as typeof jwt.verify);
2428

2529
// Mock LobbyService to allow joining
2630
vi.spyOn(LobbyService, 'getById').mockResolvedValue({ _id: mockLobbyId, maxCollaborators: 10, bannedUsers: [] } as any);
27-
vi.spyOn(LobbyService, 'validateJoinAccess').mockImplementation(() => {});
28-
vi.spyOn(LobbyService, 'validateCapacity').mockImplementation(() => {});
31+
vi.spyOn(LobbyService, 'validateJoinAccess').mockImplementation(() => { });
32+
vi.spyOn(LobbyService, 'validateCapacity').mockImplementation(() => { });
2933

3034
// Mock CanvasService
3135
vi.spyOn(CanvasService, 'getState').mockResolvedValue({ width: 100, height: 100, palette: [], data: new Uint8Array() });
@@ -38,11 +42,13 @@ export const createTestServer = (): Promise<{ io: Server; httpServer: HTTPServer
3842
const io = new Server(httpServer);
3943
setupSocket(io);
4044

41-
return new Promise((resolve) => {
45+
return new Promise((resolve, reject) => {
4246
httpServer.listen(() => {
4347
const address = httpServer.address();
44-
const port = typeof address === 'string' ? 0 : address?.port || 0;
45-
resolve({ io, httpServer, port });
48+
if (!address || typeof address === 'string') {
49+
return reject(new Error('Failed to gracefully acquire a port number for the test server.'));
50+
}
51+
resolve({ io, httpServer, port: address.port });
4652
});
4753
});
4854
};

0 commit comments

Comments
 (0)