mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix: Prevent workflow breaking when credential type is unknown (#6923)
This commit is contained in:
parent
297c3c91f2
commit
e83b93f293
|
@ -91,7 +91,7 @@ export default defineComponent({
|
|||
currentUser(): IUser | null {
|
||||
return this.usersStore.currentUser;
|
||||
},
|
||||
credentialType(): ICredentialType {
|
||||
credentialType(): ICredentialType | undefined {
|
||||
return this.credentialsStore.getCredentialTypeByName(this.data.type);
|
||||
},
|
||||
credentialPermissions(): IPermissions | null {
|
||||
|
|
|
@ -304,7 +304,7 @@ export default defineComponent({
|
|||
|
||||
// If there is already selected type, use it
|
||||
if (this.selectedCredential !== '') {
|
||||
return this.credentialsStore.getCredentialTypeByName(this.selectedCredential);
|
||||
return this.credentialsStore.getCredentialTypeByName(this.selectedCredential) ?? null;
|
||||
} else if (this.requiredCredentials) {
|
||||
// Otherwise, use credential type that corresponds to the first auth option in the node definition
|
||||
const nodeAuthOptions = getNodeAuthOptions(this.activeNodeType);
|
||||
|
|
|
@ -109,6 +109,7 @@ export default defineComponent({
|
|||
const supported = this.getSupportedSets(this.parameter.credentialTypes);
|
||||
|
||||
const checkedCredType = this.credentialsStore.getCredentialTypeByName(name);
|
||||
if (!checkedCredType) return false;
|
||||
|
||||
for (const property of supported.has) {
|
||||
if (checkedCredType[property as keyof ICredentialType] !== undefined) {
|
||||
|
|
|
@ -291,14 +291,14 @@ export default defineComponent({
|
|||
});
|
||||
},
|
||||
credentialTypesNodeDescription(): INodeCredentialDescription[] {
|
||||
const node = this.node as INodeUi;
|
||||
const node = this.node;
|
||||
|
||||
const credType = this.credentialsStore.getCredentialTypeByName(this.overrideCredType);
|
||||
|
||||
if (credType) return [credType];
|
||||
|
||||
const activeNodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (activeNodeType && activeNodeType.credentials) {
|
||||
if (activeNodeType?.credentials) {
|
||||
return activeNodeType.credentials;
|
||||
}
|
||||
|
||||
|
@ -308,11 +308,12 @@ export default defineComponent({
|
|||
const returnData: {
|
||||
[key: string]: string;
|
||||
} = {};
|
||||
let credentialType: ICredentialType | null;
|
||||
let credentialType: ICredentialType | undefined;
|
||||
for (const credentialTypeName of this.credentialTypesNode) {
|
||||
credentialType = this.credentialsStore.getCredentialTypeByName(credentialTypeName);
|
||||
returnData[credentialTypeName] =
|
||||
credentialType !== null ? credentialType.displayName : credentialTypeName;
|
||||
returnData[credentialTypeName] = credentialType
|
||||
? credentialType.displayName
|
||||
: credentialTypeName;
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
|
@ -347,7 +348,7 @@ export default defineComponent({
|
|||
options = options.concat(
|
||||
this.credentialsStore.allUsableCredentialsByType[type].map((option: any) => ({
|
||||
...option,
|
||||
typeDisplayName: this.credentialsStore.getCredentialTypeByName(type).displayName,
|
||||
typeDisplayName: this.credentialsStore.getCredentialTypeByName(type)?.displayName,
|
||||
})),
|
||||
);
|
||||
});
|
||||
|
@ -436,10 +437,9 @@ export default defineComponent({
|
|||
|
||||
const selectedCredentials = this.credentialsStore.getCredentialById(credentialId);
|
||||
const selectedCredentialsType = this.showAll ? selectedCredentials.type : credentialType;
|
||||
const oldCredentials =
|
||||
this.node.credentials && this.node.credentials[selectedCredentialsType]
|
||||
? this.node.credentials[selectedCredentialsType]
|
||||
: {};
|
||||
const oldCredentials = this.node.credentials?.[selectedCredentialsType]
|
||||
? this.node.credentials[selectedCredentialsType]
|
||||
: {};
|
||||
|
||||
const selected = { id: selectedCredentials.id, name: selectedCredentials.name };
|
||||
|
||||
|
@ -513,9 +513,9 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
getIssues(credentialTypeName: string): string[] {
|
||||
const node = this.node as INodeUi;
|
||||
const node = this.node;
|
||||
|
||||
if (node.issues === undefined || node.issues.credentials === undefined) {
|
||||
if (node.issues?.credentials === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -526,11 +526,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
isCredentialExisting(credentialType: string): boolean {
|
||||
if (
|
||||
!this.node.credentials ||
|
||||
!this.node.credentials[credentialType] ||
|
||||
!this.node.credentials[credentialType].id
|
||||
) {
|
||||
if (!this.node.credentials?.[credentialType]?.id) {
|
||||
return false;
|
||||
}
|
||||
const { id } = this.node.credentials[credentialType];
|
||||
|
|
|
@ -35,10 +35,12 @@ export default defineComponent({
|
|||
const oauth1Api = this.$locale.baseText('generic.oauth1Api');
|
||||
const oauth2Api = this.$locale.baseText('generic.oauth2Api');
|
||||
|
||||
return this.credentialsStore
|
||||
.getCredentialTypeByName(this.activeCredentialType)
|
||||
.displayName.replace(new RegExp(`${oauth1Api}|${oauth2Api}`), '')
|
||||
.trim();
|
||||
return (
|
||||
this.credentialsStore
|
||||
.getCredentialTypeByName(this.activeCredentialType)
|
||||
?.displayName.replace(new RegExp(`${oauth1Api}|${oauth2Api}`), '')
|
||||
.trim() || ''
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -126,7 +126,7 @@ export const nodeHelpers = defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
if (this.hasNodeExecutionIssues(node) === true && !ignoreIssues.includes('execution')) {
|
||||
if (this.hasNodeExecutionIssues(node) && !ignoreIssues.includes('execution')) {
|
||||
if (nodeIssues === null) {
|
||||
nodeIssues = {};
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ export const nodeHelpers = defineComponent({
|
|||
const foundIssues: INodeIssueObjectProperty = {};
|
||||
|
||||
let userCredentials: ICredentialsResponse[] | null;
|
||||
let credentialType: ICredentialType | null;
|
||||
let credentialType: ICredentialType | undefined;
|
||||
let credentialDisplayName: string;
|
||||
let selectedCredentials: INodeCredentialsDetails;
|
||||
|
||||
|
@ -258,7 +258,7 @@ export const nodeHelpers = defineComponent({
|
|||
selectedCredsAreUnusable(node, genericAuthType)
|
||||
) {
|
||||
const credential = this.credentialsStore.getCredentialTypeByName(genericAuthType);
|
||||
return this.reportUnsetCredential(credential);
|
||||
return credential ? this.reportUnsetCredential(credential) : null;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -271,7 +271,7 @@ export const nodeHelpers = defineComponent({
|
|||
|
||||
if (selectedCredsDoNotExist(node, nodeCredentialType, stored)) {
|
||||
const credential = this.credentialsStore.getCredentialTypeByName(nodeCredentialType);
|
||||
return this.reportUnsetCredential(credential);
|
||||
return credential ? this.reportUnsetCredential(credential) : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,7 +282,7 @@ export const nodeHelpers = defineComponent({
|
|||
selectedCredsAreUnusable(node, nodeCredentialType)
|
||||
) {
|
||||
const credential = this.credentialsStore.getCredentialTypeByName(nodeCredentialType);
|
||||
return this.reportUnsetCredential(credential);
|
||||
return credential ? this.reportUnsetCredential(credential) : null;
|
||||
}
|
||||
|
||||
for (const credentialTypeDescription of nodeType.credentials) {
|
||||
|
@ -301,7 +301,7 @@ export const nodeHelpers = defineComponent({
|
|||
credentialDisplayName = credentialType.displayName;
|
||||
}
|
||||
|
||||
if (!node.credentials || !node.credentials?.[credentialTypeDescription.name]) {
|
||||
if (!node.credentials?.[credentialTypeDescription.name]) {
|
||||
// Credentials are not set
|
||||
if (credentialTypeDescription.required) {
|
||||
foundIssues[credentialTypeDescription.name] = [
|
||||
|
@ -312,9 +312,7 @@ export const nodeHelpers = defineComponent({
|
|||
}
|
||||
} else {
|
||||
// If they are set check if the value is valid
|
||||
selectedCredentials = node.credentials[
|
||||
credentialTypeDescription.name
|
||||
] as INodeCredentialsDetails;
|
||||
selectedCredentials = node.credentials[credentialTypeDescription.name];
|
||||
if (typeof selectedCredentials === 'string') {
|
||||
selectedCredentials = {
|
||||
id: null,
|
||||
|
@ -409,16 +407,14 @@ export const nodeHelpers = defineComponent({
|
|||
return [];
|
||||
}
|
||||
const executionData = this.workflowsStore.getWorkflowExecution.data;
|
||||
if (!executionData || !executionData.resultData) {
|
||||
if (!executionData?.resultData) {
|
||||
// unknown status
|
||||
return [];
|
||||
}
|
||||
const runData = executionData.resultData.runData;
|
||||
|
||||
if (
|
||||
runData === null ||
|
||||
runData[node.name] === undefined ||
|
||||
!runData[node.name][runIndex].data ||
|
||||
!runData?.[node.name]?.[runIndex].data ||
|
||||
runData[node.name][runIndex].data === undefined
|
||||
) {
|
||||
return [];
|
||||
|
@ -457,12 +453,7 @@ export const nodeHelpers = defineComponent({
|
|||
|
||||
const runData: IRunData | null = workflowRunData;
|
||||
|
||||
if (
|
||||
runData === null ||
|
||||
!runData[node] ||
|
||||
!runData[node][runIndex] ||
|
||||
!runData[node][runIndex].data
|
||||
) {
|
||||
if (!runData?.[node]?.[runIndex]?.data) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import type { INodeUi, IUsedCredential } from '../Interface';
|
||||
import type {
|
||||
INodeUi,
|
||||
IUsedCredential,
|
||||
ICredentialMap,
|
||||
ICredentialsDecryptedResponse,
|
||||
ICredentialsResponse,
|
||||
ICredentialsState,
|
||||
ICredentialTypeMap,
|
||||
} from '../Interface';
|
||||
import {
|
||||
createNewCredential,
|
||||
deleteCredential,
|
||||
|
@ -15,19 +23,11 @@ import { setCredentialSharedWith } from '@/api/credentials.ee';
|
|||
import { makeRestApiRequest } from '@/utils/apiUtils';
|
||||
import { getAppNameFromCredType } from '@/utils/nodeTypesUtils';
|
||||
import { EnterpriseEditionFeature, STORES } from '@/constants';
|
||||
import type {
|
||||
ICredentialMap,
|
||||
ICredentialsDecryptedResponse,
|
||||
ICredentialsResponse,
|
||||
ICredentialsState,
|
||||
ICredentialTypeMap,
|
||||
} from '@/Interface';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import type {
|
||||
ICredentialsDecrypted,
|
||||
ICredentialType,
|
||||
INodeCredentialTestResult,
|
||||
INodeProperties,
|
||||
INodeTypeDescription,
|
||||
IUser,
|
||||
} from 'n8n-workflow';
|
||||
|
@ -77,7 +77,7 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, {
|
|||
return (node: INodeUi): ICredentialsResponse[] => {
|
||||
let credentials: ICredentialsResponse[] = [];
|
||||
const nodeType = useNodeTypesStore().getNodeType(node.type, node.typeVersion);
|
||||
if (nodeType && nodeType.credentials) {
|
||||
if (nodeType?.credentials) {
|
||||
nodeType.credentials.forEach((cred) => {
|
||||
credentials = credentials.concat(this.allUsableCredentialsByType[cred.name]);
|
||||
});
|
||||
|
@ -106,7 +106,7 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, {
|
|||
);
|
||||
},
|
||||
getCredentialTypeByName() {
|
||||
return (type: string): ICredentialType => this.credentialTypes[type];
|
||||
return (type: string): ICredentialType | undefined => this.credentialTypes[type];
|
||||
},
|
||||
getCredentialById() {
|
||||
return (id: string): ICredentialsResponse => this.credentials[id];
|
||||
|
@ -149,9 +149,10 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, {
|
|||
},
|
||||
getScopesByCredentialType() {
|
||||
return (credentialTypeName: string) => {
|
||||
const credentialType = this.getCredentialTypeByName(credentialTypeName) as {
|
||||
properties: INodeProperties[];
|
||||
};
|
||||
const credentialType = this.getCredentialTypeByName(credentialTypeName);
|
||||
if (!credentialType) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const scopeProperty = credentialType.properties.find((p) => p.name === 'scope');
|
||||
|
||||
|
@ -232,7 +233,7 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, {
|
|||
// enable oauth event to track change between modals
|
||||
},
|
||||
async fetchCredentialTypes(forceFetch: boolean): Promise<void> {
|
||||
if (this.allCredentialTypes.length > 0 && forceFetch !== true) {
|
||||
if (this.allCredentialTypes.length > 0 && !forceFetch) {
|
||||
return;
|
||||
}
|
||||
const rootStore = useRootStore();
|
||||
|
@ -337,8 +338,8 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, {
|
|||
const { credentialTypeName } = params;
|
||||
let newName = DEFAULT_CREDENTIAL_NAME;
|
||||
if (!TYPES_WITH_DEFAULT_NAME.includes(credentialTypeName)) {
|
||||
const { displayName } = this.getCredentialTypeByName(credentialTypeName);
|
||||
newName = getAppNameFromCredType(displayName);
|
||||
const cred = this.getCredentialTypeByName(credentialTypeName);
|
||||
newName = cred ? getAppNameFromCredType(cred.displayName) : '';
|
||||
newName =
|
||||
newName.length > 0
|
||||
? `${newName} ${DEFAULT_CREDENTIAL_POSTFIX}`
|
||||
|
|
|
@ -212,7 +212,7 @@ export const getNodeAuthOptions = (
|
|||
const cred = getNodeCredentialForSelectedAuthType(nodeType, option.value);
|
||||
if (cred) {
|
||||
hasOverrides =
|
||||
useCredentialsStore().getCredentialTypeByName(cred.name).__overwrittenProperties !==
|
||||
useCredentialsStore().getCredentialTypeByName(cred.name)?.__overwrittenProperties !==
|
||||
undefined;
|
||||
}
|
||||
return {
|
||||
|
|
Loading…
Reference in a new issue