1
0

xhttp-session-id.test.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { describe, expect, it } from 'vitest';
  2. import { validateSessionIDLength, validateSessionIDTable } from '@/lib/xray/xhttp-session-id';
  3. import { XHttpStreamSettingsSchema } from '@/schemas/protocols/stream/xhttp';
  4. // xray-core #6258: sessionPlacement/sessionKey were renamed to
  5. // sessionIDPlacement/sessionIDKey. The schema must lift legacy keys off
  6. // stored configs so an upgraded panel never silently drops them.
  7. describe('XHttpStreamSettingsSchema legacy migration', () => {
  8. it('lifts legacy sessionPlacement/sessionKey onto the renamed keys', () => {
  9. const parsed = XHttpStreamSettingsSchema.parse({
  10. sessionPlacement: 'cookie',
  11. sessionKey: 'x_session',
  12. });
  13. expect(parsed.sessionIDPlacement).toBe('cookie');
  14. expect(parsed.sessionIDKey).toBe('x_session');
  15. // legacy keys must not survive — we never emit both names
  16. expect((parsed as Record<string, unknown>).sessionPlacement).toBeUndefined();
  17. expect((parsed as Record<string, unknown>).sessionKey).toBeUndefined();
  18. });
  19. it('prefers an explicit new key over a legacy one', () => {
  20. const parsed = XHttpStreamSettingsSchema.parse({
  21. sessionPlacement: 'cookie',
  22. sessionIDPlacement: 'header',
  23. });
  24. expect(parsed.sessionIDPlacement).toBe('header');
  25. });
  26. it('defaults the new fields to empty', () => {
  27. const parsed = XHttpStreamSettingsSchema.parse({});
  28. expect(parsed.sessionIDTable).toBe('');
  29. expect(parsed.sessionIDLength).toBe('');
  30. });
  31. });
  32. describe('sessionID validators', () => {
  33. it('accepts empty and ASCII tables, rejects non-ASCII', async () => {
  34. await expect(validateSessionIDTable(null, '')).resolves.toBeUndefined();
  35. await expect(validateSessionIDTable(null, 'Base62')).resolves.toBeUndefined();
  36. await expect(validateSessionIDTable(null, 'ABCdef0123')).resolves.toBeUndefined();
  37. await expect(validateSessionIDTable(null, ' café')).rejects.toThrow();
  38. });
  39. it('accepts a positive length/range, rejects zero or junk', async () => {
  40. await expect(validateSessionIDLength(null, '')).resolves.toBeUndefined();
  41. await expect(validateSessionIDLength(null, '8')).resolves.toBeUndefined();
  42. await expect(validateSessionIDLength(null, '16-32')).resolves.toBeUndefined();
  43. await expect(validateSessionIDLength(null, '8-8')).resolves.toBeUndefined();
  44. await expect(validateSessionIDLength(null, '0-16')).rejects.toThrow();
  45. await expect(validateSessionIDLength(null, '32-16')).rejects.toThrow();
  46. await expect(validateSessionIDLength(null, 'abc')).rejects.toThrow();
  47. });
  48. });