@backstage/plugin-proxy-backend 0.2.42-next.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/alpha/package.json +1 -1
- package/config.d.ts +56 -44
- package/dist/index.alpha.d.ts +1 -4
- package/dist/index.cjs.js +55 -32
- package/dist/index.cjs.js.map +1 -1
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @backstage/plugin-proxy-backend
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7daf65bfcfa1: Defining proxy endpoints directly under the root `proxy` configuration key is deprecated. Endpoints should now be declared under `proxy.endpoints` instead. The `skipInvalidProxies` and `reviveConsumedRequestBodies` can now also be configured through static configuration.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config`
|
|
12
|
+
- 4b82382ed8c2: Fixed invalid configuration schema. The configuration schema may be more strict as a result.
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/backend-common@0.19.2
|
|
15
|
+
- @backstage/backend-plugin-api@0.6.0
|
|
16
|
+
- @backstage/config@1.0.8
|
|
17
|
+
|
|
18
|
+
## 0.3.0-next.2
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- 7daf65bfcfa1: Defining proxy endpoints directly under the root `proxy` configuration key is deprecated. Endpoints should now be declared under `proxy.endpoints` instead. The `skipInvalidProxies` and `reviveConsumedRequestBodies` can now also be configured through static configuration.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/backend-plugin-api@0.6.0-next.2
|
|
28
|
+
- @backstage/backend-common@0.19.2-next.2
|
|
29
|
+
|
|
3
30
|
## 0.2.42-next.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/config.d.ts
CHANGED
|
@@ -15,51 +15,63 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
export interface Config {
|
|
18
|
-
/**
|
|
19
|
-
* A list of forwarding-proxies. Each key is a route to match,
|
|
20
|
-
* below the prefix that the proxy plugin is mounted on. It must
|
|
21
|
-
* start with a '/'.
|
|
22
|
-
*/
|
|
23
18
|
proxy?: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Rather than failing to start up, the proxy backend will instead just warn on invalid endpoints.
|
|
21
|
+
*/
|
|
22
|
+
skipInvalidProxies?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Revive request bodies that have already been consumed by earlier middleware.
|
|
26
|
+
*/
|
|
27
|
+
reviveConsumedRequestBodies?: boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A list of forwarding-proxies. Each key is a route to match,
|
|
31
|
+
* below the prefix that the proxy plugin is mounted on. It must
|
|
32
|
+
* start with a '/'.
|
|
33
|
+
*/
|
|
34
|
+
endpoints?: {
|
|
35
|
+
[key: string]:
|
|
36
|
+
| string
|
|
37
|
+
| {
|
|
38
|
+
/**
|
|
39
|
+
* Target of the proxy. Url string to be parsed with the url module.
|
|
40
|
+
*/
|
|
41
|
+
target: string;
|
|
42
|
+
/**
|
|
43
|
+
* Object with extra headers to be added to target requests.
|
|
44
|
+
*/
|
|
45
|
+
headers?: {
|
|
46
|
+
/** @visibility secret */
|
|
47
|
+
Authorization?: string;
|
|
48
|
+
/** @visibility secret */
|
|
49
|
+
authorization?: string;
|
|
50
|
+
/** @visibility secret */
|
|
51
|
+
'X-Api-Key'?: string;
|
|
52
|
+
/** @visibility secret */
|
|
53
|
+
'x-api-key'?: string;
|
|
54
|
+
[key: string]: string | undefined;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Changes the origin of the host header to the target URL. Default: true.
|
|
58
|
+
*/
|
|
59
|
+
changeOrigin?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Rewrite target's url path. Object-keys will be used as RegExp to match paths.
|
|
62
|
+
* If pathRewrite is not specified, it is set to a single rewrite that removes the entire prefix and route.
|
|
63
|
+
*/
|
|
64
|
+
pathRewrite?: { [regexp: string]: string };
|
|
65
|
+
/**
|
|
66
|
+
* Limit the forwarded HTTP methods, for example allowedMethods: ['GET'] to enforce read-only access.
|
|
67
|
+
*/
|
|
68
|
+
allowedMethods?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Limit the forwarded HTTP methods. By default, only the headers that are considered safe for CORS
|
|
71
|
+
* and headers that are set by the proxy will be forwarded.
|
|
72
|
+
*/
|
|
73
|
+
allowedHeaders?: string[];
|
|
44
74
|
};
|
|
45
|
-
|
|
46
|
-
* Changes the origin of the host header to the target URL. Default: true.
|
|
47
|
-
*/
|
|
48
|
-
changeOrigin?: boolean;
|
|
49
|
-
/**
|
|
50
|
-
* Rewrite target's url path. Object-keys will be used as RegExp to match paths.
|
|
51
|
-
* If pathRewrite is not specified, it is set to a single rewrite that removes the entire prefix and route.
|
|
52
|
-
*/
|
|
53
|
-
pathRewrite?: { [regexp: string]: string };
|
|
54
|
-
/**
|
|
55
|
-
* Limit the forwarded HTTP methods, for example allowedMethods: ['GET'] to enforce read-only access.
|
|
56
|
-
*/
|
|
57
|
-
allowedMethods?: string[];
|
|
58
|
-
/**
|
|
59
|
-
* Limit the forwarded HTTP methods. By default, only the headers that are considered safe for CORS
|
|
60
|
-
* and headers that are set by the proxy will be forwarded.
|
|
61
|
-
*/
|
|
62
|
-
allowedHeaders?: string[];
|
|
63
|
-
};
|
|
75
|
+
};
|
|
64
76
|
};
|
|
65
77
|
}
|
package/dist/index.alpha.d.ts
CHANGED
|
@@ -35,10 +35,7 @@ export declare function createRouter(options: RouterOptions): Promise<express.Ro
|
|
|
35
35
|
*
|
|
36
36
|
* @alpha
|
|
37
37
|
*/
|
|
38
|
-
export declare const proxyPlugin: (
|
|
39
|
-
skipInvalidProxies?: boolean | undefined;
|
|
40
|
-
reviveConsumedRequestBodies?: boolean | undefined;
|
|
41
|
-
} | undefined) => BackendFeature;
|
|
38
|
+
export declare const proxyPlugin: () => BackendFeature;
|
|
42
39
|
|
|
43
40
|
/** @public */
|
|
44
41
|
export declare interface RouterOptions {
|
package/dist/index.cjs.js
CHANGED
|
@@ -99,26 +99,53 @@ function buildMiddleware(pathPrefix, logger, route, config, reviveConsumedReques
|
|
|
99
99
|
}
|
|
100
100
|
return httpProxyMiddleware.createProxyMiddleware(filter, fullConfig);
|
|
101
101
|
}
|
|
102
|
+
function readProxyConfig(config, logger) {
|
|
103
|
+
var _a, _b;
|
|
104
|
+
const endpoints = (_a = config.getOptionalConfig("proxy.endpoints")) == null ? void 0 : _a.get();
|
|
105
|
+
if (endpoints) {
|
|
106
|
+
return endpoints;
|
|
107
|
+
}
|
|
108
|
+
const root = (_b = config.getOptionalConfig("proxy")) == null ? void 0 : _b.get();
|
|
109
|
+
if (!root) {
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
const rootEndpoints = Object.fromEntries(
|
|
113
|
+
Object.entries(root).filter(([key]) => key.startsWith("/"))
|
|
114
|
+
);
|
|
115
|
+
if (Object.keys(rootEndpoints).length === 0) {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
logger.warn(
|
|
119
|
+
"Configuring proxy endpoints in the root 'proxy' configuration is deprecated. Move this configuration to 'proxy.endpoints' instead."
|
|
120
|
+
);
|
|
121
|
+
return rootEndpoints;
|
|
122
|
+
}
|
|
102
123
|
async function createRouter(options) {
|
|
103
|
-
var _a;
|
|
124
|
+
var _a, _b, _c, _d;
|
|
104
125
|
const router = Router__default["default"]();
|
|
105
126
|
let currentRouter = Router__default["default"]();
|
|
127
|
+
const skipInvalidProxies = (_b = (_a = options.skipInvalidProxies) != null ? _a : options.config.getOptionalBoolean("proxy.skipInvalidProxies")) != null ? _b : false;
|
|
128
|
+
const reviveConsumedRequestBodies = (_d = (_c = options.reviveConsumedRequestBodies) != null ? _c : options.config.getOptionalBoolean("proxy.reviveConsumedRequestBodies")) != null ? _d : false;
|
|
129
|
+
const proxyOptions = {
|
|
130
|
+
skipInvalidProxies,
|
|
131
|
+
reviveConsumedRequestBodies,
|
|
132
|
+
logger: options.logger
|
|
133
|
+
};
|
|
106
134
|
const externalUrl = await options.discovery.getExternalBaseUrl("proxy");
|
|
107
135
|
const { pathname: pathPrefix } = new URL(externalUrl);
|
|
108
|
-
const proxyConfig = (
|
|
109
|
-
configureMiddlewares(
|
|
136
|
+
const proxyConfig = readProxyConfig(options.config, options.logger);
|
|
137
|
+
configureMiddlewares(proxyOptions, currentRouter, pathPrefix, proxyConfig);
|
|
110
138
|
router.use((...args) => currentRouter(...args));
|
|
111
139
|
if (options.config.subscribe) {
|
|
112
140
|
let currentKey = JSON.stringify(proxyConfig);
|
|
113
141
|
options.config.subscribe(() => {
|
|
114
|
-
|
|
115
|
-
const newProxyConfig = (_a2 = options.config.getOptional("proxy")) != null ? _a2 : {};
|
|
142
|
+
const newProxyConfig = readProxyConfig(options.config, options.logger);
|
|
116
143
|
const newKey = JSON.stringify(newProxyConfig);
|
|
117
144
|
if (currentKey !== newKey) {
|
|
118
145
|
currentKey = newKey;
|
|
119
146
|
currentRouter = Router__default["default"]();
|
|
120
147
|
configureMiddlewares(
|
|
121
|
-
|
|
148
|
+
proxyOptions,
|
|
122
149
|
currentRouter,
|
|
123
150
|
pathPrefix,
|
|
124
151
|
newProxyConfig
|
|
@@ -151,32 +178,28 @@ function configureMiddlewares(options, router, pathPrefix, proxyConfig) {
|
|
|
151
178
|
});
|
|
152
179
|
}
|
|
153
180
|
|
|
154
|
-
const proxyPlugin = backendPluginApi.createBackendPlugin(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
})
|
|
179
|
-
);
|
|
181
|
+
const proxyPlugin = backendPluginApi.createBackendPlugin({
|
|
182
|
+
pluginId: "proxy",
|
|
183
|
+
register(env) {
|
|
184
|
+
env.registerInit({
|
|
185
|
+
deps: {
|
|
186
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
187
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
188
|
+
logger: backendPluginApi.coreServices.logger,
|
|
189
|
+
httpRouter: backendPluginApi.coreServices.httpRouter
|
|
190
|
+
},
|
|
191
|
+
async init({ config, discovery, logger, httpRouter }) {
|
|
192
|
+
httpRouter.use(
|
|
193
|
+
await createRouter({
|
|
194
|
+
config,
|
|
195
|
+
discovery,
|
|
196
|
+
logger: backendCommon.loggerToWinstonLogger(logger)
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
});
|
|
180
203
|
|
|
181
204
|
exports.createRouter = createRouter;
|
|
182
205
|
exports.proxyPlugin = proxyPlugin;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport {\n createProxyMiddleware,\n fixRequestBody,\n Options,\n RequestHandler,\n} from 'http-proxy-middleware';\nimport { Logger } from 'winston';\nimport http from 'http';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\n\n// A list of headers that are always forwarded to the proxy targets.\nconst safeForwardHeaders = [\n // https://fetch.spec.whatwg.org/#cors-safelisted-request-header\n 'cache-control',\n 'content-language',\n 'content-length',\n 'content-type',\n 'expires',\n 'last-modified',\n 'pragma',\n\n // host is overridden by default. if changeOrigin is configured to false,\n // we assume this is a intentional and should also be forwarded.\n 'host',\n\n // other headers that we assume to be ok\n 'accept',\n 'accept-language',\n 'user-agent',\n];\n\n/** @public */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n discovery: PluginEndpointDiscovery;\n skipInvalidProxies?: boolean;\n reviveConsumedRequestBodies?: boolean;\n}\n\nexport interface ProxyConfig extends Options {\n allowedMethods?: string[];\n allowedHeaders?: string[];\n reviveRequestBody?: boolean;\n}\n\n// Creates a proxy middleware, possibly with defaults added on top of the\n// given config.\nexport function buildMiddleware(\n pathPrefix: string,\n logger: Logger,\n route: string,\n config: string | ProxyConfig,\n reviveConsumedRequestBodies?: boolean,\n): RequestHandler {\n const fullConfig =\n typeof config === 'string' ? { target: config } : { ...config };\n\n // Validate that target is a valid URL.\n if (typeof fullConfig.target !== 'string') {\n throw new Error(`Proxy target must be a string`);\n }\n try {\n // eslint-disable-next-line no-new\n new URL(fullConfig.target! as string);\n } catch {\n throw new Error(\n `Proxy target is not a valid URL: ${fullConfig.target ?? ''}`,\n );\n }\n\n // Default is to do a path rewrite that strips out the proxy's path prefix\n // and the rest of the route.\n if (fullConfig.pathRewrite === undefined) {\n let routeWithSlash = route.endsWith('/') ? route : `${route}/`;\n\n if (!pathPrefix.endsWith('/') && !routeWithSlash.startsWith('/')) {\n // Need to insert a / between pathPrefix and routeWithSlash\n routeWithSlash = `/${routeWithSlash}`;\n } else if (pathPrefix.endsWith('/') && routeWithSlash.startsWith('/')) {\n // Never expect this to happen at this point in time as\n // pathPrefix is set using `getExternalBaseUrl` which \"Returns the\n // external HTTP base backend URL for a given plugin,\n // **without a trailing slash.**\". But in case this changes in future, we\n // need to drop a / on either pathPrefix or routeWithSlash\n routeWithSlash = routeWithSlash.substring(1);\n }\n\n // The ? makes the slash optional for the rewrite, so that a base path without an ending slash\n // will also be matched (e.g. '/sample' and then requesting just '/api/proxy/sample' without an\n // ending slash). Otherwise the target gets called with the full '/api/proxy/sample' path\n // appended.\n fullConfig.pathRewrite = {\n [`^${pathPrefix}${routeWithSlash}?`]: '/',\n };\n }\n\n // Default is to update the Host header to the target\n if (fullConfig.changeOrigin === undefined) {\n fullConfig.changeOrigin = true;\n }\n\n // Attach the logger to the proxy config\n fullConfig.logProvider = () => logger;\n // http-proxy-middleware uses this log level to check if it should log the\n // requests that it proxies. Setting this to the most verbose log level\n // ensures that it always logs these requests. Our logger ends up deciding\n // if the logs are displayed or not.\n fullConfig.logLevel = 'debug';\n\n // Only return the allowed HTTP headers to not forward unwanted secret headers\n const requestHeaderAllowList = new Set<string>(\n [\n // allow all safe headers\n ...safeForwardHeaders,\n\n // allow all headers that are set by the proxy\n ...((fullConfig.headers && Object.keys(fullConfig.headers)) || []),\n\n // allow all configured headers\n ...(fullConfig.allowedHeaders || []),\n ].map(h => h.toLocaleLowerCase()),\n );\n\n // Use the custom middleware filter to do two things:\n // 1. Remove any headers not in the allow list to stop them being forwarded\n // 2. Only permit the allowed HTTP methods if configured\n //\n // We are filtering the proxy request headers here rather than in\n // `onProxyReq` because when global-agent is enabled then `onProxyReq`\n // fires _after_ the agent has already sent the headers to the proxy\n // target, causing a ERR_HTTP_HEADERS_SENT crash\n const filter = (_pathname: string, req: http.IncomingMessage): boolean => {\n const headerNames = Object.keys(req.headers);\n headerNames.forEach(h => {\n if (!requestHeaderAllowList.has(h.toLocaleLowerCase())) {\n delete req.headers[h];\n }\n });\n\n return fullConfig?.allowedMethods?.includes(req.method!) ?? true;\n };\n // Makes http-proxy-middleware logs look nicer and include the mount path\n filter.toString = () => route;\n\n // Only forward the allowed HTTP headers to not forward unwanted secret headers\n const responseHeaderAllowList = new Set<string>(\n [\n // allow all safe headers\n ...safeForwardHeaders,\n\n // allow all configured headers\n ...(fullConfig.allowedHeaders || []),\n ].map(h => h.toLocaleLowerCase()),\n );\n\n // only forward the allowed headers in backend->client\n fullConfig.onProxyRes = (proxyRes: http.IncomingMessage) => {\n const headerNames = Object.keys(proxyRes.headers);\n\n headerNames.forEach(h => {\n if (!responseHeaderAllowList.has(h.toLocaleLowerCase())) {\n delete proxyRes.headers[h];\n }\n });\n };\n\n if (reviveConsumedRequestBodies) {\n fullConfig.onProxyReq = fixRequestBody;\n }\n\n return createProxyMiddleware(filter, fullConfig);\n}\n\n/**\n * Creates a new {@link https://expressjs.com/en/api.html#router | \"express router\"} that proxy each target configured under the `proxy` key of the config\n * @example\n * ```ts\n * let router = await createRouter({logger, config, discovery});\n * ```\n * @config\n * ```yaml\n * proxy:\n * simple-example: http://simple.example.com:8080 # Opt 1 Simple URL String\n * '/larger-example/v1': # Opt 2 `http-proxy-middleware` compatible object\n * target: http://larger.example.com:8080/svc.v1\n * headers:\n * Authorization: Bearer ${EXAMPLE_AUTH_TOKEN}\n *```\n * @see https://backstage.io/docs/plugins/proxying\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n let currentRouter = Router();\n\n const externalUrl = await options.discovery.getExternalBaseUrl('proxy');\n const { pathname: pathPrefix } = new URL(externalUrl);\n\n const proxyConfig = options.config.getOptional('proxy') ?? {};\n configureMiddlewares(options, currentRouter, pathPrefix, proxyConfig);\n router.use((...args) => currentRouter(...args));\n\n if (options.config.subscribe) {\n let currentKey = JSON.stringify(proxyConfig);\n\n options.config.subscribe(() => {\n const newProxyConfig = options.config.getOptional('proxy') ?? {};\n const newKey = JSON.stringify(newProxyConfig);\n\n if (currentKey !== newKey) {\n currentKey = newKey;\n currentRouter = Router();\n configureMiddlewares(\n options,\n currentRouter,\n pathPrefix,\n newProxyConfig,\n );\n }\n });\n }\n\n return router;\n}\n\nfunction configureMiddlewares(\n options: RouterOptions,\n router: express.Router,\n pathPrefix: string,\n proxyConfig: any,\n) {\n Object.entries<any>(proxyConfig).forEach(([route, proxyRouteConfig]) => {\n try {\n router.use(\n route,\n buildMiddleware(\n pathPrefix,\n options.logger,\n route,\n proxyRouteConfig,\n options.reviveConsumedRequestBodies,\n ),\n );\n } catch (e) {\n if (options.skipInvalidProxies) {\n options.logger.warn(`skipped configuring ${route} due to ${e.message}`);\n } else {\n throw e;\n }\n }\n });\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * The proxy backend plugin.\n *\n * @alpha\n */\nexport const proxyPlugin = createBackendPlugin(\n (options?: {\n skipInvalidProxies?: boolean;\n reviveConsumedRequestBodies?: boolean;\n }) => ({\n pluginId: 'proxy',\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n logger: coreServices.logger,\n httpRouter: coreServices.httpRouter,\n },\n async init({ config, discovery, logger, httpRouter }) {\n httpRouter.use(\n await createRouter({\n config,\n discovery,\n logger: loggerToWinstonLogger(logger),\n skipInvalidProxies: options?.skipInvalidProxies,\n reviveConsumedRequestBodies: options?.reviveConsumedRequestBodies,\n }),\n );\n },\n });\n },\n }),\n);\n"],"names":["_a","fixRequestBody","createProxyMiddleware","Router","createBackendPlugin","coreServices","loggerToWinstonLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport {\n createProxyMiddleware,\n fixRequestBody,\n Options,\n RequestHandler,\n} from 'http-proxy-middleware';\nimport { Logger } from 'winston';\nimport http from 'http';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\n\n// A list of headers that are always forwarded to the proxy targets.\nconst safeForwardHeaders = [\n // https://fetch.spec.whatwg.org/#cors-safelisted-request-header\n 'cache-control',\n 'content-language',\n 'content-length',\n 'content-type',\n 'expires',\n 'last-modified',\n 'pragma',\n\n // host is overridden by default. if changeOrigin is configured to false,\n // we assume this is a intentional and should also be forwarded.\n 'host',\n\n // other headers that we assume to be ok\n 'accept',\n 'accept-language',\n 'user-agent',\n];\n\n/** @public */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n discovery: PluginEndpointDiscovery;\n skipInvalidProxies?: boolean;\n reviveConsumedRequestBodies?: boolean;\n}\n\nexport interface ProxyConfig extends Options {\n allowedMethods?: string[];\n allowedHeaders?: string[];\n reviveRequestBody?: boolean;\n}\n\n// Creates a proxy middleware, possibly with defaults added on top of the\n// given config.\nexport function buildMiddleware(\n pathPrefix: string,\n logger: Logger,\n route: string,\n config: string | ProxyConfig,\n reviveConsumedRequestBodies?: boolean,\n): RequestHandler {\n const fullConfig =\n typeof config === 'string' ? { target: config } : { ...config };\n\n // Validate that target is a valid URL.\n if (typeof fullConfig.target !== 'string') {\n throw new Error(`Proxy target must be a string`);\n }\n try {\n // eslint-disable-next-line no-new\n new URL(fullConfig.target! as string);\n } catch {\n throw new Error(\n `Proxy target is not a valid URL: ${fullConfig.target ?? ''}`,\n );\n }\n\n // Default is to do a path rewrite that strips out the proxy's path prefix\n // and the rest of the route.\n if (fullConfig.pathRewrite === undefined) {\n let routeWithSlash = route.endsWith('/') ? route : `${route}/`;\n\n if (!pathPrefix.endsWith('/') && !routeWithSlash.startsWith('/')) {\n // Need to insert a / between pathPrefix and routeWithSlash\n routeWithSlash = `/${routeWithSlash}`;\n } else if (pathPrefix.endsWith('/') && routeWithSlash.startsWith('/')) {\n // Never expect this to happen at this point in time as\n // pathPrefix is set using `getExternalBaseUrl` which \"Returns the\n // external HTTP base backend URL for a given plugin,\n // **without a trailing slash.**\". But in case this changes in future, we\n // need to drop a / on either pathPrefix or routeWithSlash\n routeWithSlash = routeWithSlash.substring(1);\n }\n\n // The ? makes the slash optional for the rewrite, so that a base path without an ending slash\n // will also be matched (e.g. '/sample' and then requesting just '/api/proxy/sample' without an\n // ending slash). Otherwise the target gets called with the full '/api/proxy/sample' path\n // appended.\n fullConfig.pathRewrite = {\n [`^${pathPrefix}${routeWithSlash}?`]: '/',\n };\n }\n\n // Default is to update the Host header to the target\n if (fullConfig.changeOrigin === undefined) {\n fullConfig.changeOrigin = true;\n }\n\n // Attach the logger to the proxy config\n fullConfig.logProvider = () => logger;\n // http-proxy-middleware uses this log level to check if it should log the\n // requests that it proxies. Setting this to the most verbose log level\n // ensures that it always logs these requests. Our logger ends up deciding\n // if the logs are displayed or not.\n fullConfig.logLevel = 'debug';\n\n // Only return the allowed HTTP headers to not forward unwanted secret headers\n const requestHeaderAllowList = new Set<string>(\n [\n // allow all safe headers\n ...safeForwardHeaders,\n\n // allow all headers that are set by the proxy\n ...((fullConfig.headers && Object.keys(fullConfig.headers)) || []),\n\n // allow all configured headers\n ...(fullConfig.allowedHeaders || []),\n ].map(h => h.toLocaleLowerCase()),\n );\n\n // Use the custom middleware filter to do two things:\n // 1. Remove any headers not in the allow list to stop them being forwarded\n // 2. Only permit the allowed HTTP methods if configured\n //\n // We are filtering the proxy request headers here rather than in\n // `onProxyReq` because when global-agent is enabled then `onProxyReq`\n // fires _after_ the agent has already sent the headers to the proxy\n // target, causing a ERR_HTTP_HEADERS_SENT crash\n const filter = (_pathname: string, req: http.IncomingMessage): boolean => {\n const headerNames = Object.keys(req.headers);\n headerNames.forEach(h => {\n if (!requestHeaderAllowList.has(h.toLocaleLowerCase())) {\n delete req.headers[h];\n }\n });\n\n return fullConfig?.allowedMethods?.includes(req.method!) ?? true;\n };\n // Makes http-proxy-middleware logs look nicer and include the mount path\n filter.toString = () => route;\n\n // Only forward the allowed HTTP headers to not forward unwanted secret headers\n const responseHeaderAllowList = new Set<string>(\n [\n // allow all safe headers\n ...safeForwardHeaders,\n\n // allow all configured headers\n ...(fullConfig.allowedHeaders || []),\n ].map(h => h.toLocaleLowerCase()),\n );\n\n // only forward the allowed headers in backend->client\n fullConfig.onProxyRes = (proxyRes: http.IncomingMessage) => {\n const headerNames = Object.keys(proxyRes.headers);\n\n headerNames.forEach(h => {\n if (!responseHeaderAllowList.has(h.toLocaleLowerCase())) {\n delete proxyRes.headers[h];\n }\n });\n };\n\n if (reviveConsumedRequestBodies) {\n fullConfig.onProxyReq = fixRequestBody;\n }\n\n return createProxyMiddleware(filter, fullConfig);\n}\n\nfunction readProxyConfig(config: Config, logger: Logger): unknown {\n const endpoints = config.getOptionalConfig('proxy.endpoints')?.get();\n if (endpoints) {\n return endpoints;\n }\n\n const root = config.getOptionalConfig('proxy')?.get();\n if (!root) {\n return {};\n }\n\n const rootEndpoints = Object.fromEntries(\n Object.entries(root).filter(([key]) => key.startsWith('/')),\n );\n if (Object.keys(rootEndpoints).length === 0) {\n return {};\n }\n\n logger.warn(\n \"Configuring proxy endpoints in the root 'proxy' configuration is deprecated. Move this configuration to 'proxy.endpoints' instead.\",\n );\n\n return rootEndpoints;\n}\n\n/**\n * Creates a new {@link https://expressjs.com/en/api.html#router | \"express router\"} that proxy each target configured under the `proxy` key of the config\n * @example\n * ```ts\n * let router = await createRouter({logger, config, discovery});\n * ```\n * @config\n * ```yaml\n * proxy:\n * simple-example: http://simple.example.com:8080 # Opt 1 Simple URL String\n * '/larger-example/v1': # Opt 2 `http-proxy-middleware` compatible object\n * target: http://larger.example.com:8080/svc.v1\n * headers:\n * Authorization: Bearer ${EXAMPLE_AUTH_TOKEN}\n *```\n * @see https://backstage.io/docs/plugins/proxying\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n let currentRouter = Router();\n\n const skipInvalidProxies =\n options.skipInvalidProxies ??\n options.config.getOptionalBoolean('proxy.skipInvalidProxies') ??\n false;\n const reviveConsumedRequestBodies =\n options.reviveConsumedRequestBodies ??\n options.config.getOptionalBoolean('proxy.reviveConsumedRequestBodies') ??\n false;\n const proxyOptions = {\n skipInvalidProxies,\n reviveConsumedRequestBodies,\n logger: options.logger,\n };\n\n const externalUrl = await options.discovery.getExternalBaseUrl('proxy');\n const { pathname: pathPrefix } = new URL(externalUrl);\n\n const proxyConfig = readProxyConfig(options.config, options.logger);\n configureMiddlewares(proxyOptions, currentRouter, pathPrefix, proxyConfig);\n router.use((...args) => currentRouter(...args));\n\n if (options.config.subscribe) {\n let currentKey = JSON.stringify(proxyConfig);\n\n options.config.subscribe(() => {\n const newProxyConfig = readProxyConfig(options.config, options.logger);\n const newKey = JSON.stringify(newProxyConfig);\n\n if (currentKey !== newKey) {\n currentKey = newKey;\n currentRouter = Router();\n configureMiddlewares(\n proxyOptions,\n currentRouter,\n pathPrefix,\n newProxyConfig,\n );\n }\n });\n }\n\n return router;\n}\n\nfunction configureMiddlewares(\n options: {\n reviveConsumedRequestBodies: boolean;\n skipInvalidProxies: boolean;\n logger: Logger;\n },\n router: express.Router,\n pathPrefix: string,\n proxyConfig: any,\n) {\n Object.entries<any>(proxyConfig).forEach(([route, proxyRouteConfig]) => {\n try {\n router.use(\n route,\n buildMiddleware(\n pathPrefix,\n options.logger,\n route,\n proxyRouteConfig,\n options.reviveConsumedRequestBodies,\n ),\n );\n } catch (e) {\n if (options.skipInvalidProxies) {\n options.logger.warn(`skipped configuring ${route} due to ${e.message}`);\n } else {\n throw e;\n }\n }\n });\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * The proxy backend plugin.\n *\n * @alpha\n */\nexport const proxyPlugin = createBackendPlugin({\n pluginId: 'proxy',\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n logger: coreServices.logger,\n httpRouter: coreServices.httpRouter,\n },\n async init({ config, discovery, logger, httpRouter }) {\n httpRouter.use(\n await createRouter({\n config,\n discovery,\n logger: loggerToWinstonLogger(logger),\n }),\n );\n },\n });\n },\n});\n"],"names":["_a","fixRequestBody","createProxyMiddleware","Router","createBackendPlugin","coreServices","loggerToWinstonLogger"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-proxy-backend",
|
|
3
3
|
"description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"clean": "backstage-cli package clean"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@backstage/backend-common": "^0.19.2
|
|
37
|
-
"@backstage/backend-plugin-api": "^0.6.0
|
|
36
|
+
"@backstage/backend-common": "^0.19.2",
|
|
37
|
+
"@backstage/backend-plugin-api": "^0.6.0",
|
|
38
38
|
"@backstage/config": "^1.0.8",
|
|
39
39
|
"@types/express": "^4.17.6",
|
|
40
40
|
"express": "^4.17.1",
|
|
@@ -48,7 +48,9 @@
|
|
|
48
48
|
"yup": "^0.32.9"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@backstage/
|
|
51
|
+
"@backstage/backend-test-utils": "^0.2.0",
|
|
52
|
+
"@backstage/cli": "^0.22.10",
|
|
53
|
+
"@backstage/config-loader": "^1.4.0",
|
|
52
54
|
"@types/http-proxy-middleware": "^0.19.3",
|
|
53
55
|
"@types/supertest": "^2.0.8",
|
|
54
56
|
"@types/uuid": "^8.0.0",
|