docs(oauth): scope what the refresh-token opt-out actually changes
Copilot review on #2114. The setting was described as taking effect "immediately", which is wrong twice over. `applyLiveServerSettings` treats OAuth as connection-time-only, so a connected client keeps the metadata it was built with — deliberately, and identically to every other field in that section (client id, secret, scopes, authorizationParams, endpoint overrides). Not wiring this one field live; saying "next connect" instead, in the docs, the checkbox description, and the type. And two pieces of state outlive the setting: the registration already held at the authorization server still lists the grant, and a refresh token issued earlier stays usable, because the SDK's `refreshAuthorization()` posts the stored token without consulting `grant_types`. So the stated cost is not guaranteed until stored OAuth state is cleared. Documented, rather than revoking credentials as a side effect of a checkbox — Clear stored OAuth state already does that explicitly. Also adds the manager->provider seam test the other bridges have: without it, deleting `requestRefreshToken:` from `createOAuthProvider` would leave the feature dead with every other test green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hzwzS8UvBsr4yZm7o7sev Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
e2fb78d999
commit
f6fca59624
2 changed files with 38 additions and 3 deletions
|
|
@ -883,7 +883,7 @@ export function ServerSettingsForm({
|
|||
/>
|
||||
<Checkbox
|
||||
label="Request refresh token"
|
||||
description="When checked, the Inspector registers with the refresh_token grant so it can renew access tokens without a new sign-in. Uncheck it for authorization servers where that grant forces an unwanted consent prompt — the SDK adds offline_access to the requested scope whenever the grant is declared, and then prompt=consent to the authorization request. On Microsoft Entra ID that routes a non-admin user into the admin-consent workflow (AADSTS90094) even after a tenant admin has consented."
|
||||
description="When checked, the Inspector registers with the refresh_token grant so it can renew access tokens without a new sign-in. Uncheck it for authorization servers where that grant forces an unwanted consent prompt — the SDK adds offline_access to the requested scope whenever the grant is declared, and then prompt=consent to the authorization request. On Microsoft Entra ID that routes a non-admin user into the admin-consent workflow (AADSTS90094) even after a tenant admin has consented. Applies on the next connect. Unchecking it does not revoke a refresh token already issued, nor the grant already registered at the authorization server — use Clear stored OAuth state below for that."
|
||||
checked={settings.oauthRequestRefreshToken ?? true}
|
||||
onChange={(e) =>
|
||||
onOAuthChange({
|
||||
|
|
|
|||
|
|
@ -1687,6 +1687,32 @@ describe("OAuthManager", () => {
|
|||
expect(navigated.searchParams.get("state")).toBe("xyz");
|
||||
});
|
||||
|
||||
// #2068 — the manager→provider bridge for the refresh-token opt-out. Same
|
||||
// gap as the authorizationParams case above: the provider test constructs
|
||||
// `BaseOAuthClientProvider` directly and the runner test stops at the
|
||||
// options object, so deleting `requestRefreshToken:` from
|
||||
// `createOAuthProvider` would leave the feature dead with every other test
|
||||
// still green.
|
||||
it("forwards the refresh-token opt-out to the provider it builds", async () => {
|
||||
const manager = new OAuthManager(createMockParams());
|
||||
manager.setOAuthConfig({ requestRefreshToken: false });
|
||||
|
||||
const provider = await manager.createOAuthProviderForTransport();
|
||||
expect(provider.clientMetadata.grant_types).toEqual([
|
||||
"authorization_code",
|
||||
]);
|
||||
});
|
||||
|
||||
it("declares the refresh_token grant when the opt-out is not configured", async () => {
|
||||
const manager = new OAuthManager(createMockParams());
|
||||
|
||||
const provider = await manager.createOAuthProviderForTransport();
|
||||
expect(provider.clientMetadata.grant_types).toEqual([
|
||||
"authorization_code",
|
||||
"refresh_token",
|
||||
]);
|
||||
});
|
||||
|
||||
it("drops a reserved key configured on the manager", async () => {
|
||||
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const params = createMockParams();
|
||||
|
|
|
|||
Loading…
Reference in a new issue