mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
fix(stalker): anchor auth-failure body detection and share it across transports
The middleware's auth failures are bare plain-text bodies, but they were matched by substring under a 200-character cap. A short page from something in FRONT of the portal — a proxy or WAF answering `<html><body>Access denied</body></html>` (38 characters) — therefore read as the portal refusing authorization, which drives probe classification and the lazy repair trigger: a portal that never answered at all could be re-probed and reclassified. The body match is now anchored to the whole reply, with the stock server's optional trailing counter still accepted. The structured `js.error`/`js.msg` fields keep the wider phrase set, since a panel fills those in deliberately. The detection also moves to `@iptvnator/shared/interfaces`. It had to live somewhere both transports can reach: the Electron main process is where these bodies actually arrive and cannot import a renderer library, which is the same reason the identity and URL builders were centralised there. `stalker-portal-discovery.utils.ts` re-exports it, so no call site changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b92503feae
commit
6cb195197d
6 files changed
+314
-102
No files matched your search
@@ -71,7 +71,17 @@ Two portal modes exist, persisted per playlist as
|
||||
except `handshake`, `get_profile`, `get_localization`, and `do_auth`
|
||||
requires `Authorization: Bearer <token>`; auth failures are HTTP 200 with a
|
||||
plain-text body (`Authorization failed.`, `Access denied.`,
|
||||
`Unauthorized request.`), never a 401/403. While a full portal is the
|
||||
`Unauthorized request.`), never a 401/403. Detection of those bodies — and
|
||||
of the JSON envelope (`{js: {error|msg}}`) some panels answer instead —
|
||||
lives in `libs/shared/interfaces/src/lib/stalker-auth-failure.util.ts`, so
|
||||
the Electron main process (where the bodies actually arrive) and the
|
||||
renderer classify identically; `stalker-portal-discovery.utils.ts`
|
||||
re-exports it. The body match is anchored to the whole reply: these are
|
||||
bare phrases, and a substring rule also accepted a short proxy or WAF page
|
||||
containing one, which then triggered portal reclassification against a
|
||||
portal that never answered. The structured `js.error`/`js.msg` fields keep
|
||||
the wider phrase set (`Invalid token`, `Auth failed`, bare `unauthorized`),
|
||||
since a panel fills those in deliberately. While a full portal is the
|
||||
active playlist, `StalkerSessionService` keeps a **watchdog** running —
|
||||
periodic authenticated `watchdog/get_events` pings (currently every 25 s;
|
||||
the protocol default expects 120 s, tracked for a later PR) whose failures
|
||||
|
||||
Reference in new issue
Block a user