@backstage/plugin-proxy-backend 0.5.12-next.0 → 0.6.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 CHANGED
@@ -1,5 +1,35 @@
1
1
  # @backstage/plugin-proxy-backend
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2d8b0e4: **BREAKING**: Removed support for the old backend system.
8
+
9
+ As part of this change the plugin export from `/alpha` as been removed. If you are currently importing `@backstage/plugin-proxy-backend/alpha`, please update your import to `@backstage/plugin-proxy-backend`.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+ - @backstage/backend-plugin-api@1.2.1
15
+ - @backstage/types@1.2.1
16
+ - @backstage/plugin-proxy-node@0.1.2
17
+
18
+ ## 0.6.0-next.1
19
+
20
+ ### Minor Changes
21
+
22
+ - 2d8b0e4: **BREAKING**: Removed support for the old backend system.
23
+
24
+ As part of this change the plugin export from `/alpha` as been removed. If you are currently importing `@backstage/plugin-proxy-backend/alpha`, please update your import to `@backstage/plugin-proxy-backend`.
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies
29
+ - @backstage/backend-plugin-api@1.2.1-next.1
30
+ - @backstage/types@1.2.1
31
+ - @backstage/plugin-proxy-node@0.1.2-next.1
32
+
3
33
  ## 0.5.12-next.0
4
34
 
5
35
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -3,10 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var plugin = require('./plugin.cjs.js');
6
- var router = require('./service/router.cjs.js');
7
6
 
8
7
 
9
8
 
10
9
  exports.default = plugin.proxyPlugin;
11
- exports.createRouter = router.createRouter;
12
10
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,4 @@
1
1
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
- import { RootConfigService, DiscoveryService } from '@backstage/backend-plugin-api';
3
- import express from 'express';
4
- import { Logger } from 'winston';
5
- import { ProxyConfig } from '@backstage/plugin-proxy-node/alpha';
6
2
 
7
3
  /**
8
4
  * The proxy backend plugin.
@@ -11,43 +7,4 @@ import { ProxyConfig } from '@backstage/plugin-proxy-node/alpha';
11
7
  */
12
8
  declare const proxyPlugin: _backstage_backend_plugin_api.BackendFeature;
13
9
 
14
- /**
15
- * @public
16
- * @deprecated Please migrate to the new backend system as this will be removed in the future.
17
- */
18
- interface RouterOptions {
19
- logger: Logger;
20
- config: RootConfigService;
21
- discovery: DiscoveryService;
22
- skipInvalidProxies?: boolean;
23
- reviveConsumedRequestBodies?: boolean;
24
- additionalEndpoints?: ProxyConfig;
25
- }
26
- /**
27
- * Creates a new
28
- * {@link https://expressjs.com/en/api.html#router | "express router"} that
29
- * proxies each target configured under the `proxy.endpoints` key of the config.
30
- *
31
- * @remarks
32
- *
33
- * Example configuration:
34
- *
35
- * ```yaml
36
- * proxy:
37
- * endpoints:
38
- * # Option 1: Simple URL String
39
- * simple-example: http://simple.example.com:8080
40
- * # Option 2: `http-proxy-middleware` compatible object
41
- * '/larger-example/v1':
42
- * target: http://larger.example.com:8080/svc.v1
43
- * headers:
44
- * Authorization: Bearer ${EXAMPLE_AUTH_TOKEN}
45
- * ```
46
- *
47
- * @see https://backstage.io/docs/plugins/proxying
48
- * @public
49
- * @deprecated Please migrate to the new backend system as this will be removed in the future.
50
- */
51
- declare function createRouter(options: RouterOptions): Promise<express.Router>;
52
-
53
- export { type RouterOptions, createRouter, proxyPlugin as default };
10
+ export { proxyPlugin as default };
@@ -1,6 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var backendCommon = require('@backstage/backend-common');
4
3
  var backendPluginApi = require('@backstage/backend-plugin-api');
5
4
  var router = require('./service/router.cjs.js');
6
5
  var alpha = require('@backstage/plugin-proxy-node/alpha');
@@ -22,10 +21,10 @@ const proxyPlugin = backendPluginApi.createBackendPlugin({
22
21
  httpRouter: backendPluginApi.coreServices.httpRouter
23
22
  },
24
23
  async init({ config, discovery, logger, httpRouter }) {
25
- await router.createRouterInternal({
24
+ await router.createRouter({
26
25
  config,
27
26
  discovery,
28
- logger: backendCommon.loggerToWinstonLogger(logger),
27
+ logger,
29
28
  httpRouterService: httpRouter,
30
29
  additionalEndpoints
31
30
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\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 { createRouterInternal } from './service/router';\nimport { proxyEndpointsExtensionPoint } from '@backstage/plugin-proxy-node/alpha';\n\n/**\n * The proxy backend plugin.\n *\n * @public\n */\nexport const proxyPlugin = createBackendPlugin({\n pluginId: 'proxy',\n register(env) {\n const additionalEndpoints = {};\n\n env.registerExtensionPoint(proxyEndpointsExtensionPoint, {\n addProxyEndpoints(endpoints) {\n Object.assign(additionalEndpoints, endpoints);\n },\n });\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 await createRouterInternal({\n config,\n discovery,\n logger: loggerToWinstonLogger(logger),\n httpRouterService: httpRouter,\n additionalEndpoints,\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","proxyEndpointsExtensionPoint","coreServices","createRouterInternal","loggerToWinstonLogger"],"mappings":";;;;;;;AA6BO,MAAM,cAAcA,oCAAoB,CAAA;AAAA,EAC7C,QAAU,EAAA,OAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,MAAM,sBAAsB,EAAC;AAE7B,IAAA,GAAA,CAAI,uBAAuBC,kCAA8B,EAAA;AAAA,MACvD,kBAAkB,SAAW,EAAA;AAC3B,QAAO,MAAA,CAAA,MAAA,CAAO,qBAAqB,SAAS,CAAA;AAAA;AAC9C,KACD,CAAA;AACD,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,YAAYA,6BAAa,CAAA;AAAA,OAC3B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,QAAQ,SAAW,EAAA,MAAA,EAAQ,YAAc,EAAA;AACpD,QAAA,MAAMC,2BAAqB,CAAA;AAAA,UACzB,MAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAA,EAAQC,oCAAsB,MAAM,CAAA;AAAA,UACpC,iBAAmB,EAAA,UAAA;AAAA,UACnB;AAAA,SACD,CAAA;AAAA;AACH,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\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 {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\nimport { proxyEndpointsExtensionPoint } from '@backstage/plugin-proxy-node/alpha';\n\n/**\n * The proxy backend plugin.\n *\n * @public\n */\nexport const proxyPlugin = createBackendPlugin({\n pluginId: 'proxy',\n register(env) {\n const additionalEndpoints = {};\n\n env.registerExtensionPoint(proxyEndpointsExtensionPoint, {\n addProxyEndpoints(endpoints) {\n Object.assign(additionalEndpoints, endpoints);\n },\n });\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 await createRouter({\n config,\n discovery,\n logger,\n httpRouterService: httpRouter,\n additionalEndpoints,\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","proxyEndpointsExtensionPoint","coreServices","createRouter"],"mappings":";;;;;;AA4BO,MAAM,cAAcA,oCAAoB,CAAA;AAAA,EAC7C,QAAU,EAAA,OAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,MAAM,sBAAsB,EAAC;AAE7B,IAAA,GAAA,CAAI,uBAAuBC,kCAA8B,EAAA;AAAA,MACvD,kBAAkB,SAAW,EAAA;AAC3B,QAAO,MAAA,CAAA,MAAA,CAAO,qBAAqB,SAAS,CAAA;AAAA;AAC9C,KACD,CAAA;AACD,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,YAAYA,6BAAa,CAAA;AAAA,OAC3B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,QAAQ,SAAW,EAAA,MAAA,EAAQ,YAAc,EAAA;AACpD,QAAA,MAAMC,mBAAa,CAAA;AAAA,UACjB,MAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAA;AAAA,UACA,iBAAmB,EAAA,UAAA;AAAA,UACnB;AAAA,SACD,CAAA;AAAA;AACH,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
@@ -24,7 +24,7 @@ const safeForwardHeaders = [
24
24
  "accept-language",
25
25
  "user-agent"
26
26
  ];
27
- function buildMiddleware(pathPrefix, logger, route, config, reviveConsumedRequestBodies, httpRouterService) {
27
+ function buildMiddleware(pathPrefix, logger, route, config, httpRouterService, reviveConsumedRequestBodies) {
28
28
  let fullConfig;
29
29
  let credentialsPolicy;
30
30
  if (typeof config === "string") {
@@ -47,7 +47,7 @@ function buildMiddleware(pathPrefix, logger, route, config, reviveConsumedReques
47
47
  );
48
48
  }
49
49
  if (credentialsPolicy === "dangerously-allow-unauthenticated") {
50
- httpRouterService?.addAuthPolicy({
50
+ httpRouterService.addAuthPolicy({
51
51
  path: route,
52
52
  allow: "unauthenticated"
53
53
  });
@@ -79,7 +79,13 @@ function buildMiddleware(pathPrefix, logger, route, config, reviveConsumedReques
79
79
  if (fullConfig.changeOrigin === void 0) {
80
80
  fullConfig.changeOrigin = true;
81
81
  }
82
- fullConfig.logProvider = () => logger;
82
+ fullConfig.logProvider = () => ({
83
+ log: logger.info.bind(logger),
84
+ debug: logger.debug.bind(logger),
85
+ info: logger.info.bind(logger),
86
+ warn: logger.warn.bind(logger),
87
+ error: logger.error.bind(logger)
88
+ });
83
89
  fullConfig.logLevel = "debug";
84
90
  const requestHeaderAllowList = new Set(
85
91
  [
@@ -146,13 +152,10 @@ function readProxyConfig(config, logger) {
146
152
  return rootEndpoints;
147
153
  }
148
154
  async function createRouter(options) {
149
- return createRouterInternal(options);
150
- }
151
- async function createRouterInternal(options) {
152
155
  const router = Router__default.default();
153
156
  let currentRouter = Router__default.default();
154
- const skipInvalidProxies = options.skipInvalidProxies ?? options.config.getOptionalBoolean("proxy.skipInvalidProxies") ?? false;
155
- const reviveConsumedRequestBodies = options.reviveConsumedRequestBodies ?? options.config.getOptionalBoolean("proxy.reviveConsumedRequestBodies") ?? false;
157
+ const skipInvalidProxies = options.config.getOptionalBoolean("proxy.skipInvalidProxies") ?? false;
158
+ const reviveConsumedRequestBodies = options.config.getOptionalBoolean("proxy.reviveConsumedRequestBodies") ?? false;
156
159
  const proxyOptions = {
157
160
  skipInvalidProxies,
158
161
  reviveConsumedRequestBodies,
@@ -190,7 +193,7 @@ async function createRouterInternal(options) {
190
193
  }
191
194
  });
192
195
  }
193
- options.httpRouterService?.use(router);
196
+ options.httpRouterService.use(router);
194
197
  return router;
195
198
  }
196
199
  function configureMiddlewares(options, router, pathPrefix, proxyConfig, httpRouterService) {
@@ -203,8 +206,8 @@ function configureMiddlewares(options, router, pathPrefix, proxyConfig, httpRout
203
206
  options.logger,
204
207
  route,
205
208
  proxyRouteConfig,
206
- options.reviveConsumedRequestBodies,
207
- httpRouterService
209
+ httpRouterService,
210
+ options.reviveConsumedRequestBodies
208
211
  )
209
212
  );
210
213
  } catch (e) {
@@ -219,5 +222,4 @@ function configureMiddlewares(options, router, pathPrefix, proxyConfig, httpRout
219
222
 
220
223
  exports.buildMiddleware = buildMiddleware;
221
224
  exports.createRouter = createRouter;
222
- exports.createRouterInternal = createRouterInternal;
223
225
  //# sourceMappingURL=router.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.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 RequestHandler,\n} from 'http-proxy-middleware';\nimport { Logger } from 'winston';\nimport http from 'http';\nimport { JsonObject } from '@backstage/types';\nimport {\n DiscoveryService,\n HttpRouterService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { ProxyConfig } from '@backstage/plugin-proxy-node/alpha';\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/**\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport interface RouterOptions {\n logger: Logger;\n config: RootConfigService;\n discovery: DiscoveryService;\n skipInvalidProxies?: boolean;\n reviveConsumedRequestBodies?: boolean;\n additionalEndpoints?: ProxyConfig;\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 httpRouterService?: HttpRouterService,\n): RequestHandler {\n let fullConfig: ProxyConfig;\n let credentialsPolicy: string;\n if (typeof config === 'string') {\n fullConfig = { target: config };\n credentialsPolicy = 'require';\n } else {\n const { credentials, ...rest } = config;\n fullConfig = rest;\n credentialsPolicy = credentials ?? 'require';\n }\n\n const credentialsPolicyCandidates = [\n 'require',\n 'forward',\n 'dangerously-allow-unauthenticated',\n ];\n if (!credentialsPolicyCandidates.includes(credentialsPolicy)) {\n const valid = credentialsPolicyCandidates.map(c => `'${c}'`).join(', ');\n throw new Error(\n `Unknown credentials policy '${credentialsPolicy}' for proxy route '${route}'; expected one of ${valid}`,\n );\n }\n\n if (credentialsPolicy === 'dangerously-allow-unauthenticated') {\n httpRouterService?.addAuthPolicy({\n path: route,\n allow: 'unauthenticated',\n });\n }\n\n // Validate that target is a valid URL.\n const targetType = typeof fullConfig.target;\n if (targetType !== 'string') {\n throw new Error(\n `Proxy target for route \"${route}\" must be a string, but is of type ${targetType}`,\n );\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 if (credentialsPolicy === 'forward') {\n requestHeaderAllowList.add('authorization');\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): JsonObject {\n const endpoints = config\n .getOptionalConfig('proxy.endpoints')\n ?.get<JsonObject>();\n if (endpoints) {\n return endpoints;\n }\n\n const root = config.getOptionalConfig('proxy')?.get<JsonObject>();\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\n * {@link https://expressjs.com/en/api.html#router | \"express router\"} that\n * proxies each target configured under the `proxy.endpoints` key of the config.\n *\n * @remarks\n *\n * Example configuration:\n *\n * ```yaml\n * proxy:\n * endpoints:\n * # Option 1: Simple URL String\n * simple-example: http://simple.example.com:8080\n * # Option 2: `http-proxy-middleware` compatible object\n * '/larger-example/v1':\n * target: http://larger.example.com:8080/svc.v1\n * headers:\n * Authorization: Bearer ${EXAMPLE_AUTH_TOKEN}\n * ```\n *\n * @see https://backstage.io/docs/plugins/proxying\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n return createRouterInternal(options);\n}\n\nexport async function createRouterInternal(\n options: RouterOptions & { httpRouterService?: HttpRouterService },\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: ProxyConfig = {\n ...(options.additionalEndpoints ?? {}),\n ...readProxyConfig(options.config, options.logger),\n };\n\n configureMiddlewares(\n proxyOptions,\n currentRouter,\n pathPrefix,\n proxyConfig,\n options.httpRouterService,\n );\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 options.httpRouterService,\n );\n }\n });\n }\n\n options.httpRouterService?.use(router);\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: ProxyConfig,\n httpRouterService?: HttpRouterService,\n) {\n Object.entries(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 httpRouterService,\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"],"names":["fixRequestBody","createProxyMiddleware","Router"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.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 type express from 'express';\nimport Router from 'express-promise-router';\nimport {\n createProxyMiddleware,\n fixRequestBody,\n RequestHandler,\n} from 'http-proxy-middleware';\nimport http from 'http';\nimport { JsonObject } from '@backstage/types';\nimport {\n DiscoveryService,\n HttpRouterService,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { ProxyConfig } from '@backstage/plugin-proxy-node/alpha';\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/**\n * @internal\n */\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n discovery: DiscoveryService;\n httpRouterService: HttpRouterService;\n additionalEndpoints?: ProxyConfig;\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: LoggerService,\n route: string,\n config: string | ProxyConfig,\n httpRouterService: HttpRouterService,\n reviveConsumedRequestBodies?: boolean,\n): RequestHandler {\n let fullConfig: ProxyConfig;\n let credentialsPolicy: string;\n if (typeof config === 'string') {\n fullConfig = { target: config };\n credentialsPolicy = 'require';\n } else {\n const { credentials, ...rest } = config;\n fullConfig = rest;\n credentialsPolicy = credentials ?? 'require';\n }\n\n const credentialsPolicyCandidates = [\n 'require',\n 'forward',\n 'dangerously-allow-unauthenticated',\n ];\n if (!credentialsPolicyCandidates.includes(credentialsPolicy)) {\n const valid = credentialsPolicyCandidates.map(c => `'${c}'`).join(', ');\n throw new Error(\n `Unknown credentials policy '${credentialsPolicy}' for proxy route '${route}'; expected one of ${valid}`,\n );\n }\n\n if (credentialsPolicy === 'dangerously-allow-unauthenticated') {\n httpRouterService.addAuthPolicy({\n path: route,\n allow: 'unauthenticated',\n });\n }\n\n // Validate that target is a valid URL.\n const targetType = typeof fullConfig.target;\n if (targetType !== 'string') {\n throw new Error(\n `Proxy target for route \"${route}\" must be a string, but is of type ${targetType}`,\n );\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 = () => ({\n log: logger.info.bind(logger),\n debug: logger.debug.bind(logger),\n info: logger.info.bind(logger),\n warn: logger.warn.bind(logger),\n error: logger.error.bind(logger),\n });\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 if (credentialsPolicy === 'forward') {\n requestHeaderAllowList.add('authorization');\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(\n config: RootConfigService,\n logger: LoggerService,\n): JsonObject {\n const endpoints = config\n .getOptionalConfig('proxy.endpoints')\n ?.get<JsonObject>();\n if (endpoints) {\n return endpoints;\n }\n\n const root = config.getOptionalConfig('proxy')?.get<JsonObject>();\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/** @internal */\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.config.getOptionalBoolean('proxy.skipInvalidProxies') ?? false;\n const 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: ProxyConfig = {\n ...(options.additionalEndpoints ?? {}),\n ...readProxyConfig(options.config, options.logger),\n };\n\n configureMiddlewares(\n proxyOptions,\n currentRouter,\n pathPrefix,\n proxyConfig,\n options.httpRouterService,\n );\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 options.httpRouterService,\n );\n }\n });\n }\n\n options.httpRouterService.use(router);\n return router;\n}\n\nfunction configureMiddlewares(\n options: {\n reviveConsumedRequestBodies: boolean;\n skipInvalidProxies: boolean;\n logger: LoggerService;\n },\n router: express.Router,\n pathPrefix: string,\n proxyConfig: ProxyConfig,\n httpRouterService: HttpRouterService,\n) {\n Object.entries(proxyConfig).forEach(([route, proxyRouteConfig]) => {\n try {\n router.use(\n route,\n buildMiddleware(\n pathPrefix,\n options.logger,\n route,\n proxyRouteConfig,\n httpRouterService,\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"],"names":["fixRequestBody","createProxyMiddleware","Router"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-proxy-backend",
3
- "version": "0.5.12-next.0",
3
+ "version": "0.6.0",
4
4
  "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend",
5
5
  "backstage": {
6
6
  "role": "backend-plugin",
@@ -9,8 +9,7 @@
9
9
  "@backstage/plugin-proxy-backend"
10
10
  ],
11
11
  "features": {
12
- ".": "@backstage/BackendFeature",
13
- "./alpha": "@backstage/BackendFeature"
12
+ ".": "@backstage/BackendFeature"
14
13
  }
15
14
  },
16
15
  "publishConfig": {
@@ -33,26 +32,10 @@
33
32
  "types": "./dist/index.d.ts",
34
33
  "default": "./dist/index.cjs.js"
35
34
  },
36
- "./alpha": {
37
- "backstage": "@backstage/BackendFeature",
38
- "require": "./dist/alpha.cjs.js",
39
- "types": "./dist/alpha.d.ts",
40
- "default": "./dist/alpha.cjs.js"
41
- },
42
35
  "./package.json": "./package.json"
43
36
  },
44
37
  "main": "./dist/index.cjs.js",
45
38
  "types": "./dist/index.d.ts",
46
- "typesVersions": {
47
- "*": {
48
- "index": [
49
- "dist/index.d.ts"
50
- ],
51
- "alpha": [
52
- "dist/alpha.d.ts"
53
- ]
54
- }
55
- },
56
39
  "files": [
57
40
  "dist",
58
41
  "config.d.ts"
@@ -67,31 +50,22 @@
67
50
  "test": "backstage-cli package test"
68
51
  },
69
52
  "dependencies": {
70
- "@backstage/backend-common": "^0.25.0",
71
- "@backstage/backend-plugin-api": "1.2.1-next.0",
72
- "@backstage/config": "1.3.2",
73
- "@backstage/plugin-proxy-node": "0.1.2-next.0",
74
- "@backstage/types": "1.2.1",
75
- "@types/express": "^4.17.6",
76
- "express": "^4.17.1",
53
+ "@backstage/backend-plugin-api": "^1.2.1",
54
+ "@backstage/plugin-proxy-node": "^0.1.2",
55
+ "@backstage/types": "^1.2.1",
77
56
  "express-promise-router": "^4.1.0",
78
- "http-proxy-middleware": "^2.0.0",
79
- "morgan": "^1.10.0",
80
- "uuid": "^11.0.0",
81
- "winston": "^3.2.1",
82
- "yaml": "^2.0.0",
83
- "yn": "^4.0.0",
84
- "yup": "^1.0.0"
57
+ "http-proxy-middleware": "^2.0.0"
85
58
  },
86
59
  "devDependencies": {
87
- "@backstage/backend-app-api": "1.2.1-next.0",
88
- "@backstage/backend-defaults": "0.8.2-next.0",
89
- "@backstage/backend-test-utils": "1.3.1-next.0",
90
- "@backstage/cli": "0.30.0",
91
- "@backstage/config-loader": "1.9.6",
92
- "@backstage/errors": "1.2.7",
60
+ "@backstage/backend-app-api": "^1.2.1",
61
+ "@backstage/backend-defaults": "^0.8.2",
62
+ "@backstage/backend-test-utils": "^1.3.1",
63
+ "@backstage/cli": "^0.31.0",
64
+ "@backstage/config-loader": "^1.10.0",
65
+ "@backstage/errors": "^1.2.7",
66
+ "@types/express": "^4.17.6",
93
67
  "@types/http-proxy-middleware": "^1.0.0",
94
- "@types/yup": "^0.32.0",
68
+ "express": "^4.17.1",
95
69
  "msw": "^2.0.0"
96
70
  },
97
71
  "configSchema": "config.d.ts"
package/dist/alpha.cjs.js DELETED
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var plugin = require('./plugin.cjs.js');
6
-
7
- const _feature = plugin.proxyPlugin;
8
-
9
- exports.default = _feature;
10
- //# sourceMappingURL=alpha.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/alpha.ts"],"sourcesContent":["/*\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 { proxyPlugin } from './plugin';\n\n/** @alpha */\nconst _feature = proxyPlugin;\nexport default _feature;\n"],"names":["proxyPlugin"],"mappings":";;;;;;AAmBA,MAAM,QAAW,GAAAA;;;;"}
package/dist/alpha.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
-
3
- /** @alpha */
4
- declare const _feature: _backstage_backend_plugin_api.BackendFeature;
5
-
6
- export { _feature as default };