mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(core): Add "Client Credentials" grant type to OAuth2 (#3489)
* ⚡ Add OAuth2 client credentials grant type * ⚡ Improvements * 🐛 Fix linting issue * 🐛 Fix typo * 🐛 Fix small issue with type * 🐛 When token expire get a new one instead of refreshing it * ⚡ Fix issue that it did not display it correctly for OAuth1 Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
@@ -57,6 +57,8 @@ import {
|
||||
WorkflowExecuteMode,
|
||||
LoggerProxy as Logger,
|
||||
IExecuteData,
|
||||
OAuth2GrantType,
|
||||
IOAuth2Credentials,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { Agent } from 'https';
|
||||
@@ -881,19 +883,46 @@ export async function requestOAuth2(
|
||||
oAuth2Options?: IOAuth2Options,
|
||||
isN8nRequest = false,
|
||||
) {
|
||||
const credentials = await this.getCredentials(credentialsType);
|
||||
const credentials = (await this.getCredentials(credentialsType)) as unknown as IOAuth2Credentials;
|
||||
|
||||
if (credentials.oauthTokenData === undefined) {
|
||||
// Only the OAuth2 with authorization code grant needs connection
|
||||
if (
|
||||
credentials.grantType === OAuth2GrantType.authorizationCode &&
|
||||
credentials.oauthTokenData === undefined
|
||||
) {
|
||||
throw new Error('OAuth credentials not connected!');
|
||||
}
|
||||
|
||||
const oAuthClient = new clientOAuth2({
|
||||
clientId: credentials.clientId as string,
|
||||
clientSecret: credentials.clientSecret as string,
|
||||
accessTokenUri: credentials.accessTokenUrl as string,
|
||||
clientId: credentials.clientId,
|
||||
clientSecret: credentials.clientSecret,
|
||||
accessTokenUri: credentials.accessTokenUrl,
|
||||
scopes: credentials.scope.split(' '),
|
||||
});
|
||||
|
||||
const oauthTokenData = credentials.oauthTokenData as clientOAuth2.Data;
|
||||
let oauthTokenData = credentials.oauthTokenData as clientOAuth2.Data;
|
||||
// if it's the first time using the credentials, get the access token and save it into the DB.
|
||||
if (credentials.grantType === OAuth2GrantType.clientCredentials && oauthTokenData === undefined) {
|
||||
const { data } = await oAuthClient.credentials.getToken();
|
||||
|
||||
// Find the credentials
|
||||
if (!node.credentials || !node.credentials[credentialsType]) {
|
||||
throw new Error(
|
||||
`The node "${node.name}" does not have credentials of type "${credentialsType}"!`,
|
||||
);
|
||||
}
|
||||
|
||||
const nodeCredentials = node.credentials[credentialsType];
|
||||
|
||||
// Save the refreshed token
|
||||
await additionalData.credentialsHelper.updateCredentials(
|
||||
nodeCredentials,
|
||||
credentialsType,
|
||||
credentials as unknown as ICredentialDataDecryptedObject,
|
||||
);
|
||||
|
||||
oauthTokenData = data;
|
||||
}
|
||||
|
||||
const token = oAuthClient.createToken(
|
||||
get(oauthTokenData, oAuth2Options?.property as string) || oauthTokenData.accessToken,
|
||||
@@ -926,8 +955,8 @@ export async function requestOAuth2(
|
||||
|
||||
if (oAuth2Options?.includeCredentialsOnRefreshOnBody) {
|
||||
const body: IDataObject = {
|
||||
client_id: credentials.clientId as string,
|
||||
client_secret: credentials.clientSecret as string,
|
||||
client_id: credentials.clientId,
|
||||
client_secret: credentials.clientSecret,
|
||||
};
|
||||
tokenRefreshOptions.body = body;
|
||||
// Override authorization property so the credentails are not included in it
|
||||
@@ -940,7 +969,15 @@ export async function requestOAuth2(
|
||||
`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Should revalidate.`,
|
||||
);
|
||||
|
||||
const newToken = await token.refresh(tokenRefreshOptions);
|
||||
let newToken;
|
||||
|
||||
// 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.`,
|
||||
@@ -960,7 +997,7 @@ export async function requestOAuth2(
|
||||
await additionalData.credentialsHelper.updateCredentials(
|
||||
nodeCredentials,
|
||||
credentialsType,
|
||||
credentials,
|
||||
credentials as unknown as ICredentialDataDecryptedObject,
|
||||
);
|
||||
|
||||
Logger.debug(
|
||||
|
||||
Reference in New Issue
Block a user