Skip to content

OAUTH-001B10 — Require exact Strava disconnect client confirmation - #611

Merged
daliu merged 1 commit into
mainfrom
codex/issue-610-strava-disconnect-confirmation
Aug 2, 2026
Merged

daliu merged 1 commit into
mainfrom
codex/issue-610-strava-disconnect-confirmation

Conversation

@daliu

@daliu daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Outcome

My Account now hides the connected Strava identity and activity only when the callable fulfills with a value presenting exactly one own enumerable data field, ok: true. Other fulfilled values use the existing fixed unknown-result view.

Officer impact: Source now preserves the connected view when a fulfilled disconnect result is not an exact confirmation. The member still sees the existing instruction to refresh before another attempt.

Officer documentation: docs/officers/EVENTS_SHOP_MEMBERS.md, existing “Strava disconnect failure privacy — SOURCE ONLY, NOT LIVE” procedure. It now covers both rejected requests and fulfilled non-confirmations, asks for #252/#610 evidence, and preserves the no-terminal refresh/stop/escalate path. No Mermaid update is needed because page structure, data movement, permissions, account ownership, and deployment topology are unchanged.

Deployment evidence: Source changed and local tests passed. This PR has not been merged or published. The website and runmprc.com are not updated; Firebase was not deployed; no Strava setting, account, token, revocation, provider call, or production data was used or changed; live behavior is not verified.

Invariant and behavior

  • The callable request remains one exact empty ordinary object.
  • A fulfilled result resolves only when it presents exactly one own enumerable data property, ok, whose data value is primitive true.
  • Success returns a fresh frozen canonical { ok: true }; the received object is never retained.
  • Null, primitives, arrays, custom/null prototypes, missing/false/non-Boolean confirmation, extra keys, symbols, non-enumerable keys, inherited fields, accessors, malformed wrappers, and exceptional inspection reject with exactly Invalid Strava disconnect response.
  • The ok accessor and unknown-field getters are not invoked.
  • Transport rejection remains outside the validation catch, uninspected, and identity-preserving.
  • The existing component catch preserves athlete/activity, re-enables Disconnect, hides Connect, and shows only the fixed refresh-before-retry alert.
  • No schema or migration is required.

Browser JavaScript cannot reliably identify a faithfully transparent nonthrowing Proxy. A value that presents the exact admitted contract is projected into a new frozen confirmation rather than retained. Revoked or throwing reflection is contained. Firebase wire decoding does not ordinarily produce Proxies or accessors.

Trustworthy RED

On exact base 9d8bfaae0a4f9e573053b4035954e933ae626875, a test-only callable fulfillment { data: { ok: false } } was required to reject with the fixed response error. Old source instead fulfilled { ok: false }.

Test-only binary diff SHA-256: 03e16813248431f9a3f33cf8a6d0a642406ab5f13419ab9f762b05de56e2794a

Reviewed implementation binary diff SHA-256: 5975d21f867b27fafab901a10f5aa84e99c063f62c94be8c182c32405225566d

Reviewed head: 4ea0b7f0e1d830f42a5c33c6d4cfed3b5f35c56d

Verification

Node.js 20 and Java 21 were used where applicable.

  • Focused OAUTH-001B10: 37/37 passed
  • Full Account suite: 188/188 passed
  • Full frontend Jest: 987/987 passed, 18 suites
  • Full Functions: 7,524 passed, 64 intentionally skipped
  • Functions lint: passed
  • Frontend lint baseline: 118 files; unchanged 113 known errors and 6 known warnings
  • Static workflow/safety: 93/93 passed
  • Firestore Rules emulator: 418/418 passed
  • Commerce transaction emulator: 63/63 passed
  • SPA navigation: 11/11 passed
  • Diagnostic production build: passed
  • Direct ESLint on both changed TypeScript files: passed
  • git diff --check: passed
  • Dependency audits, no fixes applied: root 59 total/4 production; Functions 8 total/8 production; no critical advisories

Self-review

  • Authorization/App Check: unchanged; this is post-callable response admission only
  • Input/state bounds: one fixed field/value; reflection is caught and no received object escapes
  • Privacy/logging: no new log or transport; fixed UI/error text only; no response/rejection detail is inspected for display or logging
  • Idempotency/retry: no call count or retry behavior changes; invalid fulfillment remains unknown and requires refresh before retry
  • Provider proof: exact shape is acknowledgement admission only and is not independent evidence of Strava revocation
  • Compatibility: valid current server { ok: true } remains accepted; callers receive a narrower safe subtype
  • Migration: none

Independent runtime/security, test, and backup-officer reviews returned GO. Two reviewers first stopped overbroad Proxy/accessor documentation wording; those exact findings were corrected and re-reviewed GO before this commit.

Residual risk and exclusions

A transparent Proxy can present the exact contract; same-realm intrinsic tampering is outside this narrow boundary. A compromised server can still return { ok: true }, so this does not authenticate provider revocation. Provider serialization/reconciliation, connection-only writers, durable audit/tombstone, IAM/encryption, protected deployment, provider configuration, and live proof remain under #88.

Closes #610.
Parent #88 remains open.

@netlify

netlify Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for luminous-fox-7c393f ready!

Name Link
🔨 Latest commit 4ea0b7f
🔍 Latest deploy log https://app.netlify.com/projects/luminous-fox-7c393f/deploys/6a6eeffad8ef7f0008e9bfc9
😎 Deploy Preview https://deploy-preview-611--luminous-fox-7c393f.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@daliu

daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

SELF-REVIEW GO on exact remote head 4ea0b7f0e1d830f42a5c33c6d4cfed3b5f35c56d (base 9d8bfaae0a4f9e573053b4035954e933ae626875, binary diff SHA-256 5975d21f867b27fafab901a10f5aa84e99c063f62c94be8c182c32405225566d).

No issue remains in the reviewed scope:

  • only the sole own enumerable ok: true data contract may resolve, and the received value is projected into a fresh frozen confirmation;
  • malformed fulfilled wrappers/data and exceptional inspection use one fixed error;
  • transport rejection identity remains outside the validation catch and is not inspected;
  • transparent Proxy limits are explicit and no received object escapes;
  • the real-service UI proof preserves athlete/activity and shows only the fixed refresh instruction for {ok:false};
  • App Check/Auth/call count, Functions/server state, schema, and migration are unchanged;
  • an admitted shape is not overclaimed as provider-revocation proof;
  • officer and SECURITY wording distinguishes source, tests, merge, website, Firebase, provider/data, and live states.

Independent exact-head runtime/security, test, and backup-officer reviews each returned GO. Their earlier documentation STOPs were corrected before commit. PR CI run 30737652078 passed all five jobs; the exact-head Netlify preview is ready and GitHub deployments are empty. No Firebase deploy, Strava/provider action, production-data operation, or live verification occurred.

@daliu
daliu merged commit 63d29be into main Aug 2, 2026
9 checks passed
@daliu
daliu deleted the codex/issue-610-strava-disconnect-confirmation branch August 2, 2026 07:24
@daliu

daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

Post-merge verification complete. Exact main 63d29bedf379a857421501a5c0938c2901618095 has the same tree (a4c23c8b69a6076f01c3f4be3f06efed50fa9a72) as reviewed head 4ea0b7f0e1d830f42a5c33c6d4cfed3b5f35c56d. Post-main CI 30737752006 passed all five jobs. GitHub deployments are empty; Netlify main attempt 6a6ef0b0b8a874000896f33a failed unpublished, while preview 6a6eeffad8ef7f0008e9bfc9 is ready but unpublished. The live marker remains #473, so production behavior is not claimed. Issue #610 is COMPLETE / CLOSED / CLAIM RELEASED.

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.

OAUTH-001B10 — Require exact Strava disconnect client confirmation

1 participant