1
0

reality.test.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { describe, it, expect } from 'vitest';
  2. import {
  3. generateX25519KeyPair,
  4. isX25519Available,
  5. randomShortId,
  6. realityClientLink,
  7. realityServerInbound,
  8. type RealityConfig,
  9. } from './reality';
  10. import { base64UrlToBytes } from './base64';
  11. import { parseLink } from './links';
  12. describe('X25519 keygen', () => {
  13. it('is available in this environment (Node 22+ / modern browser)', () => {
  14. expect(isX25519Available()).toBe(true);
  15. });
  16. it('produces 32-byte base64url keys that differ', async () => {
  17. const { privateKey, publicKey } = await generateX25519KeyPair();
  18. expect(privateKey).not.toMatch(/[+/=]/);
  19. expect(publicKey).not.toMatch(/[+/=]/);
  20. expect(base64UrlToBytes(privateKey)).toHaveLength(32);
  21. expect(base64UrlToBytes(publicKey)).toHaveLength(32);
  22. expect(privateKey).not.toEqual(publicKey);
  23. });
  24. it('generates a fresh keypair each call', async () => {
  25. const a = await generateX25519KeyPair();
  26. const b = await generateX25519KeyPair();
  27. expect(a.privateKey).not.toEqual(b.privateKey);
  28. });
  29. });
  30. describe('randomShortId', () => {
  31. it('returns lowercase hex of the requested byte length', () => {
  32. const id = randomShortId(4);
  33. expect(id).toMatch(/^[0-9a-f]{8}$/);
  34. });
  35. });
  36. const CONFIG: RealityConfig = {
  37. address: 'example.com',
  38. port: 443,
  39. uuid: '11111111-2222-3333-4444-555555555555',
  40. dest: 'www.microsoft.com:443',
  41. serverNames: ['www.microsoft.com'],
  42. shortIds: ['ab12'],
  43. privateKey: 'PRIV',
  44. publicKey: 'PUB',
  45. fingerprint: 'chrome',
  46. spiderX: '/',
  47. flow: 'xtls-rprx-vision',
  48. };
  49. describe('realityClientLink', () => {
  50. it('builds a parseable vless link with the public REALITY params', () => {
  51. const link = realityClientLink(CONFIG);
  52. const parsed = parseLink(link);
  53. expect(parsed.protocol).toBe('vless');
  54. expect(parsed.credential).toBe(CONFIG.uuid);
  55. expect(parsed.port).toBe(443);
  56. expect(parsed.params.security).toBe('reality');
  57. expect(parsed.params.pbk).toBe('PUB');
  58. expect(parsed.params.sid).toBe('ab12');
  59. expect(parsed.params.sni).toBe('www.microsoft.com');
  60. expect(parsed.params.flow).toBe('xtls-rprx-vision');
  61. // The private key must never appear in a client link.
  62. expect(link).not.toContain('PRIV');
  63. });
  64. });
  65. describe('realityServerInbound', () => {
  66. it('produces a vless+reality inbound with the private key', () => {
  67. const inbound = realityServerInbound(CONFIG) as {
  68. protocol: string;
  69. streamSettings: { security: string; realitySettings: { privateKey: string; dest: string } };
  70. };
  71. expect(inbound.protocol).toBe('vless');
  72. expect(inbound.streamSettings.security).toBe('reality');
  73. expect(inbound.streamSettings.realitySettings.privateKey).toBe('PRIV');
  74. expect(inbound.streamSettings.realitySettings.dest).toBe('www.microsoft.com:443');
  75. });
  76. });