- Shipped
- September 4, 2026 at 11:40 PM UTC
- Author
- Kamo
- Commit
- 8b44eb3
An organization that brought its own Google or Entra app registered that app in its own account, under its own brand, and is now told on its settings screen to authorize api.<its own domain>. This makes the service send that. Both legs go through one chooser, because they have to agree: the value on the authorization request and the value replayed on the token exchange must be byte-identical or the provider rejects the exchange. The callback leg is public and sessionless — the browser arrives from the provider with no Kamo session — so the organization comes out of `state`, which is why orgIdFromState exists alongside providerFromState. Gated on the org owning the client, and that gate is not incidental. Kamo's platform registration holds exactly one redirect URI, on the platform host; sending a per-org address against it is a redirect_uri_mismatch the org cannot fix from anywhere inside Kamo, because they do not own that Google project. hasOrgOwnClient is the same question PlatformOAuthClientResolver answers when it picks which client id to send, so the credential and the redirect can never disagree about which app is connecting. Only the authority is rewritten, so GOOGLE_OAUTH_REDIRECT_URI keeps its path and its scheme. OAuthRedirectUriTest calls the controller's own private chooser rather than restating it, and pins the configured defaults against OAuthCallbackPaths — the table the settings screen reads. That guard is the point of the test file: if the two drift, nothing here fails. It fails inside Google, weeks later, for an organization that copied a string off a screen that was already wrong. It also caught the one real bug in this change: platformProviderFor switches on the enum, and a switch over a null enum throws rather than falling to its default arm — so a callback whose state would not decode took an NPE on the way to its own error page.