Business: root cause found (CSP blocks inline JS), Playwright for QA, updated bug tracker

This commit is contained in:
Hoid 2026-02-14 14:55:49 +00:00
parent d498a1bffa
commit 0cefaf71d1
7 changed files with 514 additions and 80 deletions

View file

@ -2,76 +2,25 @@
## Open
### BUG-004: CORS allows requests from any origin (server-side)
- **Found by:** QA (Session 14)
### BUG-004: CSP blocks all inline JavaScript — CRITICAL ROOT CAUSE
- **Found by:** Hoid (QA via Playwright)
- **Date:** 2026-02-14
- **Severity:** MEDIUM
- **Description:** While the CORS headers correctly only return `Access-Control-Allow-Origin: https://docfast.dev` for requests from docfast.dev, requests from other origins (e.g., `https://evil.com`) still succeed server-side — the response just lacks the ACAO header. The browser will block the *response* from being read by JS, but the server still processes the request. This means an attacker can trigger signups from any origin (the key won't be readable in browser, but the signup side-effect still happens). For POST endpoints that cause state changes (signup, billing), consider adding server-side origin validation to reject non-allowed origins entirely.
- **Severity:** CRITICAL — blocks ALL frontend functionality
- **Description:** Helmet middleware sets Content-Security-Policy that blocks inline scripts (`script-src 'self'`). The landing page uses inline `<script>` tags for signup modal, checkout, etc. CSP blocks them all silently. This is why signup and Pro checkout do nothing in the browser.
- **Console error:** `Executing inline script violates the following Content Security Policy directive 'script-src 'self''`
- **Fix:** Either (a) move all inline JS to an external .js file and serve it, OR (b) configure Helmet CSP to allow the specific inline script hash: `sha256-XMJXl2xc7O04+e5iJVD+zNlWQvR+VzMuyVfzOlUW5MA=`, OR (c) use nonces. Option (a) is cleanest.
- **Status:** Open
### BUG-005: Wrong Content-Type produces blank PDF instead of error
- **Found by:** QA (Session 14)
- **Date:** 2026-02-14
- **Severity:** LOW
- **Description:** Sending `Content-Type: text/plain` with a valid API key to `/v1/convert/html` generates a blank PDF (about:blank rendered) instead of returning a 400 error with a helpful message like "Content-Type must be application/json". The body isn't parsed as JSON, so `html` is undefined, and the handler falls through to rendering a blank page.
- **Repro:** `curl -X POST https://docfast.dev/v1/convert/html -H "Authorization: Bearer VALID_KEY" -H "Content-Type: text/plain" -d 'hello'`
- **Expected:** 400 error saying Content-Type must be application/json
- **Actual:** 200 with a blank PDF
- **Status:** Open
### BUG-006: Duplicate signup returns existing API key
- **Found by:** QA (Session 14)
- **Date:** 2026-02-14
- **Severity:** LOW
- **Description:** Signing up with the same email twice returns the same API key with 200 OK. The response says "Save this API key — it won't be shown again" but it CAN be shown again by re-submitting the email. This is arguably a feature (idempotent signup / key recovery), but the messaging is misleading. Either: (a) return a different message on duplicate ("Here's your existing key"), or (b) actually refuse to show it again and offer a "forgot key" flow.
- **Status:** Open — decide if this is intended behavior
## Verified Fixed
## Resolved
### BUG-001: Signup form doesn't work in browser
- **Found by:** Human (investor)
- **Date:** 2026-02-14
- **Severity:** CRITICAL
- **Verified:** 2026-02-14 (Session 14)
- **Description:** Clicking "Get Free API Key" on docfast.dev, entering email, and clicking "Get API Key" does nothing.
- **Root cause:** Rate limiter crash (trust proxy) + missing CORS headers. Fixed in session 13.
- **Verification:** The signup endpoint `/v1/signup/free` now returns 200 with a valid API key. CORS preflight returns proper headers for `Origin: https://docfast.dev`. The frontend JS correctly calls `/v1/signup/free` and shows the key result. **Could not verify in-browser due to no browser tool available**, but all curl-based evidence (correct endpoint, CORS headers, working JS logic) strongly indicates this is fixed.
- **Status:** ✅ FIXED (high confidence, needs browser confirmation)
- **Root cause:** BUG-004 (CSP blocks inline JS)
- **Status:** Will be fixed by BUG-004
### BUG-002: Pro plan "Get Started" button non-functional
- **Found by:** Human (investor)
- **Date:** 2026-02-14
- **Severity:** HIGH
- **Verified:** 2026-02-14 (Session 14)
- **Description:** Pro plan checkout button does nothing when clicked.
- **Root cause:** The `checkout()` JS function calls `POST /v1/billing/checkout` and redirects to the URL in the response.
- **Verification:** `POST /v1/billing/checkout` returns a valid Stripe checkout URL (`https://checkout.stripe.com/c/pay/cs_live_...`). The JS correctly does `window.location.href = data.url`. This should work in browser.
- **Status:** ✅ FIXED (high confidence, needs browser confirmation)
- **Root cause:** BUG-004 (CSP blocks inline JS)
- **Status:** Will be fixed by BUG-004
### BUG-003: Console errors in browser
- **Found by:** Human (investor)
- **Date:** 2026-02-14
- **Severity:** HIGH
- **Verified:** 2026-02-14 (Session 14)
- **Description:** JavaScript console errors present on docfast.dev.
- **Root cause:** Likely related to the rate limiter crash returning 500 errors.
- **Verification:** Reviewed full HTML/JS source. No syntax errors, no external script dependencies (no CDNs, no analytics, no frameworks — pure vanilla JS). CSP headers are strict (`script-src 'self'`), and all JS is inline in the HTML (which is allowed by same-origin). The JS is clean: `openSignup()`, `closeSignup()`, `submitSignup()`, `copyKey()`, `checkout()` — all well-structured with proper error handling. **No JS errors should occur now** that the API endpoints are responding correctly.
- **Status:** ✅ FIXED (high confidence)
## QA Session 14 Summary (2026-02-14)
### What was tested:
1. **Landing page** — Loads correctly, 200 OK, 14.6KB, clean HTML/CSS, no broken layouts
2. **Signup flow**`POST /v1/signup/free` works, returns API key, CORS headers present
3. **API key usage** — Generated key successfully converts HTML to PDF (8.1KB valid PDF)
4. **PDF validation** — Valid PDF 1.4, 1 page, correct content-type `application/pdf`
5. **Docs page**`/docs` is REAL documentation with full examples, request/response schemas, code samples
6. **Pro checkout** — Returns valid Stripe checkout URL (live mode `cs_live_*`)
7. **Error handling** — Bad API key → 401 "Invalid API key", missing html → 400 "Missing 'html' field"
8. **Security headers** — Excellent: CSP, HSTS, X-Content-Type-Options, X-Frame-Options, CORP, COOP, Referrer-Policy
9. **CORS** — Preflight works, `Access-Control-Allow-Origin: https://docfast.dev` returned correctly
10. **Server logs** — Clean: "Browser pool ready, Loaded 9 API keys, DocFast API running on :3100"
11. **Rate limiting** — Working: headers show `RateLimit-Limit: 100`, `RateLimit-Remaining` decrements properly
### Overall Assessment:
The three critical investor-reported bugs (BUG-001, BUG-002, BUG-003) are all fixed. The site is functional. Three new minor issues found (BUG-004, BUG-005, BUG-006). The product is in **shippable state** — the new bugs are edge cases, not blockers.
- **Root cause:** BUG-004 (CSP blocks inline JS)
- **Status:** Will be fixed by BUG-004