Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor into credential-type param #3304

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
6bbd86d
:zap: Refactor into cred type param
ivov May 16, 2022
1cac801
:zap: Componentize scopes notice
ivov May 16, 2022
e3f8b79
:fire: Remove unused data
ivov May 16, 2022
1baa913
:fire: Remove unused `loadOptions`
ivov May 16, 2022
e8401ea
:zap: Componentize `NodeCredentialType`
ivov May 16, 2022
4b66ca3
:twisted_rightwards_arrows: Merge parent branch
ivov May 16, 2022
6c87cfb
:bug: Fix param validation
ivov May 16, 2022
4a94b05
:fire: Remove dup methods
ivov May 16, 2022
d0456ee
:zap: Refactor all references to `isHttpRequestNodeV2`
ivov May 16, 2022
fd57ad4
:art: Fix styling
ivov May 16, 2022
d4c2336
:fire: Remove unused import
ivov May 16, 2022
3b80952
:fire: Remove unused properties
ivov May 16, 2022
9f8689a
:art: Fix spacing for Pipedrive Trigger node
ivov May 16, 2022
db1d610
:art: Undo Webhook node styling change
ivov May 16, 2022
6621748
:fire: Remove unused style
ivov May 17, 2022
b5be6a2
:zap: Cover `httpHeaderAuth` edge case
ivov May 17, 2022
e8aa594
:bug: Fix `this.node` reference
ivov May 17, 2022
80189a4
:truck: Rename to `credentialsSelect`
ivov May 17, 2022
d6c7fcd
:bug: Fix mistaken renaming
ivov May 17, 2022
64cb690
:zap: Set one attribute per line
ivov May 17, 2022
81fac7e
:zap: Move condition to instantiation site
ivov May 17, 2022
50328c5
:truck: Rename prop
ivov May 17, 2022
ed1078c
:zap: Refactor away `prepareScopesNotice`
ivov May 17, 2022
e45eaef
:pencil2: Rename i18n keys
ivov May 17, 2022
501cb14
:pencil2: Update i18n calls
ivov May 17, 2022
2a3c80e
:pencil2: Add more i18n keys
ivov May 17, 2022
5d869c0
:fire: Remove unused props
ivov May 17, 2022
0049432
:pencil2: Add explanatory comment
ivov May 17, 2022
a8cb799
:zap: Adjust check in `hasProxyAuth`
ivov May 17, 2022
d9b05bf
:zap: Refactor `credentialSelected` from prop to event
ivov May 17, 2022
c8fbf73
:zap: Eventify `valueChanged`, `setFocus`, `onBlur`
ivov May 17, 2022
137a413
:zap: Eventify `optionSelected`
ivov May 17, 2022
254e06b
:zap: Add `noDataExpression`
ivov May 17, 2022
cc172e9
:fire: Remove logging
ivov May 17, 2022
e1af33f
:fire: Remove URL from scopes
ivov May 17, 2022
0be195d
:zap: Disregard expressions for display
ivov May 17, 2022
f6d5aac
:art: Use CSS modules
ivov May 17, 2022
120666a
:blue_book: Tigthen interface
ivov May 18, 2022
9b497b8
:bug: Fix generic auth display
ivov May 18, 2022
bf59650
:bug: Fix generic auth validation
ivov May 18, 2022
458ab04
:blue_book: Loosen type
ivov May 18, 2022
637c985
:truck: Move event params to end
ivov May 19, 2022
cdcd82d
:zap: Generalize reference
ivov May 19, 2022
89d0732
:zap: Refactor generic auth as `credentialsSelect` param
ivov May 19, 2022
361b9a3
:rewind: Restore check for `httpHeaderAuth `
ivov May 19, 2022
973c58c
:truck: Rename `existing` to `predefined`
ivov May 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions packages/editor-ui/src/components/CredentialsSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<template>
<div>
<div :class="$style['parameter-value-container']">
<n8n-select
:size="inputSize"
filterable
:value="displayValue"
:placeholder="parameter.placeholder ? getPlaceholder() : $locale.baseText('parameterInput.select')"
:title="displayTitle"
@change="(value) => $emit('valueChanged', value)"
@keydown.stop
@focus="$emit('setFocus')"
@blur="$emit('onBlur')"
>
<n8n-option
v-for="credType in supportedCredentialTypes"
:value="credType.name"
:key="credType.name"
>
<div class="list-option">
<div class="option-headline">
{{ credType.displayName }}
</div>
<div
v-if="credType.description"
class="option-description"
v-html="credType.description"
/>
</div>
</n8n-option>
</n8n-select>
<slot name="issues-and-options" />
</div>

<scopes-notice
v-if="scopes.length > 0"
:activeCredentialType="activeCredentialType"
:scopes="scopes"
/>
<div>
<node-credentials
:node="node"
:overrideCredType="node.parameters[parameter.name]"
@credentialSelected="(updateInformation) => $emit('credentialSelected', updateInformation)"
/>
</div>
</div>
</template>

<script lang="ts">
import { ICredentialType } from 'n8n-workflow';
import Vue from 'vue';
import { mapGetters } from 'vuex';
import ScopesNotice from '@/components/ScopesNotice.vue';
import NodeCredentials from '@/components/NodeCredentials.vue';

export default Vue.extend({
name: 'CredentialsSelect',
components: {
ScopesNotice,
NodeCredentials,
},
props: [
'activeCredentialType',
'node',
'parameter',
'inputSize',
'displayValue',
'isReadOnly',
'displayTitle',
],
computed: {
...mapGetters('credentials', ['allCredentialTypes', 'getScopesByCredentialType']),
scopes(): string[] {
if (!this.activeCredentialType) return [];

return this.getScopesByCredentialType(this.activeCredentialType);
},
supportedCredentialTypes(): ICredentialType[] {
return this.allCredentialTypes.filter((c: ICredentialType) => this.isSupported(c.name));
},
},
methods: {
/**
* Check if a credential type belongs to one of the supported sets defined
* in the `credentialTypes` key in a `credentialsSelect` parameter
*/
isSupported(name: string): boolean {
const supported = this.getSupportedSets(this.parameter.credentialTypes);

const checkedCredType = this.$store.getters['credentials/getCredentialTypeByName'](name);

for (const property of supported.has) {
if (checkedCredType[property] !== undefined) {

// edge case: `httpHeaderAuth` has `authenticate` auth but belongs to generic auth
if (name === 'httpHeaderAuth' && property === 'authenticate') continue;

return true;
}
}

if (
checkedCredType.extends &&
checkedCredType.extends.some(
(parentType: string) => supported.extends.includes(parentType),
)
) {
return true;
}

if (checkedCredType.extends && supported.extends.length) {
// recurse upward until base credential type
// e.g. microsoftDynamicsOAuth2Api -> microsoftOAuth2Api -> oAuth2Api
return checkedCredType.extends.reduce(
(acc: boolean, parentType: string) => acc || this.isSupported(parentType),
false,
);
}

return false;
},
getSupportedSets(credentialTypes: string[]) {
return credentialTypes.reduce<{ extends: string[]; has: string[] }>((acc, cur) => {
const _extends = cur.split('extends:');

if (_extends.length === 2) {
acc.extends.push(_extends[1]);
return acc;
}

const _has = cur.split('has:');

if (_has.length === 2) {
acc.has.push(_has[1]);
return acc;
}

return acc;
}, { extends: [], has: [] });
},
},
});
</script>

<style module lang="scss">
.parameter-value-container {
display: flex;
align-items: center;
}

</style>
27 changes: 4 additions & 23 deletions packages/editor-ui/src/components/NodeCredentials.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export default mixins(
name: 'NodeCredentials',
props: [
'node', // INodeUi
'overrideCredType', // cred type
],
data () {
return {
Expand All @@ -99,14 +100,6 @@ export default mixins(
credentialOptions: 'allCredentialsByType',
getCredentialTypeByName: 'getCredentialTypeByName',
}),
isProxyAuth(): boolean {
return this.isHttpRequestNodeV2(this.node) &&
this.node.parameters.authentication === 'existingCredentialType';
},
isGenericAuth(): boolean {
return this.isHttpRequestNodeV2(this.node) &&
this.node.parameters.authentication === 'genericCredentialType';
},
credentialTypesNode (): string[] {
return this.credentialTypesNodeDescription
.map((credentialTypeDescription) => credentialTypeDescription.name);
Expand All @@ -120,17 +113,9 @@ export default mixins(
credentialTypesNodeDescription (): INodeCredentialDescription[] {
const node = this.node as INodeUi;

if (this.isGenericAuth) {
const { genericAuthType } = this.node.parameters as { genericAuthType: string };

return [this.getCredentialTypeByName(genericAuthType)];
}
const credType = this.getCredentialTypeByName(this.overrideCredType);

if (this.isProxyAuth) {
const { nodeCredentialType } = this.node.parameters as { nodeCredentialType?: string };

if (nodeCredentialType) return [this.getCredentialTypeByName(nodeCredentialType)];
}
if (credType) return [credType];

const activeNodeType = this.$store.getters.nodeType(node.type, node.typeVersion) as INodeTypeDescription | null;
if (activeNodeType && activeNodeType.credentials) {
Expand Down Expand Up @@ -321,11 +306,7 @@ export default mixins(

<style lang="scss" module>
.container {
margin: 0;

> * {
margin-bottom: var(--spacing-xs);
}
margin-top: var(--spacing-xs);
}

.warning {
Expand Down
76 changes: 0 additions & 76 deletions packages/editor-ui/src/components/NodeSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@
:hideDelete="true"
:nodeValues="nodeValues" path="parameters" @valueChanged="valueChanged"
>
<n8n-notice
v-if="isHttpRequestNodeV2(node) && this.activeCredential.scopes.length > 0"
:content="scopesShortContent"
:fullContent="scopesFullContent"
/>
<node-credentials
:node="node"
@credentialSelected="credentialSelected"
Expand Down Expand Up @@ -95,7 +90,6 @@ import { nodeHelpers } from '@/components/mixins/nodeHelpers';

import mixins from 'vue-typed-mixins';
import NodeExecuteButton from './NodeExecuteButton.vue';
import { mapGetters } from 'vuex';

export default mixins(
externalHooks,
Expand All @@ -114,10 +108,6 @@ export default mixins(
NodeExecuteButton,
},
computed: {
...mapGetters('credentials', [
'getCredentialTypeByName',
'getScopesByCredentialType',
]),
nodeType (): INodeTypeDescription | null {
if (this.node) {
return this.$store.getters.nodeType(this.node.type, this.node.typeVersion);
Expand Down Expand Up @@ -178,31 +168,6 @@ export default mixins(

return this.nodeType.properties;
},
scopesShortContent (): string {
return this.$locale.baseText(
'nodeSettings.scopes.notice',
{
adjustToNumber: this.activeCredential.scopes.length,
interpolate: {
activeCredential: this.activeCredential.shortDisplayName,
},
},
);
},
scopesFullContent (): string {
return this.$locale.baseText(
'nodeSettings.scopes.expandedNoticeWithScopes',
{
adjustToNumber: this.activeCredential.scopes.length,
interpolate: {
activeCredential: this.activeCredential.shortDisplayName,
scopes: this.activeCredential.scopes.map(
(scope: string) => scope.replace(/\//g, '/<wbr>'),
).join('<br>'),
},
},
);
},
},
props: {
eventBus: {
Expand All @@ -225,10 +190,6 @@ export default mixins(
notes: '',
parameters: {},
} as INodeParameters,
activeCredential: {
shortDisplayName: '',
scopes: [] as string[],
},

nodeSettings: [
{
Expand Down Expand Up @@ -330,28 +291,6 @@ export default mixins(
},
},
methods: {
async prepareScopesNotice(credentialTypeName: string) {
if (
!this.isHttpRequestNodeV2(this.node) ||
!credentialTypeName || !credentialTypeName.endsWith('OAuth2Api')
) {
this.activeCredential.scopes = [];
return;
}

const { name, displayName } = this.getCredentialTypeByName(credentialTypeName);

this.activeCredential.scopes = this.getScopesByCredentialType(name);
this.activeCredential.shortDisplayName = this.shortenCredentialDisplayName(displayName);
},
shortenCredentialDisplayName (credentialDisplayName: string) {
const oauth1Api = this.$locale.baseText('nodeSettings.oauth1Api');
const oauth2Api = this.$locale.baseText('nodeSettings.oauth2Api');

return credentialDisplayName
.replace(new RegExp(`${oauth1Api}|${oauth2Api}`), '')
.trim();
},
onNodeExecute () {
this.$emit('execute');
},
Expand Down Expand Up @@ -428,13 +367,6 @@ export default mixins(
});
},
valueChanged (parameterData: IUpdateInformation) {
if (
this.isHttpRequestNodeV2(this.node) &&
parameterData.name === 'parameters.nodeCredentialType'
) {
this.prepareScopesNotice(parameterData.value as string);
}

let newValue: NodeParameterValue;
if (parameterData.hasOwnProperty('value')) {
// New value is given
Expand Down Expand Up @@ -613,14 +545,6 @@ export default mixins(
},
mounted () {
this.setNodeValues();

if (
this.isHttpRequestNodeV2(this.node) &&
this.node.parameters.authentication === 'existingCredentialType'
) {
this.prepareScopesNotice(this.node.parameters.nodeCredentialType as string);
}

if (this.eventBus) {
(this.eventBus as Vue).$on('openSettings', () => {
this.openPanel = 'settings';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/components/NodeWebhooks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export default mixins(

.webhoooks {
padding-bottom: var(--spacing-xs);
margin: var(--spacing-xs) 0 0 0;
margin: var(--spacing-xs) 0;
border-bottom: 1px solid #ccc;

.headline {
Expand Down
Loading