feat(Shopify Node): Add OAuth support (#3389)

*  wip

*  Add includeAccessTokenInHeader option to OAuth2

* 🔨 fixed build error, fixed trigger node when using token auth

* 🔨 fixed trigger when using oauth2

* 🔨 changed default auth method to access token

*  Improvements

*  Improvements

*  Improvements

*  Rename includeAccessTokenInHeader to keyToIncludeInAccessTokenHeader

*  Assign values to only header property

* 🔥 Remove unreachable code

*  Add keyToIncludeInAccessTokenHeader when isN8nRequest

*  Add CC grant type when isN8nRequest

Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
Co-authored-by: Jan Oberhauser <janober@users.noreply.github.com>
This commit is contained in:
Michael Kret
2022-07-15 11:36:01 +03:00
committed by GitHub
parent 74064325c8
commit 945e25a77c
9 changed files with 333 additions and 12 deletions

View File

@@ -277,6 +277,7 @@ async function parseRequestObject(requestObject: IDataObject) {
// If we have body and possibly form
if (requestObject.form !== undefined) {
// merge both objects when exist.
// @ts-ignore
requestObject.body = Object.assign(requestObject.body, requestObject.form);
}
axiosConfig.data = requestObject.body as FormData | GenericValue | GenericValue[];
@@ -953,6 +954,13 @@ export async function requestOAuth2(
// @ts-ignore
newRequestOptions?.headers?.Authorization.split(' ')[1];
}
if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
Object.assign(newRequestOptions.headers, {
[oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
});
}
if (isN8nRequest) {
return this.helpers.httpRequest(newRequestOptions).catch(async (error: AxiosError) => {
if (error.response?.status === 401) {
@@ -970,10 +978,24 @@ export async function requestOAuth2(
Authorization: '',
};
}
const newToken = await token.refresh(tokenRefreshOptions);
let newToken;
Logger.debug(
`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`,
);
// if it's OAuth2 with client credentials grant type, get a new token
// instead of refreshing it.
if (OAuth2GrantType.clientCredentials === credentials.grantType) {
newToken = await token.client.credentials.getToken();
} else {
newToken = await token.refresh(tokenRefreshOptions);
}
Logger.debug(
`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`,
);
credentials.oauthTokenData = newToken.data;
// Find the credentials
if (!node.credentials || !node.credentials[credentialsType]) {
@@ -988,11 +1010,19 @@ export async function requestOAuth2(
credentials,
);
const refreshedRequestOption = newToken.sign(requestOptions as clientOAuth2.RequestObject);
if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
Object.assign(newRequestOptions.headers, {
[oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
});
}
return this.helpers.httpRequest(refreshedRequestOption);
}
throw error;
});
}
return this.helpers.request!(newRequestOptions).catch(async (error: IResponseError) => {
const statusCodeReturned =
oAuth2Options?.tokenExpiredStatusCode === undefined
@@ -1057,9 +1087,13 @@ export async function requestOAuth2(
// Make the request again with the new token
const newRequestOptions = newToken.sign(requestOptions as clientOAuth2.RequestObject);
if (isN8nRequest) {
return this.helpers.httpRequest(newRequestOptions);
if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
Object.assign(newRequestOptions.headers, {
[oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
});
}
return this.helpers.request!(newRequestOptions);
}