diff --git a/CHANGELOG.md b/CHANGELOG.md index a4f1edb4d8..4e351eb68f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ from published versions since it shows up in the VS Code extension changelog tab and is confusing to users. Add it back between releases if needed. --> +## Unreleased + +### Changed + +- Rename `coder.experimental.oauth` to `coder.oauth.enabled` now that OAuth is + generally available. Existing values remain effective until the new setting is + explicitly set in user settings. OAuth remains disabled by default. + ## [v1.17.0](https://github.com/coder/vscode-coder/releases/tag/v1.17.0) 2026-10-13 ### Added diff --git a/package.json b/package.json index bc49d8444f..d22f6df183 100644 --- a/package.json +++ b/package.json @@ -183,13 +183,11 @@ "default": false, "scope": "application" }, - "coder.experimental.oauth": { - "markdownDescription": "Enable [OAuth 2.1](https://coder.com/docs/admin/integrations/oauth2-provider) authentication. When enabled, you'll be prompted to choose between OAuth and session token authentication during login. OAuth provides automatic token refresh, eliminating the need to manually re-authenticate when your session expires.", + "coder.oauth.enabled": { + "markdownDescription": "Offer [OAuth 2.1](https://coder.com/docs/admin/integrations/oauth2-provider) authentication during login when supported by the deployment. OAuth provides automatic token refresh.", "type": "boolean", "default": false, - "tags": [ - "experimental" - ] + "scope": "application" }, "coder.sshFlags": { "markdownDescription": "Additional flags to pass to the `coder ssh` command when establishing SSH connections. Enter each flag as a separate array item; values are passed verbatim and in order. See the [CLI ssh reference](https://coder.com/docs/reference/cli/ssh) for available flags.\n\nNote: `--network-info-dir` and `--ssh-host-prefix` are ignored (managed internally). Prefer `#coder.proxyLogDirectory#` over `--log-dir`/`-l` for full functionality.", diff --git a/src/supportBundle/settings.ts b/src/supportBundle/settings.ts index db68e4eda1..d13d6b6fc4 100644 --- a/src/supportBundle/settings.ts +++ b/src/supportBundle/settings.ts @@ -23,10 +23,10 @@ const COLLECTED_SETTINGS: readonly string[] = [ "coder.disableSignatureVerification", "coder.disableUpdateNotifications", "coder.enableDownloads", - "coder.experimental.oauth", "coder.httpClientLogLevel", "coder.insecure", "coder.networkThreshold.latencyMs", + "coder.oauth.enabled", "coder.proxyBypass", "coder.proxyLogDirectory", "coder.sshConfig", diff --git a/src/ui/prompts.ts b/src/ui/prompts.ts index 8f0b2585f9..942a999375 100644 --- a/src/ui/prompts.ts +++ b/src/ui/prompts.ts @@ -150,11 +150,12 @@ export async function maybeAskAuthMethod( client: CoderApi, logger: Logger, ): Promise { - const experimentalOAuthEnabled = vscode.workspace - .getConfiguration() - .get("coder.experimental.oauth", false); + const config = vscode.workspace.getConfiguration(); + const oauthEnabled = + config.inspect("coder.oauth.enabled")?.globalValue ?? + config.get("coder.experimental.oauth", false); - if (!experimentalOAuthEnabled) { + if (!oauthEnabled) { return "legacy"; } diff --git a/test/unit/supportBundle/settings.test.ts b/test/unit/supportBundle/settings.test.ts index 43f4c9abe0..41f99269f2 100644 --- a/test/unit/supportBundle/settings.test.ts +++ b/test/unit/supportBundle/settings.test.ts @@ -48,6 +48,7 @@ describe("collectSettingsFile", () => { "coder.defaultUrl": "https://coder.example.com", "coder.proxyLogDirectory": "/home/user/.coder/logs", "coder.insecure": true, + "coder.oauth.enabled": true, "coder.httpClientLogLevel": "debug", }, { @@ -77,6 +78,7 @@ describe("collectSettingsFile", () => { globalValue: "/home/user/.coder/logs", }, "coder.insecure": { defaultValue: false, globalValue: true }, + "coder.oauth.enabled": { defaultValue: false, globalValue: true }, "coder.httpClientLogLevel": { defaultValue: "info", globalValue: "debug", @@ -110,6 +112,7 @@ describe("collectSettingsFile", () => { "/home/user/.coder/logs", ); expect(settings["coder.insecure"]?.effective).toBe(true); + expect(settings["coder.oauth.enabled"]?.effective).toBe(true); expect(settings["coder.httpClientLogLevel"]?.effective).toBe("debug"); }); diff --git a/test/unit/ui/prompts.test.ts b/test/unit/ui/prompts.test.ts index 91efe42437..c75d26e5eb 100644 --- a/test/unit/ui/prompts.test.ts +++ b/test/unit/ui/prompts.test.ts @@ -23,7 +23,7 @@ const client = { getAxiosInstance: vi.fn() } as unknown as CoderApi; describe("maybeAskAuthMethod", () => { beforeEach(() => { vi.clearAllMocks(); - new MockConfigurationProvider().set("coder.experimental.oauth", true); + new MockConfigurationProvider().set("coder.oauth.enabled", true); }); function mockSupport(support: OAuthSupport) { @@ -48,6 +48,34 @@ describe("maybeAskAuthMethod", () => { expect(vscode.window.showWarningMessage).not.toHaveBeenCalled(); }); + it.each([ + { enabled: undefined, oldEnabled: undefined, expected: "legacy" }, + { enabled: undefined, oldEnabled: false, expected: "legacy" }, + { enabled: undefined, oldEnabled: true, expected: "oauth" }, + { enabled: false, oldEnabled: true, expected: "legacy" }, + { enabled: true, oldEnabled: false, expected: "oauth" }, + ])( + "uses $expected with new=$enabled and old=$oldEnabled", + async ({ enabled, oldEnabled, expected }) => { + const config = new MockConfigurationProvider(); + config.setDefault("coder.oauth.enabled", false); + config.set("coder.oauth.enabled", enabled); + config.set("coder.experimental.oauth", oldEnabled); + mockSupport("supported"); + vi.mocked(vscode.window.showQuickPick).mockResolvedValue({ + label: "OAuth (Recommended)", + value: "oauth", + } as vscode.QuickPickItem); + + expect(await maybeAskAuthMethod(client, createMockLogger())).toBe( + expected, + ); + expect(OAuthMetadataClient.checkOAuthSupport).toHaveBeenCalledTimes( + expected === "oauth" ? 1 : 0, + ); + }, + ); + it("asks for the method when OAuth is supported", async () => { mockSupport("supported"); vi.mocked(vscode.window.showQuickPick).mockResolvedValue({