mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Move csp
and external_url
under http
(#135639)
* Move `csp` and `external_url` under `http` * start fixing imports * update codeowners * fix more imports
This commit is contained in:
parent
d44189578b
commit
c0a629bb1b
25 changed files with 137 additions and 140 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
@ -330,7 +330,7 @@
|
|||
# Kibana Platform Security
|
||||
/packages/kbn-crypto/ @elastic/kibana-security
|
||||
/packages/kbn-handlebars/ @elastic/kibana-security
|
||||
/src/core/server/csp/ @elastic/kibana-security @elastic/kibana-core
|
||||
/src/core/server/http/csp/ @elastic/kibana-security @elastic/kibana-core
|
||||
/src/plugins/interactive_setup/ @elastic/kibana-security
|
||||
/test/interactive_setup_api_integration/ @elastic/kibana-security
|
||||
/test/interactive_setup_functional/ @elastic/kibana-security
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* 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 { TypeOf, schema } from '@kbn/config-schema';
|
||||
import { IExternalUrlPolicy } from '.';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type ExternalUrlConfigType = TypeOf<typeof config.schema>;
|
||||
|
||||
const allowSchema = schema.boolean();
|
||||
|
||||
const hostSchema = schema.string();
|
||||
|
||||
const protocolSchema = schema.string({
|
||||
validate: (value) => {
|
||||
// tools.ietf.org/html/rfc3986#section-3.1
|
||||
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||
const schemaRegex = /^[a-zA-Z][a-zA-Z0-9\+\-\.]*$/;
|
||||
if (!schemaRegex.test(value))
|
||||
throw new Error(
|
||||
'Protocol must begin with a letter, and can only contain letters, numbers, and the following characters: `+ - .`'
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const policySchema = schema.object({
|
||||
allow: allowSchema,
|
||||
protocol: schema.maybe(protocolSchema),
|
||||
host: schema.maybe(hostSchema),
|
||||
});
|
||||
|
||||
export const config = {
|
||||
path: 'externalUrl',
|
||||
schema: schema.object({
|
||||
policy: schema.arrayOf<IExternalUrlPolicy>(policySchema, {
|
||||
defaultValue: [
|
||||
{
|
||||
allow: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}),
|
||||
};
|
|
@ -6,13 +6,13 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { config } from './config';
|
||||
import { cspConfig } from './config';
|
||||
|
||||
describe('config.validate()', () => {
|
||||
it(`does not allow "disableEmbedding" to be set to true`, () => {
|
||||
// This is intentionally not editable in the raw CSP config.
|
||||
// Users should set `server.securityResponseHeaders.disableEmbedding` to control this config property.
|
||||
expect(() => config.schema.validate({ disableEmbedding: true })).toThrowError(
|
||||
expect(() => cspConfig.schema.validate({ disableEmbedding: true })).toThrowError(
|
||||
'[disableEmbedding]: expected value to equal [false]'
|
||||
);
|
||||
});
|
||||
|
@ -20,7 +20,7 @@ describe('config.validate()', () => {
|
|||
describe(`"script_src"`, () => {
|
||||
it(`throws if containing 'unsafe-inline' when 'strict' is true`, () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: true,
|
||||
warnLegacyBrowsers: false,
|
||||
script_src: [`'self'`, `unsafe-inline`],
|
||||
|
@ -30,7 +30,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: true,
|
||||
warnLegacyBrowsers: false,
|
||||
script_src: [`'self'`, `'unsafe-inline'`],
|
||||
|
@ -42,7 +42,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it(`throws if containing 'unsafe-inline' when 'warnLegacyBrowsers' is true`, () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: false,
|
||||
warnLegacyBrowsers: true,
|
||||
script_src: [`'self'`, `unsafe-inline`],
|
||||
|
@ -52,7 +52,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: false,
|
||||
warnLegacyBrowsers: true,
|
||||
script_src: [`'self'`, `'unsafe-inline'`],
|
||||
|
@ -64,7 +64,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it(`does not throw if containing 'unsafe-inline' when 'strict' and 'warnLegacyBrowsers' are false`, () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: false,
|
||||
warnLegacyBrowsers: false,
|
||||
script_src: [`'self'`, `unsafe-inline`],
|
||||
|
@ -72,7 +72,7 @@ describe('config.validate()', () => {
|
|||
).not.toThrow();
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
strict: false,
|
||||
warnLegacyBrowsers: false,
|
||||
script_src: [`'self'`, `'unsafe-inline'`],
|
||||
|
@ -82,7 +82,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
script_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -92,7 +92,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
script_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -100,7 +100,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
script_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -112,7 +112,7 @@ describe('config.validate()', () => {
|
|||
describe(`"worker_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
worker_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -122,7 +122,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
worker_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -130,7 +130,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
worker_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -142,7 +142,7 @@ describe('config.validate()', () => {
|
|||
describe(`"style_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
style_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -152,7 +152,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
style_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -160,7 +160,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
style_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -172,7 +172,7 @@ describe('config.validate()', () => {
|
|||
describe(`"connect_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
connect_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -182,7 +182,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
connect_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -190,7 +190,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
connect_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -202,7 +202,7 @@ describe('config.validate()', () => {
|
|||
describe(`"default_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
default_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -212,7 +212,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
default_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -220,7 +220,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
default_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -232,7 +232,7 @@ describe('config.validate()', () => {
|
|||
describe(`"font_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
font_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -242,7 +242,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
font_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -250,7 +250,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
font_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -262,7 +262,7 @@ describe('config.validate()', () => {
|
|||
describe(`"frame_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -272,7 +272,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -280,7 +280,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -292,7 +292,7 @@ describe('config.validate()', () => {
|
|||
describe(`"img_src"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
img_src: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -302,7 +302,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
img_src: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -310,7 +310,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
img_src: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -322,7 +322,7 @@ describe('config.validate()', () => {
|
|||
describe(`"frame_ancestors"`, () => {
|
||||
it('throws if using an `nonce-*` value', () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_ancestors: [`hello`, `nonce-foo`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -332,7 +332,7 @@ describe('config.validate()', () => {
|
|||
|
||||
it("throws if using `none` or `'none'`", () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_ancestors: [`hello`, `none`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
|
@ -340,7 +340,7 @@ describe('config.validate()', () => {
|
|||
);
|
||||
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
cspConfig.schema.validate({
|
||||
frame_ancestors: [`hello`, `'none'`],
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
|
@ -114,7 +114,7 @@ const configSchema = schema.object(
|
|||
*/
|
||||
export type CspConfigType = TypeOf<typeof configSchema>;
|
||||
|
||||
export const config: ServiceConfigDescriptor<CspConfigType> = {
|
||||
export const cspConfig: ServiceConfigDescriptor<CspConfigType> = {
|
||||
// TODO: Move this to server.csp using config deprecations
|
||||
// ? https://github.com/elastic/kibana/pull/52251
|
||||
path: 'csp',
|
|
@ -7,19 +7,19 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { config } from './config';
|
||||
import { cspConfig } from './config';
|
||||
|
||||
const origSchema = config.schema;
|
||||
const origSchema = cspConfig.schema;
|
||||
|
||||
export const mockConfig = {
|
||||
create(defaultDisableUnsafeEval: boolean) {
|
||||
// @ts-expect-error: Property 'extends' does not exist on type??
|
||||
config.schema = config.schema.extends({
|
||||
cspConfig.schema = cspConfig.schema.extends({
|
||||
disableUnsafeEval: schema.boolean({ defaultValue: defaultDisableUnsafeEval }),
|
||||
});
|
||||
return config;
|
||||
return cspConfig;
|
||||
},
|
||||
reset() {
|
||||
config.schema = origSchema;
|
||||
cspConfig.schema = origSchema;
|
||||
},
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { CspConfig } from './csp_config';
|
||||
import { config as cspConfig, CspConfigType } from './config';
|
||||
import { cspConfig, CspConfigType } from './config';
|
||||
import { mockConfig } from './csp_config.test.mocks';
|
||||
|
||||
// CSP rules aren't strictly additive, so any change can potentially expand or
|
|
@ -6,10 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { config, CspConfigType } from './config';
|
||||
import { cspConfig, CspConfigType } from './config';
|
||||
import { CspDirectives } from './csp_directives';
|
||||
|
||||
const DEFAULT_CONFIG = Object.freeze(config.schema.validate({}));
|
||||
const DEFAULT_CONFIG = Object.freeze(cspConfig.schema.validate({}));
|
||||
|
||||
/**
|
||||
* CSP configuration for use in Kibana.
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { CspDirectives } from './csp_directives';
|
||||
import { config as cspConfig } from './config';
|
||||
import { cspConfig } from './config';
|
||||
|
||||
describe('CspDirectives', () => {
|
||||
describe('#addDirectiveValue', () => {
|
|
@ -6,8 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { CspConfig, ICspConfig } from './csp_config';
|
||||
import { CspConfigType, config } from './config';
|
||||
|
||||
export { CspConfig, config };
|
||||
export type { CspConfigType, ICspConfig };
|
||||
export { CspConfig } from './csp_config';
|
||||
export type { ICspConfig } from './csp_config';
|
||||
export { cspConfig } from './config';
|
||||
export type { CspConfigType } from './config';
|
|
@ -6,11 +6,11 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { config } from './config';
|
||||
import { externalUrlConfig } from './config';
|
||||
|
||||
describe('externalUrl config', () => {
|
||||
it('provides a default policy allowing all external urls', () => {
|
||||
expect(config.schema.validate({})).toMatchInlineSnapshot(`
|
||||
expect(externalUrlConfig.schema.validate({})).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"policy": Array [
|
||||
Object {
|
||||
|
@ -22,7 +22,7 @@ describe('externalUrl config', () => {
|
|||
});
|
||||
|
||||
it('allows an empty policy', () => {
|
||||
expect(config.schema.validate({ policy: [] })).toMatchInlineSnapshot(`
|
||||
expect(externalUrlConfig.schema.validate({ policy: [] })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"policy": Array [],
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ describe('externalUrl config', () => {
|
|||
|
||||
it('allows a policy with just a protocol', () => {
|
||||
expect(
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
||||
|
@ -53,7 +53,7 @@ describe('externalUrl config', () => {
|
|||
|
||||
it('allows a policy with just a host', () => {
|
||||
expect(
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
||||
|
@ -75,7 +75,7 @@ describe('externalUrl config', () => {
|
|||
|
||||
it('allows a policy with both host and protocol', () => {
|
||||
expect(
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
||||
|
@ -99,7 +99,7 @@ describe('externalUrl config', () => {
|
|||
|
||||
it('allows a policy without a host or protocol', () => {
|
||||
expect(
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
||||
|
@ -120,7 +120,7 @@ describe('externalUrl config', () => {
|
|||
describe('protocols', () => {
|
||||
['http', 'https', 'ftp', 'ftps', 'custom-protocol+123.bar'].forEach((protocol) => {
|
||||
it(`allows a protocol of "${protocol}"`, () => {
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
||||
|
@ -134,7 +134,7 @@ describe('externalUrl config', () => {
|
|||
['1http', '', 'custom-protocol()', 'https://'].forEach((protocol) => {
|
||||
it(`disallows a protocol of "${protocol}"`, () => {
|
||||
expect(() =>
|
||||
config.schema.validate({
|
||||
externalUrlConfig.schema.validate({
|
||||
policy: [
|
||||
{
|
||||
allow: true,
|
49
src/core/server/http/external_url/config.ts
Normal file
49
src/core/server/http/external_url/config.ts
Normal file
|
@ -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 { TypeOf, schema } from '@kbn/config-schema';
|
||||
import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';
|
||||
import { IExternalUrlPolicy } from '.';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type ExternalUrlConfigType = TypeOf<typeof externalUrlConfigSchema>;
|
||||
|
||||
const policySchema = schema.object({
|
||||
allow: schema.boolean(),
|
||||
host: schema.maybe(schema.string()),
|
||||
protocol: schema.maybe(
|
||||
schema.string({
|
||||
validate: (value) => {
|
||||
// tools.ietf.org/html/rfc3986#section-3.1
|
||||
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||
const schemaRegex = /^[a-zA-Z][a-zA-Z0-9\+\-\.]*$/;
|
||||
if (!schemaRegex.test(value))
|
||||
throw new Error(
|
||||
'Protocol must begin with a letter, and can only contain letters, numbers, and the following characters: `+ - .`'
|
||||
);
|
||||
},
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
const externalUrlConfigSchema = schema.object({
|
||||
policy: schema.arrayOf<IExternalUrlPolicy>(policySchema, {
|
||||
defaultValue: [
|
||||
{
|
||||
allow: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
export const externalUrlConfig: ServiceConfigDescriptor<ExternalUrlConfigType> = {
|
||||
path: 'externalUrl',
|
||||
schema: externalUrlConfigSchema,
|
||||
};
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import { createSHA256Hash } from '@kbn/crypto';
|
||||
import { config } from './config';
|
||||
import { externalUrlConfig } from './config';
|
||||
|
||||
const DEFAULT_CONFIG = Object.freeze(config.schema.validate({}));
|
||||
const DEFAULT_CONFIG = Object.freeze(externalUrlConfig.schema.validate({}));
|
||||
|
||||
/**
|
||||
* External Url configuration for use in Kibana.
|
|
@ -8,5 +8,5 @@
|
|||
|
||||
export { ExternalUrlConfig } from './external_url_config';
|
||||
export type { IExternalUrlConfig, IExternalUrlPolicy } from './external_url_config';
|
||||
export { config } from './config';
|
||||
export { externalUrlConfig } from './config';
|
||||
export type { ExternalUrlConfigType } from './config';
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
import uuid from 'uuid';
|
||||
import { config, HttpConfig } from './http_config';
|
||||
import { config as cspConfig } from '../csp';
|
||||
import { ExternalUrlConfig } from '../external_url';
|
||||
import { cspConfig } from './csp';
|
||||
import { ExternalUrlConfig } from './external_url';
|
||||
|
||||
const validHostnames = ['www.example.com', '8.8.8.8', '::1', 'localhost', '0.0.0.0'];
|
||||
const invalidHostnames = ['asdf$%^', '0'];
|
||||
|
|
|
@ -15,8 +15,8 @@ import { hostname } from 'os';
|
|||
import url from 'url';
|
||||
|
||||
import type { Duration } from 'moment';
|
||||
import { CspConfigType, CspConfig, ICspConfig } from '../csp';
|
||||
import { ExternalUrlConfig, IExternalUrlConfig } from '../external_url';
|
||||
import { CspConfigType, CspConfig, ICspConfig } from './csp';
|
||||
import { ExternalUrlConfig, IExternalUrlConfig } from './external_url';
|
||||
import {
|
||||
securityResponseHeadersSchema,
|
||||
parseRawSecurityResponseHeadersConfig,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Server } from '@hapi/hapi';
|
|||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import { configMock } from '@kbn/config-mocks';
|
||||
|
||||
import { CspConfig } from '../csp';
|
||||
import { CspConfig } from './csp';
|
||||
import { mockRouter, RouterMock } from './router/router.mock';
|
||||
import {
|
||||
InternalHttpServicePreboot,
|
||||
|
@ -28,7 +28,7 @@ import { sessionStorageMock } from './cookie_session_storage.mocks';
|
|||
import { OnPostAuthToolkit } from './lifecycle/on_post_auth';
|
||||
import { OnPreAuthToolkit } from './lifecycle/on_pre_auth';
|
||||
import { OnPreResponseToolkit } from './lifecycle/on_pre_response';
|
||||
import { ExternalUrlConfig } from '../external_url';
|
||||
import { ExternalUrlConfig } from './external_url';
|
||||
import type { IAuthHeadersStorage } from './auth_headers_storage';
|
||||
|
||||
type BasePathMocked = jest.Mocked<InternalHttpServiceSetup['basePath']>;
|
||||
|
|
|
@ -19,8 +19,8 @@ import { HttpService } from '.';
|
|||
import { HttpConfigType, config } from './http_config';
|
||||
import { httpServerMock } from './http_server.mocks';
|
||||
import { contextServiceMock } from '../context/context_service.mock';
|
||||
import { config as cspConfig } from '../csp';
|
||||
import { config as externalUrlConfig, ExternalUrlConfig } from '../external_url';
|
||||
import { cspConfig } from './csp';
|
||||
import { externalUrlConfig, ExternalUrlConfig } from './external_url';
|
||||
import { Router } from './router';
|
||||
|
||||
const logger = loggingSystemMock.create();
|
||||
|
|
|
@ -18,7 +18,7 @@ import type { InternalExecutionContextSetup } from '@kbn/core-execution-context-
|
|||
|
||||
import type { RequestHandlerContext } from '..';
|
||||
import { InternalContextSetup, InternalContextPreboot } from '../context';
|
||||
import { CspConfigType, config as cspConfig } from '../csp';
|
||||
import { CspConfigType, cspConfig } from './csp';
|
||||
|
||||
import { Router } from './router';
|
||||
import { HttpConfig, HttpConfigType, config as httpConfig } from './http_config';
|
||||
|
@ -34,11 +34,7 @@ import {
|
|||
} from './types';
|
||||
|
||||
import { registerCoreHandlers } from './lifecycle_handlers';
|
||||
import {
|
||||
ExternalUrlConfigType,
|
||||
config as externalUrlConfig,
|
||||
ExternalUrlConfig,
|
||||
} from '../external_url';
|
||||
import { ExternalUrlConfigType, externalUrlConfig, ExternalUrlConfig } from './external_url';
|
||||
|
||||
export interface PrebootDeps {
|
||||
context: InternalContextPreboot;
|
||||
|
|
|
@ -97,3 +97,9 @@ export type {
|
|||
} from './types';
|
||||
export { BasePath } from './base_path_service';
|
||||
export type { IBasePath } from './base_path_service';
|
||||
|
||||
export { cspConfig, CspConfig } from './csp';
|
||||
export type { ICspConfig } from './csp';
|
||||
|
||||
export { externalUrlConfig, ExternalUrlConfig } from './external_url';
|
||||
export type { IExternalUrlConfig, IExternalUrlPolicy } from './external_url';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { IContextProvider, IContextContainer } from '../context';
|
||||
import { ICspConfig } from '../csp';
|
||||
import { ICspConfig } from './csp';
|
||||
import { GetAuthState, IsAuthenticated } from './auth_state_storage';
|
||||
import { IAuthHeadersStorage } from './auth_headers_storage';
|
||||
import { IRouter } from './router';
|
||||
|
@ -20,7 +20,7 @@ import { OnPreAuthHandler } from './lifecycle/on_pre_auth';
|
|||
import { OnPostAuthHandler } from './lifecycle/on_post_auth';
|
||||
import { OnPreResponseHandler } from './lifecycle/on_pre_response';
|
||||
import { IBasePath } from './base_path_service';
|
||||
import { ExternalUrlConfig } from '../external_url';
|
||||
import { ExternalUrlConfig } from './external_url';
|
||||
import type { PluginOpaqueId, RequestHandlerContext } from '..';
|
||||
|
||||
/**
|
||||
|
|
|
@ -122,9 +122,6 @@ export type {
|
|||
} from './context';
|
||||
export type { CoreId } from '@kbn/core-base-common-internal';
|
||||
|
||||
export { CspConfig } from './csp';
|
||||
export type { ICspConfig } from './csp';
|
||||
|
||||
export { ElasticsearchConfig, pollEsNodesVersion } from './elasticsearch';
|
||||
export type {
|
||||
ElasticsearchServicePreboot,
|
||||
|
@ -156,7 +153,6 @@ export type {
|
|||
UnauthorizedErrorHandler,
|
||||
} from './elasticsearch';
|
||||
|
||||
export type { IExternalUrlConfig, IExternalUrlPolicy } from './external_url';
|
||||
export type {
|
||||
AuthenticationHandler,
|
||||
AuthHeaders,
|
||||
|
@ -231,10 +227,13 @@ export type {
|
|||
SessionStorageFactory,
|
||||
DestructiveRouteMethod,
|
||||
SafeRouteMethod,
|
||||
KibanaRequest,
|
||||
ICspConfig,
|
||||
IExternalUrlConfig,
|
||||
IExternalUrlPolicy,
|
||||
} from './http';
|
||||
|
||||
export { kibanaResponseFactory, validBodyOutput, CoreKibanaRequest } from './http';
|
||||
export type { KibanaRequest } from './http';
|
||||
export { kibanaResponseFactory, validBodyOutput, CoreKibanaRequest, CspConfig } from './http';
|
||||
|
||||
export type {
|
||||
HttpResourcesRenderOptions,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import type { ThemeVersion } from '@kbn/ui-shared-deps-npm';
|
||||
import type { InjectedMetadata } from '@kbn/core-injected-metadata-common-internal';
|
||||
import { InternalElasticsearchServiceSetup } from '../elasticsearch';
|
||||
import { ICspConfig } from '../csp';
|
||||
import { ICspConfig } from '../http';
|
||||
import { InternalHttpServicePreboot, InternalHttpServiceSetup, KibanaRequest } from '../http';
|
||||
import { UiPlugins } from '../plugins';
|
||||
import { IUiSettingsClient } from '../ui_settings';
|
||||
|
|
|
@ -43,9 +43,8 @@ import { CapabilitiesService } from './capabilities';
|
|||
// do not try to shorten the import to `./status`, it will break server test mocking
|
||||
import { StatusService } from './status/status_service';
|
||||
|
||||
import { config as cspConfig } from './csp';
|
||||
import { config as elasticsearchConfig } from './elasticsearch';
|
||||
import { config as httpConfig } from './http';
|
||||
import { config as httpConfig, cspConfig, externalUrlConfig } from './http';
|
||||
import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects';
|
||||
import { config as uiSettingsConfig } from './ui_settings';
|
||||
import { config as statusConfig } from './status';
|
||||
|
@ -55,7 +54,6 @@ import { InternalCorePreboot, InternalCoreSetup, InternalCoreStart } from './int
|
|||
import { CoreUsageDataService } from './core_usage_data';
|
||||
import { DeprecationsService, config as deprecationConfig } from './deprecations';
|
||||
import { CoreRouteHandlerContext } from './core_route_handler_context';
|
||||
import { config as externalUrlConfig } from './external_url';
|
||||
import { PrebootCoreRouteHandlerContext } from './preboot_core_route_handler_context';
|
||||
import { PrebootService } from './preboot';
|
||||
import { DiscoveredPlugins } from './plugins';
|
||||
|
|
|
@ -44,4 +44,4 @@ export type {
|
|||
export type { DomainDeprecationDetails, DeprecationsGetResponse } from './deprecations/types';
|
||||
export * from './ui_settings/types';
|
||||
export type { EnvironmentMode, PackageInfo } from '@kbn/config';
|
||||
export type { ExternalUrlConfig, IExternalUrlPolicy } from './external_url';
|
||||
export type { ExternalUrlConfig, IExternalUrlPolicy } from './http';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue