fix(core): Handle invalid JSON responses from OAuth2 token endpoints (#27089)
This commit is contained in:
@@ -127,7 +127,17 @@ export class ClientOAuth2 {
|
||||
const body = response.data as string;
|
||||
|
||||
if (contentType.startsWith('application/json')) {
|
||||
return JSON.parse(body) as T;
|
||||
try {
|
||||
return JSON.parse(body) as T;
|
||||
} catch {
|
||||
const preview = body.length > 100 ? body.slice(0, 100) + '...' : body;
|
||||
throw new ResponseError(
|
||||
response.status,
|
||||
body,
|
||||
undefined,
|
||||
`Expected JSON response from OAuth2 token endpoint but received: ${preview}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType.startsWith('application/x-www-form-urlencoded')) {
|
||||
|
||||
@@ -139,6 +139,38 @@ describe('ClientOAuth2', () => {
|
||||
expect(result.message).toEqual(`Unsupported content type: ${contentType}`);
|
||||
});
|
||||
|
||||
it('should throw ResponseError when application/json response contains invalid JSON', async () => {
|
||||
const htmlBody = '<!DOCTYPE html><html><body>Service Unavailable</body></html>';
|
||||
mockTokenResponse({
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: htmlBody,
|
||||
});
|
||||
|
||||
const result = await makeTokenCall().catch((err) => err);
|
||||
expect(result).toBeInstanceOf(ResponseError);
|
||||
expect(result.status).toBe(200);
|
||||
expect(result.body).toBe(htmlBody);
|
||||
expect(result.message).toContain(
|
||||
'Expected JSON response from OAuth2 token endpoint but received:',
|
||||
);
|
||||
expect(result.message).toContain('<!DOCTYPE html>');
|
||||
});
|
||||
|
||||
it('should truncate long invalid JSON response bodies in the error message', async () => {
|
||||
const longBody = 'x'.repeat(200);
|
||||
mockTokenResponse({
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: longBody,
|
||||
});
|
||||
|
||||
const result = await makeTokenCall().catch((err) => err);
|
||||
expect(result).toBeInstanceOf(ResponseError);
|
||||
expect(result.status).toBe(200);
|
||||
expect(result.message).toContain('x'.repeat(100) + '...');
|
||||
});
|
||||
|
||||
it('should reject 4xx responses with auth errors', async () => {
|
||||
mockTokenResponse({
|
||||
status: 401,
|
||||
|
||||
Reference in New Issue
Block a user