Skip to content

Commit

Permalink
Add UI notifier to indicate secret fields and to remember / reenter v…
Browse files Browse the repository at this point in the history
…alues (#80657) (#81371)

* Initial work

* Add messaging to Jira connector

* Add messaging to PagerDuty connector

* Add messaging to Email connector

* Add messaging to ServiceNow connector

* Add messaging to Webhook connector

* Add unit tests

* Fix jest test

* Apply design feedback

* Apply copy feedback

* Fix failing test

* Fix connector descriptions for jira and resilient

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
mikecote and kibanamachine authored Oct 21, 2020
1 parent 2145fc3 commit b6e8e5c
Show file tree
Hide file tree
Showing 19 changed files with 746 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,51 @@ describe('EmailActionConnectorFields renders', () => {
expect(wrapper.find('[data-test-subj="emailUserInput"]').length > 0).toBeFalsy();
expect(wrapper.find('[data-test-subj="emailPasswordInput"]').length > 0).toBeFalsy();
});

test('should display a message to remember username and password when creating a connector with authentication', () => {
const actionConnector = {
actionTypeId: '.email',
config: {
hasAuth: true,
},
secrets: {},
} as EmailActionConnector;
const wrapper = mountWithIntl(
<EmailActionConnectorFields
action={actionConnector}
errors={{ from: [], port: [], host: [], user: [], password: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toEqual(0);
});

test('should display a message when editing an authenticated email connector explaining why username and password must be re-entered', () => {
const actionConnector = {
secrets: {},
id: 'test',
actionTypeId: '.email',
name: 'email',
config: {
from: 'test@test.com',
hasAuth: true,
},
} as EmailActionConnector;
const wrapper = mountWithIntl(
<EmailActionConnectorFields
action={actionConnector}
errors={{ from: [], port: [], host: [], user: [], password: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toEqual(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EuiFieldPassword,
EuiSwitch,
EuiFormRow,
EuiText,
EuiTitle,
EuiSpacer,
EuiCallOut,
Expand Down Expand Up @@ -56,7 +57,7 @@ export const EmailActionConnectorFields: React.FunctionComponent<ActionConnector
>
<FormattedMessage
id="xpack.triggersActionsUI.components.builtinActionTypes.emailAction.configureAccountsHelpLabel"
defaultMessage="Configuring email accounts."
defaultMessage="Configure email accounts"
/>
</EuiLink>
}
Expand Down Expand Up @@ -202,17 +203,7 @@ export const EmailActionConnectorFields: React.FunctionComponent<ActionConnector
</EuiFlexGroup>
{hasAuth ? (
<>
{action.id ? (
<>
<EuiSpacer size="m" />
<EuiCallOut
size="s"
title="Username and password are encrypted. Please reenter values for these fields."
iconType="iInCircle"
/>
<EuiSpacer size="m" />
</>
) : null}
{getEncryptedFieldNotifyLabel(!action.id)}
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem>
<EuiFormRow
Expand Down Expand Up @@ -289,5 +280,40 @@ function nullableString(str: string | null | undefined) {
return str;
}

function getEncryptedFieldNotifyLabel(isCreate: boolean) {
if (isCreate) {
return (
<Fragment>
<EuiSpacer size="s" />
<EuiText size="s" data-test-subj="rememberValuesMessage">
<FormattedMessage
id="xpack.triggersActionsUI.components.builtinActionTypes.emailAction.rememberValuesLabel"
defaultMessage="Remember these values. You must reenter them each time you edit the connector."
/>
</EuiText>
<EuiSpacer size="s" />
</Fragment>
);
}
return (
<Fragment>
<EuiSpacer size="m" />
<EuiCallOut
size="s"
iconType="iInCircle"
data-test-subj="reenterValuesMessage"
title={i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.emailAction.reenterValuesLabel',
{
defaultMessage:
'Username and password are encrypted. Please reenter values for these fields.',
}
)}
/>
<EuiSpacer size="m" />
</Fragment>
);
}

// eslint-disable-next-line import/no-default-export
export { EmailActionConnectorFields as default };
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('jira connector validation', () => {
errors: {
apiUrl: ['URL is required.'],
email: [],
apiToken: ['API token or Password is required'],
apiToken: ['API token or password is required'],
projectKey: ['Project key is required'],
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,60 @@ describe('JiraActionConnectorFields renders', () => {
wrapper.find('[data-test-subj="connector-jira-apiToken-form-input"]').length > 0
).toBeTruthy();
});

test('should display a message on create to remember credentials', () => {
const actionConnector = {
actionTypeId: '.jira',
isPreconfigured: false,
secrets: {},
config: {},
} as JiraActionConnector;
const deps = {
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart,
};
const wrapper = mountWithIntl(
<JiraConnectorFields
action={actionConnector}
errors={{ apiUrl: [], email: [], apiToken: [], projectKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toEqual(0);
});

test('should display a message on edit to re-enter credentials', () => {
const actionConnector = {
secrets: {
email: 'email',
apiToken: 'token',
},
id: 'test',
actionTypeId: '.jira',
isPreconfigured: false,
name: 'jira',
config: {
apiUrl: 'https://test/',
projectKey: 'CK',
},
} as JiraActionConnector;
const deps = {
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart,
};
const wrapper = mountWithIntl(
<JiraConnectorFields
action={actionConnector}
errors={{ apiUrl: [], email: [], apiToken: [], projectKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toEqual(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import React, { useCallback } from 'react';

import {
EuiCallOut,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiFieldPassword,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';

import { isEmpty } from 'lodash';
Expand Down Expand Up @@ -133,6 +136,20 @@ const JiraConnectorFields: React.FC<ActionConnectorFieldsProps<JiraActionConnect
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<EuiFlexGroup>
<EuiFlexItem>
<EuiTitle size="xxs">
<h4>{i18n.JIRA_AUTHENTICATION_LABEL}</h4>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow fullWidth>{getEncryptedFieldNotifyLabel(!action.id)}</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow
Expand Down Expand Up @@ -205,5 +222,23 @@ const JiraConnectorFields: React.FC<ActionConnectorFieldsProps<JiraActionConnect
);
};

function getEncryptedFieldNotifyLabel(isCreate: boolean) {
if (isCreate) {
return (
<EuiText size="s" data-test-subj="rememberValuesMessage">
{i18n.JIRA_REMEMBER_VALUES_LABEL}
</EuiText>
);
}
return (
<EuiCallOut
size="s"
iconType="iInCircle"
title={i18n.JIRA_REENTER_VALUES_LABEL}
data-test-subj="reenterValuesMessage"
/>
);
}

// eslint-disable-next-line import/no-default-export
export { JiraConnectorFields as default };
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
export const JIRA_DESC = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.selectMessageText',
{
defaultMessage: 'Push or update data to a new issue in Jira',
defaultMessage: 'Create an incident in Jira.',
}
);

Expand Down Expand Up @@ -55,31 +55,54 @@ export const JIRA_PROJECT_KEY_REQUIRED = i18n.translate(
}
);

export const JIRA_AUTHENTICATION_LABEL = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.authenticationLabel',
{
defaultMessage: 'Authentication',
}
);

export const JIRA_REMEMBER_VALUES_LABEL = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.rememberValuesLabel',
{
defaultMessage:
'Remember these values. You must reenter them each time you edit the connector.',
}
);

export const JIRA_REENTER_VALUES_LABEL = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.reenterValuesLabel',
{
defaultMessage:
'Authentication credentials are encrypted. Please reenter values for these fields.',
}
);

export const JIRA_EMAIL_LABEL = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.emailTextFieldLabel',
{
defaultMessage: 'Email or Username',
defaultMessage: 'Username or email address',
}
);

export const JIRA_EMAIL_REQUIRED = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredEmailTextField',
{
defaultMessage: 'Email or Username is required',
defaultMessage: 'Username or email address is required',
}
);

export const JIRA_API_TOKEN_LABEL = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.apiTokenTextFieldLabel',
{
defaultMessage: 'API token or Password',
defaultMessage: 'API token or password',
}
);

export const JIRA_API_TOKEN_REQUIRED = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredApiTokenTextField',
{
defaultMessage: 'API token or Password is required',
defaultMessage: 'API token or password is required',
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,56 @@ describe('PagerDutyActionConnectorFields renders', () => {
);
expect(wrapper.find('[data-test-subj="pagerdutyRoutingKeyInput"]').length > 0).toBeTruthy();
});

test('should display a message on create to remember credentials', () => {
const actionConnector = {
actionTypeId: '.pagerduty',
secrets: {},
config: {},
} as PagerDutyActionConnector;
const deps = {
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart,
};
const wrapper = mountWithIntl(
<PagerDutyActionConnectorFields
action={actionConnector}
errors={{ index: [], routingKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toEqual(0);
});

test('should display a message on edit to re-enter credentials', () => {
const actionConnector = {
secrets: {
routingKey: 'test',
},
id: 'test',
actionTypeId: '.pagerduty',
name: 'pagerduty',
config: {
apiUrl: 'http:\\test',
},
} as PagerDutyActionConnector;
const deps = {
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart,
};
const wrapper = mountWithIntl(
<PagerDutyActionConnectorFields
action={actionConnector}
errors={{ index: [], routingKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
readOnly={false}
/>
);
expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0);
expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toEqual(0);
});
});
Loading

0 comments on commit b6e8e5c

Please sign in to comment.