Skip to content

Commit 706b84c

Browse files
BYKcodex
andcommitted
fix(cli): Report the refresh request host on connection errors
Use the actual request origin in network and TLS diagnostics so self-hosted refresh failures identify the instance that failed. Co-Authored-By: OpenAI gpt-6-sol <noreply@openai.com>
1 parent 316c0fb commit 706b84c

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

‎packages/cli/src/lib/oauth.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,12 @@ async function fetchWithConnectionError(
215215
if (!(error instanceof Error)) {
216216
throw error;
217217
}
218+
const targetOrigin = new URL(url).origin;
218219

219220
// TLS certificate errors — give actionable guidance
220221
if (isTlsCertError(error)) {
221222
throw new ApiError(
222-
`TLS certificate error connecting to ${getSentryUrl()}`,
223+
`TLS certificate error connecting to ${targetOrigin}`,
223224
0,
224225
buildTlsErrorDetail(error)
225226
);
@@ -232,7 +233,7 @@ async function fetchWithConnectionError(
232233

233234
if (isConnectionError) {
234235
throw new ApiError(
235-
`Cannot connect to Sentry at ${getSentryUrl()}`,
236+
`Cannot connect to Sentry at ${targetOrigin}`,
236237
0,
237238
"Check your network connection and SENTRY_URL configuration"
238239
);

‎packages/cli/test/lib/security/refresh-token-poison.test.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,26 @@ describe("CVE defense-in-depth: refresh token", () => {
8787
expect(fetchCalls).toHaveLength(1);
8888
expect(fetchCalls[0]).toBe("https://sentry.example.com/oauth/token/");
8989
});
90+
91+
test.each([
92+
["network", new Error("fetch failed"), "Cannot connect to Sentry at"],
93+
[
94+
"TLS",
95+
new Error("unable to verify the first certificate"),
96+
"TLS certificate error connecting to",
97+
],
98+
])("%s refresh failure names the credential host", async (_, failure, prefix) => {
99+
delete process.env.SENTRY_HOST;
100+
delete process.env.SENTRY_URL;
101+
const credentialHost = "https://sentry.example.com:8443";
102+
globalThis.fetch = (async (input: RequestInfo | URL) => {
103+
fetchCalls.push(extractFetchUrl(input));
104+
throw failure;
105+
}) as typeof fetch;
106+
107+
await expect(
108+
refreshAccessToken("fake-refresh-token", { credentialHost })
109+
).rejects.toThrow(`${prefix} ${credentialHost}`);
110+
expect(fetchCalls).toEqual([`${credentialHost}/oauth/token/`]);
111+
});
90112
});

0 commit comments

Comments
 (0)