fix: recover from expired enterprise auth on remote config load (#31661)

This commit is contained in:
Ayush Thakur 2026-06-10 20:32:09 +05:30 committed by GitHub
commit 02608a4e97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 67 additions and 7 deletions

View file

@ -1,6 +1,7 @@
import { test, expect, describe, afterEach, beforeEach, spyOn } from "bun:test"
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
import { Effect, Exit, Layer, Option } from "effect"
import { Cause, Effect, Exit, Layer, Option } from "effect"
import { NamedError } from "@opencode-ai/core/util/error"
import { FetchHttpClient, HttpClient, HttpClientResponse } from "effect/unstable/http"
import { NodeFileSystem, NodePath } from "@effect/platform-node"
import { Config } from "@/config/config"
@ -71,6 +72,7 @@ const wellKnownAuth = (url: string) =>
function remoteConfigClient(input: {
wellKnown: unknown
remote?: unknown
remoteHtml?: string
seen: { wellKnown?: string; remote?: string; authorization?: string }
}) {
return HttpClient.make((request) => {
@ -78,9 +80,17 @@ function remoteConfigClient(input: {
input.seen.wellKnown = request.url
return Effect.succeed(json(request, input.wellKnown))
}
if (input.remote !== undefined && request.url.includes("config.example.com")) {
if (request.url.includes("config.example.com") && (input.remote !== undefined || input.remoteHtml !== undefined)) {
input.seen.remote = request.url
input.seen.authorization = request.headers.authorization
if (input.remoteHtml !== undefined) {
return Effect.succeed(
HttpClientResponse.fromWeb(
request,
new Response(input.remoteHtml, { status: 200, headers: { "content-type": "text/html; charset=utf-8" } }),
),
)
}
return Effect.succeed(json(request, input.remote))
}
return Effect.succeed(json(request, {}, 404))
@ -214,6 +224,7 @@ const wellKnown = (input: {
config?: unknown
remoteConfig?: { url: string; headers?: Record<string, string> }
remote?: unknown
remoteHtml?: string
wellKnown?: unknown
}) => {
const seen: { wellKnown?: string; remote?: string; authorization?: string } = {}
@ -224,6 +235,7 @@ const wellKnown = (input: {
...(input.remoteConfig !== undefined ? { remote_config: input.remoteConfig } : {}),
},
remote: input.remote,
remoteHtml: input.remoteHtml,
})
return {
seen,
@ -1635,6 +1647,24 @@ invalidRemoteWellKnown.it.instance("wellknown remote_config rejects non-object c
}),
)
const loginPageWellKnown = wellKnown({
remoteConfig: { url: "https://config.example.com/opencode.json" },
remoteHtml: "<!DOCTYPE html><html><head><title>Sign in</title></head><body>Login required</body></html>",
})
loginPageWellKnown.it.instance(
"wellknown remote_config surfaces an actionable auth error when the gateway returns an HTML login page",
() =>
Effect.gen(function* () {
const exit = yield* Config.use.get().pipe(Effect.exit)
expect(loginPageWellKnown.seen.remote).toBe("https://config.example.com/opencode.json")
expect(Exit.isFailure(exit)).toBe(true)
const error = Exit.isFailure(exit) ? Cause.squash(exit.cause) : undefined
expect(NamedError.hasName(error, "ConfigRemoteAuthError")).toBe(true)
expect((error as { data?: { url?: string } }).data?.url).toBe("https://example.com")
}),
)
describe("resolvePluginSpec", () => {
test("keeps package specs unchanged", async () => {
await using tmp = await tmpdir()