Outcome
Bound the existing Strava authorization-code input before credentials, provider access, or Firestore. A malformed or oversized browser value must fail with one fixed public authorization error and no side effect.
Parent/canonical tracker: #88
This is an atomic OAUTH-001C input-containment child. It does not complete OAUTH-001C or canonical #88.
Exact claimed paths
functions/strava.js — only the stravaExchangeCode authorization-code validation hunk and its bounded constant
functions/strava.test.js — focused authorization-code fixtures/tests only
All other paths and existing hunks are immutable.
Invariant and allowed transitions
- App Check remains first.
- Auth remains second.
- Code validation occurs after Auth and before reading Strava credentials, calling
fetch, obtaining document references, reading/writing Firestore, or creating timestamps.
- Only a primitive string with length 1 through 1,024 UTF-16 code units is admitted.
- The admitted code is opaque: do not trim, normalize, case-fold, parse, apply a provider-specific regular expression, or otherwise change it.
- Missing, null, undefined, empty, non-string, boxed-string, array/object, and oversized values return
invalid-argument with the existing fixed Strava authorization could not be completed. message.
- Invalid input is never included in an error or log.
- A 1-character code and an exact 1,024-character code reach the mocked provider code-unit-for-code-unit.
- Existing provider failure redaction and the successful server-only exchange/write/minimal-result contract remain unchanged.
Failure cases and tests
Synthetic values and installed fetch/Firestore mocks only; never call Strava or Firebase.
- App Check failure wins before Auth, validation, credentials, provider, or Firestore.
- Missing Auth wins before inspecting code validity, credentials, provider, or Firestore.
- Table-driven invalid primitive/structured values stop before credentials, provider, and Firestore.
- An exact 1,025-character value fails with the same fixed public result and no side effect.
- Boundary values of length 1 and 1,024 are sent unchanged in the mocked JSON request and preserve successful writes/result.
- Whitespace, Unicode, case, and punctuation inside an admitted nonempty code are preserved rather than treated as a provider-policy decision.
- Existing non-success, transport, response-parse, and success tests remain green.
Capture an intended old-source red case for oversized input before the implementation, then run focused and relevant full checks.
Explicit exclusions / residual risk
- callback URL/history scrubbing
- server-issued, UID/session-bound, one-use state, TTL, replay prevention, or cleanup
- a provider-specific code grammar or exact Strava length claim
- validation of the successful token/athlete response
- App Check callback handoff
- scopes, athlete/account ownership, token refresh concurrency, revoke/audit, IAM/encryption
- provider console, credentials, capacity, Firebase deployment, website publication, production data, migration, or live verification
Migration and officer impact
Migration impact: none. No stored data or schema changes.
Officer impact: none in this source child. The existing browser callback already presents the fixed #242 member message; this issue changes only the server-side admission bound. No officer procedure changes because no navigation, public wording, permissions, data movement, deployment, or officer task changes.
Officer documentation: None — server input containment only; #88 and the live child issue carry engineering/deployment evidence.
Coordination and completion evidence
Before editing: assign this issue and post a timestamped CLAIMED comment naming the agent, branch, exact base SHA, paths, and hunk boundary. Re-read live claims/open PRs first and stop on overlap.
Every PR/delivery report must separately state source, tests, merge, website publication, runmprc.com, Firebase deployment, Strava/provider configuration, production data, and live behavior. A green workflow is not deployment proof.
Outcome
Bound the existing Strava authorization-code input before credentials, provider access, or Firestore. A malformed or oversized browser value must fail with one fixed public authorization error and no side effect.
Parent/canonical tracker: #88
This is an atomic OAUTH-001C input-containment child. It does not complete OAUTH-001C or canonical #88.
Exact claimed paths
functions/strava.js— only thestravaExchangeCodeauthorization-code validation hunk and its bounded constantfunctions/strava.test.js— focused authorization-code fixtures/tests onlyAll other paths and existing hunks are immutable.
Invariant and allowed transitions
fetch, obtaining document references, reading/writing Firestore, or creating timestamps.invalid-argumentwith the existing fixedStrava authorization could not be completed.message.Failure cases and tests
Synthetic values and installed fetch/Firestore mocks only; never call Strava or Firebase.
Capture an intended old-source red case for oversized input before the implementation, then run focused and relevant full checks.
Explicit exclusions / residual risk
Migration and officer impact
Migration impact: none. No stored data or schema changes.
Officer impact: none in this source child. The existing browser callback already presents the fixed #242 member message; this issue changes only the server-side admission bound. No officer procedure changes because no navigation, public wording, permissions, data movement, deployment, or officer task changes.
Officer documentation: None — server input containment only; #88 and the live child issue carry engineering/deployment evidence.
Coordination and completion evidence
Before editing: assign this issue and post a timestamped
CLAIMEDcomment naming the agent, branch, exact base SHA, paths, and hunk boundary. Re-read live claims/open PRs first and stop on overlap.Every PR/delivery report must separately state source, tests, merge, website publication,
runmprc.com, Firebase deployment, Strava/provider configuration, production data, and live behavior. A green workflow is not deployment proof.