Skip to content

feat(auth): harden registration and protected sessions - #1415

Merged
mftee merged 2 commits into
CodeGirlsInc:mainfrom
khaadish:feature/registration-auth-and-locale-safety
Sep 25, 2026
Merged

mftee merged 2 commits into
CodeGirlsInc:mainfrom
khaadish:feature/registration-auth-and-locale-safety

Conversation

@khaadish

Copy link
Copy Markdown
Contributor

Summary

  • add live password confirmation and accessible strength feedback to registration
  • persist the selected locale through next-intl routing
  • verify protected sessions server-side and add secure cookie-backed refresh/logout handling

Issues

Validation

  • static diff, whitespace, import/export, and secret review completed
  • automated tests, lint/typecheck, builds, dependency installation, and CI were not run per maintainer request

Closes #1305
Closes #1306
Closes #1307
Closes #1308

Add server-verified protected-route sessions, secure cookie-backed refresh/logout, locale persistence, and accessible registration validation and strength feedback.

Closes CodeGirlsInc#1305
Closes CodeGirlsInc#1306
Closes CodeGirlsInc#1307
Closes CodeGirlsInc#1308
@vercel

vercel Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

@khaadish is attempting to deploy a commit to the Mftee's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Sep 25, 2026

Copy link
Copy Markdown

@khaadish Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Resolve auth-session.ts: keep this PR's DEFAULT_POST_LOGIN_PATH="/" redesign
(middleware/tests consistently treat "/" as the protected landing page),
carry forward main's hasStoredSession() from CodeGirlsInc#1414 (decoupled, dashboardHref
comes from an explicit prop, not this constant).

Resolve robots.ts: keep main's per-locale disallowedPaths from CodeGirlsInc#1413; this
PR's own edit here was unrelated to its scope and would have blanket-disallowed
the whole site.

@mftee mftee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed. This is a substantial, well-integrated rework: live password confirmation with accessible strength feedback on registration (with real requirement rules mirroring the backend DTO's validation), locale persistence via a cookie instead of an authenticated-only backend call, and a genuinely stronger protected-session model — the middleware now verifies the access cookie against the backend on every protected-route request (fail-closed with a 503 rather than silently letting traffic through when the auth service is unreachable), falls back to a dedicated session-refresh redirect when only a refresh cookie is present, and guards against open-redirect via the param (rejects protocol-relative and control-character payloads, strips locale prefixes). Extensive new middleware test coverage backs all of this.

This PR conflicted with both #1413 (robots.ts) and #1414 (auth-session.ts) — the auth-session.ts conflict was substantive, not just textual: this PR deliberately redefines DEFAULT_POST_LOGIN_PATH from '/dashboard' to '/' as part of making '/' the actual protected landing page (consistent throughout the new middleware and its test suite). I kept that redesign and carried forward #1414's hasStoredSession() helper alongside it (confirmed it's decoupled — the 404 page's dashboard link uses an explicit homeHref prop, not this constant). Separately, this PR's own robots.ts edit looked like an unrelated accidental regression (would have blanket-disallowed the whole site) and was out of scope for its linked issues, so I discarded it and kept #1413's correct per-locale disallow list. CI failures reproduce identically on main. Approving.

@mftee mftee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed. This is a substantial, well-integrated rework: live password confirmation with accessible strength feedback on registration (with real requirement rules mirroring the backend DTO's validation), locale persistence via a cookie instead of an authenticated-only backend call, and a genuinely stronger protected-session model — the middleware now verifies the access cookie against the backend on every protected-route request (fail-closed with a 503 rather than silently letting traffic through when the auth service is unreachable), falls back to a dedicated session-refresh redirect when only a refresh cookie is present, and guards against open-redirect via the redirect param (rejects protocol-relative and control-character payloads, strips locale prefixes). Extensive new middleware test coverage backs all of this.

This PR conflicted with both #1413 (robots.ts) and #1414 (auth-session.ts) — the auth-session.ts conflict was substantive, not just textual: this PR deliberately redefines DEFAULT_POST_LOGIN_PATH from '/dashboard' to '/' as part of making '/' the actual protected landing page (consistent throughout the new middleware and its test suite). I kept that redesign and carried forward #1414's hasStoredSession() helper alongside it (confirmed it's decoupled — the 404 page's dashboard link uses an explicit homeHref prop, not this constant). Separately, this PR's own robots.ts edit looked like an unrelated accidental regression (would have blanket-disallowed the whole site) and was out of scope for its linked issues, so I discarded it and kept #1413's correct per-locale disallow list. CI failures reproduce identically on main. Approving.

@mftee
mftee merged commit 8b0fce1 into CodeGirlsInc:main Sep 25, 2026
0 of 6 checks passed
mftee added a commit to khalyaro/SMALDA that referenced this pull request Sep 25, 2026
- register-auth.dto.ts / lib/schemas/auth.ts: keep contract-driven minLength
  (this PR's design) combined with main's password complexity rules and
  translated message keys (from CodeGirlsInc#1415) rather than either side alone.
- Bumped the stale api-contracts.json register.password.minLength (6->8) and
  fullName.minLength (1->2) to match the password policy already merged in
  CodeGirlsInc#1415, and re-ran contracts/sync.mjs to propagate to both copies.
- Kept app/schemas/register.schema.ts and e2e/dialog.spec.ts, which this PR
  deleted for reasons unrelated to its own scope (predates CodeGirlsInc#1415's
  RegisterForm.tsx, which still imports the former; the latter's coverage
  isn't replaced elsewhere in this PR).
mftee pushed a commit that referenced this pull request Sep 25, 2026
Centralizes shared API constraints into contracts/api-contracts.json, adds dispute-filing E2E coverage across three browsers, and includes app-level code in Jest coverage. Fixed a stale contract value and two unrelated file deletions found while resolving conflicts with #1415. Closes #1325, #1326, #1327, #1328.
mftee added a commit to Muhammadjazuli/SMALDA that referenced this pull request Sep 25, 2026
Both CodeGirlsInc#1415 (already merged) and this PR independently rewrote api-client.ts
and auth-session.ts with different, incompatible session-refresh designs.
Synthesized rather than picked a side:

- Kept this PR's authGeneration/AbortController invalidation mechanism
  (invalidateRefresh/RefreshInvalidatedError) since this PR's own
  auth-session.ts (storeSession) depends on it, non-conflicting call sites
  confirm the sync clearSession() -> SessionStateResult contract (e.g.
  settings/security/page.tsx checks .ok synchronously, would not type-check
  against CodeGirlsInc#1415's Promise<boolean>), and the resume-aware redirectToLogin
  (appends ?resume= from a pending session-state group) is real, tested
  functionality from this PR's own scope.
- Kept CodeGirlsInc#1415's refresh-token ROTATION handling (persisting the server's
  rotated refresh_token) and its RefreshError(status, definitive)/
  isDefinitiveRefreshError distinction + cross-tab refresh adoption, since
  dropping either would regress against CodeGirlsInc#1398's already-merged
  reuse-detection/family-revocation, and SessionRefreshClient.tsx (already
  merged, not touched by this PR) imports isDefinitiveRefreshError directly.
- clearSession is now synchronous (SessionStateResult, matching this PR's
  real non-conflicting call sites) but still fires the backend logout call
  fire-and-forget so CodeGirlsInc#1415's server-side revocation still happens.
- Removed a dead cookie-clearing line (document.cookie = 'token=...') present
  in both sides' versions of this logic — nothing in the codebase ever sets a
  cookie named 'token'; the real session cookies are named via
  ACCESS_COOKIE_NAME/REFRESH_COOKIE_NAME in auth-cookie.ts.
- Rewrote test-utils/api-client.test.ts and LoginForm.test.tsx assertions
  that depended on the losing side's implementation details (async boolean
  clearSession, /dashboard redirect, relative request URLs).

Could not run tsc or jest locally to verify this (no node_modules on this
machine) — CI is the real check for this commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants