Skip to content

fix: bind pinning provider fetch fallback to globalThis for browser compatibility#477

Merged
FSM1 merged 9 commits into
mainfrom
fix/pinning-provider-fetch-binding
Jun 10, 2026
Merged

fix: bind pinning provider fetch fallback to globalThis for browser compatibility#477
FSM1 merged 9 commits into
mainfrom
fix/pinning-provider-fetch-binding

Conversation

@FSM1

@FSM1 FSM1 commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • The fix: KuboProvider and PsaProvider defaulted to unbound globalThis.fetch and invoked it as this.fetchFn(...). Native browser fetch called with this set to the provider instance throws TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation, which broke all uploads for accounts with external/dual pinning mode — instant 0% failure with no network request and no console output (the error was swallowed by a silent catch in the upload pipeline). Node's fetch is not this-sensitive, so no automated test ever caught it; the bug was latent since Phase 21. Fix: globalThis.fetch.bind(globalThis) in both providers.
  • Regression tests: added this-sensitive fetch stubs to both provider test suites that reproduce the exact production failure pre-fix (PinataProvider uses bare fetch(...) calls and was never affected).
  • UAT debt cleared 18 → 0: completed human UAT records for phases 19.1 (9/9 pass), 21 (4/5 pass, 3 gaps diagnosed), and 35 (Phala items resolved against post-chore(infra): switch staging TEE worker from Phala Cloud to local Docker #472 infra). The fix was verified end-to-end in a real browser against a local Kubo node, including an in-app upload in external-only mode with zero relay calls.
  • Docs: updated stale planning docs that still described the staging TEE worker as a Phala Cloud CVM — staging has run a local Docker simulator on the VPS since chore(infra): switch staging TEE worker from Phala Cloud to local Docker #472; Phala Cloud CVM remains the production design.

Diagnosed gaps recorded for follow-up (not fixed here)

  • Web app never calls PATCH /vault/byo-status, so the advisory quota badge is unreachable through the product flow (major, 21-UAT)
  • MigrationProgress stops polling permanently after a terminal job; failed jobs render as "migrating:" (minor, 21-UAT)
  • Migration stats double-count when the API 120s batch timeout fires mid-batch (minor, 21-UAT)
  • Orphaned PHALA_CLOUD_API_KEY secret + PHALA_TEE_WORKER_URL variable in the GitHub staging environment (minor, 35-UAT)

Test plan

  • pnpm --filter @cipherbox/sdk-core test — including new browser this-binding regression tests, proven to fail pre-fix
  • Live browser verification: negative control reproduced Illegal invocation; fixed provider pinned successfully to a real Kubo node (ipfs pin ls confirmed recursive pin)
  • In-app upload under external-only pinning mode: completed with pins landing on the BYO node and zero relay calls

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed browser compatibility issue in SDK that prevented fetch-based pinning operations from completing successfully.
  • Version Updates

    • Web app upgraded to 0.42.0
    • SDK Core updated to 0.36.2

FSM1 and others added 8 commits June 10, 2026 15:03
…diagnosed

Human verification items from 19.1-VERIFICATION.md executed via driven
browser session. All 9 tests passed: upload, folder create/move/rename,
bin delete/restore round-trip, logout/re-login lifecycle.

Findings recorded in UAT Gaps for fix planning:
- major: KuboProvider/PsaProvider unbound globalThis.fetch fallback
  throws Illegal invocation in browsers - external/dual pinning upload
  has never worked in a browser (Phase 21 surface, exact fix documented)
- minor: bin rows show 0 B for deleted file size
- cosmetic: delete dialog claims action cannot be undone despite bin

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 36431b6e6b11
KuboProvider and PsaProvider defaulted fetchFn to unbound globalThis.fetch
and invoked it as this.fetchFn(url). Native browser fetch called with
this set to the provider instance throws TypeError Illegal invocation,
so external-only and dual-pin upload failed instantly at 0% in browsers.
Node fetch is not this-sensitive, which is why unit and integration
tests never caught it.

Found during Phase 19.1 human UAT (see 19.1-UAT.md Gaps). Regression
tests stub a this-sensitive fetch that mirrors the browser contract;
verified to fail with the exact production error without the fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 5fa84813c643
Entire-Checkpoint: 6bb75352d8d3
…orker

STORAGE tab UX and the credential-encryption property verified in a
real browser session. The pinning fix from 9789efa is e2e-verified:
actual kubo-provider source pinned to the byo-ipfs-kubo Docker node
with native fetch, while the pre-fix pattern reproduces Illegal
invocation as a negative control.

Remaining items (advisory badge, migration controls, in-app BYO upload
wiring) are gated on a working local TEE worker: TEE_WORKER_URL
defaults to port 3001 which mock-ipns-routing occupies, and
TEE_WORKER_SECRET is unset. Details in 21-UAT.md Environment Blockers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 1db7735447d5
Local TEE worker now runs in Docker simulator mode (port 3002, epoch 1
key matches DB via deterministic HKDF seed), unblocking the previously
env-blocked items. Connection test, migration controls, and external
mode upload all verified live against the byo-ipfs-kubo node.

Diagnosed gaps:
- major: web never calls PATCH /vault/byo-status, advisory badge
  unreachable through product flow (rendering verified working)
- minor: MigrationProgress polling never restarts after save when the
  previous job ended terminal; stale failed job shown as migrating
- minor: migration stats double-count on API batch timeout (44+33>57)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 739dddf21e95
…staging infra

Both human_verification items concerned external state and were verified
remotely. The Phala CVM health check is obsolete: f270d84 intentionally
retired the staging CVM in favor of a local Docker simulator on the VPS,
and the replacement deployment is verified started via deploy run logs
plus live API version match. GitHub staging env config verified present
but now orphaned. Two minor gaps recorded: orphaned PHALA_* CI config and
stale ENVIRONMENTS.md staging TEE docs.

UAT debt audit now reports zero outstanding items.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 920410650ab4
…mulator

PR #472 moved the staging TEE worker from a Phala Cloud CVM back to a
local Docker Compose service in simulator mode, but the planning docs
still described the CVM as the live staging deployment. Rework the
ENVIRONMENTS.md staging TEE section around the simulator, move the CVM
identity-preservation warning to the production section, replace the
fictional TEE_ENABLED/TEE_PROVIDER/PHALA_API_URL env rows with the real
TEE_WORKER_URL/TEE_WORKER_SECRET vars, and fix the codebase docs that
claimed staging deploys to Phala. Phala Cloud CVM remains documented as
the production design. Resolves the stale-docs gap from 35-UAT.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 34152199eb92
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 9b14fefbebc5
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 85f79772-82dc-40db-9f65-7e69bf7e491f

📥 Commits

Reviewing files that changed from the base of the PR and between 0977aa4 and cef85ca.

📒 Files selected for processing (17)
  • .planning/ENVIRONMENTS.md
  • .planning/codebase/ARCHITECTURE.md
  • .planning/codebase/CONCERNS.md
  • .planning/codebase/INTEGRATIONS.md
  • .planning/codebase/STACK.md
  • .planning/codebase/STRUCTURE.md
  • .planning/phases/19.1-extract-core-crypto-sdk-as-shared-package/19.1-UAT.md
  • .planning/phases/19.1-extract-core-crypto-sdk-as-shared-package/19.1-VERIFICATION.md
  • .planning/phases/21-byo-ipfs-node-support/21-UAT.md
  • .planning/phases/21-byo-ipfs-node-support/21-VERIFICATION.md
  • .planning/phases/35-phala-testnet-tee-migration/35-UAT.md
  • .planning/phases/35-phala-testnet-tee-migration/35-VERIFICATION.md
  • packages/sdk-core/src/__tests__/pinning/kubo-provider.test.ts
  • packages/sdk-core/src/__tests__/pinning/psa-provider.test.ts
  • packages/sdk-core/src/pinning/kubo-provider.ts
  • packages/sdk-core/src/pinning/psa-provider.ts
  • release-please-config.json

Walkthrough

This PR combines a browser compatibility fix in the SDK pinning providers (KuboProvider, PsaProvider) with comprehensive documentation updates reflecting the staging TEE infrastructure transition from Phala Cloud CVM to a local Docker simulator deployment. It resolves identified gaps from Phase 35 TEE migration and Phase 19.1 UAT, updating all planning documents to reflect the new deployment topology.

Changes

TEE Infrastructure & SDK Fetch Binding

Layer / File(s) Summary
Browser fetch binding fix in pinning providers
packages/sdk-core/src/pinning/kubo-provider.ts, packages/sdk-core/src/pinning/psa-provider.ts, packages/sdk-core/src/__tests__/pinning/*
KuboProvider and PsaProvider now bind globalThis.fetch to the global context to prevent browser "Illegal invocation" errors when fetch is invoked with incorrect this binding. Regression tests confirm binding is captured at construction and pin operations succeed.
TEE environment architecture documentation
.planning/ENVIRONMENTS.md
Staging TEE infrastructure now runs as a Docker simulator on the staging VPS with deterministic HKDF-derived keys, replacing Phala Cloud CVM. Updated API environment variables (TEE_WORKER_URL, TEE_WORKER_SECRET), docker-compose configuration, local development guidance, incident runbook health checks, and implementation checklist tied to PR #472.
Architecture and integration documentation alignment
.planning/codebase/ARCHITECTURE.md, CONCERNS.md, INTEGRATIONS.md, STACK.md, STRUCTURE.md
Supporting docs updated to align with staging Docker simulator deployment. Path references changed from tee-worker/ to apps/tee-worker/, deployment descriptions clarified (staging simulator vs production Phala Cloud CVM), CVM single-provider risks documented, and stale CI-oriented references removed.
Phase 19.1 validation
.planning/phases/19.1-extract-core-crypto-sdk-as-shared-package/19.1-UAT.md, 19.1-VERIFICATION.md
Phase 19.1 UAT marked complete with 9 passing test cases. Verification marked as passed following human UAT on 2026-06-10. Gaps section documents the unbound fetch issue (now fixed in this PR) and recycle-bin metadata discrepancies.
Phase 21 validation
.planning/phases/21-byo-ipfs-node-support/21-UAT.md, 21-VERIFICATION.md
Phase 21 UAT documents environment setup with local TEE worker Docker container in simulator mode. Five test cases recorded covering storage, credential flow, BYO quota badge (fails on missing endpoint call), migration polling (passes but notes timeout/count gaps), and BYO login/upload activation. Verification marked as passed.
Phase 35 TEE migration validation
.planning/phases/35-phala-testnet-tee-migration/35-UAT.md, 35-VERIFICATION.md
Phase 35 UAT verifies staging TEE worker deployment in Docker simulator mode, confirms GitHub environment secrets exist, skips retired CVM health check. Documents two gaps: orphaned GitHub entries (PHALA_CLOUD_API_KEY, PHALA_TEE_WORKER_URL) and stale ENVIRONMENTS.md documentation (resolved by this PR). Verification reformatted and marked as passed.
Release version updates
release-please-config.json
Version bumps: apps/web 0.41.0→0.42.0, packages/sdk-core 0.36.1→0.36.2 to trigger releases with fetch binding fix and documentation updates.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • FSM1/cipher-box#49: Earlier environment architecture documentation update defining per-environment TEE isolation and republishing config wiring (staging simulator vs local/CI/no-TEE).
  • FSM1/cipher-box#395: Preceding refactor of KuboProvider and PsaProvider to use configurable fetch plumbing, now extended with this PR's bind(globalThis) context preservation.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the primary fix: binding the fetch fallback to globalThis for browser compatibility in pinning providers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pinning-provider-fetch-binding

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added release:sdk-core:fix Patch version bump (bug fix) for sdk-core release:sdk:fix Patch version bump (bug fix) for sdk release:web:fix Patch version bump (bug fix) for web release:tee-worker:fix Patch version bump (bug fix) for tee-worker labels Jun 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Release Preview

Package Bump Label Source
sdk patch release:sdk:fix Cascade (sdk-core patch)
sdk-core patch release:sdk-core:fix Direct (fix commit)
tee-worker patch release:tee-worker:fix Cascade (sdk-core patch)
web minor release:web:fix Cascade (sdk-core patch)

Cascade Details

  • sdk-core patch -> sdk patch (direct dependency)
  • sdk-core patch -> web patch (direct dependency)
  • sdk-core patch -> tee-worker patch (direct dependency)

@FSM1 FSM1 closed this Jun 10, 2026
@FSM1 FSM1 reopened this Jun 10, 2026
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.34%. Comparing base (46d0668) to head (cef85ca).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
packages/sdk-core/src/pinning/kubo-provider.ts 0.00% 1 Missing ⚠️
packages/sdk-core/src/pinning/psa-provider.ts 0.00% 1 Missing ⚠️

❌ Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #477   +/-   ##
=======================================
  Coverage   62.34%   62.34%           
=======================================
  Files         135      135           
  Lines       10157    10157           
  Branches     1081     1081           
=======================================
  Hits         6332     6332           
  Misses       3601     3601           
  Partials      224      224           
Flag Coverage Δ
api 84.67% <0.00%> (ø)
api-client 84.67% <0.00%> (ø)
core 84.67% <0.00%> (ø)
crypto 84.67% <0.00%> (ø)
sdk 84.67% <0.00%> (ø)
sdk-core 84.67% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/sdk-core/src/pinning/kubo-provider.ts 97.64% <0.00%> (ø)
packages/sdk-core/src/pinning/psa-provider.ts 87.75% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@FSM1 FSM1 merged commit 39dd78e into main Jun 10, 2026
26 checks passed
@FSM1 FSM1 deleted the fix/pinning-provider-fetch-binding branch June 10, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:sdk:fix Patch version bump (bug fix) for sdk release:sdk-core:fix Patch version bump (bug fix) for sdk-core release:tee-worker:fix Patch version bump (bug fix) for tee-worker release:web:fix Patch version bump (bug fix) for web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant