mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 01:56:16 -08:00
fix(stalker): warm the session against the repaired portal configuration
Found while auditing my own static branch against the create_link path rather than waiting for the next review round. `executeStalkerRequest` applies the lazy-repair override on its first line, so the create_link path always talks to the configuration a completed repair proved good. The session warm-up I added did not: it handed `ensureToken` the caller's pre-repair row, so a portal whose endpoint or mode had been repaired would handshake against the configuration the repair had already rejected — stranding the session precisely on the portals repair exists to rescue. The override now happens inside `ensureStalkerSession`, mirroring `executeStalkerRequest`'s first line, so every caller inherits the rule instead of each having to remember it. Mutation-checked: dropping the override fails the new test alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9afdad0279
commit
277e0a0385
3 files changed
+56
-3
No files matched your search
@@ -375,7 +375,9 @@ export class StreamResolverService {
|
||||
// `ensureToken` performs the handshake + get_profile — and
|
||||
// validates the identity the cached token was negotiated for,
|
||||
// which the raw `getCachedToken` below cannot — without minting a
|
||||
// link; a simple portal returns null immediately.
|
||||
// link; a simple portal returns null immediately. The raw row goes
|
||||
// in: the helper applies the repair override itself, exactly as
|
||||
// `executeStalkerRequest` does on the branch below.
|
||||
await this.warmStalkerSession(playlist);
|
||||
|
||||
return this.buildStalkerPlayback(item, playlist, {
|
||||
|
||||
+38
@@ -214,6 +214,44 @@ describe('stalker-player-request.utils', () => {
|
||||
expect(dataService.sendIpcEvent).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handshakes against a repaired endpoint, not the stale one', async () => {
|
||||
// `executeStalkerRequest` applies the repair override on its first
|
||||
// line, so the static path must too — handshaking against the
|
||||
// configuration a repair has already proven broken would strand
|
||||
// the session.
|
||||
const stale = {
|
||||
...PLAYLIST,
|
||||
portalUrl: 'http://demo.example/portal.php',
|
||||
isFullStalkerPortal: true,
|
||||
} as PlaylistMeta;
|
||||
const repaired = {
|
||||
...stale,
|
||||
portalUrl: 'http://demo.example/stalker_portal/server/load.php',
|
||||
} as PlaylistMeta;
|
||||
|
||||
await fetchStalkerPlaybackLink(
|
||||
{
|
||||
dataService: dataService as never,
|
||||
stalkerSession: stalkerSession as StalkerSessionService,
|
||||
portalRepair: {
|
||||
applyOverride: jest.fn().mockReturnValue(repaired),
|
||||
shouldAttemptRepair: jest.fn().mockReturnValue(false),
|
||||
repairPortal: jest.fn().mockResolvedValue(null),
|
||||
},
|
||||
},
|
||||
{
|
||||
playlist: stale,
|
||||
selectedContentType: 'itv',
|
||||
cmd: 'ffrt3 http://cdn.example/live/42.m3u8',
|
||||
linkFlags: { use_http_tmp_link: '0' },
|
||||
}
|
||||
);
|
||||
|
||||
expect(stalkerSession.ensureToken).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ portalUrl: repaired.portalUrl })
|
||||
);
|
||||
});
|
||||
|
||||
it('skips the handshake for a simple portal', async () => {
|
||||
await fetchStalkerPlaybackLink(deps(), {
|
||||
playlist: PLAYLIST,
|
||||
|
||||
@@ -59,13 +59,26 @@ export async function ensureStalkerSession(
|
||||
playlist: PlaylistMeta | undefined,
|
||||
logger?: { warn(...args: unknown[]): void }
|
||||
): Promise<void> {
|
||||
if (!playlist || !isFullStalkerPortalPlaylist(playlist)) {
|
||||
if (!playlist) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The repair override is applied here for the same reason
|
||||
// `executeStalkerRequest` applies it on its first line: a completed repair
|
||||
// may have moved the endpoint or the mode while the caller still holds the
|
||||
// pre-repair row, and handshaking against the configuration a repair has
|
||||
// already proven broken would strand the session.
|
||||
const effective = deps.portalRepair
|
||||
? deps.portalRepair.applyOverride(playlist)
|
||||
: playlist;
|
||||
|
||||
if (!isFullStalkerPortalPlaylist(effective)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await deps.stalkerSession.ensureToken(
|
||||
toStalkerSessionPlaylist(playlist)
|
||||
toStalkerSessionPlaylist(effective)
|
||||
);
|
||||
} catch (error) {
|
||||
logger?.warn('Could not establish the Stalker session', error);
|
||||
|
||||
Reference in new issue
Block a user