WS-3 PR-B2b: A13-3 + single-cookie + single-host (incl. flatpickr precursor) #6
Reference in New Issue
Block a user
Delete Branch "feat/ws-3-pr-b2b-single-cookie-deploy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Final consolidation step in WS-3 single-SPA migration. Three primary deliverables plus three bonus catch-up commits surfaced during build verification.
Primary scope:
postLoginRedirect(closes A13-3)crewli_portal_token+ Origin-resolution machinery purged server-sideapps/portalbuild dropped fromdeploy.sh,portal.crewli.app301-redirect template addedBonus catch-up (surfaced during build verification, applied on this branch):
auto-imports.d.tsandcomponents.d.tsregen — pre-existing PR-B2a drift surfaced by flatpickr's pnpm installCommits
96cb1512e94a10a748c9e812cc177a69b03ad23847eb48557289e735Acceptance gates (all green)
php artisan testcomposer analyse(Larastan)composer rector --dry-runpnpm testpnpm typecheckpnpm lintpnpm buildbash -n deploy.shLocked design decisions
crewli_app_token— no session breakage on deployfrontend_portal_urlconfig key retained (Phase A Q1 — three non-auth consumers in email controllers; refactor tracked asTECH-FRONTEND-URL-CONSOLIDATE)README.md,Makefile,CLAUDE.md(Phase A Q2 — 9 other files deferred asTECH-DOCS-APPS-PORTAL-PURGE)A13-1finding actualised + flipped toRESOLVED(Phase A Q4) since the underlying localStorage→httpOnly migration shipped earlier in the consolidation arcportal.crewli.appDNS retirement is operational, not code (deferred)Notable deviations from original plan
68f1e6f; actual main was5380722post-WS-TOOLING-001. No conflicts — WS-TOOLING-001 was guard-rail tooling, didn't touch auth/deploy paths.InvitationController.phpalso used the removedresolveCookieName($request)/makeAuthCookie($cookieName, $token)signature. Original prompt's caller list missed this; same one-line removal pattern applied in the same commit.Out of scope (tracked in BACKLOG)
TECH-FRONTEND-URL-CONSOLIDATE— refactor 3 email controllers to drop per-app URL map (low priority, code cleanliness)TECH-DOCS-APPS-PORTAL-PURGE— sweep 9 other doc files (.cursor/, MASTER_PROMPT_, SETUP, dev-guide, CLAUDE_CODE_TOOLING) — singlechore(docs)PR, low priorityOPS — Retire portal.crewli.app DNS record— operational task, no deadlineFiles changed
git diff main --statacross all 8 commits: ~23 files, net deletions exceed insertions despite gaining 10 frontend test cases.Replaces the WS-3 PR-B2a minimum precaution (`startsWith('/') && !startsWith('//')`) with a layered validator that rejects every input that is not a strict relative path. isSafeRelativePath rejects: - Empty / null / undefined input - Non-`/`-prefixed paths (including leading whitespace) - Protocol-relative URLs (`//evil.com`) - Backslash anywhere (browsers normalise `\` → `/` in some contexts; `/\evil.com` parses as `//evil.com`) - ASCII control characters `\x00`–`\x1F` and `\x7F` (NUL, tab, LF, CR, DEL, etc. — header-injection vectors) - Anything the URL constructor parses to a different origin than the synthetic invalid origin used as the resolution base The URL-constructor check is the authoritative guard; the prefix and character checks are fast pre-filters that short-circuit common attack shapes without paying the URL allocation. Test coverage expands from 6 → 16 cases. New cases pin the backslash, control-character, leading-whitespace, and positive- character-set contracts. The URL-encoded-slash-in-query case documents that we don't false-positive on `%2F` in query strings. Closes A13-3 (open-redirect on post-login). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>