Module: Browserctl::Detectors::AuthRequired

Defined in:
lib/browserctl/detectors/auth_required.rb

Overview

Detects “you need to log in again” — the signal that flips a workflow’s ‘load_state` into `state rotate` territory. Lives alongside the older `Detectors.cloudflare?` and follows the same `(page) -> Result` shape.

Three independent checks, evaluated in order. The first to fire wins:

1. URL → login path. The page is currently sitting on /login,
   /signin, /auth/login, or a similar canonical login route. This
   catches redirect-based auth ("we noticed you're not logged in").
2. Recent HTTP 401 / 403. The most recent network response on this
   page was an auth challenge from the backend.
3. Cookie ledger. A caller-supplied list of cookies contains entries
   that have already expired. Useful when the daemon is preflighting
   a bundle before navigating.

Each check is pure — no daemon dependencies — so the same detector runs server-side (handlers/observation.rb) and client-side (workflow ‘load_state` hook).

Defined Under Namespace

Classes: Result

Constant Summary collapse

LOGIN_PATH_RE =
%r{(?:^|/)(login|signin|sign[-_]in|auth/(?:login|signin)|account/login)(?:/|$|\?)}i
AUTH_HTTP_STATUSES =
[401, 403].freeze

Class Method Summary collapse

Class Method Details

.detect(page, recent_responses: [], cookies: nil, suggested_flow: nil) ⇒ Result

Run every check; return the first triggered Result, or a non- triggered Result if all pass.

Parameters:

  • page (#current_url)

    anything quacking like a Page

  • recent_responses (Array<Hash>) (defaults to: [])

    each ‘{ status:, url: }`; the caller is responsible for collecting these (e.g. via Ferrum’s network.traffic). Empty by default so callers without traffic instrumentation still get the URL/cookie checks.

  • cookies (Array<Hash>, nil) (defaults to: nil)

    each ‘{ name:, expires: }`; `expires` is a unix timestamp. nil to skip the cookie check.

  • suggested_flow (String, nil) (defaults to: nil)

    flow name to surface when the detector fires — populated by callers from the bundle manifest.

Returns:



48
49
50
51
52
53
54
# File 'lib/browserctl/detectors/auth_required.rb', line 48

def detect(page, recent_responses: [], cookies: nil, suggested_flow: nil)
  [
    check_url(page, suggested_flow),
    check_responses(recent_responses, suggested_flow),
    check_cookies(cookies, suggested_flow)
  ].find(&:triggered) || negative
end

.triggered?(page) ⇒ Boolean

Convenience predicate matching the existing ‘Detectors.cloudflare?` style. Callers that just need a boolean can use this.

Returns:

  • (Boolean)


58
59
60
# File 'lib/browserctl/detectors/auth_required.rb', line 58

def triggered?(page, **)
  detect(page, **).triggered
end