Files
smartvpn/test/test.vpnconfig.node.ts

180 lines
4.8 KiB
TypeScript

import { tap, expect } from '@git.zone/tstest/tapbundle';
import { VpnConfig } from '../ts/index.js';
import type { IVpnClientConfig, IVpnServerConfig } from '../ts/index.js';
// Valid 32-byte base64 keys for testing
const TEST_KEY_A = 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=';
const TEST_KEY_B = 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=';
const TEST_KEY_C = 'Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2M=';
tap.test('VpnConfig: validate valid client config', async () => {
const config: IVpnClientConfig = {
serverUrl: 'wss://vpn.example.com/tunnel',
serverPublicKey: TEST_KEY_A,
clientPrivateKey: TEST_KEY_B,
clientPublicKey: TEST_KEY_C,
dns: ['1.1.1.1', '8.8.8.8'],
mtu: 1420,
keepaliveIntervalSecs: 30,
};
// Should not throw
VpnConfig.validateClientConfig(config);
});
tap.test('VpnConfig: reject client config without serverUrl', async () => {
const config = {
serverPublicKey: TEST_KEY_A,
clientPrivateKey: TEST_KEY_B,
clientPublicKey: TEST_KEY_C,
} as IVpnClientConfig;
let threw = false;
try {
VpnConfig.validateClientConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('serverUrl');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject client config with invalid serverUrl scheme', async () => {
const config: IVpnClientConfig = {
serverUrl: 'http://vpn.example.com/tunnel',
serverPublicKey: TEST_KEY_A,
clientPrivateKey: TEST_KEY_B,
clientPublicKey: TEST_KEY_C,
};
let threw = false;
try {
VpnConfig.validateClientConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('wss://');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject client config without clientPrivateKey', async () => {
const config = {
serverUrl: 'wss://vpn.example.com/tunnel',
serverPublicKey: TEST_KEY_A,
clientPublicKey: TEST_KEY_C,
} as IVpnClientConfig;
let threw = false;
try {
VpnConfig.validateClientConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('clientPrivateKey');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject client config with invalid MTU', async () => {
const config: IVpnClientConfig = {
serverUrl: 'wss://vpn.example.com/tunnel',
serverPublicKey: TEST_KEY_A,
clientPrivateKey: TEST_KEY_B,
clientPublicKey: TEST_KEY_C,
mtu: 100,
};
let threw = false;
try {
VpnConfig.validateClientConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('mtu');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject client config with invalid DNS', async () => {
const config: IVpnClientConfig = {
serverUrl: 'wss://vpn.example.com/tunnel',
serverPublicKey: TEST_KEY_A,
clientPrivateKey: TEST_KEY_B,
clientPublicKey: TEST_KEY_C,
dns: ['not-an-ip'],
};
let threw = false;
try {
VpnConfig.validateClientConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('DNS');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: validate valid server config', async () => {
const config: IVpnServerConfig = {
listenAddr: '0.0.0.0:443',
privateKey: TEST_KEY_A,
publicKey: TEST_KEY_B,
subnet: '10.8.0.0/24',
dns: ['1.1.1.1'],
mtu: 1420,
enableNat: true,
clients: [
{ clientId: 'test-client', publicKey: TEST_KEY_C },
],
};
// Should not throw
VpnConfig.validateServerConfig(config);
});
tap.test('VpnConfig: reject server config with invalid subnet', async () => {
const config: IVpnServerConfig = {
listenAddr: '0.0.0.0:443',
privateKey: TEST_KEY_A,
publicKey: TEST_KEY_B,
subnet: 'invalid',
};
let threw = false;
try {
VpnConfig.validateServerConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('subnet');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject server config without privateKey', async () => {
const config = {
listenAddr: '0.0.0.0:443',
publicKey: TEST_KEY_B,
subnet: '10.8.0.0/24',
} as IVpnServerConfig;
let threw = false;
try {
VpnConfig.validateServerConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('privateKey');
}
expect(threw).toBeTrue();
});
tap.test('VpnConfig: reject server config with invalid client publicKey', async () => {
const config: IVpnServerConfig = {
listenAddr: '0.0.0.0:443',
privateKey: TEST_KEY_A,
publicKey: TEST_KEY_B,
subnet: '10.8.0.0/24',
clients: [
{ clientId: 'bad-client', publicKey: 'short-key' },
],
};
let threw = false;
try {
VpnConfig.validateServerConfig(config);
} catch (e) {
threw = true;
expect((e as Error).message).toContain('publicKey');
}
expect(threw).toBeTrue();
});
export default tap.start();