Skip to content

OAUTH-001C1J — Require exact Strava exchange client confirmation #612

Closed

Description

@daliu

Outcome

The browser must navigate away from the Strava callback only after the callable returns the exact documented success confirmation. Any other fulfilled result must use the existing fixed callback-failure screen.

Parent: #88

Problem

src/services/strava/stravaService.ts currently returns arbitrary fulfilled stravaExchangeCode data. StravaCallback treats every fulfillment as success. A fulfilled null, { ok: false }, malformed athlete ID, accessor, or hostile reflection result can therefore produce a false-success navigation even though the client has no valid confirmation.

Invariant and allowed transitions

  • Admit only a value presenting exactly two own enumerable data fields: primitive ok: true and a primitive positive safe-integer athleteId.
  • Return a fresh frozen canonical confirmation; never retain or return the received object.
  • Malformed fulfillment or exceptional result/data/structure inspection throws only Invalid Strava exchange response.
  • A callable transport rejection remains uninspected and identity-preserving.
  • The existing callback rejection path keeps the cleaned callback page on its fixed failure screen and must not navigate.
  • An exact client confirmation is acknowledgement admission only. It does not independently prove provider exchange, paired Firestore persistence, provider origin, deployment, or live behavior.

Scope

  • src/services/strava/stravaService.ts: exact response reader and narrowed return type for stravaExchangeCode only.
  • src/pages/account/Account.test.tsx: focused service matrix plus one real-service/callback composition proof.
  • SECURITY.md: RISK-009 current-source and residual boundary only.
  • docs/officers/EVENTS_SHOP_MEMBERS.md: existing Strava callback-failure procedure only.

No StravaCallback.tsx, Function, Rules, workflow, package, schema, migration, Firebase, provider, production-data, or live change is included.

Required RED and coverage

On exact base 63d29bedf379a857421501a5c0938c2901618095, fulfill the mocked callable with { data: { ok: false, athleteId: 608 } } and require the real service to reject with the fixed response error. The old source must fulfill. The callback composition test must prove the same malformed fulfillment stays on the fixed failure screen and does not navigate.

Cover exact valid bounds; fresh/frozen projection; missing, extra, inherited, symbol, non-enumerable, accessor, primitive, array, custom-prototype, malformed ok, malformed/non-safe/non-positive athleteId, throwing/revoked/transparent Proxy behavior; exceptional outer-result/data access where representable; and transport-rejection identity. Preserve existing callback cleanup, lifecycle, App Check handoff, rejection, and exact success behavior.

Dependencies

All source dependencies are merged. Provider configuration, IAM/encryption, deployment, and live proof remain separate #88 gates.

Acceptance criteria

  • The trustworthy RED fails on the exact base and passes with the fix.
  • Exact confirmation is the only fulfilled value that can reach callback success.
  • Invalid fulfillment cannot navigate, log, display, retain, coerce, or serialize supplied details.
  • Transport rejection behavior and all existing callback behavior remain compatible.
  • Focused checks and the relevant full suites pass.
  • Exact-head security, lifecycle, privacy, test-quality, and backup-officer reviews find no STOP.

Officer impact: A member will no longer see a false successful Strava callback transition when the website receives an invalid fulfilled confirmation. The fixed retry instruction remains visible.

Officer documentation: docs/officers/EVENTS_SHOP_MEMBERS.md existing Strava callback-failure procedure.

Deployment evidence: At claim time, no source change, test result, merge, website publication, runmprc.com verification, Firebase deployment, Strava/provider action, production-data action, or live-behavior verification is claimed. Final evidence must record each surface separately.

Activity

  1. self-assigned this
    on Aug 2, 2026
  2. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    CLAIMED by /root at 2026-08-02T07:34:49Z on branch codex/issue-612-strava-exchange-confirmation, exact base 63d29bedf379a857421501a5c0938c2901618095.

    This atomic OAUTH-001C1J child owns only the four paths and exact client fulfilled-confirmation outcome listed in the issue. It excludes Functions/server behavior, scope policy, response-byte bounds, athlete ownership, provider/local reconciliation, audit, IAM/encryption, deployment, production data, provider configuration, live behavior, and completion of #88.

  3. added
    bugSomething isn't working
    priority:P0Launch blocker or urgent security risk
    type:securitySecurity or privacy boundary
    area:authAuthentication and authorization
    area:webWeb application and hosting
    size:SSmall focused issue
    status:in-progressClaimed and actively being implemented
    type:testingTest infrastructure and quality gates
    area:privacyPersonal data, consent, minimization, retention, and privacy operations
    on Aug 2, 2026
  4. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    Trustworthy RED recorded before runtime or documentation edits.

    • Exact base: 63d29bedf379a857421501a5c0938c2901618095
    • Test-only binary diff SHA-256: 1d897e7868e04aa27cfcbc94dd6244f0f2f22c7baf7fb8c7a5e04f7e0c216014
    • Command: Node 20, CI=true npm test -- --runInBand src/pages/account/Account.test.tsx --testNamePattern='OAUTH-001C1J'
    • Result on old source: 52 failed, 1 passed. The sole pass was transport-rejection identity, which must remain compatible.
    • Critical witness: fulfilled { data: { ok: false, athleteId: 612 } } reached Account destination with replacement navigation; the new composition assertion required the existing fixed callback alert and no navigation.
    • Additional failures prove the old service returned the received object, admitted malformed/missing/extra/accessor/non-enumerable/symbol/unsafe-ID values, and exposed exceptional outer-result/data/reflection failures instead of the fixed response boundary.

    The RED used only made-up values and mocked Firebase/callable boundaries. No provider, Firebase project, production data, deployment, or live surface was contacted or changed.

  5. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    Corrected exact-base RED evidence — this supersedes the earlier test-only hash after five legacy successful mocks were corrected from the impossible athleteId: null shape to positive athlete IDs.

    • Exact base: 63d29bedf379a857421501a5c0938c2901618095
    • Current test-only binary diff SHA-256: ddcdfb68ec47f40c9d8a38c30d463ac7bf8ed2b51d130a338ce6a65b9cc53875
    • Node 20 exact-base RED: 52 failed, 188 skipped, 1 passed, 241 total.
    • Critical witness: the old service admitted { data: { ok: false, athleteId: 612 } }, so the real callback composition navigated to Account instead of staying on the cleaned fixed-failure page.
    • The sole compatible pass was transport-rejection identity, which must remain unchanged.
    • The five corrected compatibility/lifecycle fixtures do not change the named RED witness or failure count.
    • After restoring the runtime change, the focused OAUTH-001C1J — Require exact Strava exchange client confirmation #612 set passes 53/53.

    No production, provider, persistence, scope, deployment, or live behavior was exercised by this evidence.

  6. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    COMPLETE / CLOSED / CLAIM RELEASED

    #612 is complete as a source-only client acknowledgement boundary.

    • Reviewed head: 07237d570ccba266dd48a265fd22b7d9ddb10365; tree 031b49e53a5b728944c2abeac18d58ffcd6f1a6d; full binary diff SHA-256 b5b08f101adb6f8712ea8bc4f03847fdab99f8759d5c1c185d4f1262127d769f.
    • PR: OAUTH-001C1J — Require exact Strava exchange client confirmation #613, squash-merged.
    • Exact main / claim-release SHA: 644d9f1fe3e6c06427412fd3ae37973dbbfeca20; the main tree exactly matches the reviewed head tree.
    • Trustworthy Node 20 exact-base RED: 52 failed, 188 skipped, 1 compatible transport-rejection pass, 241 total. Current focused set: 53/53; Account: 241/241; full frontend: 1,040/1,040.
    • Independent exact-head runtime/security/lifecycle/privacy, RED/test-quality, and backup-officer/documentation reviews: GO. Self-review: GO, no actionable findings.
    • PR CI 30738759163: all five jobs passed. Exact-main CI 30738868932: all five jobs passed.
    • Netlify PR preview 6a6ef803662161000886623a: ready at the reviewed head, deploy-preview context, unpublished.
    • Ordinary main Netlify attempt 6a6ef8d14154fc0008c2aabb: error, published_at: null. GitHub deployments for exact main: [].
    • The existing published Netlify deploy remains 6a6dc9ea588b0c0008036312 at control commit 9ad6837756cdd409d296009fde5082eeeae5c059. The OAUTH-001C1J — Require exact Strava exchange client confirmation #612 website change was not published, so runmprc.com was not verified for it.
    • Firebase deployment, Strava/provider configuration or contact, production-data action, real callback/account use, and live-behavior verification: not performed.

    The browser now admits only the exact two-field confirmation and uses the existing fixed callback failure for malformed fulfillment. This does not prove provider exchange, paired persistence, athlete ownership, approved scopes, deployment, or live behavior. Remaining #88 work includes provider response bounds/timeouts, scope/account policy, reconciliation, audit, IAM/encryption, native enforcement, release, and provider/live evidence.

    CLAIM RELEASED at exact main 644d9f1fe3e6c06427412fd3ae37973dbbfeca20. No #612 path or outcome ownership remains.

  7. removed their assignment
    on Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authAuthentication and authorizationarea:privacyPersonal data, consent, minimization, retention, and privacy operationsarea:stravaStrava integrationarea:webWeb application and hostingbugSomething isn't workingpriority:P0Launch blocker or urgent security risksize:SSmall focused issuetype:reliabilityReliability and recoverytype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions