Skip to content

fix: stop persisting the editor configuration in localStorage - #613

Draft
dcalhoun wants to merge 4 commits into
task/stabilize-rest-request-relayfrom
task/remove-gbkit-global-from-local-storage
Draft

fix: stop persisting the editor configuration in localStorage#613
dcalhoun wants to merge 4 commits into
task/stabilize-rest-request-relayfrom
task/remove-gbkit-global-from-local-storage

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Sep 1, 2026

Copy link
Copy Markdown
Member

What?

Stop mirroring the editor configuration (window.GBKit) into localStorage on iOS and Android, and drop the JavaScript fallback that read it.

Why?

GBKit carries the site credential and the local server's port and tokens, all valid only for the load that injected them. iOS mirrored it into localStorage, which the default website data store keeps on disk across launches, so a stale copy could outlive the session and hand a previous session's port and token to anything reading through the fallback.

Nothing needs the copy. The persisted copy arrived with the global in #14, when iOS injected the configuration with evaluateJavaScript after the page had loaded. #15 moved iOS to a document-start WKUserScript, which WebKit replays on every navigation, including the reload after a WebContent process termination. Android re-injects the global on every page start and wipes web storage before each load. Boot also waits for window.GBKit before anything reads the configuration and, outside ?dev_mode, aborts when it never arrives, so the fallback was unreachable in production.

Stacked atop #611 (task/stabilize-rest-request-relay), which first worked around the stale relay details in ef857d07 and c69054dd, then reverted the iOS half in 1494ca63 pending this change to both platforms.

How?

  • getGBKit returns the injected global or an empty object.
  • iOS drops the setItem line from the document-start script and removes the key instead, so devices upgraded from an earlier version are scrubbed. A test pins the script's shape.
  • Android drops the setItem line and the matching removeItem in clearConfig.
  • The CORS rationale comments on both platforms name window.GBKit alone as where the token lives.

Testing Instructions

  1. Run make test-js, make test-swift-package, and make test-android.
  2. In the iOS demo, open a post, then force a WebContent process termination (Activity Monitor: quit com.apple.WebKit.WebContent for the Simulator). The editor should reload with the current post.
  3. In the Android demo, open a post, background the app until the activity is recreated, then return. The editor should reload with the current post.
  4. On iOS, upgrade from a build before this change with a post open, then reopen a post. Safari Web Inspector's Storage tab for the editor page should show no GBKit key.

Note: make test-android fails six HttpServerAuthenticationTests cases locally with a 407 on a valid token. They fail identically with these changes reverted, and neither the server nor the test has changed since #561.

Screenshots or screencast

N/A

🤖 Generated with Claude Code

https://claude.ai/code/session_01JsMCoa3jNEuvnhxicDVRBV

@github-actions github-actions Bot added the [Type] Bug An existing feature does not function as intended label Sep 1, 2026
@wpmobilebot

wpmobilebot commented Sep 1, 2026

Copy link
Copy Markdown

XCFramework Build

This PR's XCFramework is available for testing. Add the following to your Package.swift:

.package(url: "https://github.com/wordpress-mobile/GutenbergKit", branch: "pr-build/613")

Built from f32075c

dcalhoun and others added 4 commits September 2, 2026 12:20
`getGBKit` fell back to a copy of the configuration in `localStorage`.
Boot waits for `window.GBKit` before anything reads the configuration,
and outside `?dev_mode` aborts when it never arrives, so the fallback
could only ever serve a previous session's values to a dev-mode page
with no host.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsMCoa3jNEuvnhxicDVRBV
`GBKit` carries the site credential and the local server's port and
tokens, all valid only for the load that injected them, and iOS mirrored
it into `localStorage`, which the default website data store keeps on
disk across launches. The document-start user script replays the global
on every navigation, including the reload after a WebContent process
termination, so the copy had no reader.

Remove the key as the configuration is injected so devices upgraded from
an earlier version are scrubbed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsMCoa3jNEuvnhxicDVRBV
`GBKit` carries the site credential and the local server's port and
token, all valid only for the load that injected them. The view
re-injects the global on every page start and wipes web storage before
each load, so the `localStorage` copy had no reader and nothing left to
clear on detach.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsMCoa3jNEuvnhxicDVRBV
The CORS rationale on both platforms named `localStorage` alongside
`window.GBKit` as where the editor holds the per-session bearer token.
The token now lives in the injected global only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsMCoa3jNEuvnhxicDVRBV
@dcalhoun
dcalhoun force-pushed the task/remove-gbkit-global-from-local-storage branch from b7d738a to f32075c Compare September 2, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants