Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/lint-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
"targets": [
"src"
],
"scannedFileCount": 102,
"scannedFileCount": 104,
"scannedFilesByExtension": {
".js": 12,
".jsx": 35,
".ts": 31,
".tsx": 24
".tsx": 26
},
"errorCount": 125,
"warningCount": 7,
Expand All @@ -31,7 +31,7 @@
".ts": 0,
".tsx": 7
},
"fingerprint": "sha256:47721020c5ff47ef62494b6dcc6f7b806a4d446d32ef5f9193b1437a324c69b0",
"fingerprint": "sha256:7ddc6bb58cff269cf95dc05fc7e649f1f91c551e972afb5d7a0d1db5e0a1c964",
"scannedFiles": [
"src/App.jsx",
"src/App.test.jsx",
Expand Down Expand Up @@ -90,6 +90,8 @@
"src/pages/legal/Terms.jsx",
"src/pages/login/LoginForm.jsx",
"src/pages/login/LoginForm.test.jsx",
"src/pages/login/VerifyEmailAction.test.tsx",
"src/pages/login/VerifyEmailAction.tsx",
"src/pages/login/loginReturnPath.ts",
"src/pages/notFound/NotFound.jsx",
"src/pages/officers/Committee.jsx",
Expand Down
2 changes: 1 addition & 1 deletion GITHUB_ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ Both the legacy member synchronization function and admin role callable grant cl

AUTH-001A now rejects unverified targets at the two existing role-grant endpoints. Do not duplicate that merged slice. It is not proof that Firebase production runs the new code, and it does not complete the remaining parent requirements below.

Adjacent account-email recovery is represented by canonical live parent [#120](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/120), not by a new AUTH-001 role-grant child. AUTH-MAIL-002A [#145](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/145) merged the account-creation/request split as `46557c7` but is not published. AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153) merged the truthful My Account resend result and browser cooldown as `23bca8c8`, but protected release run `29252492614` stopped before build and published nothing. AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) tracks one neutral password-reset request result and repeat-safe browser cooldown. Incoming action-code states remain proposed as C2. None grants membership, proves provider delivery, or proves Firebase API enumeration protection.
Adjacent account-email recovery is represented by canonical live parent [#120](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/120), not by a new AUTH-001 role-grant child. AUTH-MAIL-002A [#145](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/145) merged the account-creation/request split as `46557c7` but is not published. AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153) merged the truthful My Account resend result and browser cooldown as `23bca8c8`, but protected release run `29252492614` stopped before build and published nothing. AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) tracks one neutral password-reset request result and repeat-safe browser cooldown. AUTH-MAIL-002C2 is represented by live child [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194): a verification-only `/auth/action` source route that scrubs capability state, requires an explicit click and provider `VERIFY_EMAIL`, and exposes only fixed non-identifying results. It must not be configured as Firebase's project-wide custom handler while reset-password and recover-email modes remain unsupported. None grants membership, proves provider delivery, reconciles the Firestore verification mirror, or proves Firebase API enumeration protection.

### Scope

Expand Down
2 changes: 1 addition & 1 deletion GITHUB_ISSUE_SLICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ An agent-ready child has one observable outcome, one trust boundary, explicit de
| AUTH-MAIL-002A | source merged through [#145](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/145) / PR #148 as `46557c7`; website/provider/live unproven | Separate account creation from verification-request acceptance/failure without exposing provider details. | Mocked create/accepted/unavailable tests; exact website and provider evidence stay separate. |
| AUTH-MAIL-002B | source/tests merged through [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153) / PR #154 as `23bca8c8`; A, #118 source; release `29252492614` stopped before build; not published | Make My Account resend report request acceptance or generic unavailability, block rapid repeats, and show the same 60-second browser cooldown after either result. | No-network double-click, timer/retry, remount, UID-change, redaction, and accessibility tests; website/provider/live states remain separate. |
| AUTH-MAIL-002C1 | source/tests tracked in live [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155); A/B; not published | Give every password-reset provider outcome one byte-equivalent neutral result, immediate repeat protection, and the same 60-second browser wait. Do not claim direct-API enumeration protection. | No-network success/failure equivalence, hostile canary, double-click, deadline/retry, unmount/remount, route/input, and accessibility tests; private provider-policy evidence stays #119. |
| AUTH-MAIL-002C2 | proposed; C1 | Add generic expired, used, already-complete, wrong-account, malformed, offline, and provider-unavailable states for incoming Firebase Auth action-code links without leaking codes or account state. | No-network state/collision/navigation/accessibility tests with fixed public recovery outcomes and callback-token redaction. |
| AUTH-MAIL-002C2 | source/tests tracked in live [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194); C1; provider not configured | Add a verification-only `/auth/action` route that scrubs one bounded capability, makes no load-time mutation, requires checked `VERIFY_EMAIL`, blocks a different signed-in account, and returns fixed already-complete/unusable/temporary states without leaking codes or account details. Do not configure it as Firebase's global handler until every enabled mode is safe. | No-network check/apply/order/race/offline/wrong-account/navigation/accessibility tests; Sentry/App Check startup suppression, Pages restoration, hostile-parameter redaction, and explicit provider/live stop condition. |
| OAUTH-001A | proposed; represented within canonical live [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88); SEC-001, AUTH-003B | Implement server-only, transaction/version-safe Strava token refresh so rotated refresh tokens cannot be lost. Do not publish a duplicate; claim/split only through #88. | Concurrent refresh/retry/conflict emulator tests. |
| OAUTH-001B | owner_action; represented within canonical live [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88); OAUTH-001A | Minimize scopes, implement disconnect/provider revocation, record encryption decision, and add access/refresh/revoke audit. Do not publish a duplicate; claim/split only through #88. | Test-provider revoke/refresh evidence and approved threat decision. |
| OAUTH-001C | proposed; represented within canonical live [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88); #99 | Create a server-safe Strava callback handoff that keeps `code`/`state` out of third parties while allowing App Check-protected `stravaExchangeCode`; retain state verification and server-only token exchange. Do not publish a duplicate; claim/split only through #88. | Encoded/case/trailing callback tests, wrong/replayed state denial, missing/invalid/valid App Check tests, and test-provider-only exchange evidence. |
Expand Down
8 changes: 7 additions & 1 deletion OPERATIONS_RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,10 @@ AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153)

AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) tracks the password-reset request source state machine: idle, requesting, finished, and retry-ready. Provider success and failure enter the same `finished` DOM, copy, accessibility state, and 60-second deadline. The browser never says sent, delivered, accepted, failed, or whether an account exists. Missing local input makes no request. A synchronous ref blocks duplicate activation; unmount discards a late result and clears the timer. Remounting may reset this usability guard.

AUTH-MAIL-002C2 [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194) tracks the verification-only `/auth/action` source state machine: ready, checking, verified, already complete when provider metadata plus the current session prove it, different signed-in account, unusable, and temporarily unavailable. The query and fragment are removed from native and router locations before an action-code check or apply. Opening the page starts no action-code check/apply and changes no account; the member must choose one large **Verify email** button. The service checks the code, requires provider operation `VERIFY_EMAIL`, compares any signed-in account without returning either address, and then applies once. Invalid, expired, used, disabled, deleted, malformed, wrong-environment, and wrong-operation links share one fixed result because Firebase cannot reliably distinguish all of them. Offline, throttled, network, and unknown errors share one temporary result. No result changes membership, roles, claims, Firestore, Functions, or mail delivery.

This route is **SOURCE ONLY, NOT LIVE**. Firebase configures one custom action handler for verification, password reset, and email recovery. The verification-only route must not become the project-wide handler. [#119](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/119) must retain/prove the default multi-mode handler or wait for separately reviewed reset and recovery coverage before provider cutover.

The source and tests do not change Firebase Auth, email templates, DNS, sender branding, account-enumeration protection, or mailbox/provider settings. Tests use a mocked request and no network. Identical browser output does not prove the direct Firebase API hides account state; the identity owner must record that provider setting privately under [#119](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/119). Do not test these flows with a production mailbox or a real member.

Release and evidence order:
Expand All @@ -621,7 +625,7 @@ Release and evidence order:
6. Use an isolated staging Firebase project and approved safe email sink before any end-to-end test.
7. Record request acceptance separately from message delivery, Spam placement, and sender configuration.
8. Keep provider/DNS/template work under [#119](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/119).
9. Keep password reset request work in AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) and incoming action-code work in the future AUTH-MAIL-002C2 under parent [#120](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/120). #153/#155 change browser results and usability timers only; they do not prove provider delivery, enumeration protection, or a durable rate limit.
9. Keep password reset request work in AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) and verification action-code source work in AUTH-MAIL-002C2 [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194) under parent [#120](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/120). #153/#155 change browser results and usability timers only. #194 handles only `verifyEmail`; it is not safe as the global custom handler. None proves provider delivery, enumeration protection, or a durable rate limit.

Rollback is a reviewed frontend revert or safe roll-forward. Do not delete or recreate an Auth account because the verification request failed.

Expand Down Expand Up @@ -651,4 +655,6 @@ For AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/

For AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155), **source/tests** means mocked reset success/failure produce byte-equivalent neutral public output, immediate repeat protection, deadline/retry/unmount tests, return-state preservation, hostile-canary redaction, and accessible controls; **merge** is a separate `main` SHA; **website publication** and **`runmprc.com` revision verification** are separate; **Firebase/provider configuration** is unchanged; and **delivery plus API enumeration protection** remain unverified. A neutral page does not prove provider policy or direct-API behavior.

For AUTH-MAIL-002C2 [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194), **source/tests** means a no-network route, immediate history scrub, explicit-click guard, provider-operation check, fixed non-identifying results, wrong-account/no-apply handling, callback startup suppression, Pages restoration, hostile-parameter redaction, and keyboard/focus/target-size checks; **merge** is a separate `main` SHA; **website publication** and **`runmprc.com` revision verification** are separate; **Firebase template/action-domain configuration** is unchanged; and **link reachability, delivery, every non-verification action mode, provider behavior, the Firestore verification mirror, and live behavior** remain unverified. Never configure a project-wide custom handler from this source result alone.

Provider configuration, production secrets, Netlify publication, Firebase deployment, and live behavior always require separate dated evidence. Local tests and a green GitHub summary do not prove them.
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ These entries are implementation evidence, not a production risk-acceptance deci
| Part of RISK-035 | The Jest environment is repaired, #124 adds the complete frontend suite as a named blocking hosted step, and #126 adds the standalone SPA callback suite. CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) merged the lockfile-bound Node 20/Java 17 `Commerce command journal emulator` job using exact demo project `demo-pay002b2-test`, Firestore only, and explicit opt-in. CI-001B4 [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) merged through [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`, adding the no-new-dependency exact-record checker over 102 frontend files, named blocking lint step, and clean-checkout step. Exact PR run `29291402007` and post-merge run `29291515653` passed every GitHub job. | The reviewable lint baseline deliberately records 125 configured errors and 7 warnings as individual file/line/column/rule/message records; it is not a clean-lint claim. Any added, removed, moved, or changed record requires review, every fatal parser/configuration failure rejects with a fixed diagnostic, and the baseline must not be regenerated just to pass. The clean check covers tracked and non-ignored untracked files; ignored dependency/build outputs are outside this proof. Hosted source checks do not configure branch protection, deploy Firebase, or prove Stripe/live behavior. #169, #173, and #182 expand the focused commerce suite; configure/prove branch-required checks and add the broader TEST-001 suite. |
| RISK-026, RISK-036 | #135 merged through PR #138 as `9eafab1217aff7058c42240aaba72d7b93f8ed24`, replacing automatic frontend-first/fail-open GitHub deployment with a tested manual exact-current-commit gate. Post-merge staging and synthetic production probes failed closed before authentication or mutation, and published neither Firebase nor Pages. | #133 must configure protected environments and least-privilege OIDC/WIF; #136 must prove staged/target deployment and clearing/readback of the existing Pages `runmprc.com` claim; a protected WEB-001 child must establish Netlify publication and rollback. No Firebase, Pages, live-host, or provider-setting change is proven by source/static tests alone. |
| RISK-039 | The #118 source slice uses an empty authenticated callable request, bounded Firebase Auth identity fields, one transactional create-only helper shared with signup, constant responses, generic failures, and a UI that hides Edit until setup and the Rules-protected read succeed. Signup and recovery never change custom claims; browser profile creation remains denied. | Source review/merge is not deployment. Under #105, deploy the exact #100 Rules plus both `createMemberOnSignUp` and `ensureMemberProfile` before the website, prove App Check policy, use a synthetic staged account, verify rollback, then record website, Function, Rules, and live behavior separately. Never repair a real profile manually. |
| RISK-040 | AUTH-MAIL-002A [#145](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/145) merged as `46557c7`: account creation returns `accepted` or `unavailable` without exposing provider details. AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153) merged as `23bca8c8`: My Account makes no false “sent” claim, blocks rapid repeats, and applies the same 60-second browser cooldown after either outcome. Its protected release run `29252492614` stopped before build because the required public App Check key was absent, so neither frontend revision is published. AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) tracks one byte-equivalent password-reset result after provider success or failure, an immediate repeat guard, and the same browser wait. Synthetic tests use mocked calls and canary values only. | Publish and verify each exact frontend revision separately. #118 profile source is merged but live behavior is unproven. Keep delivery, Spam, DNS, templates, and private Firebase email-enumeration-protection readback under #119. Identical browser copy does not prove the direct Firebase API suppresses account-state differences. An accepted verification request does not prove delivery, and browser cooldowns can reset; they are not server abuse protection. Incoming action-code recovery remains AUTH-MAIL-002C2 under #120. |
| RISK-040 | AUTH-MAIL-002A [#145](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/145) merged as `46557c7`: account creation returns `accepted` or `unavailable` without exposing provider details. AUTH-MAIL-002B [#153](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/153) merged as `23bca8c8`: My Account makes no false “sent” claim, blocks rapid repeats, and applies the same 60-second browser cooldown after either outcome. Its protected release run `29252492614` stopped before build because the required public App Check key was absent, so neither frontend revision is published. AUTH-MAIL-002C1 [#155](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/155) tracks one byte-equivalent password-reset request result after provider success or failure. AUTH-MAIL-002C2 [#194](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/194) tracks the source-only `/auth/action` verification path: the initial capability suppresses Sentry/App Check, the page removes native and router query/fragment state, a scanner-style page load makes no action-code check/apply and no account mutation, and one deliberate action requires provider `VERIFY_EMAIL` before apply. Fixed results expose no email, code, raw provider error, account identity, or provider-directed navigation. Synthetic tests use mocks and canary values only. | Publish and verify each exact frontend revision separately. The existing #99 Pages bridge briefly uses tab-local session storage for the return route and deletes it before React; a failed root load can leave it until tab close, while direct-rewrite hosting avoids that residual. #194 adds no storage write. #118 profile source is merged but live behavior is unproven. Keep delivery, Spam, DNS, templates, provider handler choice, and private Firebase email-enumeration-protection readback under #119. Firebase uses one custom handler for verification, password reset, and email recovery; never point its global action URL at the verification-only #194 route until every enabled mode is safely handled, or keep the default multi-mode handler. Accepted requests do not prove delivery, browser cooldowns are not abuse controls, Auth verification does not grant membership, and the Firestore verification mirror remains unfinished AUTH-001 work. |

## 5. Threat model

Expand Down
Loading