mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
* fix(pwa): bring the Stalker transport to parity with Electron The self-hosted PWA's /stalker proxy now derives its portal requests from the same shared identity and URL builders as the Electron main process: MAG User-Agent/X-User-Agent, full STB cookie (mac + stb_lang + timezone + serial-derived __cfduid), SN header, JsHttpRequest=1-xml defaulting, and the sn-only-on-get_profile rule. macAddress/token/serialNumber are control params consumed into headers and never echoed into the portal's query string (handshake keeps its candidate token — protocol content). The stalker-mock-server /stalker route mirrors the new contract through the same shared builder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(stalker): forward the full identity header set in the mock /stalker mirror Greptile review: the synthetic portal request kept only the cookie and Authorization from the generated identity, so mock handlers could never validate the SN/MAG-UA/Accept/Language/Connection headers the real proxy sends. Forward the complete set, lowercased the way Express normalizes incoming headers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
94 lines
3.3 KiB
TypeScript
94 lines
3.3 KiB
TypeScript
import { LEGACY_DEFAULT_STALKER_SERIAL } from './stalker-identity.utils';
|
|
import { buildStalkerIdentityRequestContext } from './stalker-request-identity.util';
|
|
|
|
describe('buildStalkerIdentityRequestContext', () => {
|
|
const macAddress = '00:1A:79:AA:BB:CC';
|
|
|
|
it('does not add SN header or force get_profile SN fields when serial is absent', () => {
|
|
const context = buildStalkerIdentityRequestContext({
|
|
macAddress,
|
|
params: {
|
|
type: 'stb',
|
|
action: 'get_profile',
|
|
sn: 'STALE-SN',
|
|
metrics: JSON.stringify({
|
|
mac: macAddress,
|
|
sn: 'STALE-SN',
|
|
}),
|
|
},
|
|
});
|
|
|
|
expect(context.effectiveSerialNumber).toBeUndefined();
|
|
expect(context.headers).not.toHaveProperty('SN');
|
|
expect(context.cookieString).not.toContain('__cfduid=');
|
|
expect(context.requestParams).not.toHaveProperty('sn');
|
|
expect(
|
|
JSON.parse(String(context.requestParams['metrics']))
|
|
).not.toHaveProperty('sn');
|
|
});
|
|
|
|
it('preserves a provided serial exactly in headers, params, and metrics', () => {
|
|
const context = buildStalkerIdentityRequestContext({
|
|
macAddress,
|
|
serialNumber: 'CustomSn123',
|
|
params: {
|
|
type: 'stb',
|
|
action: 'get_profile',
|
|
metrics: JSON.stringify({
|
|
mac: macAddress,
|
|
}),
|
|
},
|
|
});
|
|
|
|
expect(context.effectiveSerialNumber).toBe('CustomSn123');
|
|
expect(context.headers['SN']).toBe('CustomSn123');
|
|
expect(context.cookieString).toContain('__cfduid=');
|
|
expect(
|
|
context.cookieString.match(/__cfduid=([^;]+)/)?.[1]
|
|
).toHaveLength(32);
|
|
expect(context.requestParams['sn']).toBe('CustomSn123');
|
|
expect(JSON.parse(String(context.requestParams['metrics']))).toEqual(
|
|
expect.objectContaining({
|
|
sn: 'CustomSn123',
|
|
})
|
|
);
|
|
});
|
|
|
|
it('treats the legacy default serial as absent', () => {
|
|
const context = buildStalkerIdentityRequestContext({
|
|
macAddress,
|
|
serialNumber: LEGACY_DEFAULT_STALKER_SERIAL,
|
|
params: {
|
|
type: 'stb',
|
|
action: 'get_profile',
|
|
sn: LEGACY_DEFAULT_STALKER_SERIAL,
|
|
metrics: JSON.stringify({
|
|
mac: macAddress,
|
|
sn: LEGACY_DEFAULT_STALKER_SERIAL,
|
|
}),
|
|
},
|
|
});
|
|
|
|
expect(context.effectiveSerialNumber).toBeUndefined();
|
|
expect(context.headers).not.toHaveProperty('SN');
|
|
expect(context.cookieString).not.toContain('__cfduid=');
|
|
expect(context.requestParams).not.toHaveProperty('sn');
|
|
expect(
|
|
JSON.parse(String(context.requestParams['metrics']))
|
|
).not.toHaveProperty('sn');
|
|
});
|
|
|
|
it('removes stale SN params from non-profile requests', () => {
|
|
const context = buildStalkerIdentityRequestContext({
|
|
macAddress,
|
|
params: {
|
|
type: 'itv',
|
|
action: 'get_ordered_list',
|
|
sn: 'STALE-SN',
|
|
},
|
|
});
|
|
|
|
expect(context.requestParams).not.toHaveProperty('sn');
|
|
});
|
|
});
|