diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts
index 560636029..fdc9e94e4 100644
--- a/packages/cli/src/Server.ts
+++ b/packages/cli/src/Server.ts
@@ -979,7 +979,7 @@ class App {
// Save the credentials in DB
await Db.collections.Credentials!.update(state.cid, newCredentialsData);
- res.sendFile(pathResolve('../templates/oauth-callback.html'));
+ res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
});
diff --git a/packages/editor-ui/src/components/CredentialsEdit.vue b/packages/editor-ui/src/components/CredentialsEdit.vue
index 782e615a3..187953ef5 100644
--- a/packages/editor-ui/src/components/CredentialsEdit.vue
+++ b/packages/editor-ui/src/components/CredentialsEdit.vue
@@ -34,11 +34,11 @@ import CredentialsInput from '@/components/CredentialsInput.vue';
import {
ICredentialsCreatedEvent,
ICredentialsDecryptedResponse,
- INodeProperties,
} from '@/Interface';
import {
ICredentialType,
+ INodeProperties,
} from 'n8n-workflow';
import mixins from 'vue-typed-mixins';
@@ -172,6 +172,42 @@ export default mixins(
},
},
methods: {
+ mergeCredentialProperties (mainProperties: INodeProperties[], addProperties: INodeProperties[]): void {
+ let existingIndex: number;
+ for (const property of addProperties) {
+ existingIndex = mainProperties.findIndex(element => element.name === property.name);
+
+ if (existingIndex === -1) {
+ // Property does not exist yet, so add
+ mainProperties.push(property);
+ } else {
+ // Property exists already, so overwrite
+ mainProperties[existingIndex] = property;
+ }
+ }
+ },
+ getCredentialProperties (name: string): INodeProperties[] {
+ let credentialsData = this.$store.getters.credentialType(name);
+
+ if (credentialsData === null) {
+ throw new Error(`Could not find credentials of type: ${name}`);
+ }
+
+ if (credentialsData.extends === undefined) {
+ return credentialsData.properties;
+ }
+
+ const combineProperties = [] as INodeProperties[];
+ for (const credentialsTypeName of credentialsData.extends) {
+ const mergeCredentialProperties = this.getCredentialProperties(credentialsTypeName);
+ this.mergeCredentialProperties(combineProperties, mergeCredentialProperties);
+ }
+
+ // The properties defined on the parent credentials take presidence
+ this.mergeCredentialProperties(combineProperties, credentialsData.properties);
+
+ return combineProperties;
+ },
getCredentialTypeData (name: string): ICredentialType | null {
let credentialData = this.$store.getters.credentialType(name);
@@ -179,25 +215,14 @@ export default mixins(
return credentialData;
}
+ // TODO: The credential-extend-resolve-logic is currently not needed in the backend
+ // as the whole credential data gets saved with the defaults. That logic should,
+ // however, probably also get improved in the future.
+
// Credentials extends another one. So get the properties of the one it
// extends and add them.
credentialData = JSON.parse(JSON.stringify(credentialData));
- let existingIndex: number;
- for (const credentialTypeName of credentialData.extends) {
- const data = this.$store.getters.credentialType(credentialTypeName);
-
- for (const property of data.properties) {
- existingIndex = credentialData.properties.findIndex(element => element.name === property.name);
-
- if (existingIndex === -1) {
- // Property does not exist yet, so add
- credentialData.properties.push(property);
- } else {
- // Property exists already, so overwrite
- credentialData.properties[existingIndex] = property;
- }
- }
- }
+ credentialData.properties = this.getCredentialProperties(credentialData.name);
return credentialData;
},
diff --git a/packages/editor-ui/src/components/CredentialsInput.vue b/packages/editor-ui/src/components/CredentialsInput.vue
index 708f72631..76aa1c667 100644
--- a/packages/editor-ui/src/components/CredentialsInput.vue
+++ b/packages/editor-ui/src/components/CredentialsInput.vue
@@ -41,18 +41,21 @@