Skip to content

Live labs: play online, accounts, leaderboard and lab points (Play Online off until launch) - #46

Open
sethsec wants to merge 14 commits into
mainfrom
online-labs
Open

sethsec wants to merge 14 commits into
mainfrom
online-labs

Conversation

@sethsec

@sethsec sethsec commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Brings browser-playable labs, hosted by Cybr, to pathfinding.cloud, backed by api.pathfinding.cloud (pathfinding-backend). Play Online stays off for everyone (PLAY_ONLINE_GLOBALLY_ENABLED = false); launch is a separate one-line PR.

What's in it

  • Play Online: live labs in game mode with Cybr's browser terminal (start, values, flag, mark complete, end). Which labs are playable comes from the backend (GET /labs/online), not labs.json.
  • Accounts: optional GitHub sign-in with no email or name collected, guest play, a username, a private profile, and shareable milestone cards.
  • Leaderboard, ranked by total lab points:
  • Online Labs in the nav. The Online filter is now a toggle; the table view is the default.
  • Terminal command reporting: each command line typed in the live terminal is sent to the backend for learner analytics (never the output). The backend redacts credentials before logging.
  • Privacy: the site has no privacy page of its own. The footer on every page and the sign-in box link to Datadog's privacy policy (https://www.datadoghq.com/legal/privacy/). The earlier draft page is deleted.
  • Preview switch: ?play_online=1 on any labs page turns Play Online on in that browser only (remembered in localStorage); ?play_online=0 turns it off. This is for testing the real site before launch. Nothing links to it.
  • Also: RUM replay masks the terminal and lab credentials, plus scene generator and game mode polish, cache-version bumps, and regenerated lab stubs and data.

Merge order

  1. Add per-lab Points for the pathfinding.cloud labs leaderboard pathfinding-labs#113 (lab points). This PR's labs.json is generated from it.
  2. ddoghq/pathfinding-backend#7 (deployed already).
  3. This PR. api.pathfinding.cloud is live.

After merging:

  1. Smoke-test https://pathfinding.cloud with ?play_online=1: sign-in, username, a live lab with terminal commands and a flag, the leaderboard and profile, a share card.
  2. Then launch by setting PLAY_ONLINE_GLOBALLY_ENABLED = true in a small follow-up PR.

Testing

  • node --check on every changed script; labs.json parses.
  • Exercised locally with make local (local backend) and make local-dev (the deployed dev API), including terminal commands arriving in Datadog.

🤖 Generated with Claude Code

… page

Replaces the mock Play Online terminal with a live lab panel backed by
pathfinding-backend: launch, readiness countdown, masked connection details,
Cybr's web terminal (vendored @cybr/labs-sdk 0.1.1 browser client), flag
submission and ending the lab. pf-account.js adds optional GitHub/Google
sign-in, username selection, progress sync, account deletion and milestone
sharing, showing only the sign-in providers the backend has enabled. New
leaderboard, profile and privacy pages. Play Online stays off in production
until the backend is live; it is enabled automatically on localhost.
…ask RUM replay

Every page now loads pf-account.js and account.css, links to the
leaderboard in the header and mobile menu, and links to the privacy page in
the footer. Datadog RUM switches to mask-user-input so session replay never
records typed input (the live lab panel also hides credentials and terminal
output entirely), and propagates trace headers to api.pathfinding.cloud so
browser sessions link to backend traces. Lab stub pages are regenerated from
the updated labs index template.
Sets supportsOnlineMode for the labs Cybr hosts, matching
DataDog/pathfinding-labs#108. The deploy workflow regenerates these files
from pathfinding-labs main, so that PR must merge before this branch deploys.
…nd highlight online play

Header: a Labs Leaderboard link and a purple account pill now sit at the far
right of every page, after the Datadog, theme and GitHub links, and show even
when the backend is unreachable. The dropdown is reduced to My profile and
Sign out; Change username and Delete account move to the profile page.

Profiles are private: /profile/ shows only the signed-in user's own profile
from /me, with the full milestone ladder (earned milestones shareable through
owner-issued links, locked ones with progress) and an Account section.
Leaderboard usernames no longer link to profiles. The leaderboard, profile
and privacy pages drop the labs search bar, and optional sections no longer
render as "null".

Online play: the home page Labs card, the catalog's getting-started banner
and the getting-started guide explain playing online for free versus
self-hosting, and the 47 online labs carry a "Play online" badge in the
catalog. The guide no longer scrolls sideways on phones. Lab stub pages are
regenerated.
…disable, panel navigation fix

Live lab terminal panel:
- Replace stacked controls/details rows with a single compact header row
- Idle banner with inline `start` and `values` commands; typing either in the
  terminal is intercepted before reaching the PTY (`\x03` sent after `values`
  to cancel the buffered input so it never executes on the next Enter)
- Braille spinner during provisioning; hold output until a real shell prompt
  is visible (non-whitespace, non-ANSI content), with a 10s fallback reveal
- Dark xterm scrollbar; reduced terminal-open min-height

Online-first game mode defaults:
- Default to Game Mode for online labs on desktop; persist mode choice to
  localStorage so switching to Single Page mode sticks across reloads
- Add `isOnlineLabBySchema` helper for init-time state defaults before
  `pfAccount` loads, fixing the lab defaulting to the self-hosted deploy panel

Helicopter disable for online labs:
- Gate movement (arrow keys, gamepad), draw, HUD hover detection, and
  collision detection on `state.heliEnabled` (false for online labs)
- `advanceGameState` overview→navigation transition and canvas click handlers
  still work for all labs so Next/Previous and clicking map elements update
  the side panel correctly regardless of helicopter mode

Bump cybr-labs-sdk from 0.1.1 to 0.1.2 (debounced PTY resize).
Regenerate 129 per-lab HTML stubs to pick up asset version bumps.
…s no browser terminal

Typing start (or pressing Start lab) while a lab was already running sent a
launch that the backend answered with resumed: true. The panel showed a
launch spinner, its terminal connect returned early because a connection
already existed, and nothing stopped the spinner. start now recognises a
running lab and connects the terminal if needed, and a resumed launch stops
its own spinner.

A lab whose browser terminal is disabled at Cybr (currently sts-001) reached
"ready" with nothing to connect and looked hung. The panel now stops the
spinner and says the terminal isn't available for that lab; the fix for the
lab itself is enabling its terminal at Cybr.

Guest session creation is single-flight in pf-account.js, so opening the
panel can no longer mint two guest sessions at once.
Which labs can be played online now comes from pathfinding-backend's
GET /labs/online, derived from Cybr's catalog (labs with a browser terminal),
instead of a supports_online_mode flag in pathfinding-labs READMEs. The
catalog, lab detail and game loaders set each lab's supportsOnlineMode from
it, so Play Online, the Play online badges, the Online Play filter (including
shared ?online= links) and the getting-started guide's starter-lab badges all
follow Cybr. While online play is switched off, no lab is shown as online.

generate-labs-json.py no longer emits supportsOnlineMode, and the field is
removed from the committed lab data.
supportsOnlineMode and onlineEndpoint are gone from labs.json; the site gets
online availability from pathfinding-backend's GET /labs/online at runtime.
…aft privacy page

The live terminal now reports each command line to pathfinding-backend
(POST /labs/:slug/terminal-commands) for learner analytics, reading it from
xterm's buffer as the shell echoed it so Tab completion and history recall are
captured as run. Output is never sent. Batches flush every 5 seconds or 10
commands, on disconnect and page hide, and before ending a lab.

The privacy page moves from docs/privacy/ to drafts/privacy/, outside what
GitHub Pages deploys, until it is reviewed or replaced by Datadog's generic
policy. Its footer, sign-in modal and getting-started links are removed, and
drafts/README.md lists what to restore to publish it. map-game.js and
pf-account.js cache versions are bumped and the lab stubs regenerated.
Introduce per-lab points parsed from the pathfinding-labs READMEs: a sortable
Points column in the table, a badge on cards, and a leaderboard now ranked and
displayed by total points rather than lab count (with points shown on the
profile too). Add an Online Labs entry to the sidebar and menus linking to the
online-only filter, and make the online filter a pressed toggle button. Default
the catalog to the table view, replace the AWS Cost column with an Online
yes/no column, and rename the remaining cost pills to 'Est. Self Hosted AWS
Cost'. Rebrand the sign-in modal and leaderboard with the product logos and
give both a more finished look, and open online-playable labs in game mode by
default.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant