From 478571839d0d9f58869585356a0b1a2b8c26b8eb Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 28 Feb 2020 15:57:09 -0500 Subject: [PATCH 1/6] Switch back to querystring-browser library --- .eslintrc.js | 2 +- NOTICE.txt | 25 +++++++++++++++ package.json | 2 +- .../lib/get_webpack_config.js | 1 + src/core/server/http/http_server.mocks.ts | 4 +-- src/core/utils/url.ts | 4 +-- src/legacy/server/logging/log_format.js | 4 +-- .../editor/legacy/console_editor/editor.tsx | 4 +-- src/plugins/console/public/lib/es/es.ts | 4 +-- .../query/timefilter/lib/parse_querystring.ts | 4 +-- .../common/url/encode_uri_query.ts | 6 ++-- .../public/history/remove_query_param.ts | 6 ++-- .../public/state_management/url/format.ts | 9 ++---- .../state_management/url/kbn_url_storage.ts | 6 ++-- .../server/series_functions/quandl.test.js | 4 +-- .../components/shared/Links/url_helpers.ts | 6 ++-- .../public/containers/with_url_state.tsx | 17 ++++------ .../plugins/canvas/public/lib/app_state.ts | 4 +-- .../plugins/canvas/public/lib/modify_url.ts | 4 +-- .../public/app/services/query_params.js | 4 +-- .../public/app/services/routing.js | 15 +++++++-- .../analytics_job_exploration.tsx | 4 +-- .../routes/datavisualizer/index_based.tsx | 4 +-- .../routing/routes/new_job/job_type.tsx | 4 +-- .../routing/routes/new_job/recognize.tsx | 8 ++--- .../routing/routes/new_job/wizard.tsx | 4 +-- .../ml/public/application/util/url_state.ts | 14 ++++----- .../reporting/public/lib/reporting_client.ts | 2 +- .../ml_host_conditional_container.tsx | 27 +++++----------- .../ml_network_conditional_container.tsx | 31 +++++-------------- .../public/components/url_state/helpers.ts | 9 +++--- .../home/snapshot_list/snapshot_list.tsx | 4 +-- .../repository_add/repository_add.tsx | 4 +-- .../uptime/public/hooks/use_url_params.ts | 11 +++---- .../public/lib/helper/stringify_url_params.ts | 4 +-- .../plugins/uptime/public/state/api/ping.ts | 4 +-- x-pack/package.json | 1 - .../analyze_in_ml_button.tsx | 9 ++---- .../containers/with_state_from_location.tsx | 17 +++++----- .../pages/link_to/redirect_to_logs.test.tsx | 6 ++-- .../link_to/redirect_to_node_logs.test.tsx | 12 +++---- .../plugins/infra/public/utils/url_state.tsx | 9 +++--- .../infra/public/utils/use_url_state.ts | 9 +++--- .../application/services/query_params.js | 4 +-- x-pack/plugins/spaces/server/lib/utils/url.ts | 4 +-- .../rollup/index_patterns_extensions.js | 25 +++++++-------- .../apis/security/saml_login.ts | 6 ++-- .../fixtures/saml_tools.ts | 4 +-- yarn.lock | 24 +++----------- 49 files changed, 184 insertions(+), 215 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 087d6276cd33f..c41c36f0720cb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -349,7 +349,7 @@ module.exports = { settings: { // instructs import/no-extraneous-dependencies to treat certain modules // as core modules, even if they aren't listed in package.json - 'import/core-modules': ['plugins', 'legacy/ui', 'uiExports'], + 'import/core-modules': ['plugins', 'legacy/ui', 'uiExports', 'querystring'], 'import/resolver': { '@kbn/eslint-import-resolver-kibana': { diff --git a/NOTICE.txt b/NOTICE.txt index 33c1d535d7df3..69be6db72cff2 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -218,3 +218,28 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--- +This product includes code that was extracted from angular@1.3. +Original license: +The MIT License + +Copyright (c) 2010-2014 Google, Inc. http://angularjs.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/package.json b/package.json index 0f04a2fba3b65..c6d858124bc3c 100644 --- a/package.json +++ b/package.json @@ -225,7 +225,7 @@ "prop-types": "15.6.0", "proxy-from-env": "1.0.0", "pug": "^2.0.4", - "query-string": "6.10.1", + "querystring-browser": "1.0.4", "raw-loader": "3.1.0", "react": "^16.12.0", "react-color": "^2.13.8", diff --git a/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js b/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js index da0b799b338ed..e02c38494991a 100755 --- a/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js +++ b/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js @@ -29,6 +29,7 @@ exports.getWebpackConfig = function(kibanaPath, projectRoot, config) { // Kibana defaults https://github.com/elastic/kibana/blob/6998f074542e8c7b32955db159d15661aca253d7/src/legacy/ui/ui_bundler_env.js#L30-L36 ui: fromKibana('src/legacy/ui/public'), test_harness: fromKibana('src/test_harness/public'), + querystring: 'querystring-browser', // Dev defaults for test bundle https://github.com/elastic/kibana/blob/6998f074542e8c7b32955db159d15661aca253d7/src/core_plugins/tests_bundle/index.js#L73-L78 ng_mock$: fromKibana('src/test_utils/public/ng_mock'), diff --git a/src/core/server/http/http_server.mocks.ts b/src/core/server/http/http_server.mocks.ts index 0a9541393284e..97fab4bc2f6ea 100644 --- a/src/core/server/http/http_server.mocks.ts +++ b/src/core/server/http/http_server.mocks.ts @@ -19,7 +19,7 @@ import { Request } from 'hapi'; import { merge } from 'lodash'; import { Socket } from 'net'; -import { stringify } from 'query-string'; +import querystring from 'querystring'; import { schema } from '@kbn/config-schema'; @@ -63,7 +63,7 @@ function createKibanaRequestMock

({ routeAuthRequired, validation = {}, }: RequestFixtureOptions = {}) { - const queryString = stringify(query, { sort: false }); + const queryString = querystring.stringify(query); return KibanaRequest.from( createRawRequestMock({ diff --git a/src/core/utils/url.ts b/src/core/utils/url.ts index 31de7e1814038..c207a2ab27ed5 100644 --- a/src/core/utils/url.ts +++ b/src/core/utils/url.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { ParsedQuery } from 'query-string'; +import { ParsedUrlQuery } from 'querystring'; import { format as formatUrl, parse as parseUrl, UrlObject } from 'url'; /** @@ -32,7 +32,7 @@ export interface URLMeaningfulParts { protocol?: string | null; slashes?: boolean | null; port?: string | null; - query: ParsedQuery; + query: ParsedUrlQuery; } /** diff --git a/src/legacy/server/logging/log_format.js b/src/legacy/server/logging/log_format.js index ca1d756704dd0..80530c6dbf950 100644 --- a/src/legacy/server/logging/log_format.js +++ b/src/legacy/server/logging/log_format.js @@ -20,7 +20,7 @@ import Stream from 'stream'; import moment from 'moment-timezone'; import { get, _ } from 'lodash'; -import queryString from 'query-string'; +import querystring from 'querystring'; import numeral from '@elastic/numeral'; import chalk from 'chalk'; import stringify from 'json-stringify-safe'; @@ -108,7 +108,7 @@ export default class TransformObjStream extends Stream.Transform { contentLength: contentLength, }; - const query = queryString.stringify(event.query, { sort: false }); + const query = querystring.stringify(event.query); if (query) data.req.url += '?' + query; data.message = data.req.method.toUpperCase() + ' '; diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index daf88e28c6440..8a4e8387260b0 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -20,7 +20,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiScreenReaderOnly, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { debounce } from 'lodash'; -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react'; // @ts-ignore import mappings from '../../../../../lib/mappings/mappings'; @@ -101,7 +101,7 @@ function EditorUI({ initialTextValue }: EditorProps) { const readQueryParams = () => { const [, queryString] = (window.location.hash || '').split('?'); - return parse(queryString || '', { sort: false }) as Required; + return parse(queryString || '') as Required; }; const loadBufferFromRemote = (url: string) => { diff --git a/src/plugins/console/public/lib/es/es.ts b/src/plugins/console/public/lib/es/es.ts index f11692e1befad..2f4498b895725 100644 --- a/src/plugins/console/public/lib/es/es.ts +++ b/src/plugins/console/public/lib/es/es.ts @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; const esVersion: string[] = []; @@ -35,7 +35,7 @@ export function send(method: string, path: string, data: any) { const wrappedDfd = $.Deferred(); // eslint-disable-line new-cap const options: JQuery.AjaxSettings = { - url: '../api/console/proxy?' + stringify({ path, method }, { sort: false }), + url: '../api/console/proxy?' + stringify({ path, method }), data, contentType: getContentType(data), cache: false, diff --git a/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts b/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts index 2220ad4eef1b7..17e3a90a39b19 100644 --- a/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts +++ b/src/plugins/data/public/query/timefilter/lib/parse_querystring.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; export function parseQueryString() { // window.location.search is an empty string @@ -26,5 +26,5 @@ export function parseQueryString() { return {}; } - return parse(hrefSplit[1], { sort: false }); + return parse(hrefSplit[1]); } diff --git a/src/plugins/kibana_utils/common/url/encode_uri_query.ts b/src/plugins/kibana_utils/common/url/encode_uri_query.ts index fb60f0ceff10f..3d61aa376bba2 100644 --- a/src/plugins/kibana_utils/common/url/encode_uri_query.ts +++ b/src/plugins/kibana_utils/common/url/encode_uri_query.ts @@ -17,7 +17,7 @@ * under the License. */ -import { ParsedQuery } from 'query-string'; +import { ParsedUrlQuery } from 'querystring'; import { transform } from 'lodash'; /** @@ -42,9 +42,9 @@ export function encodeUriQuery(val: string, pctEncodeSpaces = false) { } export const encodeQuery = ( - query: ParsedQuery, + query: ParsedUrlQuery | {}, encodeFunction: (val: string, pctEncodeSpaces?: boolean) => string = encodeUriQuery -) => +): ParsedUrlQuery => transform(query, (result, value, key) => { if (key) { const singleValue = Array.isArray(value) ? value.join(',') : value; diff --git a/src/plugins/kibana_utils/public/history/remove_query_param.ts b/src/plugins/kibana_utils/public/history/remove_query_param.ts index bf945e5b064aa..868829548651c 100644 --- a/src/plugins/kibana_utils/public/history/remove_query_param.ts +++ b/src/plugins/kibana_utils/public/history/remove_query_param.ts @@ -17,18 +17,18 @@ * under the License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import { History, Location } from 'history'; import { url } from '../../common'; export function removeQueryParam(history: History, param: string, replace: boolean = true) { const oldLocation = history.location; const search = (oldLocation.search || '').replace(/^\?/, ''); - const query = parse(search, { sort: false }); + const query = parse(search); delete query[param]; - const newSearch = stringify(url.encodeQuery(query), { sort: false, encode: false }); + const newSearch = stringify(url.encodeQuery(query)); const newLocation: Location = { ...oldLocation, search: newSearch, diff --git a/src/plugins/kibana_utils/public/state_management/url/format.ts b/src/plugins/kibana_utils/public/state_management/url/format.ts index 2912b665ff014..456bd9f5bf3fa 100644 --- a/src/plugins/kibana_utils/public/state_management/url/format.ts +++ b/src/plugins/kibana_utils/public/state_management/url/format.ts @@ -18,21 +18,18 @@ */ import { format as formatUrl } from 'url'; -import { stringify, ParsedQuery } from 'query-string'; +import { stringify, ParsedUrlQuery } from 'querystring'; import { parseUrl, parseUrlHash } from './parse'; import { url as urlUtils } from '../../../common'; export function replaceUrlHashQuery( rawUrl: string, - queryReplacer: (query: ParsedQuery) => ParsedQuery + queryReplacer: (query: ParsedUrlQuery) => ParsedUrlQuery ) { const url = parseUrl(rawUrl); const hash = parseUrlHash(rawUrl); const newQuery = queryReplacer(hash?.query || {}); - const searchQueryString = stringify(urlUtils.encodeQuery(newQuery), { - sort: false, - encode: false, - }); + const searchQueryString = stringify(urlUtils.encodeQuery(newQuery)); if ((!hash || !hash.search) && !searchQueryString) return rawUrl; // nothing to change. return original url return formatUrl({ diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index 40a411d425a54..923a0215b3e95 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -18,7 +18,7 @@ */ import { format as formatUrl } from 'url'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { createBrowserHistory, History } from 'history'; import { decodeState, encodeState } from '../state_encoder'; import { getCurrentUrl, parseUrl, parseUrlHash } from './parse'; @@ -244,11 +244,11 @@ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): return formatUrl({ pathname: stripBasename(parsedUrl.pathname), - search: stringify(urlUtils.encodeQuery(parsedUrl.query), { sort: false, encode: false }), + search: stringify(urlUtils.encodeQuery(parsedUrl.query)), hash: parsedHash ? formatUrl({ pathname: parsedHash.pathname, - search: stringify(urlUtils.encodeQuery(parsedHash.query), { sort: false, encode: false }), + search: stringify(urlUtils.encodeQuery(parsedHash.query)), }) : parsedUrl.hash, }); diff --git a/src/plugins/timelion/server/series_functions/quandl.test.js b/src/plugins/timelion/server/series_functions/quandl.test.js index 67d81e56f145f..c309de4afb09a 100644 --- a/src/plugins/timelion/server/series_functions/quandl.test.js +++ b/src/plugins/timelion/server/series_functions/quandl.test.js @@ -17,7 +17,7 @@ * under the License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import fn from './quandl'; import moment from 'moment'; import fetchMock from 'node-fetch'; @@ -26,7 +26,7 @@ const parseURL = require('url').parse; const tlConfig = require('./fixtures/tl_config')(); function parseUrlParams(url) { - return parse(parseURL(url).query, { sort: false }); + return parse(parseURL(url).query); } jest.mock('node-fetch', () => diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts index c7d71d0b6dac5..b592cfe6c12b3 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { LocalUIFilterName } from '../../../../../../../plugins/apm/server/lib/ui_filters/local_ui_filters/config'; import { url } from '../../../../../../../../src/plugins/kibana_utils/public'; export function toQuery(search?: string): APMQueryParamsRaw { - return search ? parse(search.slice(1), { sort: false }) : {}; + return search ? parse(search.slice(1)) : {}; } export function fromQuery(query: Record) { @@ -18,7 +18,7 @@ export function fromQuery(query: Record) { encodeURIComponent(value).replace(/%3A/g, ':') ); - return stringify(encodedQuery, { sort: false, encode: false }); + return stringify(encodedQuery); } export type APMQueryParams = { diff --git a/x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx b/x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx index c8f756da985a7..71e9163fe22e7 100644 --- a/x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx +++ b/x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import React from 'react'; import { withRouter, RouteComponentProps } from 'react-router-dom'; import { FlatObject } from '../frontend_types'; @@ -31,9 +31,7 @@ export class WithURLStateComponent extends React.Compon > { private get URLState(): URLState { // slice because parse does not account for the initial ? in the search string - return parse(decodeURIComponent(this.props.history.location.search).substring(1), { - sort: false, - }) as URLState; + return parse(decodeURIComponent(this.props.history.location.search).substring(1)) as URLState; } private historyListener: (() => void) | null = null; @@ -65,13 +63,10 @@ export class WithURLStateComponent extends React.Compon newState = state; } - const search: string = stringify( - { - ...pastState, - ...newState, - }, - { sort: false } - ); + const search: string = stringify({ + ...pastState, + ...newState, + }); const newLocation = { ...this.props.history.location, diff --git a/x-pack/legacy/plugins/canvas/public/lib/app_state.ts b/x-pack/legacy/plugins/canvas/public/lib/app_state.ts index d431202ba75a4..ec97ddd398dc5 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/app_state.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/app_state.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import { get } from 'lodash'; // @ts-ignore untyped local import { getInitialState } from '../state/initial_state'; @@ -38,7 +38,7 @@ export function getDefaultAppState(): AppState { export function getCurrentAppState(): AppState { const history = historyProvider(getWindow()); const { search } = history.getLocation(); - const qs = !!search ? parse(search.replace(/^\?/, ''), { sort: false }) : {}; + const qs = !!search ? parse(search.replace(/^\?/, '')) : {}; const appState = assignAppState({}, qs); return appState; diff --git a/x-pack/legacy/plugins/canvas/public/lib/modify_url.ts b/x-pack/legacy/plugins/canvas/public/lib/modify_url.ts index d128dc432e9cf..890138c41d7bf 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/modify_url.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/modify_url.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ParsedQuery } from 'query-string'; +import { ParsedUrlQuery } from 'querystring'; import { format as formatUrl, parse as parseUrl, UrlObject } from 'url'; /** @@ -20,7 +20,7 @@ export interface URLMeaningfulParts { protocol?: string | null; slashes?: boolean | null; port?: string | null; - query: ParsedQuery; + query: ParsedUrlQuery; } /** diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js index af462bfeffcf5..f0871d62976ed 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; export function extractQueryParams(queryString) { const hrefSplit = queryString.split('?'); @@ -12,5 +12,5 @@ export function extractQueryParams(queryString) { return {}; } - return parse(hrefSplit[1], { sort: false }); + return parse(hrefSplit[1]); } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js index 487b1068794f9..febe5bfaf6642 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js @@ -9,7 +9,7 @@ */ import { createLocation } from 'history'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { APPS, BASE_PATH, BASE_PATH_REMOTE_CLUSTERS } from '../../../common/constants'; const isModifiedEvent = event => @@ -22,8 +22,17 @@ const queryParamsFromObject = (params, encodeParams = false) => { return; } - const paramsStr = stringify(params, { sort: false, encode: encodeParams }); - return `?${paramsStr}`; + const paramStr = stringify( + params, + '&', + '=', + encodeParams + ? {} + : { + encodeURIComponent: val => val, // Don't encode special chars + } + ); + return `?${paramStr}`; }; const appToBasePathMap = { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx index e00ff0333bb73..62da03c654fb3 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { decode } from 'rison-node'; @@ -34,7 +34,7 @@ export const analyticsJobExplorationRoute: MlRoute = { const PageWrapper: FC = ({ location, deps }) => { const { context } = useResolver('', undefined, deps.config, basicResolvers(deps)); - const { _g }: Record = parse(location.search, { sort: false }); + const { _g }: Record = parse(location.search); let globalState: any = null; try { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx index 74ab916cb443f..e8994dae5113c 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { MlRoute, PageLoader, PageProps } from '../../router'; @@ -35,7 +35,7 @@ export const indexBasedRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { index, savedSearchId }: Record = parse(location.search, { sort: false }); + const { index, savedSearchId }: Record = parse(location.search); const { context } = useResolver(index, savedSearchId, deps.config, { checkBasicLicense, loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx index f0a25d880a082..95f545565f224 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { MlRoute, PageLoader, PageProps } from '../../router'; @@ -31,7 +31,7 @@ export const jobTypeRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { index, savedSearchId }: Record = parse(location.search, { sort: false }); + const { index, savedSearchId }: Record = parse(location.search); const { context } = useResolver(index, savedSearchId, deps.config, basicResolvers(deps)); return ( diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index 12687fd71edc5..b20f6b73a9351 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { MlRoute, PageLoader, PageProps } from '../../router'; @@ -39,7 +39,7 @@ export const checkViewOrCreateRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { id, index, savedSearchId }: Record = parse(location.search, { sort: false }); + const { id, index, savedSearchId }: Record = parse(location.search); const { context, results } = useResolver(index, savedSearchId, deps.config, { ...basicResolvers(deps), existingJobsAndGroups: mlJobService.getJobAndGroupIds, @@ -53,9 +53,7 @@ const PageWrapper: FC = ({ location, deps }) => { }; const CheckViewOrCreateWrapper: FC = ({ location, deps }) => { - const { id: moduleId, index: indexPatternId }: Record = parse(location.search, { - sort: false, - }); + const { id: moduleId, index: indexPatternId }: Record = parse(location.search); // the single resolver checkViewOrCreateJobs redirects only. so will always reject useResolver(undefined, undefined, deps.config, { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx index b1256e21888d9..2c2062530b401 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; @@ -112,7 +112,7 @@ export const categorizationRoute: MlRoute = { }; const PageWrapper: FC = ({ location, jobType, deps }) => { - const { index, savedSearchId }: Record = parse(location.search, { sort: false }); + const { index, savedSearchId }: Record = parse(location.search); const { context, results } = useResolver(index, savedSearchId, deps.config, { ...basicResolvers(deps), privileges: checkCreateJobsPrivilege, diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts index b0699116895d4..25fd022a3ed73 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import { useCallback } from 'react'; import { isEqual } from 'lodash'; import { decode, encode } from 'rison-node'; @@ -32,12 +32,12 @@ function isRisonSerializationRequired(queryParam: string): boolean { export function getUrlState(search: string): Dictionary { const urlState: Dictionary = {}; - const parsedQueryString = parse(search, { sort: false }); + const parsedQueryString = parse(search); try { Object.keys(parsedQueryString).forEach(a => { if (isRisonSerializationRequired(a)) { - urlState[a] = decode(parsedQueryString[a] as string); + urlState[a] = decode(parsedQueryString[a]); } else { urlState[a] = parsedQueryString[a]; } @@ -63,7 +63,7 @@ export const useUrlState = (accessor: string): UrlState => { const setUrlState = useCallback( (attribute: string | Dictionary, value?: any) => { const urlState = getUrlState(search); - const parsedQueryString = parse(search, { sort: false }); + const parsedQueryString = parse(search); if (!Object.prototype.hasOwnProperty.call(urlState, accessor)) { urlState[accessor] = {}; @@ -83,7 +83,7 @@ export const useUrlState = (accessor: string): UrlState => { } try { - const oldLocationSearch = stringify(parsedQueryString, { sort: false, encode: false }); + const oldLocationSearch = stringify(parsedQueryString); Object.keys(urlState).forEach(a => { if (isRisonSerializationRequired(a)) { @@ -92,11 +92,11 @@ export const useUrlState = (accessor: string): UrlState => { parsedQueryString[a] = urlState[a]; } }); - const newLocationSearch = stringify(parsedQueryString, { sort: false, encode: false }); + const newLocationSearch = stringify(parsedQueryString); if (oldLocationSearch !== newLocationSearch) { history.push({ - search: stringify(parsedQueryString, { sort: false }), + search: stringify(parsedQueryString), }); } } catch (error) { diff --git a/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts b/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts index d471dc57fc9e1..4b2bf5c3ca726 100644 --- a/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts +++ b/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { npStart } from 'ui/new_platform'; // @ts-ignore import rison from 'rison-node'; diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx index b5aacdf664c67..c65ac17690952 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +// eslint-disable-next-line import/no-nodejs-modules +import { parse, stringify } from 'querystring'; import React from 'react'; import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom'; @@ -31,17 +32,12 @@ export const MlHostConditionalContainer = React.memo(({ exact path={url} render={({ location }) => { - const queryStringDecoded = parse(location.search.substring(1), { - sort: false, - }) as Required; + const queryStringDecoded = parse(location.search.substring(1)); if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ; }} /> @@ -61,10 +57,7 @@ export const MlHostConditionalContainer = React.memo(({ queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } if (emptyEntity(hostName)) { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ( @@ -76,19 +69,13 @@ export const MlHostConditionalContainer = React.memo(({ hosts, queryStringDecoded.query || '' ); - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ( ); } else { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ( { - const queryStringDecoded = parse(location.search.substring(1), { - sort: false, - }) as Required; + const queryStringDecoded = parse(location.search.substring(1)) as Required; if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ; }} @@ -54,19 +50,14 @@ export const MlNetworkConditionalContainer = React.memo { - const queryStringDecoded = parse(location.search.substring(1), { - sort: false, - }) as Required; + const queryStringDecoded = parse(location.search.substring(1)) as Required; if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } if (emptyEntity(ip)) { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ; } else if (multipleEntities(ip)) { @@ -76,16 +67,10 @@ export const MlNetworkConditionalContainer = React.memo; } else { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded), { - sort: false, - encode: false, - }); + const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); return ; } }} diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts index d085af91da1f0..1c8fa1b56187e 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts @@ -5,7 +5,8 @@ */ import { isEmpty } from 'lodash/fp'; -import { parse, stringify } from 'query-string'; +// eslint-disable-next-line import/no-nodejs-modules +import { parse, stringify } from 'querystring'; import { decode, encode } from 'rison-node'; import * as H from 'history'; @@ -43,7 +44,7 @@ export const encodeRisonUrlState = (state: any) => encode(state); export const getQueryStringFromLocation = (search: string) => search.substring(1); export const getParamFromQueryString = (queryString: string, key: string) => { - const parsedQueryString = parse(queryString, { sort: false }); + const parsedQueryString = parse(queryString); const queryParam = parsedQueryString[key]; return Array.isArray(queryParam) ? queryParam[0] : queryParam; @@ -52,11 +53,11 @@ export const getParamFromQueryString = (queryString: string, key: string) => { export const replaceStateKeyInQueryString = (stateKey: string, urlState: T) => ( queryString: string ): string => { - const previousQueryValues = parse(queryString, { sort: false }); + const previousQueryValues = parse(queryString); if (urlState == null || (typeof urlState === 'string' && urlState === '')) { delete previousQueryValues[stateKey]; - return stringify(url.encodeQuery(previousQueryValues), { sort: false, encode: false }); + return stringify(url.encodeQuery(previousQueryValues)); } // ಠ_ಠ Code was copied from x-pack/legacy/plugins/infra/public/utils/url_state.tsx ಠ_ಠ diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx index 8192fe4e026af..08565cd94ad28 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { Fragment, useState, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { EuiButton, EuiCallOut, EuiLink, EuiEmptyPrompt, EuiSpacer, EuiIcon } from '@elastic/eui'; @@ -86,7 +86,7 @@ export const SnapshotList: React.FunctionComponent(undefined); useEffect(() => { if (search) { - const parsedParams = parse(search.replace(/^\?/, ''), { sort: false }); + const parsedParams = parse(search.replace(/^\?/, '')); const { repository, policy } = parsedParams; if (policy && policy !== filteredPolicy) { diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/repository_add/repository_add.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/repository_add/repository_add.tsx index a12ecb4baef5d..860f83cf80936 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/repository_add/repository_add.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/repository_add/repository_add.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; import React, { useEffect, useState } from 'react'; import { RouteComponentProps } from 'react-router-dom'; @@ -45,7 +45,7 @@ export const RepositoryAdd: React.FunctionComponent = ({ if (error) { setSaveError(error); } else { - const { redirect } = parse(search.replace(/^\?/, ''), { sort: false }); + const { redirect } = parse(search.replace(/^\?/, '')); history.push(redirect ? (redirect as string) : `${BASE_PATH}/${section}/${name}`); } diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts b/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts index dc309943d7cf9..41c2a4b7c2478 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts +++ b/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import { useLocation, useHistory } from 'react-router-dom'; import { UptimeUrlParams, getSupportedUrlParams } from '../lib/helper'; @@ -23,9 +23,7 @@ export const useUrlParams: UptimeUrlParamsHook = () => { search = location.search; } - const params = search - ? parse(search[0] === '?' ? search.slice(1) : search, { sort: false }) - : {}; + const params = search ? parse(search[0] === '?' ? search.slice(1) : search) : {}; return getSupportedUrlParams(params); }; @@ -33,7 +31,7 @@ export const useUrlParams: UptimeUrlParamsHook = () => { const updateUrlParams: UpdateUrlParams = updatedParams => { if (!history || !location) return; const { pathname, search } = location; - const currentParams = parse(search[0] === '?' ? search.slice(1) : search, { sort: false }); + const currentParams = parse(search[0] === '?' ? search.slice(1) : search); const mergedParams = { ...currentParams, ...updatedParams, @@ -52,8 +50,7 @@ export const useUrlParams: UptimeUrlParamsHook = () => { ...params, [key]: value, }; - }, {}), - { sort: false } + }, {}) ), }); }; diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts index a8ce86c4399e2..d955e38abb57d 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { UptimeUrlParams } from './url_params'; import { CLIENT_DEFAULTS } from '../../../common/constants'; @@ -38,5 +38,5 @@ export const stringifyUrlParams = (params: Partial, ignoreEmpty } }); } - return `?${stringify(params, { sort: false })}`; + return `?${stringify(params)}`; }; diff --git a/x-pack/legacy/plugins/uptime/public/state/api/ping.ts b/x-pack/legacy/plugins/uptime/public/state/api/ping.ts index c61bf42c8c90e..db8c9cdfd7520 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/ping.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/ping.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { getApiPath } from '../../lib/helper'; import { APIFn } from './types'; import { GetPingHistogramParams, HistogramResult } from '../../../common/types'; @@ -25,7 +25,7 @@ export const fetchPingHistogram: APIFn ...(statusFilter && { statusFilter }), ...(filters && { filters }), }; - const urlParams = stringify(params, { sort: false }); + const urlParams = stringify(params); const response = await fetch(`${url}?${urlParams}`); if (!response.ok) { throw new Error(response.statusText); diff --git a/x-pack/package.json b/x-pack/package.json index 96e06dd71b3fe..c528ff5d3d6eb 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -295,7 +295,6 @@ "proper-lockfile": "^3.2.0", "puid": "1.0.7", "puppeteer-core": "^1.19.0", - "query-string": "6.10.1", "raw-loader": "3.1.0", "re-resizable": "^6.1.1", "react": "^16.12.0", diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx index 6b946898f6330..31c097b983240 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx @@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { encode } from 'rison-node'; import url from 'url'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { TimeRange } from '../../../../common/http_api/shared/time_range'; import { url as urlUtils } from '../../../../../../../src/plugins/kibana_utils/public'; @@ -62,7 +62,7 @@ const getOverallAnomalyExplorerLink = (pathname: string, jobId: string, timeRang }, }); - const hash = `/explorer?${stringify(urlUtils.encodeQuery({ _g }), { encode: false })}`; + const hash = `/explorer?${stringify(urlUtils.encodeQuery({ _g }))}`; return url.format({ pathname, @@ -95,10 +95,7 @@ const getPartitionSpecificSingleMetricViewerLink = ( }, }); - const hash = `/timeseriesexplorer?${stringify(urlUtils.encodeQuery({ _g, _a }), { - sort: false, - encode: false, - })}`; + const hash = `/timeseriesexplorer?${stringify(urlUtils.encodeQuery({ _g, _a }))}`; return url.format({ pathname, diff --git a/x-pack/plugins/infra/public/containers/with_state_from_location.tsx b/x-pack/plugins/infra/public/containers/with_state_from_location.tsx index 2a9676046d451..4e837014f00d1 100644 --- a/x-pack/plugins/infra/public/containers/with_state_from_location.tsx +++ b/x-pack/plugins/infra/public/containers/with_state_from_location.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import { Location } from 'history'; import { omit } from 'lodash'; import React from 'react'; @@ -102,7 +102,7 @@ const encodeRisonAppState = (state: AnyObject) => ({ export const mapRisonAppLocationToState = ( mapState: (risonAppState: AnyObject) => State = (state: AnyObject) => state as State ) => (location: Location): State => { - const queryValues = parse(location.search.substring(1), { sort: false }); + const queryValues = parse(location.search.substring(1)); const decodedState = decodeRisonAppState(queryValues); return mapState(decodedState); }; @@ -110,20 +110,17 @@ export const mapRisonAppLocationToState = ( export const mapStateToRisonAppLocation = ( mapState: (state: State) => AnyObject = (state: State) => state ) => (state: State, location: Location): Location => { - const previousQueryValues = parse(location.search.substring(1), { sort: false }); + const previousQueryValues = parse(location.search.substring(1)); const previousState = decodeRisonAppState(previousQueryValues); const encodedState = encodeRisonAppState({ ...previousState, ...mapState(state), }); - const newQueryValues = stringify( - { - ...previousQueryValues, - ...encodedState, - }, - { sort: false } - ); + const newQueryValues = stringify({ + ...previousQueryValues, + ...encodedState, + }); return { ...location, search: `?${newQueryValues}`, diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx index 3efefe93990bd..5ae51555ea6dc 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx @@ -19,7 +19,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -33,7 +33,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -45,7 +45,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx index 7c1cb9d7329ef..fb1f503dcd43a 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx @@ -35,7 +35,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -47,7 +47,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -59,7 +59,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -73,7 +73,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -89,7 +89,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -103,7 +103,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index bf4cfbaf05965..ae3b834fa301d 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify, ParsedUrlQuery } from 'querystring'; import { History, Location } from 'history'; import { throttle } from 'lodash'; import React from 'react'; @@ -145,7 +145,7 @@ const encodeRisonUrlState = (state: any) => encode(state); export const getQueryStringFromLocation = (location: Location) => location.search.substring(1); export const getParamFromQueryString = (queryString: string, key: string): string | undefined => { - const parsedQueryString: Record = parse(queryString, { sort: false }); + const parsedQueryString: Record = parse(queryString); const queryParam = parsedQueryString[key]; return Array.isArray(queryParam) ? queryParam[0] : queryParam; @@ -155,7 +155,7 @@ export const replaceStateKeyInQueryString = ( stateKey: string, urlState: UrlState | undefined ) => (queryString: string) => { - const previousQueryValues = parse(queryString, { sort: false }); + const previousQueryValues = parse(queryString); const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; @@ -163,8 +163,7 @@ export const replaceStateKeyInQueryString = ( url.encodeQuery({ ...previousQueryValues, [stateKey]: encodedUrlState, - }), - { sort: false, encode: false } + }) ); }; diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index 7a63b48fa9a1a..574457d54c51f 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'query-string'; +import { parse, stringify } from 'querystring'; import { Location } from 'history'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { decode, encode, RisonValue } from 'rison-node'; @@ -101,7 +101,7 @@ const encodeRisonUrlState = (state: any) => encode(state); const getQueryStringFromLocation = (location: Location) => location.search.substring(1); const getParamFromQueryString = (queryString: string, key: string) => { - const parsedQueryString = parse(queryString, { sort: false }); + const parsedQueryString = parse(queryString); const queryParam = parsedQueryString[key]; return Array.isArray(queryParam) ? queryParam[0] : queryParam; @@ -111,7 +111,7 @@ export const replaceStateKeyInQueryString = ( stateKey: string, urlState: UrlState | undefined ) => (queryString: string) => { - const previousQueryValues = parse(queryString, { sort: false }); + const previousQueryValues = parse(queryString); const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; @@ -119,8 +119,7 @@ export const replaceStateKeyInQueryString = ( url.encodeQuery({ ...previousQueryValues, [stateKey]: encodedUrlState, - }), - { sort: false, encode: false } + }) ); }; diff --git a/x-pack/plugins/remote_clusters/public/application/services/query_params.js b/x-pack/plugins/remote_clusters/public/application/services/query_params.js index af462bfeffcf5..f0871d62976ed 100644 --- a/x-pack/plugins/remote_clusters/public/application/services/query_params.js +++ b/x-pack/plugins/remote_clusters/public/application/services/query_params.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'query-string'; +import { parse } from 'querystring'; export function extractQueryParams(queryString) { const hrefSplit = queryString.split('?'); @@ -12,5 +12,5 @@ export function extractQueryParams(queryString) { return {}; } - return parse(hrefSplit[1], { sort: false }); + return parse(hrefSplit[1]); } diff --git a/x-pack/plugins/spaces/server/lib/utils/url.ts b/x-pack/plugins/spaces/server/lib/utils/url.ts index c91934bb99f1f..a5797c0f87868 100644 --- a/x-pack/plugins/spaces/server/lib/utils/url.ts +++ b/x-pack/plugins/spaces/server/lib/utils/url.ts @@ -8,7 +8,7 @@ // DIRECT COPY FROM `src/core/utils/url`, since it's not possible to import from there, // nor can I re-export from `src/core/server`... -import { ParsedQuery } from 'query-string'; +import { ParsedUrlQuery } from 'querystring'; import { format as formatUrl, parse as parseUrl, UrlObject } from 'url'; export interface URLMeaningfulParts { @@ -19,7 +19,7 @@ export interface URLMeaningfulParts { protocol: string | null; slashes: boolean | null; port: string | null; - query: ParsedQuery | {}; + query: ParsedUrlQuery | {}; } /** diff --git a/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js b/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js index e1a435e000fae..3a18b13de36e7 100644 --- a/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js +++ b/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { registerHelpers } from './rollup.test_helpers'; import { INDEX_TO_ROLLUP_MAPPINGS, INDEX_PATTERNS_EXTENSION_BASE_PATH } from './constants'; import { getRandomString } from './lib'; @@ -38,7 +38,7 @@ export default function({ getService }) { it('"params" is required', async () => { params = { pattern: 'foo' }; - uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + uri = `${BASE_URI}?${stringify(params)}`; ({ body } = await supertest.get(uri).expect(400)); expect(body.message).to.contain( '[request query.params]: expected value of type [string]' @@ -47,14 +47,14 @@ export default function({ getService }) { it('"params" must be a valid JSON string', async () => { params = { pattern: 'foo', params: 'foobarbaz' }; - uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + uri = `${BASE_URI}?${stringify(params)}`; ({ body } = await supertest.get(uri).expect(400)); expect(body.message).to.contain('[request query.params]: expected JSON string'); }); it('"params" requires a "rollup_index" property', async () => { params = { pattern: 'foo', params: JSON.stringify({}) }; - uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + uri = `${BASE_URI}?${stringify(params)}`; ({ body } = await supertest.get(uri).expect(400)); expect(body.message).to.contain('[request query.params]: "rollup_index" is required'); }); @@ -64,7 +64,7 @@ export default function({ getService }) { pattern: 'foo', params: JSON.stringify({ rollup_index: 'my_index', someProp: 'bar' }), }; - uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + uri = `${BASE_URI}?${stringify(params)}`; ({ body } = await supertest.get(uri).expect(400)); expect(body.message).to.contain('[request query.params]: someProp is not allowed'); }); @@ -75,7 +75,7 @@ export default function({ getService }) { params: JSON.stringify({ rollup_index: 'bar' }), meta_fields: 'stringValue', }; - uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + uri = `${BASE_URI}?${stringify(params)}`; ({ body } = await supertest.get(uri).expect(400)); expect(body.message).to.contain( '[request query.meta_fields]: could not parse array value from [stringValue]' @@ -83,13 +83,10 @@ export default function({ getService }) { }); it('should return 404 the rollup index to query does not exist', async () => { - uri = `${BASE_URI}?${stringify( - { - pattern: 'foo', - params: JSON.stringify({ rollup_index: 'bar' }), - }, - { sort: false } - )}`; + uri = `${BASE_URI}?${stringify({ + pattern: 'foo', + params: JSON.stringify({ rollup_index: 'bar' }), + })}`; ({ body } = await supertest.get(uri).expect(404)); expect(body.message).to.contain('[index_not_found_exception] no such index [bar]'); }); @@ -107,7 +104,7 @@ export default function({ getService }) { pattern: indexName, params: JSON.stringify({ rollup_index: rollupIndex }), }; - const uri = `${BASE_URI}?${stringify(params, { sort: false })}`; + const uri = `${BASE_URI}?${stringify(params)}`; const { body } = await supertest.get(uri).expect(200); // Verify that the fields for wildcard correspond to our declared mappings diff --git a/x-pack/test/saml_api_integration/apis/security/saml_login.ts b/x-pack/test/saml_api_integration/apis/security/saml_login.ts index b8296aa703607..fefc235e315fd 100644 --- a/x-pack/test/saml_api_integration/apis/security/saml_login.ts +++ b/x-pack/test/saml_api_integration/apis/security/saml_login.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import url from 'url'; import { delay } from 'bluebird'; import expect from '@kbn/expect'; @@ -443,7 +443,7 @@ export default function({ getService }: FtrProviderContext) { it('should invalidate access token on IdP initiated logout', async () => { const logoutRequest = await createLogoutRequest({ sessionIndex: idpSessionIndex }); const logoutResponse = await supertest - .get(`/api/security/logout?${stringify(logoutRequest, { sort: false })}`) + .get(`/api/security/logout?${stringify(logoutRequest)}`) .set('Cookie', sessionCookie.cookieString()) .expect(302); @@ -479,7 +479,7 @@ export default function({ getService }: FtrProviderContext) { it('should invalidate access token on IdP initiated logout even if there is no Kibana session', async () => { const logoutRequest = await createLogoutRequest({ sessionIndex: idpSessionIndex }); const logoutResponse = await supertest - .get(`/api/security/logout?${stringify(logoutRequest, { sort: false })}`) + .get(`/api/security/logout?${stringify(logoutRequest)}`) .expect(302); expect(logoutResponse.headers['set-cookie']).to.be(undefined); diff --git a/x-pack/test/saml_api_integration/fixtures/saml_tools.ts b/x-pack/test/saml_api_integration/fixtures/saml_tools.ts index bbe0df7ff3a2c..a39606c33cf42 100644 --- a/x-pack/test/saml_api_integration/fixtures/saml_tools.ts +++ b/x-pack/test/saml_api_integration/fixtures/saml_tools.ts @@ -6,7 +6,7 @@ import crypto from 'crypto'; import fs from 'fs'; -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import url from 'url'; import zlib from 'zlib'; import { promisify } from 'util'; @@ -140,7 +140,7 @@ export async function getLogoutRequest({ }; const signer = crypto.createSign('RSA-SHA256'); - signer.update(stringify(queryStringParameters, { sort: false })); + signer.update(stringify(queryStringParameters)); queryStringParameters.Signature = signer.sign(signingKey.toString(), 'base64'); return queryStringParameters; diff --git a/yarn.lock b/yarn.lock index 7f38495c20f4a..f399507bfdac4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23883,15 +23883,6 @@ qs@~6.4.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM= -query-string@6.10.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.10.1.tgz#30b3505f6fca741d5ae541964d1b3ae9dc2a0de8" - integrity sha512-SHTUV6gDlgMXg/AQUuLpTiBtW/etZ9JT6k6RCtCyqADquApLX0Aq5oK/s5UeTUAWBG50IExjIr587GqfXRfM4A== - dependencies: - decode-uri-component "^0.2.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - query-string@^4.1.0, query-string@^4.2.2: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -23909,6 +23900,11 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +querystring-browser@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/querystring-browser/-/querystring-browser-1.0.4.tgz#f2e35881840a819bc7b1bf597faf0979e6622dc6" + integrity sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY= + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -27494,11 +27490,6 @@ spdy@^4.0.1: select-hose "^2.0.0" spdy-transport "^3.0.0" -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -27807,11 +27798,6 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= - string-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" From 7e4404e8946a3a45ccfd74f1fc111f3845674ecc Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 28 Feb 2020 17:57:44 -0500 Subject: [PATCH 2/6] Stop double-encoding --- .../common/url/encode_uri_query.test.ts | 23 +++++++++++++++++++ .../common/url/encode_uri_query.ts | 5 +++- src/plugins/kibana_utils/common/url/index.ts | 3 ++- .../public/history/remove_query_param.ts | 4 ++-- .../public/state_management/url/format.ts | 4 ++-- .../state_management/url/kbn_url_storage.ts | 6 ++--- .../infra/public/utils/use_url_state.ts | 10 ++++---- 7 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/plugins/kibana_utils/common/url/encode_uri_query.test.ts b/src/plugins/kibana_utils/common/url/encode_uri_query.test.ts index b600822946299..c255cf4699334 100644 --- a/src/plugins/kibana_utils/common/url/encode_uri_query.test.ts +++ b/src/plugins/kibana_utils/common/url/encode_uri_query.test.ts @@ -67,4 +67,27 @@ describe('encodeQuery', () => { g: 'null', }); }); + + test('encodeQuery without encoding', () => { + expect( + encodeQuery( + { + a: 'asdf1234asdf', + b: "-_.!~*'() -_.!~*'()", + c: ':@$, :@$,', + d: "&;=+# &;=+#'", + f: ' ', + g: 'null', + }, + v => v + ) + ).toEqual({ + a: 'asdf1234asdf', + b: "-_.!~*'() -_.!~*'()", + c: ':@$, :@$,', + d: "&;=+# &;=+#'", + f: ' ', + g: 'null', + }); + }); }); diff --git a/src/plugins/kibana_utils/common/url/encode_uri_query.ts b/src/plugins/kibana_utils/common/url/encode_uri_query.ts index 3d61aa376bba2..616a5aeea9fb1 100644 --- a/src/plugins/kibana_utils/common/url/encode_uri_query.ts +++ b/src/plugins/kibana_utils/common/url/encode_uri_query.ts @@ -17,7 +17,7 @@ * under the License. */ -import { ParsedUrlQuery } from 'querystring'; +import { stringify, ParsedUrlQuery } from 'querystring'; import { transform } from 'lodash'; /** @@ -55,3 +55,6 @@ export const encodeQuery = ( ); } }); + +export const makeUrlFromQuery = (query: ParsedUrlQuery | {}) => + stringify(query, undefined, undefined, { encodeURIComponent: encodeUriQuery }); diff --git a/src/plugins/kibana_utils/common/url/index.ts b/src/plugins/kibana_utils/common/url/index.ts index 7b74f07e598ee..6621e6ce8b802 100644 --- a/src/plugins/kibana_utils/common/url/index.ts +++ b/src/plugins/kibana_utils/common/url/index.ts @@ -17,9 +17,10 @@ * under the License. */ -import { encodeUriQuery, encodeQuery } from './encode_uri_query'; +import { encodeUriQuery, encodeQuery, makeUrlFromQuery } from './encode_uri_query'; export const url = { encodeQuery, encodeUriQuery, + makeUrlFromQuery, }; diff --git a/src/plugins/kibana_utils/public/history/remove_query_param.ts b/src/plugins/kibana_utils/public/history/remove_query_param.ts index 868829548651c..929ae36033d91 100644 --- a/src/plugins/kibana_utils/public/history/remove_query_param.ts +++ b/src/plugins/kibana_utils/public/history/remove_query_param.ts @@ -17,7 +17,7 @@ * under the License. */ -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; import { History, Location } from 'history'; import { url } from '../../common'; @@ -28,7 +28,7 @@ export function removeQueryParam(history: History, param: string, replace: boole delete query[param]; - const newSearch = stringify(url.encodeQuery(query)); + const newSearch = url.makeUrlFromQuery(query); const newLocation: Location = { ...oldLocation, search: newSearch, diff --git a/src/plugins/kibana_utils/public/state_management/url/format.ts b/src/plugins/kibana_utils/public/state_management/url/format.ts index 456bd9f5bf3fa..cd25d0724e7e6 100644 --- a/src/plugins/kibana_utils/public/state_management/url/format.ts +++ b/src/plugins/kibana_utils/public/state_management/url/format.ts @@ -18,7 +18,7 @@ */ import { format as formatUrl } from 'url'; -import { stringify, ParsedUrlQuery } from 'querystring'; +import { ParsedUrlQuery } from 'querystring'; import { parseUrl, parseUrlHash } from './parse'; import { url as urlUtils } from '../../../common'; @@ -29,7 +29,7 @@ export function replaceUrlHashQuery( const url = parseUrl(rawUrl); const hash = parseUrlHash(rawUrl); const newQuery = queryReplacer(hash?.query || {}); - const searchQueryString = stringify(urlUtils.encodeQuery(newQuery)); + const searchQueryString = urlUtils.makeUrlFromQuery(newQuery); if ((!hash || !hash.search) && !searchQueryString) return rawUrl; // nothing to change. return original url return formatUrl({ diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index 923a0215b3e95..9003427d88ab7 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -18,7 +18,7 @@ */ import { format as formatUrl } from 'url'; -import { stringify } from 'querystring'; +// import { stringify } from 'querystring'; import { createBrowserHistory, History } from 'history'; import { decodeState, encodeState } from '../state_encoder'; import { getCurrentUrl, parseUrl, parseUrlHash } from './parse'; @@ -244,11 +244,11 @@ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): return formatUrl({ pathname: stripBasename(parsedUrl.pathname), - search: stringify(urlUtils.encodeQuery(parsedUrl.query)), + search: urlUtils.makeUrlFromQuery(parsedUrl.query), hash: parsedHash ? formatUrl({ pathname: parsedHash.pathname, - search: stringify(urlUtils.encodeQuery(parsedHash.query)), + search: urlUtils.makeUrlFromQuery(parsedHash.query), }) : parsedUrl.hash, }); diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index 574457d54c51f..edae4df309ba2 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -115,12 +115,10 @@ export const replaceStateKeyInQueryString = ( const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return stringify( - url.encodeQuery({ - ...previousQueryValues, - [stateKey]: encodedUrlState, - }) - ); + return url.makeUrlFromQuery({ + ...previousQueryValues, + [stateKey]: encodedUrlState, + }); }; const replaceQueryStringInLocation = (location: Location, queryString: string): Location => { From 945990ebaadd08fb3da7b863d95b1910524a1a66 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Wed, 4 Mar 2020 17:15:59 -0500 Subject: [PATCH 3/6] Update more encoding uses --- .../public/state_management/url/kbn_url_storage.ts | 1 - .../public/components/shared/Links/url_helpers.ts | 4 ++-- .../public/app/services/routing.js | 4 ++-- .../analytics_job_exploration.tsx | 2 +- .../plugins/ml/public/application/util/url_state.ts | 5 +++-- .../ml_host_conditional_container.tsx | 8 +++----- .../ml_network_conditional_container.tsx | 10 +++++----- .../siem/public/components/url_state/helpers.ts | 13 +++++-------- .../log_analysis_results/analyze_in_ml_button.tsx | 5 ++--- x-pack/plugins/infra/public/utils/url_state.tsx | 10 ++++------ 10 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index 9003427d88ab7..0bca1f7b6e8bd 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -18,7 +18,6 @@ */ import { format as formatUrl } from 'url'; -// import { stringify } from 'querystring'; import { createBrowserHistory, History } from 'history'; import { decodeState, encodeState } from '../state_encoder'; import { getCurrentUrl, parseUrl, parseUrlHash } from './parse'; diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts index b592cfe6c12b3..7b2d8cf56f889 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { LocalUIFilterName } from '../../../../../../../plugins/apm/server/lib/ui_filters/local_ui_filters/config'; import { url } from '../../../../../../../../src/plugins/kibana_utils/public'; @@ -18,7 +18,7 @@ export function fromQuery(query: Record) { encodeURIComponent(value).replace(/%3A/g, ':') ); - return stringify(encodedQuery); + return url.makeUrlFromQuery(encodedQuery); } export type APMQueryParams = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js index febe5bfaf6642..f40e3c4dd5938 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js @@ -24,8 +24,8 @@ const queryParamsFromObject = (params, encodeParams = false) => { const paramStr = stringify( params, - '&', - '=', + undefined, + undefined, encodeParams ? {} : { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx index 62da03c654fb3..c520d6b0a8d96 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx @@ -34,7 +34,7 @@ export const analyticsJobExplorationRoute: MlRoute = { const PageWrapper: FC = ({ location, deps }) => { const { context } = useResolver('', undefined, deps.config, basicResolvers(deps)); - const { _g }: Record = parse(location.search); + const { _g }: Record = parse(location.search.substring(1)); let globalState: any = null; try { diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts index 25fd022a3ed73..cbca2a494c730 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts @@ -9,6 +9,7 @@ import { useCallback } from 'react'; import { isEqual } from 'lodash'; import { decode, encode } from 'rison-node'; import { useHistory, useLocation } from 'react-router-dom'; +import { url } from '../../../../../../../src/plugins/kibana_utils/common/url'; import { Dictionary } from '../../../common/types/common'; @@ -83,7 +84,7 @@ export const useUrlState = (accessor: string): UrlState => { } try { - const oldLocationSearch = stringify(parsedQueryString); + const oldLocationSearch = url.makeUrlFromQuery(parsedQueryString); Object.keys(urlState).forEach(a => { if (isRisonSerializationRequired(a)) { @@ -92,7 +93,7 @@ export const useUrlState = (accessor: string): UrlState => { parsedQueryString[a] = urlState[a]; } }); - const newLocationSearch = stringify(parsedQueryString); + const newLocationSearch = url.makeUrlFromQuery(parsedQueryString); if (oldLocationSearch !== newLocationSearch) { history.push({ diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx index c65ac17690952..7ba56e85ab50d 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx @@ -37,7 +37,7 @@ export const MlHostConditionalContainer = React.memo(({ if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); + const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); return ; }} /> @@ -49,15 +49,13 @@ export const MlHostConditionalContainer = React.memo(({ params: { hostName }, }, }) => { - const queryStringDecoded = parse(location.search.substring(1), { - sort: false, - }) as Required; + const queryStringDecoded = parse(location.search.substring(1)) as Required; if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } if (emptyEntity(hostName)) { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); + const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); return ( diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_network_conditional_container.tsx b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_network_conditional_container.tsx index cc41301b4f898..8d9d0f874c3ab 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_network_conditional_container.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_network_conditional_container.tsx @@ -5,7 +5,7 @@ */ // eslint-disable-next-line import/no-nodejs-modules -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; import React from 'react'; import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom'; @@ -37,7 +37,7 @@ export const MlNetworkConditionalContainer = React.memo; }} @@ -57,7 +57,7 @@ export const MlNetworkConditionalContainer = React.memo; } else if (multipleEntities(ip)) { @@ -67,10 +67,10 @@ export const MlNetworkConditionalContainer = React.memo; } else { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); + const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); return ; } }} diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts index 1c8fa1b56187e..e1086a95bf8a3 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts @@ -57,7 +57,7 @@ export const replaceStateKeyInQueryString = (stateKey: string, urlState: T) = if (urlState == null || (typeof urlState === 'string' && urlState === '')) { delete previousQueryValues[stateKey]; - return stringify(url.encodeQuery(previousQueryValues)); + return url.makeUrlFromQuery(previousQueryValues); } // ಠ_ಠ Code was copied from x-pack/legacy/plugins/infra/public/utils/url_state.tsx ಠ_ಠ @@ -65,13 +65,10 @@ export const replaceStateKeyInQueryString = (stateKey: string, urlState: T) = const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return stringify( - url.encodeQuery({ - ...previousQueryValues, - [stateKey]: encodedUrlState, - }), - { sort: false, encode: false } - ); + return url.makeUrlFromQuery({ + ...previousQueryValues, + [stateKey]: encodedUrlState, + }); }; export const replaceQueryStringInLocation = ( diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx index 31c097b983240..63906aff5e2d1 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx @@ -9,7 +9,6 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { encode } from 'rison-node'; import url from 'url'; -import { stringify } from 'querystring'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { TimeRange } from '../../../../common/http_api/shared/time_range'; import { url as urlUtils } from '../../../../../../../src/plugins/kibana_utils/public'; @@ -62,7 +61,7 @@ const getOverallAnomalyExplorerLink = (pathname: string, jobId: string, timeRang }, }); - const hash = `/explorer?${stringify(urlUtils.encodeQuery({ _g }))}`; + const hash = `/explorer?${urlUtils.makeUrlFromQuery({ _g })}`; return url.format({ pathname, @@ -95,7 +94,7 @@ const getPartitionSpecificSingleMetricViewerLink = ( }, }); - const hash = `/timeseriesexplorer?${stringify(urlUtils.encodeQuery({ _g, _a }))}`; + const hash = `/timeseriesexplorer?${urlUtils.makeUrlFromQuery({ _g, _a })}`; return url.format({ pathname, diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index ae3b834fa301d..5ccc6d3d11876 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -159,12 +159,10 @@ export const replaceStateKeyInQueryString = ( const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return stringify( - url.encodeQuery({ - ...previousQueryValues, - [stateKey]: encodedUrlState, - }) - ); + return url.makeUrlFromQuery({ + ...previousQueryValues, + [stateKey]: encodedUrlState, + }); }; const replaceQueryStringInLocation = (location: Location, queryString: string): Location => { From f26a1ca57d175ca2e40617ec510198b8eafdf6a5 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Wed, 4 Mar 2020 17:55:46 -0500 Subject: [PATCH 4/6] Fix more issues --- .../public/components/shared/Links/url_helpers.ts | 6 ++++-- .../plugins/ml/public/application/util/url_state.ts | 8 ++++---- .../public/pages/link_to/redirect_to_logs.test.tsx | 6 +++--- .../pages/link_to/redirect_to_node_logs.test.tsx | 12 ++++++------ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts index 7b2d8cf56f889..afdddb6144aef 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse } from 'querystring'; +import { parse, stringify } from 'querystring'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { LocalUIFilterName } from '../../../../../../../plugins/apm/server/lib/ui_filters/local_ui_filters/config'; import { url } from '../../../../../../../../src/plugins/kibana_utils/public'; @@ -18,7 +18,9 @@ export function fromQuery(query: Record) { encodeURIComponent(value).replace(/%3A/g, ':') ); - return url.makeUrlFromQuery(encodedQuery); + return stringify(encodedQuery, undefined, undefined, { + encodeURIComponent: (c: unknown) => c + }); } export type APMQueryParams = { diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts index cbca2a494c730..2fb5ce6100453 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; import { useCallback } from 'react'; import { isEqual } from 'lodash'; import { decode, encode } from 'rison-node'; @@ -33,7 +33,7 @@ function isRisonSerializationRequired(queryParam: string): boolean { export function getUrlState(search: string): Dictionary { const urlState: Dictionary = {}; - const parsedQueryString = parse(search); + const parsedQueryString = parse(search.substring(1)); try { Object.keys(parsedQueryString).forEach(a => { @@ -64,7 +64,7 @@ export const useUrlState = (accessor: string): UrlState => { const setUrlState = useCallback( (attribute: string | Dictionary, value?: any) => { const urlState = getUrlState(search); - const parsedQueryString = parse(search); + const parsedQueryString = parse(search.substring(1)); if (!Object.prototype.hasOwnProperty.call(urlState, accessor)) { urlState[accessor] = {}; @@ -97,7 +97,7 @@ export const useUrlState = (accessor: string): UrlState => { if (oldLocationSearch !== newLocationSearch) { history.push({ - search: stringify(parsedQueryString), + search: url.makeUrlFromQuery(parsedQueryString), }); } } catch (error) { diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx index 5ae51555ea6dc..3efefe93990bd 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx @@ -19,7 +19,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -33,7 +33,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -45,7 +45,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx index fb1f503dcd43a..2291306937109 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.test.tsx @@ -35,7 +35,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -47,7 +47,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -59,7 +59,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -73,7 +73,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -89,7 +89,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -103,7 +103,7 @@ describe('RedirectToNodeLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); From 8f8bf42cabf8ce120dc96726617aa9b1cf06746a Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Thu, 5 Mar 2020 11:33:19 -0500 Subject: [PATCH 5/6] Stop using strict URI encoding, it's not required --- .../routing/routes/datavisualizer/index_based.tsx | 2 +- .../public/application/routing/routes/new_job/job_type.tsx | 2 +- .../public/application/routing/routes/new_job/recognize.tsx | 6 ++++-- .../ml/public/application/routing/routes/new_job/wizard.tsx | 2 +- .../plugins/ml/public/application/util/url_state.test.ts | 5 ++--- .../legacy/plugins/ml/public/application/util/url_state.ts | 2 +- .../ml/conditional_links/ml_host_conditional_container.tsx | 2 +- .../plugins/siem/public/components/url_state/helpers.ts | 2 +- .../plugins/uptime/public/state/api/monitor_duration.ts | 2 +- x-pack/plugins/infra/public/utils/url_state.tsx | 2 +- x-pack/plugins/infra/public/utils/use_url_state.ts | 2 +- x-pack/test/functional/apps/infra/link_to.ts | 2 +- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx index f8d05794c4c76..1a67e9a117858 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx @@ -35,7 +35,7 @@ export const indexBasedRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { index, savedSearchId }: Record = parse(location.search); + const { index, savedSearchId }: Record = parse(location.search.substring(1)); const { context } = useResolver(index, savedSearchId, deps.config, { checkBasicLicense, loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx index 95f545565f224..5d61c35b587e6 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/job_type.tsx @@ -31,7 +31,7 @@ export const jobTypeRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { index, savedSearchId }: Record = parse(location.search); + const { index, savedSearchId }: Record = parse(location.search.substring(1)); const { context } = useResolver(index, savedSearchId, deps.config, basicResolvers(deps)); return ( diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index b20f6b73a9351..8c26aeb03df75 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -39,7 +39,7 @@ export const checkViewOrCreateRoute: MlRoute = { }; const PageWrapper: FC = ({ location, deps }) => { - const { id, index, savedSearchId }: Record = parse(location.search); + const { id, index, savedSearchId }: Record = parse(location.search.substring(1)); const { context, results } = useResolver(index, savedSearchId, deps.config, { ...basicResolvers(deps), existingJobsAndGroups: mlJobService.getJobAndGroupIds, @@ -53,7 +53,9 @@ const PageWrapper: FC = ({ location, deps }) => { }; const CheckViewOrCreateWrapper: FC = ({ location, deps }) => { - const { id: moduleId, index: indexPatternId }: Record = parse(location.search); + const { id: moduleId, index: indexPatternId }: Record = parse( + location.search.substring(1) + ); // the single resolver checkViewOrCreateJobs redirects only. so will always reject useResolver(undefined, undefined, deps.config, { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx index 2c2062530b401..0e5a4c7ad2066 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/new_job/wizard.tsx @@ -112,7 +112,7 @@ export const categorizationRoute: MlRoute = { }; const PageWrapper: FC = ({ location, jobType, deps }) => { - const { index, savedSearchId }: Record = parse(location.search); + const { index, savedSearchId }: Record = parse(location.search.substring(1)); const { context, results } = useResolver(index, savedSearchId, deps.config, { ...basicResolvers(deps), privileges: checkCreateJobsPrivilege, diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.test.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.test.ts index 0813f2e3da97f..adab9ecd3944f 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.test.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.test.ts @@ -63,7 +63,7 @@ describe('useUrlState', () => { mockHistoryPush.mockClear(); }); - test('pushes a properly encoded search string to history', () => { + test('pushes a the search string to history', () => { const { result } = renderHook(() => useUrlState('_a')); act(() => { @@ -74,8 +74,7 @@ describe('useUrlState', () => { }); expect(mockHistoryPush).toHaveBeenCalledWith({ - search: - '_a=%28mlExplorerFilter%3A%28%29%2CmlExplorerSwimlane%3A%28viewByFieldName%3Aaction%29%2Cquery%3A%28%29%29&_g=%28ml%3A%28jobIds%3A%21%28dec-2%29%29%2CrefreshInterval%3A%28display%3AOff%2Cpause%3A%21f%2Cvalue%3A0%29%2Ctime%3A%28from%3A%272019-01-01T00%3A03%3A40.000Z%27%2Cmode%3Aabsolute%2Cto%3A%272019-08-30T11%3A55%3A07.000Z%27%29%29&savedSearchId=571aaf70-4c88-11e8-b3d7-01146121b73d', + search: `_a=(mlExplorerFilter:(),mlExplorerSwimlane:(viewByFieldName:action),query:())&_g=(ml:(jobIds:!(dec-2)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2019-01-01T00:03:40.000Z',mode:absolute,to:'2019-08-30T11:55:07.000Z'))&savedSearchId=571aaf70-4c88-11e8-b3d7-01146121b73d`, }); }); }); diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts index 2fb5ce6100453..7ad334a2d79ce 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts @@ -38,7 +38,7 @@ export function getUrlState(search: string): Dictionary { try { Object.keys(parsedQueryString).forEach(a => { if (isRisonSerializationRequired(a)) { - urlState[a] = decode(parsedQueryString[a]); + urlState[a] = decode(parsedQueryString[a] as string); } else { urlState[a] = parsedQueryString[a]; } diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx index 7ba56e85ab50d..913f0c03d20d2 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx @@ -35,7 +35,7 @@ export const MlHostConditionalContainer = React.memo(({ const queryStringDecoded = parse(location.search.substring(1)); if (queryStringDecoded.query != null) { - queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); + queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query as string); } const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); return ; diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts index e1086a95bf8a3..1cc7fb550b3ed 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts @@ -6,7 +6,7 @@ import { isEmpty } from 'lodash/fp'; // eslint-disable-next-line import/no-nodejs-modules -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; import { decode, encode } from 'rison-node'; import * as H from 'history'; diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts b/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts index 44e797457e5fd..1d33ab5a5b936 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { stringify } from 'query-string'; +import { stringify } from 'querystring'; import { getApiPath } from '../../lib/helper'; import { BaseParams } from './types'; diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index 5ccc6d3d11876..f3f4091cd7772 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify, ParsedUrlQuery } from 'querystring'; +import { parse } from 'querystring'; import { History, Location } from 'history'; import { throttle } from 'lodash'; import React from 'react'; diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index edae4df309ba2..4e2343a002b7e 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { parse, stringify } from 'querystring'; +import { parse } from 'querystring'; import { Location } from 'history'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { decode, encode, RisonValue } from 'rison-node'; diff --git a/x-pack/test/functional/apps/infra/link_to.ts b/x-pack/test/functional/apps/infra/link_to.ts index 7f803d9c3d0c1..78a501735744a 100644 --- a/x-pack/test/functional/apps/infra/link_to.ts +++ b/x-pack/test/functional/apps/infra/link_to.ts @@ -22,7 +22,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { state: undefined, }; const expectedSearchString = - "sourceId=default&logPosition=(position:(tiebreaker:0,time:1565707203194),streamLive:!f)&logFilter=(expression:'trace.id:433b4651687e18be2c6c8e3b11f53d09',kind:kuery)"; + "logPosition=(position:(tiebreaker:0,time:1565707203194),streamLive:!f)&logFilter=(expression:'trace.id:433b4651687e18be2c6c8e3b11f53d09',kind:kuery)&sourceId=default"; const expectedRedirectPath = '/logs/stream?'; await pageObjects.common.navigateToUrlWithBrowserHistory( From 1b9b195b7887bfc6f13fc848931853955fdcb1c6 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Thu, 5 Mar 2020 16:46:26 -0500 Subject: [PATCH 6/6] Update --- NOTICE.txt | 25 ------------------- .../common/url/encode_uri_query.ts | 5 +++- src/plugins/kibana_utils/common/url/index.ts | 10 ++++++-- .../public/history/remove_query_param.ts | 2 +- .../public/state_management/url/format.ts | 2 +- .../state_management/url/kbn_url_storage.ts | 4 +-- .../components/shared/Links/url_helpers.ts | 4 +-- .../ml/public/application/util/url_state.ts | 6 ++--- .../ml_host_conditional_container.tsx | 8 +++--- .../ml_network_conditional_container.tsx | 8 +++--- .../public/components/url_state/helpers.ts | 4 +-- .../analyze_in_ml_button.tsx | 4 +-- .../plugins/infra/public/utils/url_state.tsx | 2 +- .../infra/public/utils/use_url_state.ts | 2 +- 14 files changed, 34 insertions(+), 52 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 69be6db72cff2..33c1d535d7df3 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -218,28 +218,3 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---- -This product includes code that was extracted from angular@1.3. -Original license: -The MIT License - -Copyright (c) 2010-2014 Google, Inc. http://angularjs.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/src/plugins/kibana_utils/common/url/encode_uri_query.ts b/src/plugins/kibana_utils/common/url/encode_uri_query.ts index 616a5aeea9fb1..64d4f06b492d3 100644 --- a/src/plugins/kibana_utils/common/url/encode_uri_query.ts +++ b/src/plugins/kibana_utils/common/url/encode_uri_query.ts @@ -56,5 +56,8 @@ export const encodeQuery = ( } }); -export const makeUrlFromQuery = (query: ParsedUrlQuery | {}) => +export const stringifyWithEncoding = (query: ParsedUrlQuery | {}) => stringify(query, undefined, undefined, { encodeURIComponent: encodeUriQuery }); + +export const stringifyWithoutEncoding = (query: ParsedUrlQuery | {}) => + stringify(query, undefined, undefined, { encodeURIComponent: (c: unknown) => c }); diff --git a/src/plugins/kibana_utils/common/url/index.ts b/src/plugins/kibana_utils/common/url/index.ts index 6621e6ce8b802..6f2c9a97117ca 100644 --- a/src/plugins/kibana_utils/common/url/index.ts +++ b/src/plugins/kibana_utils/common/url/index.ts @@ -17,10 +17,16 @@ * under the License. */ -import { encodeUriQuery, encodeQuery, makeUrlFromQuery } from './encode_uri_query'; +import { + encodeUriQuery, + encodeQuery, + stringifyWithEncoding, + stringifyWithoutEncoding, +} from './encode_uri_query'; export const url = { encodeQuery, encodeUriQuery, - makeUrlFromQuery, + stringifyWithEncoding, + stringifyWithoutEncoding, }; diff --git a/src/plugins/kibana_utils/public/history/remove_query_param.ts b/src/plugins/kibana_utils/public/history/remove_query_param.ts index 929ae36033d91..265209b4f9790 100644 --- a/src/plugins/kibana_utils/public/history/remove_query_param.ts +++ b/src/plugins/kibana_utils/public/history/remove_query_param.ts @@ -28,7 +28,7 @@ export function removeQueryParam(history: History, param: string, replace: boole delete query[param]; - const newSearch = url.makeUrlFromQuery(query); + const newSearch = url.stringifyWithEncoding(query); const newLocation: Location = { ...oldLocation, search: newSearch, diff --git a/src/plugins/kibana_utils/public/state_management/url/format.ts b/src/plugins/kibana_utils/public/state_management/url/format.ts index cd25d0724e7e6..bdf618789429b 100644 --- a/src/plugins/kibana_utils/public/state_management/url/format.ts +++ b/src/plugins/kibana_utils/public/state_management/url/format.ts @@ -29,7 +29,7 @@ export function replaceUrlHashQuery( const url = parseUrl(rawUrl); const hash = parseUrlHash(rawUrl); const newQuery = queryReplacer(hash?.query || {}); - const searchQueryString = urlUtils.makeUrlFromQuery(newQuery); + const searchQueryString = urlUtils.stringifyWithEncoding(newQuery); if ((!hash || !hash.search) && !searchQueryString) return rawUrl; // nothing to change. return original url return formatUrl({ diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index 0bca1f7b6e8bd..5669fafd2bf35 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -243,11 +243,11 @@ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): return formatUrl({ pathname: stripBasename(parsedUrl.pathname), - search: urlUtils.makeUrlFromQuery(parsedUrl.query), + search: urlUtils.stringifyWithEncoding(parsedUrl.query), hash: parsedHash ? formatUrl({ pathname: parsedHash.pathname, - search: urlUtils.makeUrlFromQuery(parsedHash.query), + search: urlUtils.stringifyWithEncoding(parsedHash.query), }) : parsedUrl.hash, }); diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts index afdddb6144aef..3d4bbfc0c4290 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -18,9 +18,7 @@ export function fromQuery(query: Record) { encodeURIComponent(value).replace(/%3A/g, ':') ); - return stringify(encodedQuery, undefined, undefined, { - encodeURIComponent: (c: unknown) => c - }); + return url.stringifyWithEncoding(encodedQuery); } export type APMQueryParams = { diff --git a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts index 7ad334a2d79ce..75b1bd55baa01 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/url_state.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/url_state.ts @@ -84,7 +84,7 @@ export const useUrlState = (accessor: string): UrlState => { } try { - const oldLocationSearch = url.makeUrlFromQuery(parsedQueryString); + const oldLocationSearch = url.stringifyWithoutEncoding(parsedQueryString); Object.keys(urlState).forEach(a => { if (isRisonSerializationRequired(a)) { @@ -93,11 +93,11 @@ export const useUrlState = (accessor: string): UrlState => { parsedQueryString[a] = urlState[a]; } }); - const newLocationSearch = url.makeUrlFromQuery(parsedQueryString); + const newLocationSearch = url.stringifyWithoutEncoding(parsedQueryString); if (oldLocationSearch !== newLocationSearch) { history.push({ - search: url.makeUrlFromQuery(parsedQueryString), + search: url.stringifyWithEncoding(parsedQueryString), }); } } catch (error) { diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx index 913f0c03d20d2..e3fca3601fa4c 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/ml_host_conditional_container.tsx @@ -37,7 +37,7 @@ export const MlHostConditionalContainer = React.memo(({ if (queryStringDecoded.query != null) { queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query as string); } - const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); + const reEncoded = urlUtils.stringifyWithoutEncoding(queryStringDecoded); return ; }} /> @@ -55,7 +55,7 @@ export const MlHostConditionalContainer = React.memo(({ queryStringDecoded.query = replaceKQLParts(queryStringDecoded.query); } if (emptyEntity(hostName)) { - const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); + const reEncoded = urlUtils.stringifyWithoutEncoding(queryStringDecoded); return ( @@ -67,13 +67,13 @@ export const MlHostConditionalContainer = React.memo(({ hosts, queryStringDecoded.query || '' ); - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); + const reEncoded = urlUtils.stringifyWithoutEncoding(queryStringDecoded); return ( ); } else { - const reEncoded = stringify(urlUtils.encodeQuery(queryStringDecoded)); + const reEncoded = urlUtils.stringifyWithoutEncoding(queryStringDecoded); return ( ; }} @@ -57,7 +57,7 @@ export const MlNetworkConditionalContainer = React.memo; } else if (multipleEntities(ip)) { @@ -67,10 +67,10 @@ export const MlNetworkConditionalContainer = React.memo; } else { - const reEncoded = urlUtils.makeUrlFromQuery(queryStringDecoded); + const reEncoded = urlUtils.stringifyWithEncoding(queryStringDecoded); return ; } }} diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts index 1cc7fb550b3ed..ad7b2f471ade1 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts @@ -57,7 +57,7 @@ export const replaceStateKeyInQueryString = (stateKey: string, urlState: T) = if (urlState == null || (typeof urlState === 'string' && urlState === '')) { delete previousQueryValues[stateKey]; - return url.makeUrlFromQuery(previousQueryValues); + return url.stringifyWithEncoding(previousQueryValues); } // ಠ_ಠ Code was copied from x-pack/legacy/plugins/infra/public/utils/url_state.tsx ಠ_ಠ @@ -65,7 +65,7 @@ export const replaceStateKeyInQueryString = (stateKey: string, urlState: T) = const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return url.makeUrlFromQuery({ + return url.stringifyWithEncoding({ ...previousQueryValues, [stateKey]: encodedUrlState, }); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx index 63906aff5e2d1..e83b0bfbdb8bd 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx @@ -61,7 +61,7 @@ const getOverallAnomalyExplorerLink = (pathname: string, jobId: string, timeRang }, }); - const hash = `/explorer?${urlUtils.makeUrlFromQuery({ _g })}`; + const hash = `/explorer?${urlUtils.stringifyWithEncoding({ _g })}`; return url.format({ pathname, @@ -94,7 +94,7 @@ const getPartitionSpecificSingleMetricViewerLink = ( }, }); - const hash = `/timeseriesexplorer?${urlUtils.makeUrlFromQuery({ _g, _a })}`; + const hash = `/timeseriesexplorer?${urlUtils.stringifyWithEncoding({ _g, _a })}`; return url.format({ pathname, diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index f3f4091cd7772..92e0ab5c3d5c9 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -159,7 +159,7 @@ export const replaceStateKeyInQueryString = ( const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return url.makeUrlFromQuery({ + return url.stringifyWithEncoding({ ...previousQueryValues, [stateKey]: encodedUrlState, }); diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index 4e2343a002b7e..d348899f6de73 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -115,7 +115,7 @@ export const replaceStateKeyInQueryString = ( const encodedUrlState = typeof urlState !== 'undefined' ? encodeRisonUrlState(urlState) : undefined; - return url.makeUrlFromQuery({ + return url.stringifyWithEncoding({ ...previousQueryValues, [stateKey]: encodedUrlState, });