mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Response Ops][Connectors] New xpack.actions.email.services.enabled
Kibana setting (#223363)
## Summary Closes #220288 ## Release note New kibana setting `xpack.actions.email.services.enabled` to enable/disable email services for email connector.
This commit is contained in:
parent
028660e4e1
commit
411ab215a5
34 changed files with 608 additions and 63 deletions
|
@ -198,7 +198,8 @@ enabled:
|
|||
- x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/embeddable_alerts_table/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/with_aws_ses_kibana_config/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/with_email_aws_ses_kbn_config/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/with_email_services_enabled_kbn_config/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/shared/config.ts
|
||||
- x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/webhook_disabled_ssl_pfx/config.ts
|
||||
- x-pack/test/functional/apps/advanced_settings/config.ts
|
||||
|
|
|
@ -150,6 +150,12 @@ $$$action-config-email-domain-allowlist$$$
|
|||
Data type: `int`
|
||||
Default: `465`
|
||||
|
||||
`xpack.actions.email.services.enabled` 
|
||||
: An array of strings indicating all email services that are enabled. Available options are `elastic-cloud`, `google-mail`, `microsoft-outlook`, `amazon-ses`, `microsoft-exchange`, and `other`. If the array is empty, no email services are enabled. The default value is `["*"]`, which enables all email services.
|
||||
|
||||
Data type: `string`
|
||||
Default: `["*"]`
|
||||
|
||||
`xpack.actions.enableFooterInEmail` 
|
||||
: A boolean value indicating that a footer with a relevant link should be added to emails sent as alerting actions.
|
||||
|
||||
|
|
|
@ -326,6 +326,28 @@ groups:
|
|||
ess: all
|
||||
# example: |
|
||||
|
||||
- setting: xpack.actions.email.services.enabled
|
||||
id: action-config-email-services-
|
||||
description: |
|
||||
An array of strings indicating all email services that are enabled. Available options are `elastic-cloud`, `google-mail`, `microsoft-outlook`, `amazon-ses`, `microsoft-exchange`, and `other`. If the array is empty, no email services are enabled. The default value is `["*"]`, which enables all email services.
|
||||
# state: deprecated/hidden/tech-preview
|
||||
# deprecation_details: ""
|
||||
# note: ""
|
||||
# tip: ""
|
||||
# warning: ""
|
||||
# important: ""
|
||||
datatype: enum
|
||||
default: ["*"]
|
||||
# options:
|
||||
# - option:
|
||||
# description: ""
|
||||
# type: static/dynamic
|
||||
applies_to:
|
||||
deployment:
|
||||
self: all
|
||||
ess: all
|
||||
# example: |
|
||||
|
||||
- setting: xpack.actions.enableFooterInEmail
|
||||
# id:
|
||||
description: |
|
||||
|
|
|
@ -214,6 +214,7 @@ kibana_vars=(
|
|||
xpack.actions.email.domain_allowlist
|
||||
xpack.actions.email.services.ses.host
|
||||
xpack.actions.email.services.ses.port
|
||||
xpack.actions.email.services.enabled
|
||||
xpack.actions.enableFooterInEmail
|
||||
xpack.actions.enabledActionTypes
|
||||
xpack.actions.maxResponseContentLength
|
||||
|
|
|
@ -203,6 +203,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'vis_type_xy.readOnly (boolean?|never)',
|
||||
'vis_type_vega.enableExternalUrls (boolean?)',
|
||||
'xpack.actions.email.domain_allowlist (array?)',
|
||||
'xpack.actions.email.services.enabled (array?)',
|
||||
'xpack.actions.webhook.ssl.pfx.enabled (boolean?)',
|
||||
'xpack.apm.serviceMapEnabled (boolean?)',
|
||||
'xpack.apm.ui.enabled (boolean?)',
|
||||
|
|
|
@ -14,12 +14,16 @@ export interface ActionsPublicPluginSetup {
|
|||
emails: string[],
|
||||
options?: ValidateEmailAddressesOptions
|
||||
): ValidatedEmail[];
|
||||
enabledEmailServices: string[];
|
||||
isWebhookSslWithPfxEnabled?: boolean;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
email: {
|
||||
domain_allowlist: string[];
|
||||
services: {
|
||||
enabled: string[];
|
||||
};
|
||||
};
|
||||
webhook: {
|
||||
ssl: {
|
||||
|
@ -32,11 +36,13 @@ export interface Config {
|
|||
|
||||
export class Plugin implements CorePlugin<ActionsPublicPluginSetup> {
|
||||
private readonly allowedEmailDomains: string[] | null = null;
|
||||
private readonly enabledEmailServices: string[];
|
||||
private readonly webhookSslWithPfxEnabled: boolean;
|
||||
|
||||
constructor(ctx: PluginInitializerContext<Config>) {
|
||||
const config = ctx.config.get();
|
||||
this.allowedEmailDomains = config.email?.domain_allowlist || null;
|
||||
this.enabledEmailServices = Array.from(new Set(config.email?.services?.enabled || ['*']));
|
||||
this.webhookSslWithPfxEnabled = config.webhook?.ssl.pfx.enabled ?? true;
|
||||
}
|
||||
|
||||
|
@ -44,6 +50,7 @@ export class Plugin implements CorePlugin<ActionsPublicPluginSetup> {
|
|||
return {
|
||||
validateEmailAddresses: (emails: string[], options: ValidateEmailAddressesOptions) =>
|
||||
validateEmails(this.allowedEmailDomains, emails, options),
|
||||
enabledEmailServices: this.enabledEmailServices,
|
||||
isWebhookSslWithPfxEnabled: this.webhookSslWithPfxEnabled,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ const createActionsConfigMock = () => {
|
|||
},
|
||||
}),
|
||||
getAwsSesConfig: jest.fn().mockReturnValue(null),
|
||||
getEnabledEmailServices: jest.fn().mockReturnValue(['*']),
|
||||
};
|
||||
return mocked;
|
||||
};
|
||||
|
|
|
@ -633,6 +633,14 @@ describe('getAwsSesConfig()', () => {
|
|||
expect(acu.getAwsSesConfig()).toEqual(null);
|
||||
});
|
||||
|
||||
test('returns null when no email.services.ses config set', () => {
|
||||
const acu = getActionsConfigurationUtilities({
|
||||
...defaultActionsConfig,
|
||||
email: { services: {} },
|
||||
});
|
||||
expect(acu.getAwsSesConfig()).toEqual(null);
|
||||
});
|
||||
|
||||
test('returns config if set', () => {
|
||||
const acu = getActionsConfigurationUtilities({
|
||||
...defaultActionsConfig,
|
||||
|
@ -652,3 +660,47 @@ describe('getAwsSesConfig()', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEnabledEmailServices()', () => {
|
||||
test('returns all services when no email config set', () => {
|
||||
const acu = getActionsConfigurationUtilities(defaultActionsConfig);
|
||||
expect(acu.getEnabledEmailServices()).toEqual(['*']);
|
||||
});
|
||||
|
||||
test('returns all services when no email.services config set', () => {
|
||||
const acu = getActionsConfigurationUtilities({ ...defaultActionsConfig, email: {} });
|
||||
expect(acu.getEnabledEmailServices()).toEqual(['*']);
|
||||
});
|
||||
|
||||
test('returns all services when no email.services.enabled config set', () => {
|
||||
const acu = getActionsConfigurationUtilities({
|
||||
...defaultActionsConfig,
|
||||
email: { services: {} },
|
||||
});
|
||||
expect(acu.getEnabledEmailServices()).toEqual(['*']);
|
||||
});
|
||||
|
||||
test('returns only enabled services', () => {
|
||||
const acu = getActionsConfigurationUtilities({
|
||||
...defaultActionsConfig,
|
||||
email: {
|
||||
services: {
|
||||
enabled: ['google-mail', 'microsoft-exchange'],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(acu.getEnabledEmailServices()).toEqual(['google-mail', 'microsoft-exchange']);
|
||||
});
|
||||
|
||||
test('returns all services when enabled is set to "*" in config', () => {
|
||||
const acu = getActionsConfigurationUtilities({
|
||||
...defaultActionsConfig,
|
||||
email: {
|
||||
services: {
|
||||
enabled: ['*'],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(acu.getEnabledEmailServices()).toEqual(['*']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -63,6 +63,7 @@ export interface ActionsConfigurationUtilities {
|
|||
};
|
||||
};
|
||||
getAwsSesConfig: () => AwsSesConfig;
|
||||
getEnabledEmailServices: () => string[];
|
||||
}
|
||||
|
||||
function allowListErrorMessage(field: AllowListingField, value: string) {
|
||||
|
@ -243,15 +244,23 @@ export function getActionsConfigurationUtilities(
|
|||
};
|
||||
},
|
||||
getAwsSesConfig: () => {
|
||||
if (config.email?.services?.ses.host && config.email?.services?.ses.port) {
|
||||
if (config.email?.services?.ses?.host && config.email?.services?.ses?.port) {
|
||||
return {
|
||||
host: config.email?.services?.ses.host,
|
||||
port: config.email?.services?.ses.port,
|
||||
host: config.email?.services?.ses?.host,
|
||||
port: config.email?.services?.ses?.port,
|
||||
secure: true,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getEnabledEmailServices() {
|
||||
const emailServices = config.email?.services?.enabled;
|
||||
if (emailServices) {
|
||||
return Array.from(new Set(Array.from(emailServices)));
|
||||
}
|
||||
|
||||
return ['*'];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ describe('config validation', () => {
|
|||
|
||||
config.email = {};
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires either domain_allowlist or services.ses to be specified"`
|
||||
`"[email]: email.domain_allowlist or email.services must be defined"`
|
||||
);
|
||||
|
||||
config.email = { domain_allowlist: [] };
|
||||
|
@ -285,35 +285,35 @@ describe('config validation', () => {
|
|||
test('validates empty email config', () => {
|
||||
config.email = {};
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires either domain_allowlist or services.ses to be specified"`
|
||||
`"[email]: email.domain_allowlist or email.services must be defined"`
|
||||
);
|
||||
});
|
||||
|
||||
test('validates email config with empty services', () => {
|
||||
config.email = { services: {} };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires either domain_allowlist or services.ses to be specified"`
|
||||
`"[email.services]: email.services.enabled or email.services.ses must be defined"`
|
||||
);
|
||||
});
|
||||
|
||||
test('validates email config with empty ses service', () => {
|
||||
config.email = { services: { ses: {} } };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires either domain_allowlist or services.ses to be specified"`
|
||||
`"[email.services.ses.host]: expected value of type [string] but got [undefined]"`
|
||||
);
|
||||
});
|
||||
|
||||
test('validates ses config with host only', () => {
|
||||
config.email = { services: { ses: { host: 'ses.host.com' } } };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires both services.ses.host and services.ses.port to be specified"`
|
||||
`"[email.services.ses.port]: expected value of type [number] but got [undefined]"`
|
||||
);
|
||||
});
|
||||
|
||||
test('validates ses config with port only', () => {
|
||||
config.email = { services: { ses: { port: 1 } } };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email]: Email configuration requires both services.ses.host and services.ses.port to be specified"`
|
||||
`"[email.services.ses.host]: expected value of type [string] but got [undefined]"`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -323,6 +323,43 @@ describe('config validation', () => {
|
|||
expect(result.email?.services?.ses).toEqual({ host: 'ses.host.com', port: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('email.services.enabled', () => {
|
||||
const config: Record<string, unknown> = {};
|
||||
test('validates email config with empty enabled services', () => {
|
||||
config.email = { services: { enabled: [] } };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[email.services.enabled]: array size is [0], but cannot be smaller than [1]"`
|
||||
);
|
||||
});
|
||||
|
||||
test('validates email config with enabled services', () => {
|
||||
config.email = { services: { enabled: ['elastic-cloud', 'amazon-ses'] } };
|
||||
const result = configSchema.validate(config);
|
||||
expect(result.email?.services?.enabled).toEqual(['elastic-cloud', 'amazon-ses']);
|
||||
});
|
||||
|
||||
test('validates email config with unexistend service', () => {
|
||||
config.email = { services: { enabled: ['fake-service'] } };
|
||||
expect(() => configSchema.validate(config)).toThrowErrorMatchingInlineSnapshot(`
|
||||
"[email.services.enabled.0]: types that failed validation:
|
||||
- [email.services.enabled.0.0]: expected value to equal [google-mail]
|
||||
- [email.services.enabled.0.1]: expected value to equal [microsoft-exchange]
|
||||
- [email.services.enabled.0.2]: expected value to equal [microsoft-outlook]
|
||||
- [email.services.enabled.0.3]: expected value to equal [amazon-ses]
|
||||
- [email.services.enabled.0.4]: expected value to equal [elastic-cloud]
|
||||
- [email.services.enabled.0.5]: expected value to equal [other]
|
||||
- [email.services.enabled.0.6]: expected value to equal [*]"
|
||||
`);
|
||||
});
|
||||
|
||||
test('validates enabled services but no ses service', () => {
|
||||
config.email = { services: { enabled: ['google-mail', 'amazon-ses'] } };
|
||||
const result = configSchema.validate(config);
|
||||
expect(result.email?.services?.enabled).toEqual(['google-mail', 'amazon-ses']);
|
||||
expect(result.email?.services?.ses).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// object creator that ensures we can create a property named __proto__ on an
|
||||
|
|
|
@ -125,22 +125,43 @@ export const configSchema = schema.object({
|
|||
{
|
||||
domain_allowlist: schema.maybe(schema.arrayOf(schema.string())),
|
||||
services: schema.maybe(
|
||||
schema.object({
|
||||
ses: schema.object({
|
||||
host: schema.maybe(schema.string({ minLength: 1 })),
|
||||
port: schema.maybe(schema.number({ min: 1, max: 65535 })),
|
||||
}),
|
||||
})
|
||||
schema.object(
|
||||
{
|
||||
enabled: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.oneOf([
|
||||
schema.literal('google-mail'),
|
||||
schema.literal('microsoft-exchange'),
|
||||
schema.literal('microsoft-outlook'),
|
||||
schema.literal('amazon-ses'),
|
||||
schema.literal('elastic-cloud'),
|
||||
schema.literal('other'),
|
||||
schema.literal('*'),
|
||||
]),
|
||||
{ minSize: 1 }
|
||||
)
|
||||
),
|
||||
ses: schema.maybe(
|
||||
schema.object({
|
||||
host: schema.string({ minLength: 1 }),
|
||||
port: schema.number({ min: 1, max: 65535 }),
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
validate: (obj) => {
|
||||
if (obj && Object.keys(obj).length === 0) {
|
||||
return 'email.services.enabled or email.services.ses must be defined';
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
validate: (obj) => {
|
||||
if (!obj.domain_allowlist && !obj.services?.ses.host && !obj.services?.ses.port) {
|
||||
return 'Email configuration requires either domain_allowlist or services.ses to be specified';
|
||||
}
|
||||
|
||||
if (obj.services?.ses && (!obj.services.ses.host || !obj.services.ses.port)) {
|
||||
return 'Email configuration requires both services.ses.host and services.ses.port to be specified';
|
||||
if (obj && Object.keys(obj).length === 0) {
|
||||
return 'email.domain_allowlist or email.services must be defined';
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ export type { ServiceParams } from './sub_action_framework/types';
|
|||
export const config: PluginConfigDescriptor<ActionsConfig> = {
|
||||
schema: configSchema,
|
||||
exposeToBrowser: {
|
||||
email: { domain_allowlist: true },
|
||||
email: { domain_allowlist: true, services: { enabled: true } },
|
||||
webhook: { ssl: { pfx: { enabled: true } } },
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const serviceParamValueToKbnSettingMap = {
|
||||
gmail: 'google-mail',
|
||||
outlook365: 'microsoft-outlook',
|
||||
ses: 'amazon-ses',
|
||||
elastic_cloud: 'elastic-cloud',
|
||||
exchange_server: 'microsoft-exchange',
|
||||
other: 'other',
|
||||
} as const;
|
|
@ -8,7 +8,7 @@
|
|||
import { TypeRegistry } from '@kbn/triggers-actions-ui-plugin/public/application/type_registry';
|
||||
import { registerConnectorTypes } from '..';
|
||||
import type { ActionTypeModel as ConnectorTypeModel } from '@kbn/triggers-actions-ui-plugin/public/types';
|
||||
import { getEmailServices } from './email';
|
||||
import { emailServices, getEmailServices } from './email';
|
||||
import {
|
||||
ValidatedEmail,
|
||||
InvalidEmailReason,
|
||||
|
@ -17,6 +17,7 @@ import {
|
|||
} from '@kbn/actions-plugin/common';
|
||||
import { experimentalFeaturesMock } from '../../mocks';
|
||||
import { ExperimentalFeaturesService } from '../../common/experimental_features_service';
|
||||
import { serviceParamValueToKbnSettingMap } from '../../../common/email/constants';
|
||||
|
||||
const CONNECTOR_TYPE_ID = '.email';
|
||||
let connectorTypeModel: ConnectorTypeModel;
|
||||
|
@ -65,14 +66,65 @@ describe('connectorTypeRegistry.get() works', () => {
|
|||
|
||||
describe('getEmailServices', () => {
|
||||
test('should return elastic cloud service if isCloudEnabled is true', () => {
|
||||
const services = getEmailServices(true);
|
||||
const services = getEmailServices(true, ['*']);
|
||||
expect(services.find((service) => service.value === 'elastic_cloud')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should not return elastic cloud service if isCloudEnabled is false', () => {
|
||||
const services = getEmailServices(false);
|
||||
const services = getEmailServices(false, ['*']);
|
||||
expect(services.find((service) => service.value === 'elastic_cloud')).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should return all services if enabledEmailsServices is *', () => {
|
||||
const services = getEmailServices(true, ['*']);
|
||||
expect(services).toEqual(emailServices);
|
||||
});
|
||||
|
||||
test('should return only specified services if enabledEmailsServices is not empty', () => {
|
||||
const services = getEmailServices(true, [
|
||||
serviceParamValueToKbnSettingMap.gmail,
|
||||
serviceParamValueToKbnSettingMap.outlook365,
|
||||
]);
|
||||
|
||||
expect(services).toEqual([
|
||||
{
|
||||
['kbn-setting-value']: 'google-mail',
|
||||
text: 'Gmail',
|
||||
value: 'gmail',
|
||||
},
|
||||
{
|
||||
['kbn-setting-value']: 'microsoft-outlook',
|
||||
text: 'Outlook',
|
||||
value: 'outlook365',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('should return enabled services and the current service if specified', () => {
|
||||
const services = getEmailServices(
|
||||
true,
|
||||
[serviceParamValueToKbnSettingMap.gmail, serviceParamValueToKbnSettingMap.outlook365],
|
||||
serviceParamValueToKbnSettingMap.other
|
||||
);
|
||||
|
||||
expect(services).toEqual([
|
||||
{
|
||||
['kbn-setting-value']: 'google-mail',
|
||||
text: 'Gmail',
|
||||
value: 'gmail',
|
||||
},
|
||||
{
|
||||
['kbn-setting-value']: 'microsoft-outlook',
|
||||
text: 'Outlook',
|
||||
value: 'outlook365',
|
||||
},
|
||||
{
|
||||
['kbn-setting-value']: 'other',
|
||||
text: 'Other',
|
||||
value: 'other',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('action params validation', () => {
|
||||
|
|
|
@ -16,50 +16,76 @@ import type {
|
|||
} from '@kbn/triggers-actions-ui-plugin/public/types';
|
||||
import { EmailActionParams, EmailConfig, EmailSecrets } from '../types';
|
||||
import { RegistrationServices } from '..';
|
||||
import { serviceParamValueToKbnSettingMap as emailKbnSettings } from '../../../common/email/constants';
|
||||
|
||||
const emailServices: EuiSelectOption[] = [
|
||||
export const emailServices: Array<EuiSelectOption & { 'kbn-setting-value': string }> = [
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.gmailServerTypeLabel', {
|
||||
defaultMessage: 'Gmail',
|
||||
}),
|
||||
value: 'gmail',
|
||||
['kbn-setting-value']: emailKbnSettings.gmail,
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.outlookServerTypeLabel', {
|
||||
defaultMessage: 'Outlook',
|
||||
}),
|
||||
value: 'outlook365',
|
||||
['kbn-setting-value']: emailKbnSettings.outlook365,
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.amazonSesServerTypeLabel', {
|
||||
defaultMessage: 'Amazon SES',
|
||||
}),
|
||||
value: 'ses',
|
||||
['kbn-setting-value']: emailKbnSettings.ses,
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.elasticCloudServerTypeLabel', {
|
||||
defaultMessage: 'Elastic Cloud',
|
||||
}),
|
||||
value: 'elastic_cloud',
|
||||
['kbn-setting-value']: emailKbnSettings.elastic_cloud,
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.exchangeServerTypeLabel', {
|
||||
defaultMessage: 'MS Exchange Server',
|
||||
}),
|
||||
value: 'exchange_server',
|
||||
['kbn-setting-value']: emailKbnSettings.exchange_server,
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.stackConnectors.components.email.otherServerTypeLabel', {
|
||||
defaultMessage: 'Other',
|
||||
}),
|
||||
value: 'other',
|
||||
['kbn-setting-value']: emailKbnSettings.other,
|
||||
},
|
||||
];
|
||||
|
||||
export function getEmailServices(isCloudEnabled: boolean) {
|
||||
return isCloudEnabled
|
||||
// Return the current service regardless of its enabled state to allow users to:
|
||||
// 1. View the current service in the dropdown UI
|
||||
// 2. Update the service configuration if needed
|
||||
// Note: The connector update endpoint will reject updates where the service
|
||||
// remains unchanged but is disabled.
|
||||
export function getEmailServices(
|
||||
isCloudEnabled: boolean,
|
||||
enabledEmailsServices: string[],
|
||||
currentService?: string
|
||||
): Array<EuiSelectOption & { 'kbn-setting-value': string }> {
|
||||
const allEmailServices = isCloudEnabled
|
||||
? emailServices
|
||||
: emailServices.filter((service) => service.value !== 'elastic_cloud');
|
||||
|
||||
if (enabledEmailsServices.includes('*')) {
|
||||
return allEmailServices;
|
||||
}
|
||||
|
||||
return allEmailServices.filter(
|
||||
(service) =>
|
||||
service.value === currentService ||
|
||||
enabledEmailsServices.includes(service['kbn-setting-value'])
|
||||
);
|
||||
}
|
||||
|
||||
export function getConnectorType(
|
||||
|
|
|
@ -7,22 +7,34 @@
|
|||
|
||||
import React, { Suspense } from 'react';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { act } from '@testing-library/react';
|
||||
import { act, screen, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { useKibana } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import EmailActionConnectorFields from './email_connector';
|
||||
import * as hooks from './use_email_config';
|
||||
import {
|
||||
AppMockRenderer,
|
||||
ConnectorFormTestProvider,
|
||||
createAppMockRenderer,
|
||||
waitForComponentToUpdate,
|
||||
} from '../lib/test_utils';
|
||||
import { getServiceConfig } from './api';
|
||||
|
||||
jest.mock('@kbn/triggers-actions-ui-plugin/public/common/lib/kibana');
|
||||
const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>;
|
||||
|
||||
jest.mock('./api', () => {
|
||||
return {
|
||||
getServiceConfig: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('EmailActionConnectorFields', () => {
|
||||
const enabledEmailServices = ['*'];
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('all connector fields are rendered', async () => {
|
||||
const actionConnector = {
|
||||
secrets: {
|
||||
|
@ -170,12 +182,11 @@ describe('EmailActionConnectorFields', () => {
|
|||
});
|
||||
|
||||
test('host, port and secure fields should be disabled when service field is set to well known service', async () => {
|
||||
const getEmailServiceConfig = jest
|
||||
.fn()
|
||||
.mockResolvedValue({ host: 'https://example.com', port: 80, secure: false });
|
||||
jest
|
||||
.spyOn(hooks, 'useEmailConfig')
|
||||
.mockImplementation(() => ({ isLoading: false, getEmailServiceConfig }));
|
||||
(getServiceConfig as jest.Mock).mockResolvedValue({
|
||||
host: 'https://example.com',
|
||||
port: 80,
|
||||
secure: false,
|
||||
});
|
||||
|
||||
const actionConnector = {
|
||||
secrets: {
|
||||
|
@ -214,12 +225,11 @@ describe('EmailActionConnectorFields', () => {
|
|||
});
|
||||
|
||||
test('host, port and secure fields should not be disabled when service field is set to other', async () => {
|
||||
const getEmailServiceConfig = jest
|
||||
.fn()
|
||||
.mockResolvedValue({ host: 'https://example.com', port: 80, secure: false });
|
||||
jest
|
||||
.spyOn(hooks, 'useEmailConfig')
|
||||
.mockImplementation(() => ({ isLoading: false, getEmailServiceConfig }));
|
||||
(getServiceConfig as jest.Mock).mockResolvedValue({
|
||||
host: 'https://example.com',
|
||||
port: 80,
|
||||
secure: false,
|
||||
});
|
||||
|
||||
const actionConnector = {
|
||||
secrets: {
|
||||
|
@ -292,7 +302,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -356,7 +366,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -415,7 +425,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -463,7 +473,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -509,7 +519,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -554,7 +564,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<EmailActionConnectorFields
|
||||
|
@ -603,7 +613,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -649,7 +659,7 @@ describe('EmailActionConnectorFields', () => {
|
|||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses }}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
|
@ -689,3 +699,102 @@ describe('EmailActionConnectorFields', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not all email services are enabled', () => {
|
||||
const enabledEmailServices = ['amazon-ses', 'other', 'microsoft-exchange'];
|
||||
let appMockRenderer: AppMockRenderer;
|
||||
const onSubmit = jest.fn();
|
||||
const validateEmailAddresses = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
appMockRenderer = createAppMockRenderer();
|
||||
validateEmailAddresses.mockReturnValue([{ valid: true }]);
|
||||
(getServiceConfig as jest.Mock).mockResolvedValue({
|
||||
host: 'https://example.com',
|
||||
port: 2255,
|
||||
secure: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('only allows enabled services to be selected only', async () => {
|
||||
const actionConnector = {
|
||||
secrets: {
|
||||
user: 'user',
|
||||
password: 'pass',
|
||||
},
|
||||
id: 'test',
|
||||
actionTypeId: '.email',
|
||||
name: 'email',
|
||||
config: {},
|
||||
isDeprecated: false,
|
||||
};
|
||||
|
||||
appMockRenderer.render(
|
||||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
isEdit={false}
|
||||
registerPreSubmitValidator={() => {}}
|
||||
/>
|
||||
</ConnectorFormTestProvider>
|
||||
);
|
||||
|
||||
const emailServiceSelect = screen.getByTestId('emailServiceSelectInput') as HTMLSelectElement;
|
||||
|
||||
const options = within(emailServiceSelect).getAllByRole('option');
|
||||
expect(options).toHaveLength(3);
|
||||
expect(options[0].textContent).toBe('Amazon SES');
|
||||
expect(options[1].textContent).toBe('MS Exchange Server');
|
||||
expect(options[2].textContent).toBe('Other');
|
||||
});
|
||||
|
||||
it('adds the current connector service to the service list even if not enabled', async () => {
|
||||
const actionConnector = {
|
||||
secrets: {
|
||||
user: 'user',
|
||||
password: 'pass',
|
||||
},
|
||||
id: 'test',
|
||||
actionTypeId: '.email',
|
||||
name: 'email',
|
||||
config: {
|
||||
from: 'test@test.com',
|
||||
test: 'test',
|
||||
service: 'gmail', // not enabled
|
||||
secure: true,
|
||||
},
|
||||
isDeprecated: false,
|
||||
};
|
||||
|
||||
appMockRenderer.render(
|
||||
<ConnectorFormTestProvider
|
||||
connector={actionConnector}
|
||||
onSubmit={onSubmit}
|
||||
connectorServices={{ validateEmailAddresses, enabledEmailServices }}
|
||||
>
|
||||
<EmailActionConnectorFields
|
||||
readOnly={false}
|
||||
isEdit={false}
|
||||
registerPreSubmitValidator={() => {}}
|
||||
/>
|
||||
</ConnectorFormTestProvider>
|
||||
);
|
||||
|
||||
const emailServiceSelect = screen.getByTestId('emailServiceSelectInput') as HTMLSelectElement;
|
||||
|
||||
const options = within(emailServiceSelect).getAllByRole('option');
|
||||
expect(options).toHaveLength(4);
|
||||
expect(options[0].textContent).toBe('Gmail');
|
||||
expect(options[1].textContent).toBe('Amazon SES');
|
||||
expect(options[2].textContent).toBe('MS Exchange Server');
|
||||
expect(options[3].textContent).toBe('Other');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { lazy, useEffect, useMemo } from 'react';
|
||||
import React, { lazy, useEffect, useMemo, useRef } from 'react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { EuiFlexItem, EuiFlexGroup, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -102,7 +102,7 @@ export const EmailActionConnectorFields: React.FunctionComponent<ActionConnector
|
|||
notifications: { toasts },
|
||||
} = useKibana().services;
|
||||
const {
|
||||
services: { validateEmailAddresses },
|
||||
services: { validateEmailAddresses, enabledEmailServices },
|
||||
} = useConnectorContext();
|
||||
|
||||
const form = useFormContext();
|
||||
|
@ -119,6 +119,15 @@ export const EmailActionConnectorFields: React.FunctionComponent<ActionConnector
|
|||
const { service = null, hasAuth = false } = config ?? {};
|
||||
const disableServiceConfig = shouldDisableEmailConfiguration(service);
|
||||
const { isLoading, getEmailServiceConfig } = useEmailConfig({ http, toasts });
|
||||
const initialService = useRef(service);
|
||||
if (!initialService.current && service) {
|
||||
initialService.current = service;
|
||||
}
|
||||
const availableEmailServices = getEmailServices(
|
||||
isCloud,
|
||||
enabledEmailServices,
|
||||
initialService.current
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchConfig() {
|
||||
|
@ -173,7 +182,7 @@ export const EmailActionConnectorFields: React.FunctionComponent<ActionConnector
|
|||
componentProps={{
|
||||
euiFieldProps: {
|
||||
'data-test-subj': 'emailServiceSelectInput',
|
||||
options: getEmailServices(isCloud),
|
||||
options: availableEmailServices,
|
||||
fullWidth: true,
|
||||
hasNoInitialSelection: true,
|
||||
disabled: readOnly || isLoading,
|
||||
|
|
|
@ -74,6 +74,7 @@ const FormTestProviderComponent: React.FC<FormTestProviderProps> = ({
|
|||
connectorServices = {
|
||||
validateEmailAddresses: jest.fn(),
|
||||
isWebhookSslWithPfxEnabled: true,
|
||||
enabledEmailServices: ['*'],
|
||||
},
|
||||
}) => {
|
||||
const { form } = useForm({ defaultValue });
|
||||
|
|
|
@ -34,6 +34,7 @@ import { getConnectorType } from '.';
|
|||
import type { ValidateEmailAddressesOptions } from '@kbn/actions-plugin/common';
|
||||
import { ActionExecutionSourceType } from '@kbn/actions-plugin/server/types';
|
||||
import { AdditionalEmailServices } from '../../../common';
|
||||
import { serviceParamValueToKbnSettingMap } from '../../../common/email/constants';
|
||||
|
||||
const sendEmailMock = sendEmail as jest.Mock;
|
||||
|
||||
|
@ -503,6 +504,75 @@ describe('params validation', () => {
|
|||
);
|
||||
}).not.toThrowError();
|
||||
});
|
||||
|
||||
test('error when using a service that is not enabled', async () => {
|
||||
const configUtils = actionsConfigMock.create();
|
||||
configUtils.getEnabledEmailServices = jest
|
||||
.fn()
|
||||
.mockReturnValue([
|
||||
serviceParamValueToKbnSettingMap.gmail,
|
||||
serviceParamValueToKbnSettingMap.elastic_cloud,
|
||||
]);
|
||||
|
||||
expect(() =>
|
||||
validateConfig(
|
||||
connectorType,
|
||||
{
|
||||
service: 'other',
|
||||
from: 'bob@example.com',
|
||||
host: 'wrong-host',
|
||||
port: 123,
|
||||
secure: true,
|
||||
hasAuth: true,
|
||||
},
|
||||
{ configurationUtilities: configUtils }
|
||||
)
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"error validating action type config: [service]: \\"other\\" is not in the list of enabled email services: google-mail,elastic-cloud"`
|
||||
);
|
||||
});
|
||||
|
||||
test('no error using enabled services = *', async () => {
|
||||
const configUtils = actionsConfigMock.create();
|
||||
configUtils.getEnabledEmailServices = jest.fn().mockReturnValue(['*']);
|
||||
|
||||
expect(() =>
|
||||
validateConfig(
|
||||
connectorType,
|
||||
{
|
||||
service: 'other',
|
||||
from: 'bob@example.com',
|
||||
host: 'wrong-host',
|
||||
port: 123,
|
||||
secure: true,
|
||||
hasAuth: true,
|
||||
},
|
||||
{ configurationUtilities: configUtils }
|
||||
)
|
||||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('does not throw when fetching service enabled in config', () => {
|
||||
const configUtils = actionsConfigMock.create();
|
||||
configUtils.getEnabledEmailServices = jest
|
||||
.fn()
|
||||
.mockReturnValue([serviceParamValueToKbnSettingMap.elastic_cloud]);
|
||||
|
||||
expect(() =>
|
||||
validateConfig(
|
||||
connectorType,
|
||||
{
|
||||
service: 'elastic_cloud',
|
||||
from: 'bob@example.com',
|
||||
host: 'dockerhost',
|
||||
port: 10025,
|
||||
secure: false,
|
||||
hasAuth: false,
|
||||
},
|
||||
{ configurationUtilities: configUtils }
|
||||
)
|
||||
).not.toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('execute()', () => {
|
||||
|
|
|
@ -34,6 +34,7 @@ import { AdditionalEmailServices } from '../../../common';
|
|||
import type { SendEmailOptions, Transport } from './send_email';
|
||||
import { sendEmail, JSON_TRANSPORT_SERVICE } from './send_email';
|
||||
import { portSchema } from '../lib/schemas';
|
||||
import { serviceParamValueToKbnSettingMap as emailKbnSettings } from '../../../common/email/constants';
|
||||
|
||||
export type EmailConnectorType = ConnectorType<
|
||||
ConnectorTypeConfigType,
|
||||
|
@ -82,6 +83,20 @@ function validateConfig(
|
|||
const config = configObject;
|
||||
const { configurationUtilities } = validatorServices;
|
||||
const awsSesConfig = configurationUtilities.getAwsSesConfig();
|
||||
const enabledServices = configurationUtilities.getEnabledEmailServices();
|
||||
|
||||
const serviceKey = config.service as keyof typeof emailKbnSettings;
|
||||
if (
|
||||
!enabledServices.includes('*') &&
|
||||
config.service in emailKbnSettings &&
|
||||
!enabledServices.includes(emailKbnSettings[serviceKey])
|
||||
) {
|
||||
throw new Error(
|
||||
`[service]: "${
|
||||
emailKbnSettings[serviceKey]
|
||||
}" is not in the list of enabled email services: ${enabledServices.join(',')}`
|
||||
);
|
||||
}
|
||||
|
||||
const emails = [config.from];
|
||||
const invalidEmailsMessage = configurationUtilities.validateEmailAddresses(emails);
|
||||
|
|
|
@ -24,7 +24,7 @@ const FormTestProviderComponent: React.FC<FormTestProviderProps> = ({
|
|||
children,
|
||||
defaultValue,
|
||||
onSubmit,
|
||||
connectorServices = { validateEmailAddresses: jest.fn() },
|
||||
connectorServices = { validateEmailAddresses: jest.fn(), enabledEmailServices: ['*'] },
|
||||
}) => {
|
||||
const { form } = useForm({ defaultValue });
|
||||
const { submit } = form;
|
||||
|
|
|
@ -90,11 +90,15 @@ export const App = ({ deps }: { deps: TriggersAndActionsUiServices }) => {
|
|||
|
||||
export const AppWithoutRouter = ({ sectionsRegex }: { sectionsRegex: string }) => {
|
||||
const {
|
||||
actions: { validateEmailAddresses, isWebhookSslWithPfxEnabled },
|
||||
actions: { validateEmailAddresses, enabledEmailServices, isWebhookSslWithPfxEnabled },
|
||||
} = useKibana().services;
|
||||
|
||||
return (
|
||||
<ConnectorProvider value={{ services: { validateEmailAddresses, isWebhookSslWithPfxEnabled } }}>
|
||||
<ConnectorProvider
|
||||
value={{
|
||||
services: { validateEmailAddresses, enabledEmailServices, isWebhookSslWithPfxEnabled },
|
||||
}}
|
||||
>
|
||||
<Routes>
|
||||
<Route
|
||||
path={`/:section(${sectionsRegex})`}
|
||||
|
|
|
@ -14,13 +14,13 @@ const style = {
|
|||
|
||||
export const RulesListSandbox = () => {
|
||||
const {
|
||||
services: { validateEmailAddresses },
|
||||
services: { validateEmailAddresses, enabledEmailServices },
|
||||
} = useConnectorContext();
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
{getRulesListLazy({
|
||||
connectorServices: { validateEmailAddresses },
|
||||
connectorServices: { validateEmailAddresses, enabledEmailServices },
|
||||
rulesListProps: {},
|
||||
})}
|
||||
</div>
|
||||
|
|
|
@ -120,12 +120,12 @@ export const App = ({ deps }: { deps: TriggersAndActionsUiServices }) => {
|
|||
|
||||
export const AppWithoutRouter = ({ sectionsRegex }: { sectionsRegex: string }) => {
|
||||
const {
|
||||
actions: { validateEmailAddresses },
|
||||
actions: { validateEmailAddresses, enabledEmailServices },
|
||||
application: { navigateToApp },
|
||||
} = useKibana().services;
|
||||
|
||||
return (
|
||||
<ConnectorProvider value={{ services: { validateEmailAddresses } }}>
|
||||
<ConnectorProvider value={{ services: { validateEmailAddresses, enabledEmailServices } }}>
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
|
|
|
@ -27,7 +27,7 @@ export const createStartServicesMock = (): TriggersAndActionsUiServices => {
|
|||
const licensingPluginMock = licensingMock.createStart();
|
||||
return {
|
||||
...core,
|
||||
actions: { validateEmailAddresses: jest.fn() },
|
||||
actions: { validateEmailAddresses: jest.fn(), enabledEmailServices: ['*'] },
|
||||
ruleTypeRegistry: {
|
||||
has: jest.fn(),
|
||||
register: jest.fn(),
|
||||
|
|
|
@ -49,7 +49,7 @@ import { getUntrackModalLazy } from './common/get_untrack_modal';
|
|||
function createStartMock(): TriggersAndActionsUIPublicPluginStart {
|
||||
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
|
||||
const ruleTypeRegistry = new TypeRegistry<RuleTypeModel>();
|
||||
const connectorServices = { validateEmailAddresses: jest.fn() };
|
||||
const connectorServices = { validateEmailAddresses: jest.fn(), enabledEmailServices: ['*'] };
|
||||
return {
|
||||
actionTypeRegistry,
|
||||
ruleTypeRegistry,
|
||||
|
|
|
@ -205,6 +205,7 @@ export class Plugin
|
|||
const ruleTypeRegistry = this.ruleTypeRegistry;
|
||||
this.connectorServices = {
|
||||
validateEmailAddresses: plugins.actions.validateEmailAddresses,
|
||||
enabledEmailServices: plugins.actions.enabledEmailServices,
|
||||
};
|
||||
|
||||
ExperimentalFeaturesService.init({ experimentalFeatures: this.experimentalFeatures });
|
||||
|
|
|
@ -400,6 +400,7 @@ export interface SnoozeSchedule {
|
|||
|
||||
export interface ConnectorServices {
|
||||
validateEmailAddresses: ActionsPublicPluginSetup['validateEmailAddresses'];
|
||||
enabledEmailServices: ActionsPublicPluginSetup['enabledEmailServices'];
|
||||
isWebhookSslWithPfxEnabled?: ActionsPublicPluginSetup['isWebhookSslWithPfxEnabled'];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const emailEnabledServices = ['google-mail', 'amazon-ses'];
|
||||
|
||||
import { FtrConfigProviderContext } from '@kbn/test';
|
||||
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const baseConfig = await readConfigFile(require.resolve('../../../../config.base.ts'));
|
||||
|
||||
return {
|
||||
...baseConfig.getAll(),
|
||||
testFiles: [require.resolve('.')],
|
||||
junit: {
|
||||
reportName:
|
||||
'Chrome X-Pack UI Functional Tests with ES SSL - Email services enabled Kibana config',
|
||||
},
|
||||
kbnTestServer: {
|
||||
...baseConfig.getAll().kbnTestServer,
|
||||
serverArgs: [
|
||||
...baseConfig.getAll().kbnTestServer.serverArgs,
|
||||
`--xpack.actions.email.services.enabled=${JSON.stringify(emailEnabledServices)}`,
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']);
|
||||
const find = getService('find');
|
||||
|
||||
describe('Email - with multiple enabled services config', () => {
|
||||
beforeEach(async () => {
|
||||
await pageObjects.common.navigateToApp('triggersActionsConnectors');
|
||||
});
|
||||
|
||||
it('should use the kibana config for enabled services', async () => {
|
||||
await pageObjects.triggersActionsUI.clickCreateConnectorButton();
|
||||
await testSubjects.click('.email-card');
|
||||
const emailServicesOptions = await find.allByCssSelector(
|
||||
'[data-test-subj="emailServiceSelectInput"] > option'
|
||||
);
|
||||
expect(emailServicesOptions.length).to.be(3);
|
||||
expect(await emailServicesOptions[0].getVisibleText()).to.be(' '); // empty option
|
||||
expect(await emailServicesOptions[1].getVisibleText()).to.be('Gmail');
|
||||
expect(await emailServicesOptions[2].getVisibleText()).to.be('Amazon SES');
|
||||
});
|
||||
});
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { FtrProviderContext } from '@kbn/test-suites-xpack-platform/alerting_api_integration/common/ftr_provider_context';
|
||||
import {
|
||||
buildUp,
|
||||
tearDown,
|
||||
} from '@kbn/test-suites-xpack-platform/alerting_api_integration/spaces_only/tests/helpers';
|
||||
|
||||
export default function actionsTests({ loadTestFile, getService }: FtrProviderContext) {
|
||||
describe('Connectors with email services enabled Kibana config', () => {
|
||||
before(async () => buildUp(getService));
|
||||
after(async () => tearDown(getService));
|
||||
|
||||
loadTestFile(require.resolve('./email'));
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue