Skip to content

feat: Authenticated API requests - #14

Merged
dcalhoun merged 7 commits into
trunkfrom
feat/authenticated-api-requests
Aug 14, 2024
Merged

dcalhoun merged 7 commits into
trunkfrom
feat/authenticated-api-requests

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Aug 13, 2024 •

Copy link
Copy Markdown
Member

Enable authenticated API requests to a site URL via the basic authentication
scheme with application passwords.

Testing Instructions

  1. Manually set siteURL and authToken values within the
    EditorViewController constructor.
  2. Build and run the demo app.
  3. Inspect the network traffic and verify the preloaded requests succeed.

Provide the editor with context managed by the host application.
Simplify retrieval of configuration values provided by the host app.
Improve performance by reducing local storage read frequency.
Communicate CORS support and avoid incorrect presumptions in
third-party responses (e.g., Jetpack adds custom header values).
Comment thread ReactApp/src/misc/api-fetch-setup.js
@dcalhoun
dcalhoun marked this pull request as ready for review August 13, 2024 19:06
@dcalhoun
dcalhoun requested a review from geriux August 13, 2024 19:06
@dcalhoun
dcalhoun enabled auto-merge (squash) August 13, 2024 19:07
export function initializeApiFetch() {
apiFetch.use(apiFetch.createRootURLMiddleware(''));
const { siteURL, authToken } = getGBKit();
const rootURL = siteURL ? `${siteURL}/wp-json/` : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just realized that for WordPress.com sites, we'll need to use https://public-api.wordpress.com/ instead. This means we'll need to remove the wp-json path and include it in the siteURL parameter. I suggest we address this in a separate PR, as I encountered some issues with the endpoint paths when attempting to connect to https://public-api.wordpress.com/.

For now this will work perfectly for self-hosted sites.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I make successful requests with this approach for an Atomic WPCOM site. Is the use of https://public-api.wordpress.com/ merely a recommendation and/or potentially required for Simple sites?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying with a simple site yeah. For Atomic, it's the same as self-hosted using the site's URL, but for Simple sites I think we'll need to go through the WordPress.com API 🤔

I ended up trying this because I checked the editor's Web view source code and for Simple sites, it sets https://public-api.wordpress.com/ for the createRootURLMiddleware middleware and for Atomic, it just uses the site's URL e.g. https://geriuxxtestingbusiness123.wpcomstaging.com/wp-json/

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. When we address this, we might consider renaming siteURL to something like siteAPIURL.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed here

@geriux geriux left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I've tested it using the host app and I was able to pass the data successfully. 🚀

Nice work!

@dcalhoun
dcalhoun merged commit 6353bb3 into trunk Aug 14, 2024
@dcalhoun
dcalhoun deleted the feat/authenticated-api-requests branch August 14, 2024 12:11
dcalhoun added a commit that referenced this pull request Sep 24, 2026
…script

The trailing `"done";` dates from #14, when the configuration was injected
with `evaluateJavaScript`, which needed a serializable trailing expression.
#15 moved the script to a document-start `WKUserScript`, whose completion
value WebKit discards, and the line has been inert since.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh
dcalhoun added a commit that referenced this pull request Sep 28, 2026
…script

The trailing `"done";` dates from #14, when the configuration was injected
with `evaluateJavaScript`, which needed a serializable trailing expression.
#15 moved the script to a document-start `WKUserScript`, whose completion
value WebKit discards, and the line has been inert since.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh
dcalhoun added a commit that referenced this pull request Sep 29, 2026
…script

The trailing `"done";` dates from #14, when the configuration was injected
with `evaluateJavaScript`, which needed a serializable trailing expression.
#15 moved the script to a document-start `WKUserScript`, whose completion
value WebKit discards, and the line has been inert since.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh
dcalhoun added a commit that referenced this pull request Sep 30, 2026
…script

The trailing `"done";` dates from #14, when the configuration was injected
with `evaluateJavaScript`, which needed a serializable trailing expression.
#15 moved the script to a document-start `WKUserScript`, whose completion
value WebKit discards, and the line has been inert since.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh
dcalhoun added a commit that referenced this pull request Sep 30, 2026
* refactor: read the editor configuration from the injected global only

`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

* fix(ios): stop persisting the editor configuration

`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

* fix(android): stop persisting the editor configuration

`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

* docs: describe where the local server's token lives

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

* docs(android): correct the CORS rationale's origin premise

The comment justified `*` partly by claiming the editor loads from
file:// (Origin null) and so can't be allowlisted. That holds on iOS,
but the Android editor has loaded from the site's own origin since #181,
where echoing the origin would be perfectly possible.

Name the document, not the origin, as what scopes the token: same-origin
site pages exist on Android, and it is the per-document JS global that
keeps them from reading it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh

* refactor(ios): drop the dead completion value from the configuration script

The trailing `"done";` dates from #14, when the configuration was injected
with `evaluateJavaScript`, which needed a serializable trailing expression.
#15 moved the script to a document-start `WKUserScript`, whose completion
value WebKit discards, and the line has been inert since.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh

* test: cover getGBKit's injected-global-only contract

`getGBKit` now ignores any persisted copy, but nothing held that contract
in place: the suite only ever exercised it through `window.GBKit`, so
restoring the storage fallback would have left every test green.

Verified as a tripwire — reinstating the fallback fails the second case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh

* docs: say when the configuration scrub runs

The iOS comment promised that an upgraded device "is scrubbed" without
saying this only happens on the next editor load, and left no signal for
when the migration can be dropped.

Document `clearConfig` as teardown-only: with the storage fallback gone,
`window.GBKit` is the editor's only source of configuration, so clearing
it under a live editor now leaves that editor unusable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zAv5Tqtqr1bcYWVDJHGAh

* docs: rest the CORS rationale on the token alone

Both comments claimed no other document can read the editor's global, which overstated the guarantee and disagreed across platforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEok5vK3cCWGfcQp8zEGWW

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants