Skip to content

fix(web): resolve public /signin /signup /auth/callback 404s - #5780

Merged
Hmbown merged 2 commits into
mainfrom
fix/public-auth-routes-5767-20260831
Aug 31, 2026
Merged

fix(web): resolve public /signin /signup /auth/callback 404s#5780
Hmbown merged 2 commits into
mainfrom
fix/public-auth-routes-5767-20260831

Conversation

@Hmbown

@Hmbown Hmbown commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #5767.

Public https://codewhale.net/signin, /signup, and /auth/callback were locale-prefixed to /en/... and 404ed. This adds locale-aware public Sign in and Create account pages (canonical mark, account-first not hostage) and hops OAuth callbacks to the CWC app with the query intact.

Does not implement CWC registration or OAuth. That remains CWC #305.

Testing

  • cd web && npx vitest run lib/public-auth-routes.test.ts lib/middleware.test.ts lib/docs-ia.test.ts (39 passed)
  • cargo fmt --all -- --check (no Rust changes)
  • cargo clippy --workspace --all-targets --all-features --locked
  • cargo test --workspace --all-features --locked

Checklist

  • Added or updated tests where relevant
  • This change does not claim a real CWC registration or OAuth lifecycle
  • Browser verification of the exact deployed revision remains founder-gated (no deploy from this PR)

Bare auth URLs were locale-prefixed into /en/signin, /en/signup, and
/en/auth/callback, which had no pages. Keep sign-in and create-account
as locale-aware public routes that use the canonical mark and send the
person to the CWC app, hop OAuth callbacks to app.codewhale.net with
the query intact, and fold /login /register aliases. Local CLI use is
not presented as requiring an account.

Closes #5767

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 1m 38s —— View job


Review: fix(web): resolve public /signin /signup /auth/callback 404s

Todo list

  • Gather context (diff, changed files)
  • Review correctness of new public auth routes / middleware
  • Review provider/model/route safety implications (N/A — web-only PR, no Rust/provider code touched)
  • Review reuse/simplification
  • Review test coverage
  • Review security (open redirect risk, etc.)
  • Post final review

Summary

This is a clean, well-scoped fix. web/lib/public-auth-routes.ts is a single source of truth for the alias/remainder logic, middleware.ts reuses the existing pathLocale/replacePathLocale helpers rather than duplicating locale detection, and the redirect ordering (canonical host → static/API bypass → auth callback → alias fold → locale detection) is correct and matches the new tests in middleware.test.ts. The /[locale]/auth/callback page is a sensible defensive fallback in case middleware is ever bypassed for that route.

No correctness bugs found. Highlights worth calling out:

  • No open redirect: publicAuthCallbackDestination (web/lib/public-auth-routes.ts:71-76) always redirects to the fixed APP_URL constant; only the query string (?code=, ?state=, etc.) is attacker-influenced, which is expected/required for an OAuth callback hop and not a host-controlled redirect.
  • Good regression coverage: public-auth-routes.test.ts even hashes the shipped codewhale-mark.png against CANONICAL_MARK_SHA256 to guard against the asset being swapped for a redrawn substitute — a nice belt-and-suspenders test for a founder-mandated asset.
  • No infinite-redirect risk: canonicalPublicAuthPath returns null for paths that are already canonical (/signin, /en/signup), verified by test, so the 308 fold can't loop.
  • Sitemap/hreflang updates (app/sitemap.ts, docs-ia.test.ts) and contentLocalesForPath fallback (en/zh default) are consistent with the new pages' actual localization (English + Chinese copy only).

Minor, non-blocking note (reuse/simplification):
publicAuthKind (web/lib/public-auth-routes.ts:35-41) resolves SIGN_IN_ALIASES/SIGN_UP_ALIASES (login, register, create-account) to "sign-in"/"sign-up", but in production this branch is never reached that way — canonicalPublicAuthPath checks the alias sets directly without calling publicAuthKind, and signin/page.tsx/signup/page.tsx hardcode their kind prop. The alias-handling in publicAuthKind is currently exercised only by public-auth-routes.test.ts, not by any live code path. Not a bug — just dead branches you could either trim or leave with a one-line comment noting they exist for API symmetry/tests.

Provider/model routing safety (the v0.8.65 EPIC #2608 invariant) doesn't apply here — this PR touches only the Next.js web app, no Rust workspace or model-routing code.

Testing note: I couldn't run npx vitest in this sandbox (node_modules isn't installed and installing would require network access), so I verified the logic by static reading against the diff and cross-checking test expectations rather than executing the suite. The PR's own reported "39 passed" for the listed files is consistent with what the test code covers.

@Hmbown
Hmbown enabled auto-merge (squash) August 31, 2026 20:20
Unblock version-drift: #5776 landed on main without a CHANGELOG receipt,
which fails every subsequent PR. #5767 is the public /signin /signup
/auth/callback fix this branch ships.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 1m 38s —— View job


Review: fix(web): resolve public /signin /signup /auth/callback 404s

  • Gather context (diff, changed files)
  • Review correctness of new public auth routes / middleware
  • Review provider/model/route safety implications
  • Review reuse/simplification
  • Review test coverage
  • Review security (open redirect risk, etc.)
  • Post final review

Summary

Clean, well-scoped fix for #5767. web/lib/public-auth-routes.ts is a single source of truth for the alias/remainder logic, middleware.ts reuses the existing pathLocale/replacePathLocale helpers instead of duplicating locale detection, and the redirect ordering (canonical host → static/API bypass → auth callback → alias fold → locale detection) is correct and matches middleware.test.ts. The /[locale]/auth/callback page (web/app/[locale]/auth/callback/page.tsx:9-23) is a sensible defensive fallback if middleware is ever bypassed.

Correctness

  • No bugs found. canonicalPublicAuthPath (web/lib/public-auth-routes.ts:49-58) intentionally returns a still-bare /signin//signup for a bare /login//register, so a bare alias takes two redirect hops (308 fold, then the locale-detect 307) rather than landing on /en/signin directly — matches the doc comment on canonicalPublicAuthPath and is covered by middleware.test.ts. Not a bug, just note it's two hops, not one.
  • canonicalPublicAuthPath returns null for already-canonical paths (verified by test), so the 308 fold can't loop.

Security

  • No open redirect: publicAuthCallbackDestination (web/lib/public-auth-routes.ts:71-76) always redirects to the fixed APP_URL constant (https://app.codewhale.net, web/lib/i18n/links.ts:21); only the query string is attacker-influenced, which is required for an OAuth callback hop and isn't a host-controlled redirect.

Provider/model/route safety (EPIC #2608)

  • N/A — web-only change, no Rust/provider/model-routing code touched.

Reuse/simplification

  • Minor, non-blocking: publicAuthKind's alias branches (web/lib/public-auth-routes.ts:38-39, resolving login/register/create-account to sign-in/sign-up) are exercised only by public-auth-routes.test.tscanonicalPublicAuthPath checks the alias sets directly, and signin/page.tsx/signup/page.tsx hardcode their kind prop. Not a bug, just dead branches in production code paths; could trim or leave a one-line note that they exist for API symmetry/tests.
  • Scope note: the changelog commit (0cf5cf3) also adds a CHANGELOG.md/crates/tui/CHANGELOG.md entry for "Public roster language is Pod" (feat: make Pod the public roster surface #5776) — a separate, already-merged feature (84f42ae) that apparently shipped without its own changelog line. Bundling that backfill into a PR titled/scoped for Fix public website auth links that resolve to localized 404s #5767 is harmless here but is unrelated scope; worth a separate commit/PR next time so changelog history maps cleanly to the feature that introduced it.

Tests

  • Good coverage: public-auth-routes.test.ts covers remainder/kind resolution, alias folding, CWC destinations, and even hashes the shipped codewhale-mark.png against CANONICAL_MARK_SHA256 to guard against asset substitution. middleware.test.ts adds cases for the callback hop (bare and locale-prefixed), alias folding (bare and locale-prefixed), and locale-prefixing of /signin//signup. docs-ia.test.ts keeps sitemap/hreflang and nav parity in sync with the new pages.
  • Testing note: I could not execute npx vitest in this sandbox (no network access to install node_modules), so this review is based on static reading of the diff cross-checked against the test expectations, not test execution. The PR's own reported "39 passed" is consistent with what the test code covers.

No blocking issues. Approve on the strength of the diff review above (test execution not independently verified — see note).

@codewhale-agent codewhale-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewhale review

PR adds locale-aware public /signin, /signup, and OAuth /auth/callback redirects with tests. The core middleware and routing logic is sound, but the PR also contains unrelated changelog entries and leaves the fallback callback page untested and duplicative.

Findings

  • [WARNING] Unrelated #5776 changelog entries included in this web auth PR (CHANGELOG.md)
    Both CHANGELOG.md and crates/tui/CHANGELOG.md gain Pod/fleet language entries (#5776) that have nothing to do with fixing public auth routes (#5767). These likely came from an unintended branch base and should be removed to keep the PR focused.
  • [INFO] Fallback OAuth callback page is untested (web/app/[locale]/auth/callback/page.tsx)
    web/app/[locale]/auth/callback/page.tsx contains query-copying logic that mirrors publicAuthCallbackDestination but has no direct test. Middleware tests cover the redirect path, but if middleware is bypassed the page itself could regress silently.
  • [INFO] Query forwarding logic is duplicated between middleware helper and fallback page (web/app/[locale]/auth/callback/page.tsx)
    The fallback callback page manually iterates searchParams to rebuild the app callback URL, while public-auth-routes.ts already provides publicAuthCallbackDestination using URL.search. Reusing the helper would avoid future divergence if the callback path or query handling changes.

Assessment

The implementation correctly redirects /auth/callback to the CWC app with query preservation, aliases /login and /register, and adds locale-aware sign-in/signup pages with tests. Main concerns are scope creep from unrelated changelog entries and lack of direct coverage for the fallback callback page. No blocking correctness issues found in the diff.


Advisory review by Codewhale (codewhale review --pr 5780 --post, head 0cf5cf3cc2aaf1f32d2c67a83b8cb51cad303253). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

@Hmbown
Hmbown merged commit 250a659 into main Aug 31, 2026
29 checks passed
@Hmbown
Hmbown deleted the fix/public-auth-routes-5767-20260831 branch August 31, 2026 21:24
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.

Fix public website auth links that resolve to localized 404s

1 participant