fix(HTTP Request Node): Include UI query parameters when signing AWS requests (#33679)

This commit is contained in:
Stephen Wright
2026-07-07 12:18:49 +01:00
committed by GitHub
parent 381d5bf3bd
commit 36a834d23d
2 changed files with 63 additions and 0 deletions
@@ -665,4 +665,63 @@ describe('awsGetSignInOptionsAndUpdateRequest', () => {
),
).toThrow(UserError);
});
it('signs and sends UI Query Parameters supplied via qs (not only qs.query)', () => {
const { url, signOpts } = awsGetSignInOptionsAndUpdateRequest(
{
uri: 'https://bedrock.us-east-1.amazonaws.com/foundation-models',
qs: { byProvider: 'anthropic', byOutputModality: 'TEXT' },
headers: {},
} as any,
baseCredentials,
'',
'GET',
'bedrock',
'us-east-1',
);
// Present in the outgoing URL...
const sentUrl = new URL(url);
expect(sentUrl.searchParams.get('byProvider')).toBe('anthropic');
expect(sentUrl.searchParams.get('byOutputModality')).toBe('TEXT');
// ...and in the signed path, so they are part of the SigV4 canonical request.
expect(signOpts.path).toContain('byProvider=anthropic');
expect(signOpts.path).toContain('byOutputModality=TEXT');
});
it('keeps query parameters embedded directly in the URL', () => {
const { url, signOpts } = awsGetSignInOptionsAndUpdateRequest(
{
uri: 'https://bedrock.us-east-1.amazonaws.com/foundation-models?byProvider=amazon',
headers: {},
} as any,
baseCredentials,
'',
'GET',
'bedrock',
'us-east-1',
);
expect(new URL(url).searchParams.get('byProvider')).toBe('amazon');
expect(signOpts.path).toContain('byProvider=amazon');
});
it('preserves the STS GetCallerIdentity special case', () => {
const { url } = awsGetSignInOptionsAndUpdateRequest(
{
uri: 'https://sts.us-east-1.amazonaws.com/',
qs: { Action: 'GetCallerIdentity' },
headers: {},
} as any,
baseCredentials,
'',
'POST',
'sts',
'us-east-1',
);
const sentUrl = new URL(url);
expect(sentUrl.searchParams.get('Action')).toBe('GetCallerIdentity');
expect(sentUrl.searchParams.get('Version')).toBe('2011-06-15');
});
});
@@ -250,6 +250,10 @@ export function awsGetSignInOptionsAndUpdateRequest(
} catch (err) {
console.error(err);
}
} else {
// UI Query Parameters are stored at the top level of requestOptions.qs, not under
// a nested `query` key, so merge the whole object to sign and send them.
query = requestWithUri.qs as IDataObject;
}
const parsed = parseAwsUrl(endpoint);
service = parsed.service;