@backstage/plugin-search-backend 0.2.5 → 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 CHANGED
@@ -1,5 +1,62 @@
1
1
  # @backstage/plugin-search-backend
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a41fbfe739: Search result location filtering
8
+
9
+ This change introduces a filter for search results based on their location protocol. The intention is to filter out unsafe or
10
+ malicious values before they can be consumed by the frontend. By default locations must be http/https URLs (or paths).
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - @backstage/backend-common@0.10.0
16
+
17
+ ## 0.2.8
18
+
19
+ ### Patch Changes
20
+
21
+ - dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly
22
+ - Updated dependencies
23
+ - @backstage/backend-common@0.9.13
24
+
25
+ ## 0.2.7
26
+
27
+ ### Patch Changes
28
+
29
+ - bab752e2b3: Change default port of backend from 7000 to 7007.
30
+
31
+ This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start.
32
+
33
+ You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values:
34
+
35
+ ```
36
+ backend:
37
+ listen: 0.0.0.0:7123
38
+ baseUrl: http://localhost:7123
39
+ ```
40
+
41
+ More information can be found here: https://backstage.io/docs/conf/writing
42
+
43
+ - Updated dependencies
44
+ - @backstage/backend-common@0.9.11
45
+
46
+ ## 0.2.6
47
+
48
+ ### Patch Changes
49
+
50
+ - a13f21cdc: Implement optional `pageCursor` based paging in search.
51
+
52
+ To use paging in your app, add a `<SearchResultPager />` to your
53
+ `SearchPage.tsx`.
54
+
55
+ - Updated dependencies
56
+ - @backstage/search-common@0.2.0
57
+ - @backstage/plugin-search-backend-node@0.4.2
58
+ - @backstage/backend-common@0.9.1
59
+
3
60
  ## 0.2.5
4
61
 
5
62
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -8,17 +8,27 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
8
8
 
9
9
  var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
10
10
 
11
- async function createRouter({
12
- engine,
13
- logger
14
- }) {
15
- const router = Router__default['default']();
11
+ const allowedLocationProtocols = ["http:", "https:"];
12
+ async function createRouter(options) {
13
+ const { engine, logger } = options;
14
+ const filterResultSet = ({ results, ...resultSet }) => ({
15
+ ...resultSet,
16
+ results: results.filter((result) => {
17
+ const protocol = new URL(result.document.location, "https://example.com").protocol;
18
+ const isAllowed = allowedLocationProtocols.includes(protocol);
19
+ if (!isAllowed) {
20
+ logger.info(`Rejected search result for "${result.document.title}" as location protocol "${protocol}" is unsafe`);
21
+ }
22
+ return isAllowed;
23
+ })
24
+ });
25
+ const router = Router__default["default"]();
16
26
  router.get("/query", async (req, res) => {
17
- const {term, filters = {}, pageCursor = ""} = req.query;
18
- logger.info(`Search request received: term="${term}", filters=${JSON.stringify(filters)}, ${pageCursor}`);
27
+ const { term, filters = {}, types, pageCursor } = req.query;
28
+ logger.info(`Search request received: term="${term}", filters=${JSON.stringify(filters)}, types=${types ? types.join(",") : ""}, pageCursor=${pageCursor != null ? pageCursor : ""}`);
19
29
  try {
20
- const results = await (engine == null ? void 0 : engine.query(req.query));
21
- res.send(results);
30
+ const resultSet = await (engine == null ? void 0 : engine.query(req.query));
31
+ res.send(filterResultSet(resultSet));
22
32
  } catch (err) {
23
33
  throw new Error(`There was a problem performing the search query. ${err}`);
24
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2021 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 express from 'express';\nimport Router from 'express-promise-router';\nimport { Logger } from 'winston';\nimport { SearchQuery, SearchResultSet } from '@backstage/search-common';\nimport { SearchEngine } from '@backstage/plugin-search-backend-node';\n\ntype RouterOptions = {\n engine: SearchEngine;\n logger: Logger;\n};\n\nexport async function createRouter({\n engine,\n logger,\n}: RouterOptions): Promise<express.Router> {\n const router = Router();\n router.get(\n '/query',\n async (\n req: express.Request<any, unknown, unknown, SearchQuery>,\n res: express.Response<SearchResultSet>,\n ) => {\n const { term, filters = {}, pageCursor = '' } = req.query;\n logger.info(\n `Search request received: term=\"${term}\", filters=${JSON.stringify(\n filters,\n )}, ${pageCursor}`,\n );\n\n try {\n const results = await engine?.query(req.query);\n res.send(results);\n } catch (err) {\n throw new Error(\n `There was a problem performing the search query. ${err}`,\n );\n }\n },\n );\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;;;4BA2BmC;AAAA,EACjC;AAAA,EACA;AAAA,GACyC;AACzC,QAAM,SAASA;AACf,SAAO,IACL,UACA,OACE,KACA,QACG;AACH,UAAM,CAAE,MAAM,UAAU,IAAI,aAAa,MAAO,IAAI;AACpD,WAAO,KACL,kCAAkC,kBAAkB,KAAK,UACvD,aACI;AAGR,QAAI;AACF,YAAM,UAAU,wCAAc,MAAM,IAAI;AACxC,UAAI,KAAK;AAAA,aACF,KAAP;AACA,YAAM,IAAI,MACR,oDAAoD;AAAA;AAAA;AAM5D,SAAO;AAAA;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2021 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 express from 'express';\nimport Router from 'express-promise-router';\nimport { Logger } from 'winston';\nimport { SearchQuery, SearchResultSet } from '@backstage/search-common';\nimport { SearchEngine } from '@backstage/plugin-search-backend-node';\n\nexport type RouterOptions = {\n engine: SearchEngine;\n logger: Logger;\n};\n\nconst allowedLocationProtocols = ['http:', 'https:'];\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { engine, logger } = options;\n\n const filterResultSet = ({ results, ...resultSet }: SearchResultSet) => ({\n ...resultSet,\n results: results.filter(result => {\n const protocol = new URL(result.document.location, 'https://example.com')\n .protocol;\n const isAllowed = allowedLocationProtocols.includes(protocol);\n if (!isAllowed) {\n logger.info(\n `Rejected search result for \"${result.document.title}\" as location protocol \"${protocol}\" is unsafe`,\n );\n }\n return isAllowed;\n }),\n });\n\n const router = Router();\n router.get(\n '/query',\n async (\n req: express.Request<any, unknown, unknown, SearchQuery>,\n res: express.Response<SearchResultSet>,\n ) => {\n const { term, filters = {}, types, pageCursor } = req.query;\n logger.info(\n `Search request received: term=\"${term}\", filters=${JSON.stringify(\n filters,\n )}, types=${types ? types.join(',') : ''}, pageCursor=${\n pageCursor ?? ''\n }`,\n );\n\n try {\n const resultSet = await engine?.query(req.query);\n res.send(filterResultSet(resultSet));\n } catch (err) {\n throw new Error(\n `There was a problem performing the search query. ${err}`,\n );\n }\n },\n );\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;;;AA2BA,MAAM,2BAA2B,CAAC,SAAS;4BAGzC,SACyB;AACzB,QAAM,EAAE,QAAQ,WAAW;AAE3B,QAAM,kBAAkB,CAAC,EAAE,YAAY;AAAkC,OACpE;AAAA,IACH,SAAS,QAAQ,OAAO,YAAU;AAChC,YAAM,WAAW,IAAI,IAAI,OAAO,SAAS,UAAU,uBAChD;AACH,YAAM,YAAY,yBAAyB,SAAS;AACpD,UAAI,CAAC,WAAW;AACd,eAAO,KACL,+BAA+B,OAAO,SAAS,gCAAgC;AAAA;AAGnF,aAAO;AAAA;AAAA;AAIX,QAAM,SAASA;AACf,SAAO,IACL,UACA,OACE,KACA,QACG;AACH,UAAM,EAAE,MAAM,UAAU,IAAI,OAAO,eAAe,IAAI;AACtD,WAAO,KACL,kCAAkC,kBAAkB,KAAK,UACvD,mBACU,QAAQ,MAAM,KAAK,OAAO,kBACpC,kCAAc;AAIlB,QAAI;AACF,YAAM,YAAY,wCAAc,MAAM,IAAI;AAC1C,UAAI,KAAK,gBAAgB;AAAA,aAClB,KAAP;AACA,YAAM,IAAI,MACR,oDAAoD;AAAA;AAAA;AAM5D,SAAO;AAAA;;;;"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,6 @@ declare type RouterOptions = {
6
6
  engine: SearchEngine;
7
7
  logger: Logger;
8
8
  };
9
- declare function createRouter({ engine, logger, }: RouterOptions): Promise<express.Router>;
9
+ declare function createRouter(options: RouterOptions): Promise<express.Router>;
10
10
 
11
- export { createRouter };
11
+ export { RouterOptions, createRouter };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-search-backend",
3
- "version": "0.2.5",
3
+ "description": "The Backstage backend plugin that provides your backstage app with search",
4
+ "version": "0.3.0",
4
5
  "main": "dist/index.cjs.js",
5
6
  "types": "dist/index.d.ts",
6
7
  "license": "Apache-2.0",
@@ -19,9 +20,9 @@
19
20
  "clean": "backstage-cli clean"
20
21
  },
21
22
  "dependencies": {
22
- "@backstage/backend-common": "^0.9.0",
23
- "@backstage/plugin-search-backend-node": "^0.4.0",
24
- "@backstage/search-common": "^0.1.2",
23
+ "@backstage/backend-common": "^0.10.0",
24
+ "@backstage/plugin-search-backend-node": "^0.4.2",
25
+ "@backstage/search-common": "^0.2.0",
25
26
  "@types/express": "^4.17.6",
26
27
  "express": "^4.17.1",
27
28
  "express-promise-router": "^4.1.0",
@@ -29,12 +30,12 @@
29
30
  "yn": "^4.0.0"
30
31
  },
31
32
  "devDependencies": {
32
- "@backstage/cli": "^0.7.9",
33
+ "@backstage/cli": "^0.10.3",
33
34
  "@types/supertest": "^2.0.8",
34
35
  "supertest": "^6.1.3"
35
36
  },
36
37
  "files": [
37
38
  "dist"
38
39
  ],
39
- "gitHead": "e436edb5bface99d33b7a0e8dd863d8e204e81fc"
40
+ "gitHead": "b315430f9dfcfa19ab0dd90f5b4ac6904938fba7"
40
41
  }