mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
fix: Resolve expressions in credentials following paired item (#8250)
## Summary Fixes the issue that pairedItem information was not available in expressions that got used in credentials ## Related tickets and issues [PAY-1207](https://linear.app/n8n/issue/PAY-1207/paireditem-expressions-not-working-correctly-in-credentials) ## Review / Merge checklist - [x] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [ ] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. > A feature is not complete without tests. --------- Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
parent
008fd5a917
commit
ccb2b076f8
|
@ -8,10 +8,14 @@ This list shows all the versions which include breaking changes and how to upgra
|
|||
|
||||
The flag `N8N_CACHE_ENABLED` was removed. The cache is now always enabled.
|
||||
|
||||
Additionally, expressions in credentials now follow the paired item, so if you have multiple input items, n8n will try to pair the matching row to fill in the credential details.
|
||||
|
||||
### When is action necessary?
|
||||
|
||||
If you are using the flag `N8N_CACHE_ENABLED`, remove it from your settings.
|
||||
|
||||
In regards to credentials, if you use expression in credentials, you might want to revisit them. Previously, n8n would stick to the first item only, but now it will try to match the proper paired item.
|
||||
|
||||
## 1.22.0
|
||||
|
||||
### What changed?
|
||||
|
|
|
@ -32,6 +32,7 @@ import type {
|
|||
INodeTypes,
|
||||
IWorkflowExecuteAdditionalData,
|
||||
ICredentialTestFunctions,
|
||||
IExecuteData,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
ICredentialsHelper,
|
||||
|
@ -339,6 +340,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
nodeCredentials: INodeCredentialsDetails,
|
||||
type: string,
|
||||
mode: WorkflowExecuteMode,
|
||||
executeData?: IExecuteData,
|
||||
raw?: boolean,
|
||||
expressionResolveValues?: ICredentialsExpressionResolveValues,
|
||||
): Promise<ICredentialDataDecryptedObject> {
|
||||
|
@ -358,6 +360,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
decryptedDataOriginal,
|
||||
type,
|
||||
mode,
|
||||
executeData,
|
||||
expressionResolveValues,
|
||||
canUseSecrets,
|
||||
);
|
||||
|
@ -371,6 +374,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
decryptedDataOriginal: ICredentialDataDecryptedObject,
|
||||
type: string,
|
||||
mode: WorkflowExecuteMode,
|
||||
executeData?: IExecuteData,
|
||||
expressionResolveValues?: ICredentialsExpressionResolveValues,
|
||||
canUseSecrets?: boolean,
|
||||
): ICredentialDataDecryptedObject {
|
||||
|
@ -412,7 +416,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
expressionResolveValues.connectionInputData,
|
||||
mode,
|
||||
additionalKeys,
|
||||
undefined,
|
||||
executeData,
|
||||
false,
|
||||
decryptedData,
|
||||
) as ICredentialDataDecryptedObject;
|
||||
|
@ -579,6 +583,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
credentialType,
|
||||
'internal' as WorkflowExecuteMode,
|
||||
undefined,
|
||||
undefined,
|
||||
user.hasGlobalScope('externalSecret:use'),
|
||||
);
|
||||
} catch (error) {
|
||||
|
|
|
@ -73,6 +73,7 @@ export abstract class AbstractOAuthController {
|
|||
credential,
|
||||
credential.type,
|
||||
'internal',
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ export class MessageEventBusDestinationWebhook
|
|||
foundCredential[1],
|
||||
foundCredential[0],
|
||||
'internal',
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
return credentialsDecrypted;
|
||||
|
|
|
@ -1882,6 +1882,7 @@ export async function getCredentials(
|
|||
type: string,
|
||||
additionalData: IWorkflowExecuteAdditionalData,
|
||||
mode: WorkflowExecuteMode,
|
||||
executeData?: IExecuteData,
|
||||
runExecutionData?: IRunExecutionData | null,
|
||||
runIndex?: number,
|
||||
connectionInputData?: INodeExecutionData[],
|
||||
|
@ -2001,6 +2002,7 @@ export async function getCredentials(
|
|||
nodeCredentials,
|
||||
type,
|
||||
mode,
|
||||
executeData,
|
||||
false,
|
||||
expressionResolveValues,
|
||||
);
|
||||
|
@ -3149,6 +3151,7 @@ export function getExecuteFunctions(
|
|||
type,
|
||||
additionalData,
|
||||
mode,
|
||||
executeData,
|
||||
runExecutionData,
|
||||
runIndex,
|
||||
connectionInputData,
|
||||
|
@ -3281,6 +3284,7 @@ export function getExecuteFunctions(
|
|||
key,
|
||||
additionalData,
|
||||
mode,
|
||||
executeData,
|
||||
runExecutionData,
|
||||
runIndex,
|
||||
connectionInputData,
|
||||
|
@ -3608,6 +3612,7 @@ export function getExecuteSingleFunctions(
|
|||
type,
|
||||
additionalData,
|
||||
mode,
|
||||
executeData,
|
||||
runExecutionData,
|
||||
runIndex,
|
||||
connectionInputData,
|
||||
|
|
|
@ -1221,44 +1221,6 @@ export class HttpRequestV3 implements INodeType {
|
|||
let nodeCredentialType: string | undefined;
|
||||
let genericCredentialType: string | undefined;
|
||||
|
||||
if (authentication === 'genericCredentialType') {
|
||||
genericCredentialType = this.getNodeParameter('genericAuthType', 0) as string;
|
||||
|
||||
if (genericCredentialType === 'httpBasicAuth') {
|
||||
try {
|
||||
httpBasicAuth = await this.getCredentials('httpBasicAuth');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpDigestAuth') {
|
||||
try {
|
||||
httpDigestAuth = await this.getCredentials('httpDigestAuth');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpHeaderAuth') {
|
||||
try {
|
||||
httpHeaderAuth = await this.getCredentials('httpHeaderAuth');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpQueryAuth') {
|
||||
try {
|
||||
httpQueryAuth = await this.getCredentials('httpQueryAuth');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpCustomAuth') {
|
||||
try {
|
||||
httpCustomAuth = await this.getCredentials('httpCustomAuth');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'oAuth1Api') {
|
||||
try {
|
||||
oAuth1Api = await this.getCredentials('oAuth1Api');
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'oAuth2Api') {
|
||||
try {
|
||||
oAuth2Api = await this.getCredentials('oAuth2Api');
|
||||
} catch {}
|
||||
}
|
||||
} else if (authentication === 'predefinedCredentialType') {
|
||||
try {
|
||||
nodeCredentialType = this.getNodeParameter('nodeCredentialType', 0) as string;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
type RequestOptions = OptionsWithUri & { useStream?: boolean };
|
||||
let requestOptions: RequestOptions = {
|
||||
uri: '',
|
||||
|
@ -1293,6 +1255,44 @@ export class HttpRequestV3 implements INodeType {
|
|||
};
|
||||
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
if (authentication === 'genericCredentialType') {
|
||||
genericCredentialType = this.getNodeParameter('genericAuthType', 0) as string;
|
||||
|
||||
if (genericCredentialType === 'httpBasicAuth') {
|
||||
try {
|
||||
httpBasicAuth = await this.getCredentials('httpBasicAuth', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpDigestAuth') {
|
||||
try {
|
||||
httpDigestAuth = await this.getCredentials('httpDigestAuth', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpHeaderAuth') {
|
||||
try {
|
||||
httpHeaderAuth = await this.getCredentials('httpHeaderAuth', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpQueryAuth') {
|
||||
try {
|
||||
httpQueryAuth = await this.getCredentials('httpQueryAuth', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'httpCustomAuth') {
|
||||
try {
|
||||
httpCustomAuth = await this.getCredentials('httpCustomAuth', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'oAuth1Api') {
|
||||
try {
|
||||
oAuth1Api = await this.getCredentials('oAuth1Api', itemIndex);
|
||||
} catch {}
|
||||
} else if (genericCredentialType === 'oAuth2Api') {
|
||||
try {
|
||||
oAuth2Api = await this.getCredentials('oAuth2Api', itemIndex);
|
||||
} catch {}
|
||||
}
|
||||
} else if (authentication === 'predefinedCredentialType') {
|
||||
try {
|
||||
nodeCredentialType = this.getNodeParameter('nodeCredentialType', 0) as string;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const requestMethod = this.getNodeParameter('method', itemIndex) as string;
|
||||
|
||||
const sendQuery = this.getNodeParameter('sendQuery', itemIndex, false) as boolean;
|
||||
|
|
|
@ -217,6 +217,7 @@ export abstract class ICredentialsHelper {
|
|||
nodeCredentials: INodeCredentialsDetails,
|
||||
type: string,
|
||||
mode: WorkflowExecuteMode,
|
||||
executeData?: IExecuteData,
|
||||
raw?: boolean,
|
||||
expressionResolveValues?: ICredentialsExpressionResolveValues,
|
||||
): Promise<ICredentialDataDecryptedObject>;
|
||||
|
|
Loading…
Reference in a new issue