Skip to content

Commit 09732bd

Browse files
committed
Merge branch 'master' into alerts/custom-recovery-action-group
* master: [Security Solution] Exceptions Cypress tests (elastic#81759) [ML] Fix spaces job ID check (elastic#84404) [Security Solution][Detections] Handle dupes when processing threshold rules (elastic#83062) skip flaky suite (elastic#84440) skip flaky suite (elastic#84445) [APM] Fix missing `service.node.name` (elastic#84269) Upgrade fp-ts to 2.8.6 (elastic#83866) Added data streams privileges to better control delete actions in UI (elastic#83573) Improve short-url redirect validation (elastic#84366) TSVB offsets (elastic#83051) [Discover] Fix navigating back when changing index pattern (elastic#84061) [Logs UI] Polish the UI for the log entry examples in the anomaly table (elastic#82139) [Logs UI] Limit the height of the "view in context" container (elastic#83178) [Application Usage] Update `schema` with new `fleet` rename (elastic#84327) fix identation in list (elastic#84301)
2 parents 23f1433 + 4546352 commit 09732bd

File tree

76 files changed

+8360
-389
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+8360
-389
lines changed

docs/developer/plugin/migrating-legacy-plugins-examples.asciidoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,9 @@ The most significant changes on the Kibana side for the consumers are the follow
902902
===== User client accessor
903903
Internal /current user client accessors has been renamed and are now
904904
properties instead of functions:
905-
** `callAsInternalUser('ping')` -> `asInternalUser.ping()`
906-
** `callAsCurrentUser('ping')` -> `asCurrentUser.ping()`
905+
906+
* `callAsInternalUser('ping')` -> `asInternalUser.ping()`
907+
* `callAsCurrentUser('ping')` -> `asCurrentUser.ping()`
907908
* the API now reflects the `Client`’s instead of leveraging the
908909
string-based endpoint names the `LegacyAPICaller` was using.
909910

src/plugins/discover/public/application/angular/discover.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
252252
if (!_.isEqual(newStatePartial, oldStatePartial)) {
253253
$scope.$evalAsync(async () => {
254254
if (oldStatePartial.index !== newStatePartial.index) {
255-
//in case of index switch the route has currently to be reloaded, legacy
255+
//in case of index pattern switch the route has currently to be reloaded, legacy
256+
$route.reload();
256257
return;
257258
}
258259

@@ -289,8 +290,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
289290
$scope.state.sort,
290291
config.get(MODIFY_COLUMNS_ON_SWITCH)
291292
);
292-
await replaceUrlAppState(nextAppState);
293-
$route.reload();
293+
await setAppState(nextAppState);
294294
}
295295
};
296296

src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const applicationUsageSchema = {
7373
logs: commonSchema,
7474
metrics: commonSchema,
7575
infra: commonSchema, // It's a forward app so we'll likely never report it
76-
ingestManager: commonSchema,
76+
fleet: commonSchema,
7777
lens: commonSchema,
7878
maps: commonSchema,
7979
ml: commonSchema,

src/plugins/share/server/routes/lib/short_url_assert_valid.test.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,39 @@
1919

2020
import { shortUrlAssertValid } from './short_url_assert_valid';
2121

22+
const PROTOCOL_ERROR = /^Short url targets cannot have a protocol/;
23+
const HOSTNAME_ERROR = /^Short url targets cannot have a hostname/;
24+
const PATH_ERROR = /^Short url target path must be in the format/;
25+
2226
describe('shortUrlAssertValid()', () => {
2327
const invalid = [
24-
['protocol', 'http://localhost:5601/app/kibana'],
25-
['protocol', 'https://localhost:5601/app/kibana'],
26-
['protocol', 'mailto:foo@bar.net'],
27-
['protocol', 'javascript:alert("hi")'], // eslint-disable-line no-script-url
28-
['hostname', 'localhost/app/kibana'],
29-
['hostname and port', 'local.host:5601/app/kibana'],
30-
['hostname and auth', 'user:pass@localhost.net/app/kibana'],
31-
['path traversal', '/app/../../not-kibana'],
32-
['deep path', '/app/kibana/foo'],
33-
['deep path', '/app/kibana/foo/bar'],
34-
['base path', '/base/app/kibana'],
28+
['protocol', 'http://localhost:5601/app/kibana', PROTOCOL_ERROR],
29+
['protocol', 'https://localhost:5601/app/kibana', PROTOCOL_ERROR],
30+
['protocol', 'mailto:foo@bar.net', PROTOCOL_ERROR],
31+
['protocol', 'javascript:alert("hi")', PROTOCOL_ERROR], // eslint-disable-line no-script-url
32+
['hostname', 'localhost/app/kibana', PATH_ERROR], // according to spec, this is not a valid URL -- you cannot specify a hostname without a protocol
33+
['hostname and port', 'local.host:5601/app/kibana', PROTOCOL_ERROR], // parser detects 'local.host' as the protocol
34+
['hostname and auth', 'user:pass@localhost.net/app/kibana', PROTOCOL_ERROR], // parser detects 'user' as the protocol
35+
['path traversal', '/app/../../not-kibana', PATH_ERROR], // fails because there are >2 path parts
36+
['path traversal', '/../not-kibana', PATH_ERROR], // fails because first path part is not 'app'
37+
['deep path', '/app/kibana/foo', PATH_ERROR], // fails because there are >2 path parts
38+
['deeper path', '/app/kibana/foo/bar', PATH_ERROR], // fails because there are >2 path parts
39+
['base path', '/base/app/kibana', PATH_ERROR], // fails because there are >2 path parts
40+
['path with an extra leading slash', '//foo/app/kibana', HOSTNAME_ERROR], // parser detects 'foo' as the hostname
41+
['path with an extra leading slash', '///app/kibana', HOSTNAME_ERROR], // parser detects '' as the hostname
42+
['path without app', '/foo/kibana', PATH_ERROR], // fails because first path part is not 'app'
43+
['path without appId', '/app/', PATH_ERROR], // fails because there is only one path part (leading and trailing slashes are trimmed)
3544
];
3645

37-
invalid.forEach(([desc, url]) => {
38-
it(`fails when url has ${desc}`, () => {
39-
try {
40-
shortUrlAssertValid(url);
41-
throw new Error(`expected assertion to throw`);
42-
} catch (err) {
43-
if (!err || !err.isBoom) {
44-
throw err;
45-
}
46-
}
46+
invalid.forEach(([desc, url, error]) => {
47+
it(`fails when url has ${desc as string}`, () => {
48+
expect(() => shortUrlAssertValid(url as string)).toThrowError(error);
4749
});
4850
});
4951

5052
const valid = [
5153
'/app/kibana',
54+
'/app/kibana/', // leading and trailing slashes are trimmed
5255
'/app/monitoring#angular/route',
5356
'/app/text#document-id',
5457
'/app/some?with=query',

src/plugins/share/server/routes/lib/short_url_assert_valid.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,22 @@ import { trim } from 'lodash';
2222
import Boom from '@hapi/boom';
2323

2424
export function shortUrlAssertValid(url: string) {
25-
const { protocol, hostname, pathname } = parse(url);
25+
const { protocol, hostname, pathname } = parse(
26+
url,
27+
false /* parseQueryString */,
28+
true /* slashesDenoteHost */
29+
);
2630

27-
if (protocol) {
31+
if (protocol !== null) {
2832
throw Boom.notAcceptable(`Short url targets cannot have a protocol, found "${protocol}"`);
2933
}
3034

31-
if (hostname) {
35+
if (hostname !== null) {
3236
throw Boom.notAcceptable(`Short url targets cannot have a hostname, found "${hostname}"`);
3337
}
3438

3539
const pathnameParts = trim(pathname === null ? undefined : pathname, '/').split('/');
36-
if (pathnameParts.length !== 2) {
40+
if (pathnameParts.length !== 2 || pathnameParts[0] !== 'app' || !pathnameParts[1]) {
3741
throw Boom.notAcceptable(
3842
`Short url target path must be in the format "/app/{{appId}}", found "${pathname}"`
3943
);

src/plugins/telemetry/schema/oss_plugins.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@
616616
}
617617
}
618618
},
619-
"ingestManager": {
619+
"fleet": {
620620
"properties": {
621621
"clicks_total": {
622622
"type": "long"

src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/time_shift.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
import _ from 'lodash';
20+
import { startsWith } from 'lodash';
2121
import moment from 'moment';
2222

2323
export function timeShift(resp, panel, series) {
@@ -26,13 +26,15 @@ export function timeShift(resp, panel, series) {
2626
const matches = series.offset_time.match(/^([+-]?[\d]+)([shmdwMy]|ms)$/);
2727

2828
if (matches) {
29-
const offsetValue = Number(matches[1]);
29+
const offsetValue = matches[1];
3030
const offsetUnit = matches[2];
31-
const offset = moment.duration(offsetValue, offsetUnit).valueOf();
3231

3332
results.forEach((item) => {
34-
if (_.startsWith(item.id, series.id)) {
35-
item.data = item.data.map(([time, value]) => [time + offset, value]);
33+
if (startsWith(item.id, series.id)) {
34+
item.data = item.data.map((row) => [
35+
moment.utc(row[0]).add(offsetValue, offsetUnit).valueOf(),
36+
row[1],
37+
]);
3638
}
3739
});
3840
}

test/api_integration/apis/saved_objects/migrations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ function getLogMock() {
5454
export default ({ getService }: FtrProviderContext) => {
5555
const esClient = getService('es');
5656

57-
describe('Kibana index migration', () => {
57+
// FLAKY: https://github.com/elastic/kibana/issues/84445
58+
describe.skip('Kibana index migration', () => {
5859
before(() => esClient.indices.delete({ index: '.migrate-*' }));
5960

6061
it('Migrates an existing index that has never been migrated before', async () => {

test/functional/apps/discover/_indexpattern_without_timefield.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import { FtrProviderContext } from '../../ftr_provider_context';
2121

2222
export default function ({ getService, getPageObjects }: FtrProviderContext) {
23+
const browser = getService('browser');
2324
const esArchiver = getService('esArchiver');
2425
const kibanaServer = getService('kibanaServer');
2526
const security = getService('security');
@@ -50,5 +51,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
5051
throw new Error('Expected timepicker to exist');
5152
}
5253
});
54+
it('should switch between with and without timefield using the browser back button', async () => {
55+
await PageObjects.discover.selectIndexPattern('without-timefield');
56+
if (await PageObjects.timePicker.timePickerExists()) {
57+
throw new Error('Expected timepicker not to exist');
58+
}
59+
60+
await PageObjects.discover.selectIndexPattern('with-timefield');
61+
if (!(await PageObjects.timePicker.timePickerExists())) {
62+
throw new Error('Expected timepicker to exist');
63+
}
64+
// Navigating back to discover
65+
await browser.goBack();
66+
if (await PageObjects.timePicker.timePickerExists()) {
67+
throw new Error('Expected timepicker not to exist');
68+
}
69+
});
5370
});
5471
}

x-pack/plugins/alerts/public/alert_api.test.ts

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import { AlertType, RecoveredActionGroup } from '../common';
88
import { httpServiceMock } from '../../../../src/core/public/mocks';
9-
import { loadAlert, loadAlertState, loadAlertType, loadAlertTypes } from './alert_api';
9+
import { loadAlert, loadAlertType, loadAlertTypes } from './alert_api';
1010
import uuid from 'uuid';
1111

1212
const http = httpServiceMock.createStartContract();
@@ -118,67 +118,3 @@ describe('loadAlert', () => {
118118
expect(http.get).toHaveBeenCalledWith(`/api/alerts/alert/${alertId}`);
119119
});
120120
});
121-
122-
describe('loadAlertState', () => {
123-
test('should call get API with base parameters', async () => {
124-
const alertId = uuid.v4();
125-
const resolvedValue = {
126-
alertTypeState: {
127-
some: 'value',
128-
},
129-
alertInstances: {
130-
first_instance: {},
131-
second_instance: {},
132-
},
133-
};
134-
http.get.mockResolvedValueOnce(resolvedValue);
135-
136-
expect(await loadAlertState({ http, alertId })).toEqual(resolvedValue);
137-
expect(http.get).toHaveBeenCalledWith(`/api/alerts/alert/${alertId}/state`);
138-
});
139-
140-
test('should parse AlertInstances', async () => {
141-
const alertId = uuid.v4();
142-
const resolvedValue = {
143-
alertTypeState: {
144-
some: 'value',
145-
},
146-
alertInstances: {
147-
first_instance: {
148-
state: {},
149-
meta: {
150-
lastScheduledActions: {
151-
group: 'first_group',
152-
date: '2020-02-09T23:15:41.941Z',
153-
},
154-
},
155-
},
156-
},
157-
};
158-
http.get.mockResolvedValueOnce(resolvedValue);
159-
160-
expect(await loadAlertState({ http, alertId })).toEqual({
161-
...resolvedValue,
162-
alertInstances: {
163-
first_instance: {
164-
state: {},
165-
meta: {
166-
lastScheduledActions: {
167-
group: 'first_group',
168-
date: new Date('2020-02-09T23:15:41.941Z'),
169-
},
170-
},
171-
},
172-
},
173-
});
174-
expect(http.get).toHaveBeenCalledWith(`/api/alerts/alert/${alertId}/state`);
175-
});
176-
177-
test('should handle empty response from api', async () => {
178-
const alertId = uuid.v4();
179-
http.get.mockResolvedValueOnce('');
180-
181-
expect(await loadAlertState({ http, alertId })).toEqual({});
182-
expect(http.get).toHaveBeenCalledWith(`/api/alerts/alert/${alertId}/state`);
183-
});
184-
});

0 commit comments

Comments
 (0)