From 8a68cd2129c6e4a9e9f4b09f859fd60e0b36eb1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Mar 2022 09:06:22 +0000 Subject: [PATCH 01/27] chore(deps): bump google-auth-library from 7.12.0 to 7.14.0 Bumps [google-auth-library](https://github.com/googleapis/google-auth-library-nodejs) from 7.12.0 to 7.14.0. - [Release notes](https://github.com/googleapis/google-auth-library-nodejs/releases) - [Changelog](https://github.com/googleapis/google-auth-library-nodejs/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-auth-library-nodejs/compare/v7.12.0...v7.14.0) --- updated-dependencies: - dependency-name: google-auth-library dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5dedbc784f..4c46fd1396 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13257,9 +13257,9 @@ globby@^7.1.1: slash "^1.0.0" google-auth-library@^7.0.0, google-auth-library@^7.0.2, google-auth-library@^7.6.1: - version "7.12.0" - resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.12.0.tgz#7965db6bc20cb31f2df05a08a296bbed6af69426" - integrity sha512-RS/whvFPMoF1hQNxnoVET3DWKPBt1Xgqe2rY0k+Jn7TNhoHlwdnSe7Rlcbo2Nub3Mt2lUVz26X65aDQrWp6x8w== + version "7.14.0" + resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.0.tgz#9d6a20592f7b4d4c463cd3e93934c4b1711d5dc6" + integrity sha512-or8r7qUqGVI3W8lVSdPh0ZpeFyQHeE73g5c0p+bLNTTUFXJ+GSeDQmZRZ2p4H8cF/RJYa4PNvi/A1ar1uVNLFA== dependencies: arrify "^2.0.0" base64-js "^1.3.0" From 414c5f09236d71302fc6a86773c6e2c25bc40d6b Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 15 Mar 2022 12:17:18 +0100 Subject: [PATCH 02/27] chore: gotta bump this package tooo... Signed-off-by: blam --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4c46fd1396..af7fd8e2c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1988,9 +1988,9 @@ xcase "^2.0.1" "@google-cloud/common@^3.7.0": - version "3.7.0" - resolved "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.0.tgz#ee3fba75aeaa614978aebf8740380670026592aa" - integrity sha512-oFgpKLjH9JTOAyQd3kB36iSuH8wNSpDKb1TywlB6zcsG0xmJFxLutmfPhz03KUxRMNQOZ1K1Gc9BYvJifVnGVA== + version "3.10.0" + resolved "https://registry.npmjs.org/@google-cloud/common/-/common-3.10.0.tgz#454d1155bb512109cd83c6183aabbd39f9aabda7" + integrity sha512-XMbJYMh/ZSaZnbnrrOFfR/oQrb0SxG4qh6hDisWCoEbFcBHV0qHQo4uXfeMCzolx2Mfkh6VDaOGg+hyJsmxrlw== dependencies: "@google-cloud/projectify" "^2.0.0" "@google-cloud/promisify" "^2.0.0" @@ -1998,7 +1998,7 @@ duplexify "^4.1.1" ent "^2.2.0" extend "^3.0.2" - google-auth-library "^7.0.2" + google-auth-library "^7.14.0" retry-request "^4.2.2" teeny-request "^7.0.0" @@ -13256,7 +13256,7 @@ globby@^7.1.1: pify "^3.0.0" slash "^1.0.0" -google-auth-library@^7.0.0, google-auth-library@^7.0.2, google-auth-library@^7.6.1: +google-auth-library@^7.0.0, google-auth-library@^7.14.0, google-auth-library@^7.6.1: version "7.14.0" resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.0.tgz#9d6a20592f7b4d4c463cd3e93934c4b1711d5dc6" integrity sha512-or8r7qUqGVI3W8lVSdPh0ZpeFyQHeE73g5c0p+bLNTTUFXJ+GSeDQmZRZ2p4H8cF/RJYa4PNvi/A1ar1uVNLFA== From e0308ca6ecd9eeda728abea5b4dfda4e61a6d6fe Mon Sep 17 00:00:00 2001 From: Marco Crivellaro Date: Wed, 16 Mar 2022 17:19:26 +0000 Subject: [PATCH 03/27] replacing workflow:write scope with workflow, workflow:write is invalid. Signed-off-by: Marco Crivellaro --- docs/features/software-templates/writing-templates.md | 2 +- packages/integration-react/src/api/ScmAuth.test.ts | 4 ++-- .../components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index 9a1cfdf736..0163877a8b 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -364,7 +364,7 @@ spec: secretsKey: USER_OAUTH_TOKEN additionalScopes: github: - - workflow:write + - workflow allowedHosts: - github.com ... diff --git a/packages/integration-react/src/api/ScmAuth.test.ts b/packages/integration-react/src/api/ScmAuth.test.ts index 1ad391d8d2..7e174c4cbf 100644 --- a/packages/integration-react/src/api/ScmAuth.test.ts +++ b/packages/integration-react/src/api/ScmAuth.test.ts @@ -153,11 +153,11 @@ describe('ScmAuth', () => { githubAuth.getCredentials({ url: 'http://example.com', additionalScope: { - customScopes: { github: ['org:read', 'workflow:write'] }, + customScopes: { github: ['org:read', 'workflow'] }, }, }), ).resolves.toMatchObject({ - token: 'repo read:org read:user org:read workflow:write', + token: 'repo read:org read:user org:read workflow', }); const gitlabAuth = ScmAuth.forGitlab(mockAuthApi); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx index 22043d5761..7fac9f7840 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx @@ -138,7 +138,7 @@ describe('RepoUrlPicker', () => { 'ui:options': { requestUserCredentials: { secretsKey: 'testKey', - additionalScopes: { github: ['workflow:write'] }, + additionalScopes: { github: ['workflow'] }, }, }, }} @@ -164,7 +164,7 @@ describe('RepoUrlPicker', () => { additionalScope: { repoWrite: true, customScopes: { - github: ['workflow:write'], + github: ['workflow'], }, }, }); From c8b295f2fbf92dc5a4350575c91c1350fd291787 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 16:14:50 +0000 Subject: [PATCH 04/27] search-common: introduce SearchDocument type This type is a subset of `IndexableDocument`, and is intended to be used in place of `IndexableDocument` in the frontend. Signed-off-by: Mike Lewis --- .changeset/happy-mugs-camp.md | 7 ++++ plugins/search-common/api-report.md | 56 ++++++++++++++++++----------- plugins/search-common/src/types.ts | 43 +++++++++++++++++----- 3 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 .changeset/happy-mugs-camp.md diff --git a/.changeset/happy-mugs-camp.md b/.changeset/happy-mugs-camp.md new file mode 100644 index 0000000000..22d13d80d1 --- /dev/null +++ b/.changeset/happy-mugs-camp.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-search-common': patch +--- + +- Introduce `SearchDocument` type. This type contains the subset of `IndexableDocument` properties relevant to the frontend, and is intended to be used for documents returned to the frontend from the search API. +- `SearchResultSet` is now a wrapper for documents of type `SearchDocument`, and is intended to be used in the frontend. This isn't a breaking change, since `IndexableDocument`s are valid `SearchDocument`s, so the old and new types are compatible. +- Introduce `IndexableResultSet` type, which wraps `IndexableDocument` instances in the same way as `SearchResultSet`. diff --git a/plugins/search-common/api-report.md b/plugins/search-common/api-report.md index 8ab25d5e42..6befd6d1ca 100644 --- a/plugins/search-common/api-report.md +++ b/plugins/search-common/api-report.md @@ -30,14 +30,17 @@ export type DocumentTypeInfo = { }; // @beta -export interface IndexableDocument { +export type IndexableDocument = SearchDocument & { authorization?: { resourceRef: string; }; - location: string; - text: string; - title: string; -} +}; + +// @beta (undocumented) +export type IndexableResult = Result; + +// @beta (undocumented) +export type IndexableResultSet = ResultSet; // @beta export type QueryRequestOptions = { @@ -47,13 +50,38 @@ export type QueryRequestOptions = { // @beta export type QueryTranslator = (query: SearchQuery) => unknown; +// @beta (undocumented) +export interface Result { + // (undocumented) + document: TDocument; + // (undocumented) + type: string; +} + +// @beta (undocumented) +export interface ResultSet { + // (undocumented) + nextPageCursor?: string; + // (undocumented) + previousPageCursor?: string; + // (undocumented) + results: Result[]; +} + +// @beta +export interface SearchDocument { + location: string; + text: string; + title: string; +} + // @beta export interface SearchEngine { getIndexer(type: string): Promise; query( query: SearchQuery, options?: QueryRequestOptions, - ): Promise; + ): Promise; setTranslator(translator: QueryTranslator): void; } @@ -70,20 +98,8 @@ export interface SearchQuery { } // @beta (undocumented) -export interface SearchResult { - // (undocumented) - document: IndexableDocument; - // (undocumented) - type: string; -} +export type SearchResult = Result; // @beta (undocumented) -export interface SearchResultSet { - // (undocumented) - nextPageCursor?: string; - // (undocumented) - previousPageCursor?: string; - // (undocumented) - results: SearchResult[]; -} +export type SearchResultSet = ResultSet; ``` diff --git a/plugins/search-common/src/types.ts b/plugins/search-common/src/types.ts index 51ce45617b..cf385cfa64 100644 --- a/plugins/search-common/src/types.ts +++ b/plugins/search-common/src/types.ts @@ -31,26 +31,45 @@ export interface SearchQuery { /** * @beta */ -export interface SearchResult { +export interface Result { type: string; - document: IndexableDocument; + document: TDocument; } /** * @beta */ -export interface SearchResultSet { - results: SearchResult[]; +export interface ResultSet { + results: Result[]; nextPageCursor?: string; previousPageCursor?: string; } /** - * Base properties that all indexed documents must include, as well as some - * common properties that documents are encouraged to use where appropriate. * @beta */ -export interface IndexableDocument { +export type SearchResult = Result; + +/** + * @beta + */ +export type SearchResultSet = ResultSet; + +/** + * @beta + */ +export type IndexableResult = Result; + +/** + * @beta + */ +export type IndexableResultSet = ResultSet; + +/** + * Base properties that all search documents must include. + * @beta + */ +export interface SearchDocument { /** * The primary name of the document (e.g. name, title, identifier, etc). */ @@ -66,7 +85,13 @@ export interface IndexableDocument { * is clicked). */ location: string; +} +/** + * Properties related to indexing of documents. + * @beta + */ +export type IndexableDocument = SearchDocument & { /** * Optional authorization information to be used when determining whether this * search result should be visible to a given user. @@ -77,7 +102,7 @@ export interface IndexableDocument { */ resourceRef: string; }; -} +}; /** * Information about a specific document type. Intended to be used in the @@ -178,5 +203,5 @@ export interface SearchEngine { query( query: SearchQuery, options?: QueryRequestOptions, - ): Promise; + ): Promise; } From 62ee65422cd20b13608c098c2c8eef0b66be2083 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:23:54 +0000 Subject: [PATCH 05/27] elasticsearch: use new IndexableResultSet type as return type of engine#query Signed-off-by: Mike Lewis --- .changeset/light-drinks-rule.md | 5 +++++ plugins/search-backend-module-elasticsearch/api-report.md | 4 ++-- .../src/engines/ElasticSearchSearchEngine.ts | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/light-drinks-rule.md diff --git a/.changeset/light-drinks-rule.md b/.changeset/light-drinks-rule.md new file mode 100644 index 0000000000..61849b514a --- /dev/null +++ b/.changeset/light-drinks-rule.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-elasticsearch': patch +--- + +Use new `IndexableResultSet` type as return type of engine#query. diff --git a/plugins/search-backend-module-elasticsearch/api-report.md b/plugins/search-backend-module-elasticsearch/api-report.md index 265fdda686..10231f3a83 100644 --- a/plugins/search-backend-module-elasticsearch/api-report.md +++ b/plugins/search-backend-module-elasticsearch/api-report.md @@ -10,10 +10,10 @@ import { Client } from '@elastic/elasticsearch'; import { Config } from '@backstage/config'; import type { ConnectionOptions } from 'tls'; import { IndexableDocument } from '@backstage/plugin-search-common'; +import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Logger } from 'winston'; import { SearchEngine } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; -import { SearchResultSet } from '@backstage/plugin-search-common'; // Warning: (ae-missing-release-tag) "ElasticSearchClientOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/plugin-search-backend-module-elasticsearch" does not have an export "ElasticSearchEngine" @@ -119,7 +119,7 @@ export class ElasticSearchSearchEngine implements SearchEngine { getIndexer(type: string): Promise; newClient(create: (options: ElasticSearchClientOptions) => T): T; // (undocumented) - query(query: SearchQuery): Promise; + query(query: SearchQuery): Promise; // Warning: (ae-forgotten-export) The symbol "ElasticSearchQueryTranslator" needs to be exported by the entry point index.d.ts // // (undocumented) diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index f2ed5ed2b0..aec225a64b 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -21,9 +21,9 @@ import { import { Config } from '@backstage/config'; import { IndexableDocument, + IndexableResultSet, SearchEngine, SearchQuery, - SearchResultSet, } from '@backstage/plugin-search-common'; import { Client } from '@elastic/elasticsearch'; import esb from 'elastic-builder'; @@ -192,7 +192,7 @@ export class ElasticSearchSearchEngine implements SearchEngine { return indexer; } - async query(query: SearchQuery): Promise { + async query(query: SearchQuery): Promise { const { elasticSearchQuery, documentTypes, pageSize } = this.translator(query); const queryIndices = documentTypes From 234e91e2eda637a28da8e8dbd188653651135347 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:29:02 +0000 Subject: [PATCH 06/27] search-module-pg: use new IndexableResultSet type as return type of engine#query Signed-off-by: Mike Lewis --- .changeset/light-drinks-rule.md | 1 + plugins/search-backend-module-pg/api-report.md | 4 ++-- .../src/PgSearchEngine/PgSearchEngine.ts | 7 +++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.changeset/light-drinks-rule.md b/.changeset/light-drinks-rule.md index 61849b514a..75eca35ad9 100644 --- a/.changeset/light-drinks-rule.md +++ b/.changeset/light-drinks-rule.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-search-backend-module-pg': patch --- Use new `IndexableResultSet` type as return type of engine#query. diff --git a/plugins/search-backend-module-pg/api-report.md b/plugins/search-backend-module-pg/api-report.md index 39847a4935..71ceac996e 100644 --- a/plugins/search-backend-module-pg/api-report.md +++ b/plugins/search-backend-module-pg/api-report.md @@ -5,11 +5,11 @@ ```ts import { BatchSearchEngineIndexer } from '@backstage/plugin-search-backend-node'; import { IndexableDocument } from '@backstage/plugin-search-common'; +import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Knex } from 'knex'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { SearchQuery } from '@backstage/plugin-search-common'; -import { SearchResultSet } from '@backstage/plugin-search-common'; // Warning: (ae-missing-release-tag) "ConcretePgSearchQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -88,7 +88,7 @@ export class PgSearchEngine implements SearchEngine { // (undocumented) getIndexer(type: string): Promise; // (undocumented) - query(query: SearchQuery): Promise; + query(query: SearchQuery): Promise; // (undocumented) setTranslator( translator: (query: SearchQuery) => ConcretePgSearchQuery, diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index 8f75112837..ea363d8ea1 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -15,7 +15,10 @@ */ import { PluginDatabaseManager } from '@backstage/backend-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; -import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; +import { + SearchQuery, + IndexableResultSet, +} from '@backstage/plugin-search-common'; import { PgSearchEngineIndexer } from './PgSearchEngineIndexer'; import { DatabaseDocumentStore, @@ -81,7 +84,7 @@ export class PgSearchEngine implements SearchEngine { }); } - async query(query: SearchQuery): Promise { + async query(query: SearchQuery): Promise { const { pgQuery, pageSize } = this.translator(query); const rows = await this.databaseStore.transaction(async tx => From d07ed471dcab452bd82ccf692daf1d3e3aa6c588 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:31:40 +0000 Subject: [PATCH 07/27] search-backend-node: use new IndexableResultSet type as return type of engine#query Signed-off-by: Mike Lewis --- .changeset/light-drinks-rule.md | 3 ++- plugins/search-backend-node/api-report.md | 4 ++-- .../search-backend-node/src/engines/LunrSearchEngine.ts | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.changeset/light-drinks-rule.md b/.changeset/light-drinks-rule.md index 75eca35ad9..b83a14c986 100644 --- a/.changeset/light-drinks-rule.md +++ b/.changeset/light-drinks-rule.md @@ -1,6 +1,7 @@ --- +'@backstage/plugin-search-backend-node': patch '@backstage/plugin-search-backend-module-elasticsearch': patch '@backstage/plugin-search-backend-module-pg': patch --- -Use new `IndexableResultSet` type as return type of engine#query. +Use new `IndexableResultSet` type as return type of query method in `SearchEngine` implementation. diff --git a/plugins/search-backend-node/api-report.md b/plugins/search-backend-node/api-report.md index e4359eafac..ebc49df280 100644 --- a/plugins/search-backend-node/api-report.md +++ b/plugins/search-backend-node/api-report.md @@ -9,13 +9,13 @@ import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { DocumentDecoratorFactory } from '@backstage/plugin-search-common'; import { DocumentTypeInfo } from '@backstage/plugin-search-common'; import { IndexableDocument } from '@backstage/plugin-search-common'; +import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Logger } from 'winston'; import { default as lunr_2 } from 'lunr'; import { QueryTranslator } from '@backstage/plugin-search-common'; import { Readable } from 'stream'; import { SearchEngine } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; -import { SearchResultSet } from '@backstage/plugin-search-common'; import { Transform } from 'stream'; import { Writable } from 'stream'; @@ -87,7 +87,7 @@ export class LunrSearchEngine implements SearchEngine { // (undocumented) protected lunrIndices: Record; // (undocumented) - query(query: SearchQuery): Promise; + query(query: SearchQuery): Promise; // (undocumented) setTranslator(translator: LunrQueryTranslator): void; // (undocumented) diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts index b1d695ad1d..09e8729ba8 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -16,8 +16,8 @@ import { IndexableDocument, + IndexableResultSet, SearchQuery, - SearchResultSet, QueryTranslator, SearchEngine, } from '@backstage/plugin-search-common'; @@ -147,7 +147,7 @@ export class LunrSearchEngine implements SearchEngine { return indexer; } - async query(query: SearchQuery): Promise { + async query(query: SearchQuery): Promise { const { lunrQueryBuilder, documentTypes, pageSize } = this.translator( query, ) as ConcreteLunrQuery; @@ -196,8 +196,8 @@ export class LunrSearchEngine implements SearchEngine { ? encodePageCursor({ page: page - 1 }) : undefined; - // Translate results into SearchResultSet - const realResultSet: SearchResultSet = { + // Translate results into IndexableResultSet + const realResultSet: IndexableResultSet = { results: results.slice(offset, offset + pageSize).map(d => { return { type: d.type, document: this.docStore[d.result.ref] }; }), From a0fbae7aeb2081efde0e17640f58a6d50d50a2ac Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:39:39 +0000 Subject: [PATCH 08/27] search-backend: use new IndexableResultSet type as return type of engine#query Signed-off-by: Mike Lewis --- .changeset/light-drinks-rule.md | 1 + .../src/service/AuthorizedSearchEngine.ts | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.changeset/light-drinks-rule.md b/.changeset/light-drinks-rule.md index b83a14c986..2b99f5988c 100644 --- a/.changeset/light-drinks-rule.md +++ b/.changeset/light-drinks-rule.md @@ -1,4 +1,5 @@ --- +'@backstage/plugin-search-backend': patch '@backstage/plugin-search-backend-node': patch '@backstage/plugin-search-backend-module-elasticsearch': patch '@backstage/plugin-search-backend-module-pg': patch diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts index 2e65e18a84..2a5fc471f5 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts @@ -25,12 +25,12 @@ import { } from '@backstage/plugin-permission-common'; import { DocumentTypeInfo, + IndexableResult, + IndexableResultSet, QueryRequestOptions, QueryTranslator, SearchEngine, SearchQuery, - SearchResult, - SearchResultSet, } from '@backstage/plugin-search-common'; import { Config } from '@backstage/config'; import { InputError } from '@backstage/errors'; @@ -85,7 +85,7 @@ export class AuthorizedSearchEngine implements SearchEngine { async query( query: SearchQuery, options: QueryRequestOptions, - ): Promise { + ): Promise { const queryStartTime = Date.now(); const authorizer = new DataLoader( @@ -144,7 +144,7 @@ export class AuthorizedSearchEngine implements SearchEngine { const { page } = decodePageCursor(query.pageCursor); const targetResults = (page + 1) * this.pageSize; - let filteredResults: SearchResult[] = []; + let filteredResults: IndexableResult[] = []; let nextPageCursor: string | undefined; let latencyBudgetExhausted = false; @@ -183,7 +183,7 @@ export class AuthorizedSearchEngine implements SearchEngine { } private async filterResults( - results: SearchResult[], + results: IndexableResult[], typeDecisions: Record, authorizer: DataLoader, ) { From 94ccd772d4796008aff3d218b8ed77b4d1977ed6 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:57:09 +0000 Subject: [PATCH 09/27] search-backend: filter out authorization property in api responses Signed-off-by: Mike Lewis --- .changeset/empty-pens-invent.md | 5 ++ .../search-backend/src/service/router.test.ts | 54 +++++++++++++++++-- plugins/search-backend/src/service/router.ts | 14 ++++- 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 .changeset/empty-pens-invent.md diff --git a/.changeset/empty-pens-invent.md b/.changeset/empty-pens-invent.md new file mode 100644 index 0000000000..4f94028fc0 --- /dev/null +++ b/.changeset/empty-pens-invent.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +Filter out `authorization` property before returning API responses. diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index bdf46a240b..2efab91256 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -19,7 +19,6 @@ import { ConfigReader } from '@backstage/config'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { IndexBuilder, - LunrSearchEngine, SearchEngine, } from '@backstage/plugin-search-backend-node'; import express from 'express'; @@ -39,8 +38,19 @@ describe('createRouter', () => { beforeAll(async () => { const logger = getVoidLogger(); - const searchEngine = new LunrSearchEngine({ logger }); - const indexBuilder = new IndexBuilder({ logger, searchEngine }); + mockSearchEngine = { + getIndexer: jest.fn(), + setTranslator: jest.fn(), + query: jest.fn().mockResolvedValue({ + results: [], + nextPageCursor: '', + previousPageCursor: '', + }), + }; + const indexBuilder = new IndexBuilder({ + logger, + searchEngine: mockSearchEngine, + }); const router = await createRouter({ engine: indexBuilder.getSearchEngine(), @@ -56,7 +66,7 @@ describe('createRouter', () => { }); beforeEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); }); describe('GET /query', () => { @@ -101,6 +111,42 @@ describe('createRouter', () => { }); }); + it('removes backend-only properties from search documents', async () => { + mockSearchEngine.query.mockResolvedValue({ + results: [ + { + type: 'software-catalog', + document: { + text: 'foo', + title: 'bar baz', + location: '/catalog/default/component/example', + authorization: { + resourceRef: 'component:default/example', + }, + }, + }, + ], + nextPageCursor: '', + previousPageCursor: '', + }); + + const response = await request(app).get('/query'); + + expect(response.status).toEqual(200); + expect(response.body).toMatchObject({ + results: [ + { + type: 'software-catalog', + document: { + text: 'foo', + title: 'bar baz', + location: '/catalog/default/component/example', + }, + }, + ], + }); + }); + describe('search result filtering', () => { beforeAll(async () => { const logger = getVoidLogger(); diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 92e4e5526f..ff91465cf4 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -26,6 +26,7 @@ import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-no import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { DocumentTypeInfo, + IndexableResultSet, SearchResultSet, } from '@backstage/plugin-search-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; @@ -89,6 +90,17 @@ export async function createRouter( }), }); + const toSearchResults = (resultSet: IndexableResultSet): SearchResultSet => ({ + ...resultSet, + results: resultSet.results.map(result => ({ + ...result, + document: { + ...result.document, + authorization: undefined, + }, + })), + }); + const router = Router(); router.get( '/query', @@ -116,7 +128,7 @@ export async function createRouter( try { const resultSet = await engine?.query(query, { token }); - res.send(filterResultSet(resultSet)); + res.send(filterResultSet(toSearchResults(resultSet))); } catch (err) { throw new Error( `There was a problem performing the search query. ${err}`, From 38e01f2f7040f26eb4aecc47728a0c9015d0abea Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 11 Mar 2022 18:59:18 +0000 Subject: [PATCH 10/27] search: switch to SearchDocument type in DefaultResultListItem props Signed-off-by: Mike Lewis --- .changeset/ninety-fishes-vanish.md | 5 +++++ plugins/search/api-report.md | 4 ++-- .../DefaultResultListItem/DefaultResultListItem.tsx | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/ninety-fishes-vanish.md diff --git a/.changeset/ninety-fishes-vanish.md b/.changeset/ninety-fishes-vanish.md new file mode 100644 index 0000000000..b0d3ac370f --- /dev/null +++ b/.changeset/ninety-fishes-vanish.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +Switch to `SearchDocument` type in `DefaultResultListItem` props diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 0a277dab85..1bdd918802 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -9,13 +9,13 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { AsyncState } from 'react-use/lib/useAsync'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; -import { IndexableDocument } from '@backstage/plugin-search-common'; import { InputBaseProps } from '@material-ui/core'; import { JsonObject } from '@backstage/types'; import { default as React_2 } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; +import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; import { SearchResult as SearchResult_2 } from '@backstage/plugin-search-common'; import { SearchResultSet } from '@backstage/plugin-search-common'; @@ -31,7 +31,7 @@ export const DefaultResultListItem: ({ }: { icon?: ReactNode; secondaryAction?: ReactNode; - result: IndexableDocument; + result: SearchDocument; lineClamp?: number | undefined; }) => JSX.Element; diff --git a/plugins/search/src/components/DefaultResultListItem/DefaultResultListItem.tsx b/plugins/search/src/components/DefaultResultListItem/DefaultResultListItem.tsx index d9fbfe315e..46045f91ee 100644 --- a/plugins/search/src/components/DefaultResultListItem/DefaultResultListItem.tsx +++ b/plugins/search/src/components/DefaultResultListItem/DefaultResultListItem.tsx @@ -15,7 +15,7 @@ */ import React, { ReactNode } from 'react'; -import { IndexableDocument } from '@backstage/plugin-search-common'; +import { SearchDocument } from '@backstage/plugin-search-common'; import { ListItem, ListItemIcon, @@ -29,7 +29,7 @@ import TextTruncate from 'react-text-truncate'; type Props = { icon?: ReactNode; secondaryAction?: ReactNode; - result: IndexableDocument; + result: SearchDocument; lineClamp?: number; }; From aab3bac7fca6d53b58ad109e4ef6dc019f04b345 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Tue, 15 Mar 2022 09:57:55 +0000 Subject: [PATCH 11/27] search-backend: switch to minor bump in changeset Signed-off-by: MT Lewis --- .changeset/empty-pens-invent.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/empty-pens-invent.md b/.changeset/empty-pens-invent.md index 4f94028fc0..d6937afc84 100644 --- a/.changeset/empty-pens-invent.md +++ b/.changeset/empty-pens-invent.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-search-backend': patch +'@backstage/plugin-search-backend': minor --- -Filter out `authorization` property before returning API responses. +**BREAKING**: The `authorization` property is no longer returned on search results when queried. Note: this will only result in a breaking change if you have custom code in your frontend that relies on the `authorization.resourceRef` property on documents. From a6d402200d21b82bd48e6e50169d06f312cb3815 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Tue, 15 Mar 2022 10:01:28 +0000 Subject: [PATCH 12/27] search-common: restrict allowed type parameters for Result and ResultSet Signed-off-by: MT Lewis --- plugins/search-common/api-report.md | 4 ++-- plugins/search-common/src/types.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/search-common/api-report.md b/plugins/search-common/api-report.md index 6befd6d1ca..bd5a56c5cc 100644 --- a/plugins/search-common/api-report.md +++ b/plugins/search-common/api-report.md @@ -51,7 +51,7 @@ export type QueryRequestOptions = { export type QueryTranslator = (query: SearchQuery) => unknown; // @beta (undocumented) -export interface Result { +export interface Result { // (undocumented) document: TDocument; // (undocumented) @@ -59,7 +59,7 @@ export interface Result { } // @beta (undocumented) -export interface ResultSet { +export interface ResultSet { // (undocumented) nextPageCursor?: string; // (undocumented) diff --git a/plugins/search-common/src/types.ts b/plugins/search-common/src/types.ts index cf385cfa64..21aed101f6 100644 --- a/plugins/search-common/src/types.ts +++ b/plugins/search-common/src/types.ts @@ -31,7 +31,7 @@ export interface SearchQuery { /** * @beta */ -export interface Result { +export interface Result { type: string; document: TDocument; } @@ -39,7 +39,7 @@ export interface Result { /** * @beta */ -export interface ResultSet { +export interface ResultSet { results: Result[]; nextPageCursor?: string; previousPageCursor?: string; From f9f512559be9764b67e788e8772a8fa218ed5d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 17 Mar 2022 15:28:18 +0100 Subject: [PATCH 13/27] fix the secret marker in database config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/wicked-feet-clap.md | 5 +++++ packages/backend-common/config.d.ts | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/wicked-feet-clap.md diff --git a/.changeset/wicked-feet-clap.md b/.changeset/wicked-feet-clap.md new file mode 100644 index 0000000000..e27f641820 --- /dev/null +++ b/.changeset/wicked-feet-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Updated the visibility of database connection fields in config to be secret diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts index 058805aa62..6c473af3c0 100644 --- a/packages/backend-common/config.d.ts +++ b/packages/backend-common/config.d.ts @@ -73,7 +73,7 @@ export interface Config { client: 'better-sqlite3' | 'sqlite3' | 'pg'; /** * Base database connection string or Knex object - * @secret + * @visibility secret */ connection: string | object; /** Database name prefix override */ @@ -109,7 +109,7 @@ export interface Config { client?: 'better-sqlite3' | 'sqlite3' | 'pg'; /** * Database connection string or Knex object override - * @secret + * @visibility secret */ connection?: string | object; /** @@ -138,7 +138,7 @@ export interface Config { store: 'redis'; /** * A redis connection string in the form `redis://user:pass@host:port`. - * @secret + * @visibility secret */ connection: string; } @@ -146,7 +146,7 @@ export interface Config { store: 'memcache'; /** * A memcache connection string in the form `user:pass@host:port`. - * @secret + * @visibility secret */ connection: string; }; From d48122a4390080c67f4045a46e7046ccfe77e97d Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Thu, 17 Mar 2022 16:00:26 +0000 Subject: [PATCH 14/27] search: discourage use of IndexableDocument in the frontend Signed-off-by: MT Lewis --- plugins/search-common/src/types.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/search-common/src/types.ts b/plugins/search-common/src/types.ts index 21aed101f6..4eedabeb71 100644 --- a/plugins/search-common/src/types.ts +++ b/plugins/search-common/src/types.ts @@ -88,7 +88,10 @@ export interface SearchDocument { } /** - * Properties related to indexing of documents. + * Properties related to indexing of documents. This type is only useful for + * backends working directly with documents being inserted or retrieved from + * search indexes. When dealing with documents in the frontend, use + * {@link SearchDocument}. * @beta */ export type IndexableDocument = SearchDocument & { From 31436ffcadc7d319cccd31d6c895594ac506f239 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Thu, 17 Mar 2022 17:17:26 +0100 Subject: [PATCH 15/27] chore: add Bonial to adopters list Signed-off-by: Patrick Jungermann --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index e00031589d..10661f9792 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -106,3 +106,4 @@ _If you're using Backstage in your organization, please try to add your company | [Alliander](https://www.alliander.com/) | [@leon-vg](https://github.com/leon-vg), [@gieljl](https://github.com/gieljl), [@niekteg](https://github.com/niekteg) | Developer portal - software catalog, technical documentation, software templates, tech radar and exploration of used tools/services | | [VIA](https://www.via.com.br) | [@vagnerguedes](https://github.com/vagnerguedes) | Centralized Developer Experience portal - Software catalog and documentation platform, software templates, techdocs, scaffolding, self-service infrastructure | | [Surevine](https://www.surevine.com/) | [@DJDANNY123](https://github.com/djdanny123) | Developer portal for software catalog, discovery and a view of the technologies we are using across the organisation, we are looking to explore how we can enrich our entities in Backstage by integrating a software bill of materials. | +| [Bonial International GmbH](https://www.bonial.com/) | [@pjungermann](https://github.com/pjungermann) | Centralized developer portal with software catalog, tech docs, templates, and more. | From 910f5b69a605dcd5f4bc435f579a925aaf2c26ec Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Thu, 17 Mar 2022 10:39:52 -0400 Subject: [PATCH 16/27] Fix double comma Signed-off-by: Joe Porpeglia --- microsite/blog/2022-03-17-backstage-1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/blog/2022-03-17-backstage-1.0.md b/microsite/blog/2022-03-17-backstage-1.0.md index 43034664a3..02ead0390c 100644 --- a/microsite/blog/2022-03-17-backstage-1.0.md +++ b/microsite/blog/2022-03-17-backstage-1.0.md @@ -45,7 +45,7 @@ In terms of maturity and stability, the road ahead for Backstage is bright and b You can read more about Backstage’s roadmap [here](https://backstage.io/docs/overview/roadmap), but in terms of maturity and stability we would like to highlight the following: - CNCF incubation: The Backstage project [recently moved from Sandbox to Incubation](https://www.cncf.io/blog/2022/03/15/backstage-project-joins-the-cncf-incubator/) phase within the [CNCF maturity levels](https://www.cncf.io/projects/#:~:text=Maturity%20levels,should%20be%20adopting%20different%20projects.). -- Security auditing and strategy: With the CNCF’s support,, the project maintainers are working on a security audit initiative to make the platform more secure and will share more details soon. The audit is part of an overall security strategy being developed this quarter. +- Security auditing and strategy: With the CNCF’s support, the project maintainers are working on a security audit initiative to make the platform more secure and will share more details soon. The audit is part of an overall security strategy being developed this quarter. - Paid plugins for advanced and enterprise use cases: Last year, [Spotify announced its work on paid plugins](https://backstage.spotify.com/blog/paid-plugins-announcement/) built on top of the Backstage open source platform. This is another example of the platform’s maturity and Spotify’s continued commitment to the project, with a focus on customers and use cases requiring enterprise-focused support and plugins developed and proven by Spotify. # Some links to peruse From f616d99f6f93cddcd141cf7a9c65122feb83558e Mon Sep 17 00:00:00 2001 From: Manuel Stein Date: Thu, 17 Mar 2022 21:59:09 +0200 Subject: [PATCH 17/27] plugin-kubernetes: fix div by zero pod resources When pods have no resources set, currentToDeclaredResourceToPerc would throw div by zero, added check Signed-off-by: Manuel Stein --- .changeset/wicked-beds-return.md | 5 +++++ plugins/kubernetes/src/utils/pod.tsx | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/wicked-beds-return.md diff --git a/.changeset/wicked-beds-return.md b/.changeset/wicked-beds-return.md new file mode 100644 index 0000000000..add952ba0a --- /dev/null +++ b/.changeset/wicked-beds-return.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes': patch +--- + +Fix division by zero in currentToDeclaredResourceToPerc when pod resources weren't set diff --git a/plugins/kubernetes/src/utils/pod.tsx b/plugins/kubernetes/src/utils/pod.tsx index 50cc983b9d..86cf90e54f 100644 --- a/plugins/kubernetes/src/utils/pod.tsx +++ b/plugins/kubernetes/src/utils/pod.tsx @@ -118,6 +118,8 @@ export const currentToDeclaredResourceToPerc = ( current: number | string, resource: number | string, ): string => { + if(Number(resource) == 0) return `0%`; + if (typeof current === 'number' && typeof resource === 'number') { return `${Math.round((current / resource) * 100)}%`; } From f6a0cf7ca5c8b71dc3f500c69b642f516be90e91 Mon Sep 17 00:00:00 2001 From: Manuel Stein Date: Thu, 17 Mar 2022 23:21:25 +0200 Subject: [PATCH 18/27] prettier Signed-off-by: Manuel Stein --- plugins/kubernetes/src/utils/pod.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes/src/utils/pod.tsx b/plugins/kubernetes/src/utils/pod.tsx index 86cf90e54f..ddc73f2d76 100644 --- a/plugins/kubernetes/src/utils/pod.tsx +++ b/plugins/kubernetes/src/utils/pod.tsx @@ -118,7 +118,7 @@ export const currentToDeclaredResourceToPerc = ( current: number | string, resource: number | string, ): string => { - if(Number(resource) == 0) return `0%`; + if (Number(resource) == 0) return `0%`; if (typeof current === 'number' && typeof resource === 'number') { return `${Math.round((current / resource) * 100)}%`; From 15d3a3c39a4adfcf812a5b3551765672262bd52b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Mar 2022 22:56:03 +0100 Subject: [PATCH 19/27] auth-node,auth-backend: remove deprecated identity result fields Signed-off-by: Patrik Oldsberg --- .changeset/fast-cheetahs-grow.md | 5 + .changeset/khaki-pears-march.md | 5 + .../src/lib/flow/authFlowHelpers.test.ts | 3 - .../src/lib/oauth/OAuthAdapter.test.ts | 104 +----------------- .../src/lib/oauth/OAuthAdapter.ts | 22 +--- .../src/providers/aws-alb/provider.test.ts | 8 +- .../src/providers/gcp-iap/provider.test.ts | 4 +- .../providers/oauth2-proxy/provider.test.ts | 9 +- .../prepareBackstageIdentityResponse.test.ts | 66 ----------- .../prepareBackstageIdentityResponse.ts | 19 +--- plugins/auth-node/api-report.md | 5 - plugins/auth-node/package.json | 1 - plugins/auth-node/src/IdentityClient.test.ts | 6 +- plugins/auth-node/src/IdentityClient.ts | 1 - plugins/auth-node/src/types.ts | 21 ---- 15 files changed, 25 insertions(+), 254 deletions(-) create mode 100644 .changeset/fast-cheetahs-grow.md create mode 100644 .changeset/khaki-pears-march.md diff --git a/.changeset/fast-cheetahs-grow.md b/.changeset/fast-cheetahs-grow.md new file mode 100644 index 0000000000..5567436b5e --- /dev/null +++ b/.changeset/fast-cheetahs-grow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-node': minor +--- + +**BREAKING**: Removed the deprecated `id` and `entity` fields from `BackstageSignInResult`. diff --git a/.changeset/khaki-pears-march.md b/.changeset/khaki-pears-march.md new file mode 100644 index 0000000000..5626bf3ea5 --- /dev/null +++ b/.changeset/khaki-pears-march.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': minor +--- + +**BREAKING**: All sign-in resolvers must now return a `token` in their sign-in result. Returning an `id` is no longer supported. diff --git a/plugins/auth-backend/src/lib/flow/authFlowHelpers.test.ts b/plugins/auth-backend/src/lib/flow/authFlowHelpers.test.ts index 07c8196dd2..87e6b96745 100644 --- a/plugins/auth-backend/src/lib/flow/authFlowHelpers.test.ts +++ b/plugins/auth-backend/src/lib/flow/authFlowHelpers.test.ts @@ -50,7 +50,6 @@ describe('oauth helpers', () => { email: 'foo@bar.com', }, backstageIdentity: { - id: 'a', token: 'a.b.c', identity: { type: 'user', @@ -110,7 +109,6 @@ describe('oauth helpers', () => { email: 'foo@bar.com', }, backstageIdentity: { - id: 'a', token: 'a.b.c', identity: { type: 'user', @@ -157,7 +155,6 @@ describe('oauth helpers', () => { displayName: "Adam l'Hôpital", }, backstageIdentity: { - id: 'a', token: 'a.b.c', identity: { type: 'user', diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts index c1130b4270..0ce9dff66c 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts @@ -17,7 +17,7 @@ import express from 'express'; import { THOUSAND_DAYS_MS, TEN_MINUTES_MS, OAuthAdapter } from './OAuthAdapter'; import { encodeState } from './helpers'; -import { OAuthHandlers, OAuthResponse, OAuthState } from './types'; +import { OAuthHandlers, OAuthState } from './types'; const mockResponseData = { providerInfo: { @@ -30,18 +30,11 @@ const mockResponseData = { email: 'foo@bar.com', }, backstageIdentity: { - id: 'foo', token: - 'eyblob.eyJzdWIiOiJqaW1teW1hcmt1bSIsImVudCI6WyJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iXX0=.eyblob', + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob', }, }; -function mkTokenBody(payload: unknown): string { - return Buffer.from(JSON.stringify(payload), 'utf8') - .toString('base64') - .replace(/=/g, ''); -} - describe('OAuthAdapter', () => { class MyAuthProvider implements OAuthHandlers { async start() { @@ -324,13 +317,11 @@ describe('OAuthAdapter', () => { expect(mockResponse.json).toHaveBeenCalledWith({ ...mockResponseData, backstageIdentity: { - id: mockResponseData.backstageIdentity.id, token: mockResponseData.backstageIdentity.token, - idToken: mockResponseData.backstageIdentity.token, identity: { - ownershipEntityRefs: ['user:default/jimmymarkum'], type: 'user', userEntityRef: 'user:default/jimmymarkum', + ownershipEntityRefs: ['user:default/jimmymarkum'], }, }, }); @@ -356,95 +347,6 @@ describe('OAuthAdapter', () => { ); }); - it('correctly populates incomplete identities', async () => { - const mockRefresh = jest.fn< - Promise<{ response: OAuthResponse }>, - [express.Request] - >(); - - const oauthProvider = new OAuthAdapter( - { - refresh: mockRefresh, - start: jest.fn(), - handler: jest.fn(), - } as OAuthHandlers, - { - ...oAuthProviderOptions, - tokenIssuer: { - issueToken: async ({ claims }) => `a.${mkTokenBody(claims)}.a`, - listPublicKeys: async () => ({ keys: [] }), - }, - disableRefresh: false, - isOriginAllowed: () => false, - }, - ); - - const mockRequest = { - header: () => 'XMLHttpRequest', - cookies: { - 'test-provider-refresh-token': 'token', - }, - query: {}, - } as unknown as express.Request; - - const mockResponse = { - json: jest.fn().mockReturnThis(), - status: jest.fn().mockReturnThis(), - } as unknown as express.Response; - - // Without a token - mockRefresh.mockResolvedValueOnce({ - response: { - ...mockResponseData, - backstageIdentity: { - id: 'foo', - token: '', - }, - }, - }); - await oauthProvider.refresh(mockRequest, mockResponse); - expect(mockResponse.json).toHaveBeenCalledTimes(1); - expect(mockResponse.json).toHaveBeenLastCalledWith({ - ...mockResponseData, - backstageIdentity: { - id: 'foo', - token: `a.${mkTokenBody({ sub: 'user:default/foo' })}.a`, - idToken: `a.${mkTokenBody({ sub: 'user:default/foo' })}.a`, - identity: { - type: 'user', - userEntityRef: 'user:default/foo', - ownershipEntityRefs: [], - }, - }, - }); - - // With a token - mockRefresh.mockResolvedValueOnce({ - response: { - ...mockResponseData, - backstageIdentity: { - id: 'foo', - token: `z.${mkTokenBody({ sub: 'user:my-ns/foo' })}.z`, - }, - }, - }); - await oauthProvider.refresh(mockRequest, mockResponse); - expect(mockResponse.json).toHaveBeenCalledTimes(2); - expect(mockResponse.json).toHaveBeenLastCalledWith({ - ...mockResponseData, - backstageIdentity: { - id: 'foo', - token: `z.${mkTokenBody({ sub: 'user:my-ns/foo' })}.z`, - idToken: `z.${mkTokenBody({ sub: 'user:my-ns/foo' })}.z`, - identity: { - type: 'user', - userEntityRef: 'user:my-ns/foo', - ownershipEntityRefs: [], - }, - }, - }); - }); - it('sets the correct cookie configuration using a callbackUrl', async () => { const config = { baseUrl: 'http://domain.org/auth', diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index 07611ddb9c..c895b82ede 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -17,11 +17,6 @@ import express, { CookieOptions } from 'express'; import crypto from 'crypto'; import { URL } from 'url'; -import { - DEFAULT_NAMESPACE, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; import { BackstageIdentityResponse, BackstageSignInResult, @@ -263,22 +258,11 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { if (!identity) { return undefined; } - - if (identity.token) { - return prepareBackstageIdentityResponse(identity); + if (!identity.token) { + throw new InputError(`Identity response must return a token`); } - const userEntityRef = stringifyEntityRef( - parseEntityRef(identity.id, { - defaultKind: 'user', - defaultNamespace: DEFAULT_NAMESPACE, - }), - ); - const token = await this.options.tokenIssuer.issueToken({ - claims: { sub: userEntityRef }, - }); - - return prepareBackstageIdentityResponse({ ...identity, token }); + return prepareBackstageIdentityResponse(identity); } private setNonceCookie = (res: express.Response, nonce: string) => { diff --git a/plugins/auth-backend/src/providers/aws-alb/provider.test.ts b/plugins/auth-backend/src/providers/aws-alb/provider.test.ts index 37b5bc1f68..eb801fdd46 100644 --- a/plugins/auth-backend/src/providers/aws-alb/provider.test.ts +++ b/plugins/auth-backend/src/providers/aws-alb/provider.test.ts @@ -123,9 +123,8 @@ describe('AwsAlbAuthProvider', () => { }), signInResolver: async () => { return { - id: 'user.name', token: - 'eyblob.eyJzdWIiOiJqaW1teW1hcmt1bSIsImVudCI6WyJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iXX0=.eyblob', + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob', }; }, }); @@ -136,11 +135,8 @@ describe('AwsAlbAuthProvider', () => { expect(mockResponse.json).toHaveBeenCalledWith({ backstageIdentity: { - id: 'user.name', token: - 'eyblob.eyJzdWIiOiJqaW1teW1hcmt1bSIsImVudCI6WyJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iXX0=.eyblob', - idToken: - 'eyblob.eyJzdWIiOiJqaW1teW1hcmt1bSIsImVudCI6WyJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iXX0=.eyblob', + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob', identity: { ownershipEntityRefs: ['user:default/jimmymarkum'], type: 'user', diff --git a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts b/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts index aab0103140..eb2f5c478d 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts @@ -45,7 +45,7 @@ describe('GcpIapProvider', () => { const iapToken = { sub: 's', email: 'e@mail.com' }; authHandler.mockResolvedValueOnce({ email: 'e@mail.com' }); - signInResolver.mockResolvedValueOnce({ id: 'i', token: backstageToken }); + signInResolver.mockResolvedValueOnce({ token: backstageToken }); tokenValidator.mockResolvedValueOnce(iapToken); const app = express(); @@ -61,8 +61,6 @@ describe('GcpIapProvider', () => { ); expect(response.body).toEqual({ backstageIdentity: { - id: 'i', - idToken: backstageToken, token: backstageToken, identity: { type: 'user', diff --git a/plugins/auth-backend/src/providers/oauth2-proxy/provider.test.ts b/plugins/auth-backend/src/providers/oauth2-proxy/provider.test.ts index 048a3b9344..61f08bc535 100644 --- a/plugins/auth-backend/src/providers/oauth2-proxy/provider.test.ts +++ b/plugins/auth-backend/src/providers/oauth2-proxy/provider.test.ts @@ -43,7 +43,7 @@ import { describe('Oauth2ProxyAuthProvider', () => { const mockToken = - 'eyblob.eyJzdWIiOiJqaW1teW1hcmt1bSIsImVudCI6WyJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iXX0=.eyblob'; + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob'; let provider: Oauth2ProxyAuthProvider; let logger: jest.Mocked; @@ -122,7 +122,6 @@ describe('Oauth2ProxyAuthProvider', () => { profile: {}, }); signInResolver.mockResolvedValue({ - id: 'some-id', token: mockToken, }); @@ -142,7 +141,6 @@ describe('Oauth2ProxyAuthProvider', () => { const profile = { displayName: 'some value' }; mockRequest.header.mockReturnValue(`Bearer token`); signInResolver.mockResolvedValue({ - id: 'some-id', token: mockToken, }); authHandler.mockResolvedValue({ profile: profile }); @@ -162,12 +160,10 @@ describe('Oauth2ProxyAuthProvider', () => { ); expect(mockResponse.json).toHaveBeenCalledWith({ backstageIdentity: { - id: 'some-id', - idToken: mockToken, identity: { - ownershipEntityRefs: ['user:default/jimmymarkum'], type: 'user', userEntityRef: 'user:default/jimmymarkum', + ownershipEntityRefs: ['user:default/jimmymarkum'], }, token: mockToken, }, @@ -186,7 +182,6 @@ describe('Oauth2ProxyAuthProvider', () => { profile: {}, }); signInResolver.mockResolvedValue({ - id: 'some-id', token: mockToken, }); }); diff --git a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.test.ts b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.test.ts index 24442379c4..dac06f964e 100644 --- a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.test.ts +++ b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.test.ts @@ -27,13 +27,10 @@ describe('prepareBackstageIdentityResponse', () => { const token = mkToken({ sub: 'k:ns/n', ent: ['k:ns/o'] }); expect( prepareBackstageIdentityResponse({ - id: 'x', token, }), ).toEqual({ - id: 'x', token, - idToken: token, identity: { type: 'user', userEntityRef: 'k:ns/n', @@ -41,67 +38,4 @@ describe('prepareBackstageIdentityResponse', () => { }, }); }); - - it('populates incomplete identities', () => { - expect( - prepareBackstageIdentityResponse({ - id: 'x', - token: mkToken({ sub: 'n' }), - }), - ).toEqual({ - id: 'x', - token: expect.any(String), - idToken: expect.any(String), - identity: { - type: 'user', - userEntityRef: 'user:default/n', - ownershipEntityRefs: [], - }, - }); - expect( - prepareBackstageIdentityResponse({ - id: 'x', - token: mkToken({ sub: 'k:n' }), - }), - ).toEqual({ - id: 'x', - token: expect.any(String), - idToken: expect.any(String), - identity: { - type: 'user', - userEntityRef: 'k:default/n', - ownershipEntityRefs: [], - }, - }); - expect( - prepareBackstageIdentityResponse({ - id: 'x', - token: mkToken({ sub: 'ns/n' }), - }), - ).toEqual({ - id: 'x', - token: expect.any(String), - idToken: expect.any(String), - identity: { - type: 'user', - userEntityRef: 'user:ns/n', - ownershipEntityRefs: [], - }, - }); - expect( - prepareBackstageIdentityResponse({ - id: 'x', - token: mkToken({ sub: 'n', ent: ['k:ns/o'] }), - }), - ).toEqual({ - id: 'x', - token: expect.any(String), - idToken: expect.any(String), - identity: { - type: 'user', - userEntityRef: 'user:default/n', - ownershipEntityRefs: ['k:ns/o'], - }, - }); - }); }); diff --git a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts index 5a4e0895d9..761618c225 100644 --- a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts +++ b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts @@ -14,11 +14,6 @@ * limitations under the License. */ -import { - DEFAULT_NAMESPACE, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; import { BackstageIdentityResponse, BackstageSignInResult, @@ -41,21 +36,11 @@ export function prepareBackstageIdentityResponse( ): BackstageIdentityResponse { const { sub, ent } = parseJwtPayload(result.token); - const userEntityRef = stringifyEntityRef( - parseEntityRef(sub, { - defaultKind: 'user', - defaultNamespace: DEFAULT_NAMESPACE, - }), - ); return { - ...{ - // TODO: idToken is for backwards compatibility and can be removed in the future - idToken: result.token, - ...result, - }, + ...result, identity: { type: 'user', - userEntityRef, + userEntityRef: sub, ownershipEntityRefs: ent ?? [], }, }; diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index 7840fc7d74..f7fdd6369b 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { Entity } from '@backstage/catalog-model'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; // @public @@ -13,10 +12,6 @@ export interface BackstageIdentityResponse extends BackstageSignInResult { // @public export interface BackstageSignInResult { - // @deprecated - entity?: Entity; - // @deprecated - id: string; token: string; } diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index fc595a13ba..cb430f2de1 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -24,7 +24,6 @@ }, "dependencies": { "@backstage/backend-common": "^0.13.1", - "@backstage/catalog-model": "^1.0.0", "@backstage/config": "^1.0.0", "@backstage/errors": "^1.0.0", "jose": "^1.27.1", diff --git a/plugins/auth-node/src/IdentityClient.test.ts b/plugins/auth-node/src/IdentityClient.test.ts index 72ef7f2a57..88d4021dc3 100644 --- a/plugins/auth-node/src/IdentityClient.test.ts +++ b/plugins/auth-node/src/IdentityClient.test.ts @@ -135,12 +135,11 @@ describe('IdentityClient', () => { const token = await factory.issueToken({ claims: { sub: 'foo' } }); const response = await client.authenticate(token); expect(response).toEqual({ - id: 'foo', token: token, identity: { - ownershipEntityRefs: [], type: 'user', userEntityRef: 'foo', + ownershipEntityRefs: [], }, }); }); @@ -202,12 +201,11 @@ describe('IdentityClient', () => { const token = await factory.issueToken({ claims: { sub: 'foo' } }); const response = await client.authenticate(token); expect(response).toEqual({ - id: 'foo', token: token, identity: { - ownershipEntityRefs: [], type: 'user', userEntityRef: 'foo', + ownershipEntityRefs: [], }, }); }); diff --git a/plugins/auth-node/src/IdentityClient.ts b/plugins/auth-node/src/IdentityClient.ts index d8e841bf75..54c2670ae8 100644 --- a/plugins/auth-node/src/IdentityClient.ts +++ b/plugins/auth-node/src/IdentityClient.ts @@ -87,7 +87,6 @@ export class IdentityClient { } const user: BackstageIdentityResponse = { - id: decoded.sub, token, identity: { type: 'user', diff --git a/plugins/auth-node/src/types.ts b/plugins/auth-node/src/types.ts index b574c2204d..0d3e015beb 100644 --- a/plugins/auth-node/src/types.ts +++ b/plugins/auth-node/src/types.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; - /** * A representation of a successful Backstage sign-in. * @@ -25,25 +23,6 @@ import { Entity } from '@backstage/catalog-model'; * @public */ export interface BackstageSignInResult { - /** - * An opaque ID that uniquely identifies the user within Backstage. - * - * This is typically the same as the user entity `metadata.name`. - * - * @deprecated Use the `identity` field instead - */ - id: string; - - /** - * The entity that the user is represented by within Backstage. - * - * This entity may or may not exist within the Catalog, and it can be used - * to read and store additional metadata about the user. - * - * @deprecated Use the `identity` field instead. - */ - entity?: Entity; - /** * The token used to authenticate the user within Backstage. */ From 6ee04078e18826d49f2385484e32d69a9dc486ae Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Mar 2022 23:17:22 +0100 Subject: [PATCH 20/27] auth-backend: deprecate tokenIssuer option of OAuthAdapter Signed-off-by: Patrik Oldsberg --- .changeset/purple-boats-punch.md | 5 +++++ plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/purple-boats-punch.md diff --git a/.changeset/purple-boats-punch.md b/.changeset/purple-boats-punch.md new file mode 100644 index 0000000000..817f0a79bc --- /dev/null +++ b/.changeset/purple-boats-punch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +**DEPRECATION**: The `tokenIssuer` option for `OAuthAdapter` is no longer needed and has been deprecated. diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index c895b82ede..637dc1cff2 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -53,7 +53,8 @@ export type Options = { cookieDomain: string; cookiePath: string; appOrigin: string; - tokenIssuer: TokenIssuer; + /** @deprecated This option is no longer needed */ + tokenIssuer?: TokenIssuer; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; }; From 19648d5cf53125f8e7a5eeb667f1074bc0e0021e Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Thu, 17 Mar 2022 23:56:49 +0100 Subject: [PATCH 21/27] fix: ref to backstage/backstage at support config warning Signed-off-by: Patrick Jungermann --- .changeset/silver-pots-call.md | 5 +++++ packages/core-components/src/hooks/useSupportConfig.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/silver-pots-call.md diff --git a/.changeset/silver-pots-call.md b/.changeset/silver-pots-call.md new file mode 100644 index 0000000000..42b3016545 --- /dev/null +++ b/.changeset/silver-pots-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +fix support config ref to use backstage/backstage diff --git a/packages/core-components/src/hooks/useSupportConfig.ts b/packages/core-components/src/hooks/useSupportConfig.ts index 546d779e01..e80eb457a1 100644 --- a/packages/core-components/src/hooks/useSupportConfig.ts +++ b/packages/core-components/src/hooks/useSupportConfig.ts @@ -42,7 +42,7 @@ const DEFAULT_SUPPORT_CONFIG: SupportConfig = { { // TODO: Update to dedicated support page on backstage.io/docs title: 'Add `app.support` config key', - url: 'https://github.com/andrewthauer/backstage/blob/master/app-config.yaml', + url: 'https://github.com/backstage/backstage/blob/master/app-config.yaml', }, ], }, From cf647f6a72ba45003d468a344382ecab60ac1915 Mon Sep 17 00:00:00 2001 From: Marcus Crane Date: Fri, 18 Mar 2022 17:36:55 +1300 Subject: [PATCH 22/27] Wire up OneLogin provider to be visible in the settings UI Signed-off-by: Marcus Crane --- .changeset/fair-lamps-leave.md | 7 +++++++ .../components/AuthProviders/DefaultProviderSettings.tsx | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 .changeset/fair-lamps-leave.md diff --git a/.changeset/fair-lamps-leave.md b/.changeset/fair-lamps-leave.md new file mode 100644 index 0000000000..9e902b51f2 --- /dev/null +++ b/.changeset/fair-lamps-leave.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Wired up the OneLogin provider to be visible in the Settings UI when configured correctly. + +Previously it wasn't visible at all. diff --git a/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx b/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx index 7025167658..019967cf55 100644 --- a/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx +++ b/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx @@ -24,6 +24,7 @@ import { microsoftAuthApiRef, bitbucketAuthApiRef, atlassianAuthApiRef, + oneloginAuthApiRef, } from '@backstage/core-plugin-api'; type Props = { @@ -80,6 +81,14 @@ export const DefaultProviderSettings = ({ configuredProviders }: Props) => ( icon={Star} /> )} + {configuredProviders.includes('onelogin') && ( + + )} {configuredProviders.includes('atlassian') && ( Date: Fri, 18 Mar 2022 15:51:28 +0700 Subject: [PATCH 23/27] fix: forward to wrong service name fix: forward to wrong service name in case backend host != frontend host Signed-off-by: Tuan Anh Tran --- contrib/chart/backstage/templates/ingress.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/chart/backstage/templates/ingress.yaml b/contrib/chart/backstage/templates/ingress.yaml index cac9b61553..7e008c5d9d 100644 --- a/contrib/chart/backstage/templates/ingress.yaml +++ b/contrib/chart/backstage/templates/ingress.yaml @@ -74,7 +74,7 @@ spec: backend: {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} service: - name: {{ include "frontend.serviceName" . }} + name: {{ include "backend.serviceName" . }} port: number: 80 {{- else -}} From a496cee4d19144094bbad026c9aac9e88f9f15f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 18 Mar 2022 11:50:53 +0100 Subject: [PATCH 24/27] Add support for string refs to the EntityRefLinks component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/red-snakes-float.md | 5 +++ plugins/catalog-react/api-report.md | 8 ++--- .../EntityRefLink/EntityRefLinks.tsx | 33 ++++++++++--------- 3 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 .changeset/red-snakes-float.md diff --git a/.changeset/red-snakes-float.md b/.changeset/red-snakes-float.md new file mode 100644 index 0000000000..f1bd16d84c --- /dev/null +++ b/.changeset/red-snakes-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Add support for string refs to the `EntityRefLinks` component diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index a1541b555e..b90072beba 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -261,15 +261,11 @@ export type EntityRefLinkProps = { } & Omit; // @public -export const EntityRefLinks: ({ - entityRefs, - defaultKind, - ...linkProps -}: EntityRefLinksProps) => JSX.Element; +export function EntityRefLinks(props: EntityRefLinksProps): JSX.Element; // @public export type EntityRefLinksProps = { - entityRefs: (Entity | CompoundEntityRef)[]; + entityRefs: (string | Entity | CompoundEntityRef)[]; defaultKind?: string; } & Omit; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx index d92cd2ec87..30dda011d4 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx @@ -25,7 +25,7 @@ import { LinkProps } from '@backstage/core-components'; * @public */ export type EntityRefLinksProps = { - entityRefs: (Entity | CompoundEntityRef)[]; + entityRefs: (string | Entity | CompoundEntityRef)[]; defaultKind?: string; } & Omit; @@ -34,17 +34,20 @@ export type EntityRefLinksProps = { * * @public */ -export const EntityRefLinks = ({ - entityRefs, - defaultKind, - ...linkProps -}: EntityRefLinksProps) => ( - <> - {entityRefs.map((r, i) => ( - - {i > 0 && ', '} - - - ))} - -); +export function EntityRefLinks(props: EntityRefLinksProps) { + const { entityRefs, defaultKind, ...linkProps } = props; + return ( + <> + {entityRefs.map((r, i) => ( + + {i > 0 && ', '} + + + ))} + + ); +} From f0284d5c1f9468e81e62556c25e9cd642615ddcd Mon Sep 17 00:00:00 2001 From: irma12 Date: Fri, 18 Mar 2022 12:32:41 +0100 Subject: [PATCH 25/27] Update roadie packages Signed-off-by: irma12 --- packages/app/package.json | 8 +- .../app/src/components/catalog/EntityPage.tsx | 12 +- yarn.lock | 183 ++++-------------- 3 files changed, 41 insertions(+), 162 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index f152df41f9..29e6541df7 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -60,10 +60,10 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "@octokit/rest": "^18.5.3", - "@roadiehq/backstage-plugin-buildkite": "^1.4.0", - "@roadiehq/backstage-plugin-github-insights": "^1.6.0", - "@roadiehq/backstage-plugin-github-pull-requests": "^1.5.0", - "@roadiehq/backstage-plugin-travis-ci": "^1.4.0", + "@roadiehq/backstage-plugin-buildkite": "^2.0.0", + "@roadiehq/backstage-plugin-github-insights": "^2.0.0", + "@roadiehq/backstage-plugin-github-pull-requests": "^2.0.0", + "@roadiehq/backstage-plugin-travis-ci": "^2.0.0", "history": "^5.0.0", "prop-types": "^15.7.2", "react": "^17.0.2", diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 0a06c4fd5d..26068c6c8f 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -180,7 +180,7 @@ export const cicdContent = ( - boolean}> + @@ -192,7 +192,7 @@ export const cicdContent = ( - boolean}> + @@ -327,9 +327,7 @@ const overviewContent = ( {cicdCard} - boolean} - > + @@ -349,9 +347,7 @@ const overviewContent = ( - boolean} - > + diff --git a/yarn.lock b/yarn.lock index d0357f1f75..ce4fb1020f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1358,123 +1358,6 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@backstage/catalog-client@^0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@backstage/catalog-client/-/catalog-client-0.9.0.tgz#3e1024fab13fd8e2000d33833d2463ea9be5df9d" - integrity sha512-mr2wrb+7uAPczOOYt07C4AbXIeX0mu+Iw6RPDNg67GvPvQVcbKCrjth9VEj8rScFGmJAn66ZcronbcZSS0MJww== - dependencies: - "@backstage/catalog-model" "^0.13.0" - "@backstage/errors" "^0.2.2" - cross-fetch "^3.1.5" - -"@backstage/catalog-model@^0.13.0": - version "0.13.0" - resolved "https://registry.npmjs.org/@backstage/catalog-model/-/catalog-model-0.13.0.tgz#abeb91522ac7ef7907907ad5bc889803131db209" - integrity sha512-Q+0C0LJ8niNQ4TXduUNTycZ2PLMbhKmfgWywunJLO34DZAoFnTWJEAdEYF536YyLciHhLO0dHRUaHY29Sdr+Xg== - dependencies: - "@backstage/config" "^0.1.15" - "@backstage/errors" "^0.2.2" - "@backstage/types" "^0.1.3" - ajv "^7.0.3" - json-schema "^0.4.0" - lodash "^4.17.21" - uuid "^8.0.0" - -"@backstage/config@^0.1.15": - version "0.1.15" - resolved "https://registry.npmjs.org/@backstage/config/-/config-0.1.15.tgz#4bad122ad861be5bd61a60639f92d2494fa245c5" - integrity sha512-eNJEYYSEu9MkrkBYiMpUBWEc3Bu64YgB9pZZGCMW7/9350tV2wbylEdoBJHslilJlJhiUyTXBckn8Ua7DOH7rw== - dependencies: - "@backstage/types" "^0.1.3" - lodash "^4.17.21" - -"@backstage/core-plugin-api@^0.8.0": - version "0.8.0" - resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.8.0.tgz#e2096bff679183168a7f9b47ed27c50a01970e32" - integrity sha512-hHTrh0lui7TAUnLdqyvNznBuoh3PNEwHnlWCcnp2wfvLc7syG5bjnzorATknCixIiWsPfod5qtSSNeO4hQoFVQ== - dependencies: - "@backstage/config" "^0.1.15" - "@backstage/types" "^0.1.3" - "@backstage/version-bridge" "^0.1.2" - history "^5.0.0" - prop-types "^15.7.2" - react-router-dom "6.0.0-beta.0" - zen-observable "^0.8.15" - -"@backstage/errors@^0.2.2": - version "0.2.2" - resolved "https://registry.npmjs.org/@backstage/errors/-/errors-0.2.2.tgz#2113e0bc859e645b8b59bfcb435f7535739b02f8" - integrity sha512-s6Ru3NL4oFiHwNsMY1uiwqNKuOu9KQWkpse3adWZsDu1fCQKOw2omQ2qBHZ4Uj1xJ6x9Ye0yNTJ4vfHfdwiaEg== - dependencies: - "@backstage/types" "^0.1.3" - cross-fetch "^3.1.5" - serialize-error "^8.0.1" - -"@backstage/integration-react@^0.1.10": - version "0.1.25" - resolved "https://registry.npmjs.org/@backstage/integration-react/-/integration-react-0.1.25.tgz#ebbdd30d66e1d210b7cd33a682ad2be0d5ea5fc0" - integrity sha512-WI0UuXcX3m1OotfvqCVtQgyish9Gk+YkLVyrwWbzHFZ0isbT2I2i6VD/iau1X55oZpaubxLZ5CzYzA4QcAdm4w== - dependencies: - "@backstage/config" "^0.1.15" - "@backstage/core-components" "^0.9.1" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/integration" "^0.8.0" - "@backstage/theme" "^0.2.15" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - react-use "^17.2.4" - -"@backstage/integration@^0.8.0": - version "0.8.0" - resolved "https://registry.npmjs.org/@backstage/integration/-/integration-0.8.0.tgz#d74131ad347272b4935973aa4bd098fad9548ce6" - integrity sha512-GfNJRdcU7NMFjVqUSJOFRRrqEjKRGmgsL+s3TDtqmqqji7XPttTKD43+Ou50hRf0dkIETe5m1XHr1Fd5ksMt9A== - dependencies: - "@backstage/config" "^0.1.15" - "@octokit/auth-app" "^3.4.0" - "@octokit/rest" "^18.5.3" - cross-fetch "^3.1.5" - git-url-parse "^11.6.0" - lodash "^4.17.21" - luxon "^2.0.2" - -"@backstage/plugin-catalog-react@^0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.9.0.tgz#ff8c09ec455655fadb2c2fafd578908138b858bc" - integrity sha512-qSiz/q7B/IlkHkx3Tcrbokm+jIOPMGjSzxdnKWv5c6KcqF+XLiVr6TavLWcAjaxk81skF8N3RCDG68tA1lL0HA== - dependencies: - "@backstage/catalog-client" "^0.9.0" - "@backstage/catalog-model" "^0.13.0" - "@backstage/core-components" "^0.9.1" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/errors" "^0.2.2" - "@backstage/integration" "^0.8.0" - "@backstage/plugin-permission-common" "^0.5.2" - "@backstage/plugin-permission-react" "^0.3.3" - "@backstage/types" "^0.1.3" - "@backstage/version-bridge" "^0.1.2" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - classnames "^2.2.6" - jwt-decode "^3.1.0" - lodash "^4.17.21" - qs "^6.9.4" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - yaml "^1.10.0" - zen-observable "^0.8.15" - -"@backstage/types@^0.1.3": - version "0.1.3" - resolved "https://registry.npmjs.org/@backstage/types/-/types-0.1.3.tgz#6613d8cbdf97d42d31cd1e66a833df533e7ccf14" - integrity sha512-fJVi4oVrlO+G3PRv1fYSll9/X4pE11HLnkI//Geare9sP6wSfp/2zXpLYfKVsG0e24jOl7Swkc8lwLkQ90zMaQ== - -"@backstage/version-bridge@^0.1.2": - version "0.1.2" - resolved "https://registry.npmjs.org/@backstage/version-bridge/-/version-bridge-0.1.2.tgz#a24f42e0f383d497576f8c9d43851c6538345c03" - integrity sha512-hwThlwfVCXaHva6IBakbHlWt3c1ev3KIwukpBlU3tDgi6tTvG8tPDe2aRwz7zzPHZRtgEw6JPvjA9gn9vSPbzQ== - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -4972,15 +4855,15 @@ resolved "https://registry.npmjs.org/@rjsf/material-ui/-/material-ui-3.2.1.tgz#84fbf322485aee3a84101e189161f0687779ec8d" integrity sha512-8UiDeDbjCImFSfOegGu13otQ7OdP9FOYpcLjeouppnhs+MPeIEAtYS+jCcBKmi3reyTagC15/KVSRhde1wS1vg== -"@roadiehq/backstage-plugin-buildkite@^1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-buildkite/-/backstage-plugin-buildkite-1.4.0.tgz#f268ba2b6f43f68158af379d55fc7e19842c1b43" - integrity sha512-bG16kyn5e/QzceGy7PXs/wb09/p7W1O+kev7V/PGECHlxgj/Gg575maFsyZU/bIGTQM3cUavwvj0pzfdXjFD3Q== +"@roadiehq/backstage-plugin-buildkite@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-buildkite/-/backstage-plugin-buildkite-2.0.0.tgz#e5da049a2e15c533228e26da1af537b3783fe5de" + integrity sha512-qurSWt+n505BXFBTzoTSXn9BPmhtLjt+SPiVYjD3KSqJ7hwOoJg3rr1wuCWigUDj1R0Kx9TgaxNscETGBzUUgQ== dependencies: - "@backstage/catalog-model" "^0.13.0" + "@backstage/catalog-model" "^1.0.0" "@backstage/core-components" "^0.9.0" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/plugin-catalog-react" "^0.9.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/theme" "^0.2.6" "@material-ui/core" "^4.12.1" "@material-ui/icons" "^4.11.2" @@ -4991,16 +4874,16 @@ react-router-dom "6.0.0-beta.0" react-use "^17.2.4" -"@roadiehq/backstage-plugin-github-insights@^1.6.0": - version "1.6.0" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-1.6.0.tgz#0ccd63ff08f720f09d0076ba3210ef2373bb62b2" - integrity sha512-TV7hrxxhJy0yN+jERVKALYW36nwvNWCpCOcBGgoBepbFCOhiUgc3g9EjRp0b0z+uUSywFkEPUYH1B1CXGzDLdw== +"@roadiehq/backstage-plugin-github-insights@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-2.0.0.tgz#1137f4f3ad5744559bf095ee868371f5fd8c60ec" + integrity sha512-6rLMWq8F6hYNAkuF+gOKyAZ/A2MGVHuNJArBJCUVhw6b/tmSxQcj78y62GaXB1Zz9KERhSk8OZf94m0+EE8C5g== dependencies: - "@backstage/catalog-model" "^0.13.0" + "@backstage/catalog-model" "^1.0.0" "@backstage/core-components" "^0.9.0" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/integration-react" "^0.1.10" - "@backstage/plugin-catalog-react" "^0.9.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/integration-react" "^1.0.0" + "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/theme" "^0.2.7" "@date-io/core" "2.10.7" "@material-ui/core" "^4.11.0" @@ -5015,15 +4898,15 @@ react-use "^17.2.4" zustand "3.6.9" -"@roadiehq/backstage-plugin-github-pull-requests@^1.5.0": - version "1.5.0" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-pull-requests/-/backstage-plugin-github-pull-requests-1.5.0.tgz#30266e037831c11842cd8e1456008fede2c6b580" - integrity sha512-jlNYV/RC0HVwkp8lCmPAhps6KpRP4OuTrsrIXt557EHWb+kuwEAV5jKaSkINvUOjIPAnOB7SA83xXWZW1Y9lig== +"@roadiehq/backstage-plugin-github-pull-requests@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-pull-requests/-/backstage-plugin-github-pull-requests-2.0.0.tgz#99ba670e1bd9bdc954b43901883aaf9832ae8942" + integrity sha512-3R9MmWGqmd7cVEZtiUShr10M8j+aM0SQUaZG1EuW+AzlErA2Zo1pcSBwKuIOcotWbyQzVsruKEPI2BrvJkJikQ== dependencies: - "@backstage/catalog-model" "^0.13.0" + "@backstage/catalog-model" "^1.0.0" "@backstage/core-components" "^0.9.0" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/plugin-catalog-react" "^0.9.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/plugin-catalog-react" "^1.0.0" "@material-ui/core" "^4.11.0" "@material-ui/icons" "^4.9.1" "@octokit/rest" "^18.5.3" @@ -5036,15 +4919,15 @@ react-router "6.0.0-beta.0" react-use "^17.2.4" -"@roadiehq/backstage-plugin-travis-ci@^1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-travis-ci/-/backstage-plugin-travis-ci-1.4.0.tgz#165b401b4b4eaae93ebb1148854c8343392f9950" - integrity sha512-tYNpfybmKiOULYoL7YV2DJ1l0e8UcbZsc3B0pSUbchPedoWlvgpXoG5BmttTZcCW8MI0e1kK2FWqwnVkvygRhQ== +"@roadiehq/backstage-plugin-travis-ci@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-travis-ci/-/backstage-plugin-travis-ci-2.0.0.tgz#d86eba878bbaa6ada77e9eda932ff25bd9121021" + integrity sha512-nrqWysSLBq4t9jVkQb5rz1pfNt2Ojlj+s0004FSNzPa8PPD+5XUhFZiS9Mi4kJVUC9BLW5SVdJzWtWEGbxyLPw== dependencies: - "@backstage/catalog-model" "^0.13.0" + "@backstage/catalog-model" "^1.0.0" "@backstage/core-components" "^0.9.0" - "@backstage/core-plugin-api" "^0.8.0" - "@backstage/plugin-catalog-react" "^0.9.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/theme" "^0.2.9" "@material-ui/core" "^4.11.3" "@material-ui/icons" "^4.11.2" @@ -12106,10 +11989,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: "@material-ui/icons" "^4.9.1" "@material-ui/lab" "4.0.0-alpha.57" "@octokit/rest" "^18.5.3" - "@roadiehq/backstage-plugin-buildkite" "^1.4.0" - "@roadiehq/backstage-plugin-github-insights" "^1.6.0" - "@roadiehq/backstage-plugin-github-pull-requests" "^1.5.0" - "@roadiehq/backstage-plugin-travis-ci" "^1.4.0" + "@roadiehq/backstage-plugin-buildkite" "^2.0.0" + "@roadiehq/backstage-plugin-github-insights" "^2.0.0" + "@roadiehq/backstage-plugin-github-pull-requests" "^2.0.0" + "@roadiehq/backstage-plugin-travis-ci" "^2.0.0" history "^5.0.0" prop-types "^15.7.2" react "^17.0.2" From 5b5f6791fced698b39f6d47e448fe5ad8fe2746f Mon Sep 17 00:00:00 2001 From: Manuel Stein Date: Fri, 18 Mar 2022 14:24:06 +0200 Subject: [PATCH 26/27] lint fix Signed-off-by: Manuel Stein --- plugins/kubernetes/src/utils/pod.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes/src/utils/pod.tsx b/plugins/kubernetes/src/utils/pod.tsx index ddc73f2d76..7bed160a5f 100644 --- a/plugins/kubernetes/src/utils/pod.tsx +++ b/plugins/kubernetes/src/utils/pod.tsx @@ -118,7 +118,7 @@ export const currentToDeclaredResourceToPerc = ( current: number | string, resource: number | string, ): string => { - if (Number(resource) == 0) return `0%`; + if (Number(resource) === 0) return `0%`; if (typeof current === 'number' && typeof resource === 'number') { return `${Math.round((current / resource) * 100)}%`; From 2a3cac4c60d744b015994514b01e10d1663db755 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 18 Mar 2022 08:30:55 -0500 Subject: [PATCH 27/27] Corrected replacements for depreciated items Signed-off-by: Andre Wanlin --- .changeset/eleven-pens-collect.md | 5 +++++ .../catalog/src/components/FilteredEntityLayout/index.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/eleven-pens-collect.md diff --git a/.changeset/eleven-pens-collect.md b/.changeset/eleven-pens-collect.md new file mode 100644 index 0000000000..0df1bb0400 --- /dev/null +++ b/.changeset/eleven-pens-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Corrected replacements for depreciated FilteredEntityLayout items diff --git a/plugins/catalog/src/components/FilteredEntityLayout/index.ts b/plugins/catalog/src/components/FilteredEntityLayout/index.ts index 892aa34147..a9277a3298 100644 --- a/plugins/catalog/src/components/FilteredEntityLayout/index.ts +++ b/plugins/catalog/src/components/FilteredEntityLayout/index.ts @@ -18,7 +18,7 @@ import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; /** * @public - * @deprecated Use `FilteredCatalogLayout` from `@backstage/plugin-catalog-react` instead. + * @deprecated Use `CatalogFilterLayout` from `@backstage/plugin-catalog-react` instead. */ export const FilteredEntityLayout = CatalogFilterLayout as (props: { children: React.ReactNode; @@ -26,12 +26,12 @@ export const FilteredEntityLayout = CatalogFilterLayout as (props: { /** * @public - * @deprecated Use `FilteredCatalogLayout.Filters` from `@backstage/plugin-catalog-react` instead. + * @deprecated Use `CatalogFilterLayout.Filters` from `@backstage/plugin-catalog-react` instead. */ export const FilterContainer = CatalogFilterLayout.Filters; /** * @public - * @deprecated Use `FilteredCatalogLayout.Content` from `@backstage/plugin-catalog-react` instead. + * @deprecated Use `CatalogFilterLayout.Content` from `@backstage/plugin-catalog-react` instead. */ export const EntityListContainer = CatalogFilterLayout.Content;