Route the application-passwords list screen through Basic auth#22894
Open
jkmassel wants to merge 2 commits into
Open
Route the application-passwords list screen through Basic auth#22894jkmassel wants to merge 2 commits into
jkmassel wants to merge 2 commits into
Conversation
Companion to `getWpApiClient` that always returns a direct-host Basic-auth client built from the SiteModel's application-password credentials, regardless of WP.com routing. `getWpApiClient` sends WPCom-flagged sites (including Atomic) through the bearer-token path and the WP.com REST proxy, which doesn't expose all of the application-password-authenticated routes. The list-screen change in the next commit needs to talk to the direct host; the auto-mint + validator work in the headless-creation PR uses this same method.
`ApplicationPasswordsViewModel.getApplicationPasswordsList` called `WpApiClientProvider.getWpApiClient(site)`, which for any WPCom-flagged site (including Atomic) routes through the WP.com REST proxy. That proxy doesn't expose the `application-passwords` routes — every request 404s with `rest_no_route`, the same upstream wordpress-rs limitation that drove dropping the headless mint attempt in this project (Automattic/wordpress-rs#1350). As a result, the list screen appeared empty / errored on Atomic sites: `getCurrentUserId` would 404, return null, and `getApplicationPasswordsList` would early-return an empty list. Switch to `WpApiClientProvider.getApplicationPasswordClient(site)`, which always builds a direct-host Basic-auth client from the stored application-password credentials. The direct host serves the `application-passwords` routes on every WordPress install, so the listing call works for Atomic and Jetpack-WPCom-REST sites in addition to true self-hosted. For self-hosted, behavior is unchanged: both client providers route self-hosted sites through `selfHostedClients.getOrPut(site.id) { createSelfHostedClient(site, ...) }`, returning the same Basic-auth client. Precondition: the SiteModel must already have credentials — typically populated by the My Site auto-mint flow on first foreground. A user reaching the list screen without ever visiting My Site would 401 instead of seeing an empty screen. That edge case can be handled separately (e.g. by minting on demand here) and is out of scope.
Collaborator
8 tasks
Contributor
|
|
Contributor
|
|
jkmassel
added a commit
that referenced
this pull request
May 25, 2026
Fixes #22884. `ApplicationPasswordsManager.getApplicationCredentials` returned `NotSupported` for any `site.isWPCom` site. The guard was correct for Simple sites but blocked Atomic sites, which are also `isWPCom`-flagged and do support REST application-password creation. Users on Atomic saw the "Authenticate using Application Password" card on My Site and had to authorize through a Chrome Custom Tab even though the app could mint the credential on their behalf. Relax the FluxC guard from `site.isWPCom` to `site.isWPComSimpleSite` and add a uniform validate-then-mint pipeline to `ApplicationPasswordViewModelSlice`: validate stored creds via wordpress-rs Basic auth against the direct host (new `ApplicationPasswordValidator`, using `WpApiClientProvider.getApplicationPasswordClient` from #22894); on Invalid, clear them via a new `SiteStore.deleteStoredApplicationPasswordCredentials` and fall through to mint via a new `SiteStore.createApplicationPassword` (FluxC Jetpack tunnel); on mint failure, the existing discovery + card path takes over. The XML-RPC-disabled card path is now gated on `!isUsingWpComRestApi` so it only fires for true self-hosted sites. Also provides the missing `@ApplicationPasswordsClientId` Dagger binding — without it any call into `ApplicationPasswordsStore` threw `NoSuchElementException`. The path was latent on these apps until the auto-mint above started routing My Site through it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Fixes a bug where the application-passwords list screen returned an empty list / auth error on Atomic sites. Targets
trunkdirectly so it can land independently — the larger Atomic headless mint work (#22885) builds on top of this.Summary
WpApiClientProvider.getApplicationPasswordClient(site)— always returns a direct-host Basic-auth client built from the SiteModel's application-password credentials, regardless of WP.com routing.getWpApiClient(site)→getApplicationPasswordClient(site)inApplicationPasswordsViewModel.kt.Root Cause
getWpApiClientroutes WPCom-flagged sites (including Atomic) through the WP.com REST proxy athttps://public-api.wordpress.com/rest/v1.1/sites/{id}/wp/v2/.... The proxy doesn't expose theapplication-passwordsroutes — every request 404s withrest_no_route. This is the same upstream wordpress-rs limitation (Automattic/wordpress-rs#1350) that drove dropping the headless wordpress-rs mint attempt in #22885.Fix
The new method
getApplicationPasswordClientalways reuses theselfHostedClientscache path — Basic auth against the direct host using the SiteModel'sapiRestUsernamePlain/apiRestPasswordPlain. The direct host serves theapplication-passwordsroutes on every WordPress install.For self-hosted sites the behaviour is unchanged: both
getWpApiClientandgetApplicationPasswordClientend up returning the same Basic-auth client viaselfHostedClients.getOrPut(site.id). For Atomic and Jetpack-WPCom-REST sites the change is what matters — we now bypass the proxy and talk to the underlying WordPress install directly.Limitations
The SiteModel must already have application-password credentials. On a Simple WPCom site there are no such credentials and the call will 401 — but that screen isn't really meant to work on Simple sites anyway. For Atomic sites, the credentials are populated by the My Site auto-mint flow once #22885 lands; in the meantime, users on Atomic still need to authorize the first time via the Custom Tab flow.
Test plan
Related