Skip to content

feat: account page with Yandex linking, and 404/500 pages - #18

Merged
TheGeniusOfEternity merged 2 commits into
mainfrom
feat/error-pages-and-account-linking
Sep 29, 2026
Merged

TheGeniusOfEternity merged 2 commits into
mainfrom
feat/error-pages-and-account-linking

Conversation

@TheGeniusOfEternity

Copy link
Copy Markdown
Owner

Independent of #17 (both based on main); expect a small CHANGELOG.md conflict for whichever merges second.

Summary

Account linking (step 3 of the Yandex sign-in design: accounts are keyed by yandexId, email clashes are refused, linking is an explicit action by a signed-in user).

  • New /account page (sidebar → "Account") with sign-in methods: email/password and Yandex ID.
  • Connect: GET /api/auth/yandex?intent=link. The intent is stored together with the OAuth state (link:<state> cookie), so it can't be swapped on the way back; the callback identifies the user by their refresh cookie (path /api/auth) and attaches the Yandex id unless another account already owns it. Results come back as /account?linked=yandex or ?link_error=….
  • Disconnect: DELETE /api/auth/yandex, refused with 409 when Yandex is the only sign-in method.
  • /api/auth/me now also returns methods: { password, yandex }.
  • The state cookie parser still accepts the old bare-state format, so logins in flight during the deploy keep working.
  • If Yandex isn't configured, the start endpoint redirects back to the app with an error instead of returning JSON 503.

Error pages

  • widgets/error-page/ErrorPage for 404/500, used for unknown routes (previously silently showed the landing), missing or unpublished public widgets, and failed editor loads (404 vs 500 by status, with retry).
  • App-level error boundary shows the 500 page instead of a blank screen.

Tests

  • Server: link start (intent bound to state), link success, identity owned by another account, no session, unlink only with a password, unconfigured provider redirects.
  • Client: ErrorPage, AccountPage (connect/disconnect, only-method guard, URL notice). Vitest now inlines @gravity-ui/* so components that import its CSS can be tested.

Test plan

  • Browser: /definitely-missing and /w/no-such-widget show 404; sidebar → Account shows methods with "Connect" for Yandex
  • Full Yandex link round-trip needs real credentials; please try on a preview/prod deploy
  • format:check, lint, typecheck, test (37 client + 34 server), build, typecheck:api

Note: I saw one unreproducible failure of rateLimit.test.ts right after a bulk file rewrite; 10 reruns were green.

- /account lists sign-in methods; connect Yandex ID via
  /api/auth/yandex?intent=link (intent bound to the OAuth state, user
  identified by the refresh cookie), disconnect only if a password remains
- /api/auth/me returns sign-in methods
- ErrorPage (widgets/error-page) for unknown routes, missing public
  widgets, failed editor loads, plus an app-level error boundary
- Unconfigured Yandex redirects back to the app instead of JSON 503
- Vitest inlines Gravity UI so components importing its CSS are testable
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
widgecode Ignored Ignored Preview Sep 29, 2026 7:18pm UTC

@TheGeniusOfEternity
TheGeniusOfEternity merged commit 7271c0d into main Sep 29, 2026
3 checks passed
@TheGeniusOfEternity
TheGeniusOfEternity deleted the feat/error-pages-and-account-linking branch September 29, 2026 19:19
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.

1 participant