Skip to content

pages: Add /support page with OAuth reset wizard (2/3 split of #1371) - #1374

Merged
jm1021 merged 6 commits into
Open-Coding-Society:mainfrom
CSA-Admin-OCS:split/pages/p2-support-page
Sep 10, 2026
Merged

pages: Add /support page with OAuth reset wizard (2/3 split of #1371)#1374
jm1021 merged 6 commits into
Open-Coding-Society:mainfrom
CSA-Admin-OCS:split/pages/p2-support-page

Conversation

@RudraBJoshi

Copy link
Copy Markdown
Contributor

Splitting #1371 into smaller, independently-reviewable PRs across spring/flask/pages. This one covers the support page.

New /support page: a topic list (currently just "Password Reset") that deep-links via ?topic=reset straight into a 3-step wizard (GitHub ID → school Google OAuth → new password), calling Spring's OAuth-verified reset endpoints. The Google ID token is only relayed raw to the backend; the identity check happens server-side. Also exports GOOGLE_CLIENT_ID once from config.js instead of copy-pasting it, and fixes a referenced-but-never-defined .password-length validation style.

Original PR: #1371

New /support page: a topic list (currently just "Password Reset") that
deep-links via ?topic=reset straight into a "Let's Reset Your Password"
wizard, skipping the topic list -- used by "Forgot your password?"
links elsewhere so /support can grow to cover more than password reset
later without adding friction.

The wizard animates through GitHub ID entry -> school Google OAuth
sign-in -> new password, calling Spring's OAuth-verified reset
endpoints (/mvc/person/reset/oauth/verify, /mvc/person/reset/oauth/complete).
The Google ID token is only relayed raw to the backend; the
digit-match/identity check happens server-side, not in this client
code. Client-side password checks: 8-character minimum and
confirm-match, with inline feedback (styled via the new .password-length
validation class, referenced by this code but never previously defined).

Exports GOOGLE_CLIENT_ID once from config.js instead of copy-pasting it
into every page that needs Google sign-in, and login.md picks up that
shared import too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
RudraBJoshi and others added 4 commits August 26, 2026 12:54
Ensures any Claude Code session working in this repo automatically sees
that .clauderc (one directory up, at the prodsys root) has the project
structure, ongoing work, deploy requirements, and known gaps -- CLAUDE.md
is auto-loaded into context at session start, .clauderc on its own is not.
Companion to a spring-side fix that force-expires a uid's MVC sessions
after /reset/oauth/complete succeeds: that invalidates the account's
sessions server-side, but doesn't clear any cookies the browser
completing the reset happens to be holding. Call Spring's /logout
(best-effort) right before redirecting to /login so this browser's
cookies get cleared too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- showResetOAuthStatus(): build the status message via createElement/
  textContent instead of innerHTML string interpolation.
- startOAuthReset(): show an inline error if the Google GSI script
  hasn't loaded, and clear the sign-in container before rendering so
  re-entering the step doesn't stack a second button.
- submitOAuthResetPassword(): route password/mismatch errors through
  the existing inline validation message instead of alert().
- .support-topic-item <li>: add role="button" tabindex="0" plus a
  delegated keydown listener, so it's keyboard-activatable.
- resetUid/resetNewPassword/resetConfirmPassword: add matching
  aria-labels (previously placeholder-only accessible names).
- Move the inline <style> block and inline style="..." attributes into
  the same SCSS partial used on pwd-reset-support
  (elements/forms/support.scss).
- login.md's signup Google client id now reads from one shared
  _config.yml value via Liquid instead of being hardcoded (this
  branch's login.md already imported GOOGLE_CLIENT_ID from config.js,
  so this applied cleanly -- p1-forgot-password-button's older
  variant, which hardcodes a local copy instead of importing, was left
  alone rather than backported into).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jm1021 closed spring Open-Coding-Society#169 as violating the project's architecture:
Spring must never push a password to Flask directly. This page's reset
wizard was relying on Spring doing exactly that internally after
/reset/oauth/complete.

Reordered step 3 to call Flask's own POST /api/reset-password directly
first (it verifies the same resetToken's HMAC itself, no network call
to Spring involved) -- this is now the authoritative write. Only once
Flask confirms success does the frontend call Spring's
/reset/oauth/complete with the same token, to sync Spring's copy.
Matches how a logged-in password change already syncs both backends
separately from the frontend (profile.html) rather than one backend
pushing to the other.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@RudraBJoshi

Copy link
Copy Markdown
Contributor Author

Reordered the reset wizard's completion step per `jm1021`'s review on spring #169.

Why: `jm1021` closed #169 (Spring PR) as violating the project's architecture — Spring must never push a password to Flask directly. This page's step 3 was relying on exactly that: it called only Spring's `/reset/oauth/complete`, which internally pushed the new password to Flask server-to-server.

Fix: step 3 now calls Flask's own `POST /api/reset-password` directly first (Flask verifies the same `resetToken`'s HMAC itself — no network call to Spring involved), and only calls Spring's `/reset/oauth/complete` with the same token afterward, once Flask confirms success. This matches how a logged-in password change already syncs both backends separately from the frontend (`profile.html`), rather than one backend pushing to the other.

Companion changes: spring #170 (removes the banned `FlaskPasswordSync` call), flask #75 (the new `/api/reset-password` endpoint this page now calls).

Claude Code tooling config, not part of the actual codebase -- doesn't
belong bundled into a feature PR. Doesn't exist upstream either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jm1021
jm1021 merged commit 36f1381 into Open-Coding-Society:main Sep 10, 2026
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.

2 participants