ClubSpark Classic Auth — Stage/Test pre-rollout baseline
Captured: 2026-07-09 · Harness: pw-harness (Playwright) · Scope: sign-up / sign-out / sign-in across the classic (legacy WS-Federation) identity platform on the stage & test tiers.
This is a pre-rollout baseline: re-run the identical commands after the deployment and diff the results. Any change from this baseline is a regression (was ✅, now ❌) or an improvement (was ❌/⛔, now ✅). Failures that are pre-existing environment/config conditions (not harness bugs) are called out per-domain so they aren’t mistaken for regressions.
Every recording has its own inline player (plus a direct link). Videos are stored in Git-LFS and bundled into the published site by the Pages workflow, so they play inline at reports.clubspark.dev (this lets the Pages site stay public even while the repo is internal). When browsing the repo on GitHub — where raw <video> tags may not render — use the per-recording direct links.
Result summary
Legend: ✅ pass · ❌ fail · ⛔ blocked (external/pre-existing) · ➖ n/a
| # | Domain | Tenant | Auth path | Sign up | Sign out | Sign in | Overall |
|---|---|---|---|---|---|---|---|
| 1 | stg-solo-web.clubspark.io/ |
Independent | Legacy WS-Fed, local form | ✅ | ✅ | ✅ | 7/7 PASS |
| 2 | stg-solo-web.clubspark.io/RITUVENUES/ |
Independent (venue) | Legacy WS-Fed, local form | ✅ | ✅ | ✅ | 9/9 PASS |
| 3 | stg-solo-custom.clubspark.ninja/ |
Independent (custom domain) | Legacy WS-Fed, local form | ✅ | ✅ | ✅ | 7/7 PASS |
| 4 | tst-fa-web.clubspark.io/ |
The FA | Legacy WS-Fed → Azure B2C | ✅ | ✅ | ✅ | 5/5 PASS |
| 5 | stg-ecb2-web.clubspark.io/ |
ECB | Legacy WS-Fed → ECB Okta | ✅ | ✅ | ✅ | 4/4 PASS |
| 6 | stage-lta.clubspark.io/ |
LTA | Legacy WS-Fed, local signin; external signup | ⛔ | ➖ | ⚠️ | see §6 |
| 7 | stg-fa-web.clubspark.io/ |
The FA | Legacy WS-Fed → Azure B2C | ❌ | ✅ | ❌ | 3/5 — wrong RP, see §7 |
5 of 7 fully green. The two not-green are gated by conditions outside the harness: §6 LTA signup is external on lta.org.uk behind reCAPTCHA; §7 stg-fa-web signup federates to the wrong (tst) relying party — validate FA on tst-fa-web (§4) instead.
How to reproduce
cd pw-harness && npm install # downloads Chromium on first run
.env carries CS_BASE, CS_LEGACY_AUTH_HOST, CS_EMAIL_DOMAIN=clubspark.dev (whitelisted so B2C/ECB OTP + activation emails reach Mailpit), and MAILPIT_*. Each domain’s exact command is in its section. Suites print a PASS/FAIL line per assertion and exit non-zero on any failure.
§1–3 · Solo / Independent — ✅ fully passing (self-serve, ClubSpark-native)
All three share the same shape: /Account/SignIn → stg-solo-auth.clubspark.io/issue/wsfed → a local EmailAddress/Password form with a self-serve Register link. Fully self-provisioning.
CS_BASE=https://stg-solo-web.clubspark.io/ CS_LEGACY_AUTH_HOST=stg-solo-auth.clubspark.io node test-legacy-auth.mjs 1 # §1 → 7/7
CS_BASE=https://stg-solo-web.clubspark.io/RITUVENUES/ CS_LEGACY_AUTH_HOST=stg-solo-auth.clubspark.io node test-legacy-auth.mjs 1 # §2 → 9/9 (+venue return-URL)
CS_BASE=https://stg-solo-custom.clubspark.ninja/ CS_LEGACY_AUTH_HOST=stg-solo-auth.clubspark.io node test-legacy-auth.mjs 1 # §3 → 7/7
Every assertion passes: signup → logged in · signout clears the WS-Fed session · signin via the stg-solo-auth form · venue return-URL (RITUVENUES) · no :8443 leak.
Recordings:
§1 · stg-solo-web (legacy) — direct link
§2 · stg-solo-web /RITUVENUES (venue) — direct link
§3 · stg-solo-custom.clubspark.ninja (custom domain) — direct link
§4 · tst-fa-web (The FA) — ✅ signup + signin working (resolved 2026-07-09)
/Account/SignIn → stg-solo-auth → HRD idp=duende → stg-solo-ids-sts → Azure B2C (b2cqathefa.b2clogin.com, b2c_1a_signup_signinmfa). Signup + signin happen on B2C; email OTP (verification + MFA) is read from Mailpit.
node fa-suite.mjs https://tst-fa-web.clubspark.io/ 1 # or `2` for a stability pass
5/5 PASS (verified stable 10/10 over 2 rounds). Flow: CREATE AN ACCOUNT → B2C signup policy b2c_1a_fasignupcustomotppff_struiverdyn → email + OTP → profile → password → create → 302 tst-solo-ids-sts/idp/fab2c/oidc-callback. Then a fresh sign-in (email + password + email-MFA OTP) federates back to tst-fa-web and lands logged-in on /Account/YourDetails.
Two enablers (both now in place): (a) email whitelist — clubspark.dev whitelisted so B2C OTP reaches Mailpit; (b) harness fix — faSignUp now waits for the URL to actually leave b2clogin.com (waitForURL(!b2clogin, 45s)) instead of checking !onB2C mid-federation (the old false negative).
FA signup intentionally returns to
tst-solo-auth(a different RP) and does not establish a web session — the account is created, and sign-in is what logs you intotst-fa-web.
Recordings:
§4 · FA signup — B2C create + OTP — direct link
§4 · FA signin + signout — B2C + MFA → logged in — direct link
§5 · stg-ecb2-web (ECB) — ✅ signup + signin working (resolved 2026-07-09)
/Account/SignIn → stg-solo-auth → HRD idp=ecb → stg-solo-ids-sts → ECB Okta (login-test.ecb.co.uk) → ECB “myaccount” SPA (myaccount-test.ecbnationalprogrammes.com). Sign-up + sign-in happen on ECB’s system (React/MUI, no CAPTCHA). Homepage always redirects to /AllStars/Search.
CS_BASE=https://stg-ecb2-web.clubspark.io/ node test-ecb-auth.mjs 1
4/4 PASS (verified stable 12/12 over 3 rounds): signup (2-step Okta wizard → create_user 200 → “ACTIVATE ACCOUNT” email link) · signin → logged in · signout · no :8443 leak.
The signin fix: after auth, ECB shows a “Confirm Your Preferences” modal whose NEXT button stays inert until each consent checkbox has an explicit choice — ecbSignIn now ticks the checkboxes (real clicks so React registers) before NEXT, which lets the federation resume (stg-solo-ids-sts/idp/ECB-OKTA/signin-oidc → stg-solo-auth → logged-in). ECB signin needs no OTP. Signing into a stale/half-provisioned account can throw ClubSpark’s generic “An error has occurred” at stg-solo-auth/issue/hrd/oauth2callback; a freshly signed-up+activated account (as the self-contained suite creates) signs in cleanly — surfaced via a clubsparkError flag.
Recordings:
§5 · ECB signup — Okta wizard + activation — direct link
§5 · ECB signin + signout — preferences modal → logged in — direct link
§6 · stage-lta (LTA) — ⛔ signup external (reCAPTCHA); signin needs a seed account
/Account/SignIn → stage-lta-auth.clubspark.io → local EmailAddress/Password form (“Login”). But registration is delegated to https://www.lta.org.uk/register and that form is protected by Google reCAPTCHA.
CS_BASE=https://stage-lta.clubspark.io/ CS_LEGACY_AUTH_HOST=stage-lta-auth.clubspark.io node test-lta-auth.mjs 1
# with a seed account: LTA_EMAIL=… LTA_PASSWORD=… …same…
- Sign up ⛔ (by design):
ltaRegisterreaches the lta.org.uk form and fills every field, then stops at theg-recaptcha-responsewall — automated self-signup is not possible (intentional anti-bot control, not a defect). - Sign in ⚠️: the LTA credential form is reachable on
stage-lta-auth(confirmed), but with no seed credentials a login can’t be completed. SupplyLTA_EMAIL/LTA_PASSWORDto exercise it. - Sign out ➖: not reachable without a completed login.
Recordings:
§6 · LTA register → reCAPTCHA wall — direct link
§6 · LTA signin form (reachability) — direct link
§7 · stg-fa-web (The FA) — ❌ signup federates to the wrong (tst) RP
Same B2C topology as §4, but here the B2C “CREATE AN ACCOUNT” journey federates back to tst-solo-ids-sts — a cross-env mismatch — so the signup round-trip can’t complete against STG.
node fa-suite.mjs https://stg-fa-web.clubspark.io/ 1
3/5 (signout ✅, no-leak ✅; signup ❌, signin ❌). Not a harness issue and not fixed by the deploy unless the B2C RP is repointed off tst. Validate FA on tst-fa-web (§4) until then; if §7 turns green after deploy, the RP was repointed.
Recordings:
§7 · stg-fa-web signup → tst RP mismatch — direct link
§7 · stg-fa-web signin (fails — no account created) — direct link
Harness changes behind this baseline
The harness was authored on Windows for the dev environment; these were needed for stage/macOS (in the working tree; nothing deployed to any environment):
- Cross-platform
.envloading (critical):.envnever loaded on macOS (a Windows-only.pathname.replace(/^\//,'')produced a relative path → silent fallback todev-hosts). Fixed withfileURLToPath. Without it a “stage” run silently hit dev. - Env-driven hosts: removed hardcoded
dev-solo-web/dev-solo-auth; addedCS_LEGACY_AUTH_HOST+CS_EMAIL_DOMAIN;WEB_HOST/LEGACY_AUTH_HOSTderive fromCS_BASE. - FA (
fa-flows.mjs):gotoFAhandles FA-branded tenants that auto-federate straight to B2C;faSignUpwaits to leaveb2clogin.combefore judging (the §4 fix). - New modules:
ecb-flows.mjs+test-ecb-auth.mjs(ECB Okta signup with keystroke input,selectOption, “ACTIVATE ACCOUNT” email, and the “Confirm Your Preferences” checkbox handling);lta-flows.mjs+test-lta-auth.mjs(LTA local signin + register-to-reCAPTCHA).
Post-deploy checklist
Re-run each command above and compare to this baseline:
- §1–3 solo/venue/custom — must stay 7/7, 9/9, 7/7. Any FAIL = regression.
- §4 tst-fa-web — must stay 5/5 (depends on the
clubspark.devemail whitelist + thefaSignUpwait fix). - §5 stg-ecb2-web — must stay 4/4 (depends on the “Confirm Your Preferences” checkbox handling). Watch the
clubsparkErrorflag on fresh accounts. - §7 stg-fa-web — expected ❌ until its B2C RP is repointed off tst; turning ✅ = that fix landed.
- §6 stage-lta — signup stays ⛔ (reCAPTCHA); supply seed creds to baseline signin/signout.