- add scripts/compass-fetch-patchright.mjs: headless patchright logs in with the parent account (no 2FA) and stores the per-child pages with a sha256 manifest - add scripts/package.json + lockfile for the patchright dependency - docs: the harness clears the Cloudflare GET but not the login POST; patchright passes it; record the real per-child URLs and the overdue counts Co-Authored-By: Paperclip <noreply@paperclip.ing>
3.2 KiB
Phase 2 — Compass login + fetch notes
Status: resolved. The login and a real per-child fetch work headless and unattended via patchright. See AUD-104.
What works
- Fetcher:
scripts/compass-fetch-patchright.mjs(patchright 1.64.0, headless). - Browser: the system Chrome
/etc/profiles/per-user/sam/bin/google-chrome(Chrome 150.0.7871.186), launched by patchright with the automation leaks patched. - Credentials:
COMPASS_USERNAME/COMPASS_PASSWORDfrom~/.config/environment.d/10-secrets.conf(parent/guardian account). - Login outcome:
POST /login?handler=Login→302, landing onHome | Compass. No 2FA was required on this login.
cd scripts && npm install # patchright, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
COMPASS_USERNAME=... COMPASS_PASSWORD=... \
node scripts/compass-fetch-patchright.mjs --child Harry --user-id 27038
Real data seen (2026-10-15)
- Harrison (Harry) ROLFE,
userId=27038— 6 overdue learning tasks, 1 due next week. - Finn ROLFE,
userId=31460— 2 overdue learning tasks. - Parent landing page:
https://nhs-vic.compass.education/.
Per-child pages:
https://nhs-vic.compass.education/—Home | Compass/Records/User.aspx?userId=27038(redirects toRecords/UserNew.aspx?userId=27038) —User: Harrison ROLFE | Compass/Organise/Calendar/—Compass Calendar
Stored under var/raw/<child>/<runId>/ (git-ignored) with <slug>.html,
<slug>.meta.json, and manifest.json (URL, title, fetched-at, bytes, sha256).
Example run var/raw/harry/2026-10-15T05-44-47-323Z/: home 301 968 B, child
profile 448 165 B, calendar 236 234 B.
Why not the pi-browser-harness
The harness (headless Chrome, chrome-pi.service, CDP 9222) clears the
Cloudflare GET challenge but not the login POST: Cloudflare answers
POST /login?handler=Login with a 403 managed challenge that headless Chrome
does not solve. Tested and did not fix: desktop-UA override, isolated browser
contexts, Sec-CH-UA metadata, focus/visibility emulation, client hints, long
waits, cooldowns. patchright passes it because it patches the CDP/automation
leaks Cloudflare detects. The harness fetcher (scripts/compass-fetch.mjs) is
kept for the unauthenticated login-page probe only.
Non-browser path (checked, then dropped)
- Compass mobile app exists (
com.jdlf.compass/ App Store778415974). - No public JSON API:
/api/*,/mobile/*,/oauth/token,/saml/metadata,/.well-known/openid-configuration,robots.txtall 404 at the origin. /oauth/?OAuthType=...exists but every guessed type returnsInvalid OAuthType; the valid type is unknown.- SAML button exists (
/login?handler=SamlSignin, POST); no GET metadata endpoint.
Notes for Phase 3
- The parent landing page is legacy server-rendered ASP.NET and already contains
the per-child overdue counts (e.g. "6 overdue learning tasks") and the
userIdlinks — good first parse target. /Records/UserNew.aspxis a React/MUI app; the Learning Tasks tab body is rendered client-side, so task detail will need the app's JSON calls (or the legacyRecords/User.aspxview) rather than the stored HTML.- Keep
var/out of git; the page HTML contains the family's personal data.