-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7727bf4
commit c0bf054
Showing
68 changed files
with
2,177 additions
and
788 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ | |
|
||
export * from './url_service'; | ||
export * from './locators'; | ||
export * from './short_urls'; |
47 changes: 47 additions & 0 deletions
47
src/plugins/share/common/url_service/locators/legacy_short_url_locator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import type { SerializableRecord } from '@kbn/utility-types'; | ||
import type { KibanaLocation, LocatorDefinition } from '../../url_service'; | ||
import { shortUrlAssertValid } from './short_url_assert_valid'; | ||
|
||
export const LEGACY_SHORT_URL_LOCATOR_ID = 'LEGACY_SHORT_URL_LOCATOR'; | ||
|
||
export interface LegacyShortUrlLocatorParams extends SerializableRecord { | ||
url: string; | ||
} | ||
|
||
export class LegacyShortUrlLocatorDefinition | ||
implements LocatorDefinition<LegacyShortUrlLocatorParams> | ||
{ | ||
public readonly id = LEGACY_SHORT_URL_LOCATOR_ID; | ||
|
||
public async getLocation(params: LegacyShortUrlLocatorParams): Promise<KibanaLocation> { | ||
const { url } = params; | ||
|
||
shortUrlAssertValid(url); | ||
|
||
const match = url.match(/^.*\/app\/([^\/#]+)(.+)$/); | ||
|
||
if (!match) { | ||
throw new Error('Unexpected URL path.'); | ||
} | ||
|
||
const [, app, path] = match; | ||
|
||
if (!app || !path) { | ||
throw new Error('Could not parse URL path.'); | ||
} | ||
|
||
return { | ||
app, | ||
path, | ||
state: {}, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/plugins/share/common/url_service/locators/short_url_assert_valid.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { shortUrlAssertValid } from './short_url_assert_valid'; | ||
|
||
describe('shortUrlAssertValid()', () => { | ||
const invalid = [ | ||
['protocol', 'http://localhost:5601/app/kibana'], | ||
['protocol', 'https://localhost:5601/app/kibana'], | ||
['protocol', 'mailto:foo@bar.net'], | ||
['protocol', 'javascript:alert("hi")'], // eslint-disable-line no-script-url | ||
['hostname', 'localhost/app/kibana'], // according to spec, this is not a valid URL -- you cannot specify a hostname without a protocol | ||
['hostname and port', 'local.host:5601/app/kibana'], // parser detects 'local.host' as the protocol | ||
['hostname and auth', 'user:pass@localhost.net/app/kibana'], // parser detects 'user' as the protocol | ||
['path traversal', '/app/../../not-kibana'], // fails because there are >2 path parts | ||
['path traversal', '/../not-kibana'], // fails because first path part is not 'app' | ||
['base path', '/base/app/kibana'], // fails because there are >2 path parts | ||
['path with an extra leading slash', '//foo/app/kibana'], // parser detects 'foo' as the hostname | ||
['path with an extra leading slash', '///app/kibana'], // parser detects '' as the hostname | ||
['path without app', '/foo/kibana'], // fails because first path part is not 'app' | ||
['path without appId', '/app/'], // fails because there is only one path part (leading and trailing slashes are trimmed) | ||
]; | ||
|
||
invalid.forEach(([desc, url, error]) => { | ||
it(`fails when url has ${desc as string}`, () => { | ||
expect(() => shortUrlAssertValid(url as string)).toThrow(); | ||
}); | ||
}); | ||
|
||
const valid = [ | ||
'/app/kibana', | ||
'/app/kibana/', // leading and trailing slashes are trimmed | ||
'/app/monitoring#angular/route', | ||
'/app/text#document-id', | ||
'/app/some?with=query', | ||
'/app/some?with=query#and-a-hash', | ||
]; | ||
|
||
valid.forEach((url) => { | ||
it(`allows ${url}`, () => { | ||
shortUrlAssertValid(url); | ||
}); | ||
}); | ||
}); |
13 changes: 13 additions & 0 deletions
13
src/plugins/share/common/url_service/locators/short_url_assert_valid.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
const REGEX = /^\/app\/[^/]+.+$/; | ||
|
||
export function shortUrlAssertValid(url: string) { | ||
if (!REGEX.test(url) || url.includes('/../')) throw new Error(`Invalid short URL: ${url}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
export * from './types'; |
141 changes: 141 additions & 0 deletions
141
src/plugins/share/common/url_service/short_urls/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { SerializableRecord } from '@kbn/utility-types'; | ||
import { VersionedState } from 'src/plugins/kibana_utils/common'; | ||
import { LocatorPublic } from '../locators'; | ||
|
||
/** | ||
* A factory for Short URL Service. We need this factory as the dependency | ||
* injection is different between the server and the client. On the server, | ||
* the Short URL Service needs a saved object client scoped to the current | ||
* request and the current Kibana version. On the client, the Short URL Service | ||
* needs no dependencies. | ||
*/ | ||
export interface IShortUrlClientFactory<D> { | ||
get(dependencies: D): IShortUrlClient; | ||
} | ||
|
||
/** | ||
* CRUD-like API for short URLs. | ||
*/ | ||
export interface IShortUrlClient { | ||
/** | ||
* Create a new short URL. | ||
* | ||
* @param locator The locator for the URL. | ||
* @param param The parameters for the URL. | ||
* @returns The created short URL. | ||
*/ | ||
create<P extends SerializableRecord>(params: ShortUrlCreateParams<P>): Promise<ShortUrl<P>>; | ||
|
||
/** | ||
* Delete a short URL. | ||
* | ||
* @param slug The ID of the short URL. | ||
*/ | ||
delete(id: string): Promise<void>; | ||
|
||
/** | ||
* Fetch a short URL. | ||
* | ||
* @param id The ID of the short URL. | ||
*/ | ||
get(id: string): Promise<ShortUrl>; | ||
|
||
/** | ||
* Fetch a short URL by its slug. | ||
* | ||
* @param slug The slug of the short URL. | ||
*/ | ||
resolve(slug: string): Promise<ShortUrl>; | ||
} | ||
|
||
/** | ||
* New short URL creation parameters. | ||
*/ | ||
export interface ShortUrlCreateParams<P extends SerializableRecord> { | ||
/** | ||
* Locator which will be used to resolve the short URL. | ||
*/ | ||
locator: LocatorPublic<P>; | ||
|
||
/** | ||
* Locator parameters which will be used to resolve the short URL. | ||
*/ | ||
params: P; | ||
|
||
/** | ||
* Optional, short URL slug - the part that will be used to resolve the short | ||
* URL. This part will be visible to the user, it can have user-friendly text. | ||
*/ | ||
slug?: string; | ||
|
||
/** | ||
* Whether to generate a slug automatically. If `true`, the slug will be | ||
* a human-readable text consisting of three worlds: "<adjective>-<adjective>-<noun>". | ||
*/ | ||
humanReadableSlug?: boolean; | ||
} | ||
|
||
/** | ||
* A representation of a short URL. | ||
*/ | ||
export interface ShortUrl<LocatorParams extends SerializableRecord = SerializableRecord> { | ||
/** | ||
* Serializable state of the short URL, which is stored in Kibana. | ||
*/ | ||
readonly data: ShortUrlData<LocatorParams>; | ||
} | ||
|
||
/** | ||
* A representation of a short URL's data. | ||
*/ | ||
export interface ShortUrlData<LocatorParams extends SerializableRecord = SerializableRecord> { | ||
/** | ||
* Unique ID of the short URL. | ||
*/ | ||
readonly id: string; | ||
|
||
/** | ||
* The slug of the short URL, the part after the `/` in the URL. | ||
*/ | ||
readonly slug: string; | ||
|
||
/** | ||
* Number of times the short URL has been resolved. | ||
*/ | ||
readonly accessCount: number; | ||
|
||
/** | ||
* The timestamp of the last time the short URL was resolved. | ||
*/ | ||
readonly accessDate: number; | ||
|
||
/** | ||
* The timestamp when the short URL was created. | ||
*/ | ||
readonly createDate: number; | ||
|
||
/** | ||
* The timestamp when the short URL was last modified. | ||
*/ | ||
readonly locator: LocatorData<LocatorParams>; | ||
} | ||
|
||
/** | ||
* Represents a serializable state of a locator. Includes locator ID, version | ||
* and its params. | ||
*/ | ||
export interface LocatorData<LocatorParams extends SerializableRecord = SerializableRecord> | ||
extends VersionedState<LocatorParams> { | ||
/** | ||
* Locator ID. | ||
*/ | ||
id: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.