import { expect, tap } from '@git.zone/tstest/tapbundle'; import { RadiusClient } from '../../ts_client/index.js'; import { RadiusServer, ERadiusCode, EAcctStatusType, } from '../../ts_server/index.js'; // Test server and client instances let server: RadiusServer; let client: RadiusClient; const TEST_SECRET = 'testing123'; const TEST_AUTH_PORT = 18120; const TEST_ACCT_PORT = 18130; tap.test('setup - create server and client', async () => { // Create server with authentication handler server = new RadiusServer({ authPort: TEST_AUTH_PORT, acctPort: TEST_ACCT_PORT, defaultSecret: TEST_SECRET, authenticationHandler: async (request) => { // Simple handler: accept user/password, reject others if (request.username === 'testuser' && request.password === 'testpass') { return { code: ERadiusCode.AccessAccept, replyMessage: 'Welcome!', sessionTimeout: 3600, }; } // Test CHAP if (request.username === 'chapuser' && request.chapPassword && request.chapChallenge) { const { RadiusAuthenticator } = await import('../../ts_server/index.js'); const isValid = RadiusAuthenticator.verifyChapResponse( request.chapPassword, request.chapChallenge, 'chappass' ); if (isValid) { return { code: ERadiusCode.AccessAccept, replyMessage: 'CHAP OK', }; } } return { code: ERadiusCode.AccessReject, replyMessage: 'Invalid credentials', }; }, accountingHandler: async (request) => { return { success: true }; }, }); await server.start(); // Create client client = new RadiusClient({ host: '127.0.0.1', authPort: TEST_AUTH_PORT, acctPort: TEST_ACCT_PORT, secret: TEST_SECRET, timeout: 2000, retries: 2, }); await client.connect(); }); tap.test('should authenticate with PAP - valid credentials', async () => { const response = await client.authenticatePap('testuser', 'testpass'); expect(response.accepted).toBeTruthy(); expect(response.rejected).toBeFalsy(); expect(response.code).toEqual(ERadiusCode.AccessAccept); expect(response.replyMessage).toEqual('Welcome!'); expect(response.sessionTimeout).toEqual(3600); }); tap.test('should reject PAP - invalid credentials', async () => { const response = await client.authenticatePap('testuser', 'wrongpass'); expect(response.accepted).toBeFalsy(); expect(response.rejected).toBeTruthy(); expect(response.code).toEqual(ERadiusCode.AccessReject); expect(response.replyMessage).toEqual('Invalid credentials'); }); tap.test('should authenticate with CHAP - valid credentials', async () => { const response = await client.authenticateChap('chapuser', 'chappass'); expect(response.accepted).toBeTruthy(); expect(response.rejected).toBeFalsy(); expect(response.code).toEqual(ERadiusCode.AccessAccept); }); tap.test('should reject CHAP - invalid credentials', async () => { const response = await client.authenticateChap('chapuser', 'wrongpass'); expect(response.accepted).toBeFalsy(); expect(response.rejected).toBeTruthy(); expect(response.code).toEqual(ERadiusCode.AccessReject); }); tap.test('should send accounting start', async () => { const response = await client.accountingStart('session-001', 'testuser'); expect(response.success).toBeTruthy(); }); tap.test('should send accounting update', async () => { const response = await client.accountingUpdate('session-001', { username: 'testuser', sessionTime: 1800, inputOctets: 512000, outputOctets: 1024000, }); expect(response.success).toBeTruthy(); }); tap.test('should send accounting stop', async () => { const response = await client.accountingStop('session-001', { username: 'testuser', sessionTime: 3600, inputOctets: 1024000, outputOctets: 2048000, terminateCause: 1, // User-Request }); expect(response.success).toBeTruthy(); }); tap.test('should send custom accounting request', async () => { const response = await client.accounting({ statusType: EAcctStatusType.Start, sessionId: 'custom-session', username: 'customuser', nasPort: 5060, calledStationId: 'called-001', callingStationId: 'calling-002', }); expect(response.success).toBeTruthy(); }); tap.test('should handle authentication with custom attributes', async () => { const response = await client.authenticate({ username: 'testuser', password: 'testpass', nasPort: 1, calledStationId: 'test-station', callingStationId: '192.168.1.100', }); expect(response.accepted).toBeTruthy(); }); tap.test('teardown - cleanup server and client', async () => { await client.disconnect(); await server.stop(); }); export default tap.start();