Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
ecb2d0a
feat(oauth): add test-only mock-IdP base URL overrides for e2e-playgr…
lakhansamani Jul 20, 2026
8dce1fc
feat(oauth): route userinfo/issuer lookups through mock-IdP override …
lakhansamani Jul 20, 2026
ffbfa5f
feat(sms): add pluggable test webhook SMS provider for e2e-playground
lakhansamani Jul 20, 2026
c1e38fc
fix(config): treat TestSMSWebhookURL as sufficient for IsSMSServiceEn…
lakhansamani Jul 20, 2026
2084e0f
chore(e2e-playground): scaffold Playwright project and make target
lakhansamani Jul 20, 2026
9a209c5
chore(e2e-playground): add mock-oauth, mock-saml-idp, sms-sink servers
lakhansamani Jul 20, 2026
f3bbd06
fix(e2e-playground): guard mock-saml-idp /sso against crashes, copy t…
lakhansamani Jul 21, 2026
1265a0a
chore(e2e-playground): add docker-compose stack and GraphQL admin see…
lakhansamani Jul 21, 2026
d258aeb
test(e2e-playground): add OIDC provider-side conformance spec
lakhansamani Jul 21, 2026
ddd2658
test(e2e-playground): add real PKCE authorization-code flow + replay …
lakhansamani Jul 21, 2026
93659b1
test(e2e-playground): add OIDC SSO relying-party (home-realm discover…
lakhansamani Jul 21, 2026
c96682b
wip(e2e-playground): SSRF test bypass + sso-discovery compose profile…
lakhansamani Jul 22, 2026
27338f8
chore(e2e-playground): containerize the Playwright runner (Task 6b)
lakhansamani Jul 22, 2026
588e758
fix(e2e-playground): mock-oauth issues id_token + nonce for any realm…
lakhansamani Jul 22, 2026
ddbc36b
fix(e2e-playground): un-skip and correct the SSO JIT-provisioning ass…
lakhansamani Jul 22, 2026
be43ce0
test(e2e-playground): add SAML SP-side conformance spec
lakhansamani Jul 22, 2026
dc5a2a3
fix(e2e-playground): make saml-sp.spec.ts's fixed-entity-id test idem…
lakhansamani Jul 22, 2026
67bc94b
wip(e2e-playground): SAML IdP-side conformance spec (Task 10, unverif…
lakhansamani Jul 23, 2026
89dcfde
fix(saml): resume SP-initiated IdP login after login, unblock ACS aut…
lakhansamani Jul 23, 2026
a1e626b
test(e2e-playground): add SCIM provisioning and cross-org isolation spec
lakhansamani Jul 23, 2026
cd10855
test(e2e-playground): add SSO home-realm discovery API spec
lakhansamani Jul 23, 2026
b689976
fix(webapp): clear mfa redirect params once mfa gate resolves
lakhansamani Jul 23, 2026
8e05233
test(e2e-playground): add shared social-login helper and Google spec
lakhansamani Jul 23, 2026
7cab0d5
refactor(e2e-playground): extract consent-denied negative-path into s…
lakhansamani Jul 23, 2026
f8a5642
test(e2e-playground): add GitHub social-login spec
lakhansamani Jul 23, 2026
f35a497
test(e2e-playground): add Facebook social-login spec
lakhansamani Jul 23, 2026
f3c2960
test(e2e-playground): add LinkedIn social-login spec
lakhansamani Jul 23, 2026
1c4dff0
test(e2e-playground): add Apple social-login spec
lakhansamani Jul 23, 2026
7bab5ee
fix(oauth): don't 400 Apple callback when returning user omits `user`…
lakhansamani Jul 23, 2026
5326c84
test(e2e-playground): cover returning Apple user login with no `user`…
lakhansamani Jul 23, 2026
283b99f
test(e2e-playground): add Twitter/X social-login spec
lakhansamani Jul 23, 2026
17e9945
fix(oauth): give Twitter/X users a stable synthetic email
lakhansamani Jul 23, 2026
ba1b9fb
test(e2e-playground): cover Twitter repeat-login identity stability
lakhansamani Jul 23, 2026
d5deabb
docs(oauth): correct misleading GitHub-noreply comparison in Twitter …
lakhansamani Jul 23, 2026
242eab3
fix(oauth): prefer X's real confirmed_email over the synthetic fallback
lakhansamani Jul 23, 2026
27db6b4
test(e2e-playground): cover Twitter confirmed_email over synthetic fa…
lakhansamani Jul 23, 2026
0fdedce
docs(oauth): stop overclaiming in-repo precedent for X's sparse-field…
lakhansamani Jul 23, 2026
d0e4be5
fix(oauth): extract real email from Discord users/@me, not oauth2/@me
lakhansamani Jul 23, 2026
fc5e3bd
test(e2e-playground): add Discord social-login spec
lakhansamani Jul 23, 2026
276405a
test(e2e-playground): add Microsoft social-login spec
lakhansamani Jul 23, 2026
d60a247
test(e2e-playground): add Twitch social-login spec
lakhansamani Jul 23, 2026
b62a553
fix(oauth): synthesize roblox email from sub instead of storing raw id
lakhansamani Jul 23, 2026
10a8706
test(e2e-playground): add Roblox social-login spec
lakhansamani Jul 23, 2026
60ff31c
test(oauth): cover empty-string sub in Roblox email fallback
lakhansamani Jul 23, 2026
3780a46
test(e2e-playground): add WebAuthn/passkey registration and login spec
lakhansamani Jul 23, 2026
51251f0
fix(meta): expose is_discord_login_enabled from the Meta resolver
lakhansamani Jul 23, 2026
0ef86c2
test(e2e-playground): add TOTP enrollment and login-challenge spec
lakhansamani Jul 23, 2026
be84685
test(e2e-playground): add SMS-OTP enrollment and login-challenge spec
lakhansamani Jul 23, 2026
f0a1d79
test(e2e-playground): add WebOTP auto-fill spec
lakhansamani Jul 23, 2026
71a338e
docs(e2e-playground): correct overclaim about authorizer-js's credent…
lakhansamani Jul 23, 2026
17a8fc9
test(e2e-playground): add magic-link login spec using Mailpit
lakhansamani Jul 23, 2026
47a1c12
fix(magic-link): require IsEmailServiceEnabled, not just EnableEmailV…
lakhansamani Jul 23, 2026
9dde089
test(e2e-playground): add MFA routing-matrix spec for EnforceMFA=true
lakhansamani Jul 23, 2026
b9b24e9
fix(e2e-playground): set --admin-cookie-secure=false on every service
lakhansamani Jul 23, 2026
fabc6b3
fix(dashboard): send double-nested pagination in OrgDomains' list query
lakhansamani Jul 23, 2026
4265af3
test(e2e-playground): add dashboard verified-domains UI spec
lakhansamani Jul 23, 2026
0ddf79f
test(e2e-playground): extend SCIM spec with filter operators and full…
lakhansamani Jul 23, 2026
af78d22
fix(webhooks): allow-list the SCIM/group webhook event names
lakhansamani Jul 23, 2026
87e1c2e
fix(graphql)!: standardize pagination on a single-level shape
lakhansamani Jul 23, 2026
b61644d
fix(dashboard): match the standardized single-level pagination shape
lakhansamani Jul 23, 2026
a86a2a5
test(e2e-playground): add TOTP and email/SMS OTP brute-force lockout …
lakhansamani Jul 23, 2026
e83ff3f
chore(web/app): bump authorizer-react to 2.2.0-rc.3
lakhansamani Jul 23, 2026
ffcfe4c
Merge remote-tracking branch 'origin/main' into worktree-playground-e2e
lakhansamani Jul 24, 2026
5610dc8
fix(makefile): always tear down e2e-playground stack, even if startup…
lakhansamani Jul 24, 2026
8509db0
test(security): add no-op regression coverage flagged in Part A review
lakhansamani Jul 24, 2026
14123a8
fix(web-otp): wire hasSmsOtp, dedup SAML resumption effect, un-skip r…
lakhansamani Jul 24, 2026
359054a
feat(webhooks): gate private-host SSRF checks behind test flag
lakhansamani Jul 24, 2026
d79b992
test(e2e): exercise SCIM provisioning webhook delivery
lakhansamani Jul 24, 2026
50ff19f
fix(e2e): fix stale double-nested pagination, raise test rate limits,…
lakhansamani Jul 24, 2026
b635fed
Merge remote-tracking branch 'origin/main' into worktree-playground-e2e
lakhansamani Jul 24, 2026
459a62d
test(e2e): add SDK-driven Go suite for the enterprise/MFA surface
lakhansamani Jul 24, 2026
fd3f4a3
test(e2e): add Python SDK-driven suite for the enterprise/MFA surface
lakhansamani Jul 24, 2026
0ae1c73
Merge branch 'worktree-agent-a1804fbb36a8c6e43' into worktree-playgro…
lakhansamani Jul 24, 2026
3d079b0
refactor(e2e): fold e2e-playground test flags into --env=e2e
lakhansamani Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ test.db
.yalc
yalc.lock
certs/
# Test-only e2e-playground fixtures are intentionally checked in (docs/superpowers/plans/2026-07-20-playground-e2e.md Global Constraints).
!e2e-playground/fixtures/certs/
!e2e-playground/mocks/mock-saml-idp/certs/
*-shm
*-wal
.idea
Expand Down
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,25 @@ perf-k6-validate:
.PHONY: perf-k6-check
perf-k6-check:
k6 run perf/k6/fga_check.js

.PHONY: e2e-playground
e2e-playground: ## Run the live-playground e2e suite (OIDC/SAML/SCIM/SSO/OAuth/MFA) against an ephemeral docker-compose stack
docker compose -f e2e-playground/docker-compose.yml up -d --wait authorizer authorizer-sso mock-oauth mock-saml-idp mailpit sms-sink; \
status=$$?; \
if [ $$status -eq 0 ]; then \
docker compose -f e2e-playground/docker-compose.yml run --rm playwright npx playwright test; \
status=$$?; \
fi; \
docker compose -f e2e-playground/docker-compose.yml down -v; \
exit $$status

.PHONY: e2e-playground-sdk
e2e-playground-sdk: ## Run the SDK-driven Go suite (drives authorizer-go over the enterprise/MFA surface) against an ephemeral docker-compose stack
docker compose -f e2e-playground/docker-compose.yml up -d --wait --build authorizer authorizer-webauthn authorizer-mfa-enforced authorizer-mfa-magic-link mock-oauth mock-saml-idp mailpit sms-sink webhook-sink; \
status=$$?; \
if [ $$status -eq 0 ]; then \
docker compose -f e2e-playground/docker-compose.yml run --rm --build go-sdk-tests; \
status=$$?; \
fi; \
docker compose -f e2e-playground/docker-compose.yml down -v; \
exit $$status
3 changes: 3 additions & 0 deletions e2e-playground/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
playwright-report
test-results
3 changes: 3 additions & 0 deletions e2e-playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
playwright-report/
test-results/
7 changes: 7 additions & 0 deletions e2e-playground/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# e2e-playground/Dockerfile
FROM mcr.microsoft.com/playwright:v1.61.1-jammy
WORKDIR /e2e
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["npx", "playwright", "test"]
84 changes: 84 additions & 0 deletions e2e-playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Live-Playground E2E Suite

A real, live-server end-to-end test suite for Authorizer. Every spec drives a real `authorizer` binary (built from this repo's source) plus a real browser (Playwright) — no unit-level mocking of Authorizer itself. Third-party services (Google/GitHub/Discord/etc. OAuth, SMS delivery, an external SAML IdP) are stood in for by small local mock servers under `mocks/`, wired in via `authorizer`'s own test-only mechanism (`--env=e2e`) — every behavior it enables is a documented no-op unless that exact env value is set, so none of this affects production behavior.

## Coverage

- OIDC provider (signup/login/PKCE/token issuance) and OIDC SSO relying-party (home-realm discovery)
- SAML SP and SAML IdP
- SCIM (CRUD, filter operators, webhooks — including real webhook delivery with HMAC verification)
- 10 social OAuth providers (Google, GitHub, Facebook, LinkedIn, Apple, Discord, Twitter, Microsoft, Twitch, Roblox)
- WebAuthn/passkeys (via Playwright's CDP-backed virtual authenticator)
- TOTP, SMS-OTP, WebOTP auto-fill, magic-link
- MFA enforcement routing matrix
- OTP brute-force lockout
- Dashboard verified-domains UI

## Prerequisites

- Docker + Docker Compose (everything else — Node, Playwright browsers, the `authorizer` binary — is built into containers; nothing needs to be installed on the host).

## Run the full suite

From the repository root:

```bash
make e2e-playground
```

This builds and starts the full docker-compose stack (six `authorizer` instances configured for different scenarios, the mock OAuth/SAML/SMS/webhook servers, Mailpit for email), runs the entire Playwright suite in a containerized runner, and **always** tears the stack down afterward (`docker compose down -v`) — including on failure or if the stack fails to start.

Equivalent to, run manually:

```bash
docker compose -f e2e-playground/docker-compose.yml up -d --wait authorizer authorizer-sso mock-oauth mock-saml-idp mailpit sms-sink
docker compose -f e2e-playground/docker-compose.yml run --rm playwright npx playwright test
docker compose -f e2e-playground/docker-compose.yml down -v
```

(The `playwright` service's own `depends_on` brings up the remaining instances — `authorizer-webauthn`, `authorizer-magic-link`, `authorizer-mfa-enforced`, `authorizer-mfa-magic-link`, `webhook-sink` — automatically; they don't need to be named in the `up` step.)

## Run a subset

Any Playwright CLI filter works. From `e2e-playground/`, after starting the stack:

```bash
# One spec file
docker compose run --rm --build playwright npx playwright test totp.spec.ts

# By name pattern
docker compose run --rm --build playwright npx playwright test -g "SCIM"

# A whole directory
docker compose run --rm --build playwright npx playwright test social/
```

**`--build` is required whenever a spec file (or anything else under `e2e-playground/`) has changed** — the `playwright` service's Dockerfile bakes test files into the image at build time rather than mounting them live; without `--build` you'll run stale tests, or Playwright will report "No tests found" if a new file was added since the image was last built.

Don't forget to tear down afterward: `docker compose -f e2e-playground/docker-compose.yml down -v`.

## Verify results after a run

Playwright's HTML report is written to `e2e-playground/playwright-report/` on the host (mounted, survives container teardown). To view it:

```bash
npx playwright show-report e2e-playground/playwright-report
```

or open `e2e-playground/playwright-report/index.html` directly in a browser. It shows every test's pass/fail status, timing, and — for failures — a full trace (screenshots, network log, action-by-action replay).

Raw output (traces, videos on retry, etc.) is under `e2e-playground/test-results/`, also host-mounted.

A clean run's terminal output ends with a summary line, e.g.:

```
XX passed (NNs)
```

Any skip is intentional and self-documenting — read the `test.skip(...)` call's message in the relevant spec file for the reason. As of this writing there are no skips tied to real product gaps.

## Notes

- Every spec seeds its own state (org, users, connections) — specs are independently runnable and safe to run in parallel or in any order.
- `authorizer-sso` runs a second, separately-configured instance (port 8081) specifically because `--enable-org-discovery=true` is a global login-UX toggle that would otherwise change behavior for every other spec sharing the default instance.
- Test-only secrets (SAML certs, JWT signing keys) live under `fixtures/certs/`, are checked in, and sign nothing real — the same pattern `make dev`'s embedded dev RSA keys already use.
Loading
Loading