fix(AWS Nodes): Handle query string and body properly for AWS related requests (#4039)

This commit is contained in:
Omar Ajoue 2022-09-06 14:33:52 +02:00 committed by GitHub
parent 637863ea02
commit 103f04e4eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 35 deletions

View file

@ -1461,19 +1461,19 @@ export async function requestWithAuthentication(
// make the updated property in the credentials // make the updated property in the credentials
// available to the authenticate method // available to the authenticate method
Object.assign(credentialsDecrypted, data); Object.assign(credentialsDecrypted, data);
requestOptions = await additionalData.credentialsHelper.authenticate(
credentialsDecrypted,
credentialsType,
requestOptions as IHttpRequestOptions,
workflow,
node,
additionalData.timezone,
);
// retry the request
return await proxyRequestToAxios(requestOptions as IDataObject);
} }
requestOptions = await additionalData.credentialsHelper.authenticate(
credentialsDecrypted,
credentialsType,
requestOptions as IHttpRequestOptions,
workflow,
node,
additionalData.timezone,
);
} }
// retry the request throw error;
return await proxyRequestToAxios(requestOptions as IDataObject);
} catch (error) { } catch (error) {
throw new NodeApiError(this.getNode(), error); throw new NodeApiError(this.getNode(), error);
} }

View file

@ -272,7 +272,7 @@ export class Aws implements ICredentialType {
credentials: ICredentialDataDecryptedObject, credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions, requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> { ): Promise<IHttpRequestOptions> {
let endpoint; let endpoint: URL;
let service = requestOptions.qs?.service as string; let service = requestOptions.qs?.service as string;
let path = requestOptions.qs?.path; let path = requestOptions.qs?.path;
const method = requestOptions.method; const method = requestOptions.method;
@ -280,27 +280,28 @@ export class Aws implements ICredentialType {
let region = credentials.region; let region = credentials.region;
const query = requestOptions.qs?.query as IDataObject; const query = requestOptions.qs?.query as IDataObject;
if (!requestOptions.baseURL && !requestOptions.url) { if (!requestOptions.baseURL && !requestOptions.url) {
let endpointString: string;
if (service === 'lambda' && credentials.lambdaEndpoint) { if (service === 'lambda' && credentials.lambdaEndpoint) {
endpoint = credentials.lambdaEndpoint; endpointString = credentials.lambdaEndpoint as string;
} else if (service === 'sns' && credentials.snsEndpoint) { } else if (service === 'sns' && credentials.snsEndpoint) {
endpoint = credentials.snsEndpoint; endpointString = credentials.snsEndpoint as string;
} else if (service === 'sqs' && credentials.sqsEndpoint) { } else if (service === 'sqs' && credentials.sqsEndpoint) {
endpoint = credentials.sqsEndpoint; endpointString = credentials.sqsEndpoint as string;
} else if (service === 's3' && credentials.s3Endpoint) { } else if (service === 's3' && credentials.s3Endpoint) {
endpoint = credentials.s3Endpoint; endpointString = credentials.s3Endpoint as string;
} else if (service === 'ses' && credentials.sesEndpoint) { } else if (service === 'ses' && credentials.sesEndpoint) {
endpoint = credentials.sesEndpoint; endpointString = credentials.sesEndpoint as string;
} else if (service === 'rekognition' && credentials.rekognitionEndpoint) { } else if (service === 'rekognition' && credentials.rekognitionEndpoint) {
endpoint = credentials.rekognitionEndpoint; endpointString = credentials.rekognitionEndpoint as string;
} else if (service === 'sqs' && credentials.sqsEndpoint) { } else if (service === 'sqs' && credentials.sqsEndpoint) {
endpoint = credentials.sqsEndpoint; endpointString = credentials.sqsEndpoint as string;
} else if (service) { } else if (service) {
endpoint = `https://${service}.${credentials.region}.amazonaws.com`; endpointString = `https://${service}.${credentials.region}.amazonaws.com`;
} }
endpoint = new URL((endpoint as string).replace('{region}', credentials.region as string)); endpoint = new URL(endpointString!.replace('{region}', credentials.region as string) + path);
} else { } else {
// If no endpoint is set, we try to decompose the path and use the default endpoint // If no endpoint is set, we try to decompose the path and use the default endpoint
const customUrl = new URL(requestOptions.baseURL! + requestOptions.url!); const customUrl = new URL(requestOptions.baseURL! + requestOptions.url! + path);
service = customUrl.hostname.split('.')[0] as string; service = customUrl.hostname.split('.')[0] as string;
region = customUrl.hostname.split('.')[1] as string; region = customUrl.hostname.split('.')[1] as string;
if (service === 'sts') { if (service === 'sts') {
@ -311,19 +312,24 @@ export class Aws implements ICredentialType {
console.log(err); console.log(err);
} }
} }
path = customUrl.pathname as string;
endpoint = customUrl; endpoint = customUrl;
} }
if (service.includes('.s3')) {
path = `${endpoint.pathname}?${queryToString(query).replace(/\+/g, '%2B')}`; if (query && Object.keys(query).length !== 0) {
Object.keys(query).forEach((key) => {
endpoint.searchParams.append(key, query[key] as string);
});
} }
path = endpoint.pathname + endpoint.search;
const signOpts = { const signOpts = {
headers: requestOptions.headers, ...requestOptions,
headers: requestOptions.headers ?? {},
host: endpoint.host, host: endpoint.host,
method, method,
path, path,
body, body: body !== '' ? body : undefined,
region, region,
} as Request; } as Request;
@ -340,10 +346,12 @@ export class Aws implements ICredentialType {
console.log(err); console.log(err);
} }
const options: IHttpRequestOptions = { const options: IHttpRequestOptions = {
...requestOptions,
headers: signOpts.headers, headers: signOpts.headers,
method, method,
url: endpoint.origin + path, url: endpoint.origin + path,
body: signOpts.body, body: signOpts.body,
qs: undefined, // override since it's already in the url
}; };
return options; return options;

View file

@ -1,11 +1,5 @@
import { URL } from 'url';
import { Request, sign } from 'aws4';
import { get } from 'lodash'; import { get } from 'lodash';
import { OptionsWithUri } from 'request';
import { parseString } from 'xml2js'; import { parseString } from 'xml2js';
import { import {
@ -20,7 +14,6 @@ import {
IHttpRequestOptions, IHttpRequestOptions,
JsonObject, JsonObject,
NodeApiError, NodeApiError,
NodeOperationError,
} from 'n8n-workflow'; } from 'n8n-workflow';
export async function awsApiRequest( export async function awsApiRequest(
@ -44,7 +37,7 @@ export async function awsApiRequest(
query, query,
}, },
method, method,
body: JSON.stringify(body), body,
url: '', url: '',
headers, headers,
//region: credentials?.region as string, //region: credentials?.region as string,