Files
dcrouter/test/test.protected-endpoint.ts
T

154 lines
4.6 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DcRouter } from '../ts/index.js';
import { TypedRequest } from '@api.global/typedrequest';
import * as interfaces from '../ts_interfaces/index.js';
import * as net from 'node:net';
let testDcRouter: DcRouter;
let adminIdentity: interfaces.data.IIdentity;
let opsServerPort: number;
const testAdminPassword = 'test-admin-password';
async function getFreePort(): Promise<number> {
return await new Promise<number>((resolve, reject) => {
const server = net.createServer();
server.once('error', reject);
server.listen(0, '127.0.0.1', () => {
const address = server.address();
const port = typeof address === 'object' && address ? address.port : 0;
server.close(() => resolve(port));
});
});
}
function getTypedRequestUrl(): string {
return `http://localhost:${opsServerPort}/typedrequest`;
}
tap.test('should start DCRouter with OpsServer', async () => {
process.env.DCROUTER_ADMIN_PASSWORD = testAdminPassword;
opsServerPort = await getFreePort();
testDcRouter = new DcRouter({
// Minimal config for testing
opsServerPort,
dbConfig: { enabled: false },
});
await testDcRouter.start();
expect(testDcRouter.opsServer).toBeInstanceOf(Object);
});
tap.test('should login as admin', async () => {
const loginRequest = new TypedRequest<interfaces.requests.IReq_AdminLoginWithUsernameAndPassword>(
getTypedRequestUrl(),
'adminLoginWithUsernameAndPassword'
);
const response = await loginRequest.fire({
username: 'admin',
password: testAdminPassword
});
expect(response).toHaveProperty('identity');
const responseIdentity = response.identity;
if (!responseIdentity) {
throw new Error('Expected admin login response to include identity');
}
adminIdentity = responseIdentity;
console.log('Admin logged in with JWT');
});
tap.test('should allow admin to verify identity', async () => {
const verifyRequest = new TypedRequest<interfaces.requests.IReq_VerifyIdentity>(
getTypedRequestUrl(),
'verifyIdentity'
);
const response = await verifyRequest.fire({
identity: adminIdentity,
});
expect(response).toHaveProperty('valid');
expect(response.valid).toBeTrue();
console.log('Admin identity verified successfully');
});
tap.test('should reject verify identity without identity', async () => {
const verifyRequest = new TypedRequest<interfaces.requests.IReq_VerifyIdentity>(
getTypedRequestUrl(),
'verifyIdentity'
);
try {
await verifyRequest.fire({} as any);
expect(true).toBeFalse(); // Should not reach here
} catch (error) {
expect(error).toBeTruthy();
console.log('Successfully rejected request without identity');
}
});
tap.test('should reject verify identity with invalid JWT', async () => {
const verifyRequest = new TypedRequest<interfaces.requests.IReq_VerifyIdentity>(
getTypedRequestUrl(),
'verifyIdentity'
);
try {
await verifyRequest.fire({
identity: {
...adminIdentity,
jwt: 'invalid.jwt.token'
},
});
expect(true).toBeFalse(); // Should not reach here
} catch (error) {
expect(error).toBeTruthy();
console.log('Successfully rejected request with invalid JWT');
}
});
tap.test('should reject protected endpoints without auth', async () => {
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
getTypedRequestUrl(),
'getHealthStatus'
);
try {
// No identity provided — should be rejected
await healthRequest.fire({} as any);
expect(true).toBeFalse(); // Should not reach here
} catch (error) {
expect(error).toBeTruthy();
console.log('Protected endpoint correctly rejects unauthenticated request');
}
});
tap.test('should allow authenticated access to protected endpoints', async () => {
const configRequest = new TypedRequest<interfaces.requests.IReq_GetConfiguration>(
getTypedRequestUrl(),
'getConfiguration'
);
const response = await configRequest.fire({
identity: adminIdentity,
});
expect(response).toHaveProperty('config');
expect(response.config).toHaveProperty('system');
expect(response.config).toHaveProperty('smartProxy');
expect(response.config).toHaveProperty('email');
expect(response.config).toHaveProperty('dns');
expect(response.config).toHaveProperty('tls');
expect(response.config).toHaveProperty('cache');
expect(response.config).toHaveProperty('radius');
expect(response.config).toHaveProperty('remoteIngress');
console.log('Authenticated access to config successful');
});
tap.test('should stop DCRouter', async () => {
await testDcRouter.stop();
});
export default tap.start();