From 280edeb67ac67a327f99c891e84d7fac68be8b65 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 30 Jan 2024 09:42:38 +0200 Subject: [PATCH 01/76] chore: add missing indexes to search table this should speed up fetching the entity facets as the original value and key are used together when fetching the facets. Signed-off-by: Heikki Hellgren --- .changeset/tiny-books-destroy.md | 5 +++ .../migrations/20240130092632_search_index.js | 45 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 .changeset/tiny-books-destroy.md create mode 100644 plugins/catalog-backend/migrations/20240130092632_search_index.js diff --git a/.changeset/tiny-books-destroy.md b/.changeset/tiny-books-destroy.md new file mode 100644 index 0000000000..2516080ec5 --- /dev/null +++ b/.changeset/tiny-books-destroy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Add index for original value in search table for faster entity facet response diff --git a/plugins/catalog-backend/migrations/20240130092632_search_index.js b/plugins/catalog-backend/migrations/20240130092632_search_index.js new file mode 100644 index 0000000000..e43b4a1aad --- /dev/null +++ b/plugins/catalog-backend/migrations/20240130092632_search_index.js @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param { import("knex").Knex } knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client === 'pg') { + await knex.raw( + 'CREATE INDEX CONCURRENTLY search_key_value_idx ON search(key, value)', + ); + await knex.raw( + 'CREATE INDEX CONCURRENTLY search_key_original_value_idx ON search(key, original_value)', + ); + } +}; + +/** + * @param { import("knex").Knex } knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client === 'pg') { + await knex.raw('DROP INDEX CONCURRENTLY search_key_value_idx'); + await knex.raw('DROP INDEX CONCURRENTLY search_key_original_value_idx'); + } +}; + +exports.config = { + transaction: false, +}; From c5a7cf4a4f635560a8eaea529ec4f9608b705a80 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 7 Feb 2024 15:01:19 +0100 Subject: [PATCH 02/76] backend-{app,plugin}-api: add initial AuthService interface + implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-app-api/api-report.md | 4 + packages/backend-app-api/package.json | 1 + .../auth/authServiceFactory.test.ts | 110 ++++++++++++ .../auth/authServiceFactory.ts | 157 ++++++++++++++++++ .../services/implementations/auth/index.ts | 17 ++ .../src/services/implementations/index.ts | 1 + packages/backend-plugin-api/api-report.md | 30 ++++ .../src/services/definitions/AuthService.ts | 54 ++++++ .../src/services/definitions/coreServices.ts | 9 + .../src/services/definitions/index.ts | 6 + yarn.lock | 1 + 11 files changed, 390 insertions(+) create mode 100644 packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts create mode 100644 packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts create mode 100644 packages/backend-app-api/src/services/implementations/auth/index.ts create mode 100644 packages/backend-plugin-api/src/services/definitions/AuthService.ts diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index f41a38de7b..6836ec40a0 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -6,6 +6,7 @@ /// import type { AppConfig } from '@backstage/config'; +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CacheClient } from '@backstage/backend-common'; import { Config } from '@backstage/config'; @@ -41,6 +42,9 @@ import { TokenManagerService } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; import { UrlReader } from '@backstage/backend-common'; +// @public (undocumented) +export const authServiceFactory: () => ServiceFactory; + // @public (undocumented) export interface Backend { // (undocumented) diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 66393853db..e899e5a075 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -65,6 +65,7 @@ "express-promise-router": "^4.1.0", "fs-extra": "^11.2.0", "helmet": "^6.0.0", + "jose": "^4.6.0", "lodash": "^4.17.21", "logform": "^2.3.2", "minimatch": "^5.0.0", diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts new file mode 100644 index 0000000000..9dc64212de --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts @@ -0,0 +1,110 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ServiceFactoryTester, + mockServices, +} from '@backstage/backend-test-utils'; +import { + InternalBackstageServiceCredentials, + InternalBackstageUserCredentials, + authServiceFactory, +} from './authServiceFactory'; +import { decodeJwt } from 'jose'; +import { discoveryServiceFactory } from '../discovery'; + +// TODO: Ship discovery mock service in the service factory tester +const mockDeps = [ + discoveryServiceFactory(), + mockServices.rootConfig.factory({ + data: { + backend: { + baseUrl: 'http://localhost', + auth: { keys: [{ secret: 'abc' }] }, + }, + }, + }), +]; + +describe('authServiceFactory', () => { + it('should authenticate issued tokens', async () => { + const tester = ServiceFactoryTester.from(authServiceFactory, { + dependencies: mockDeps, + }); + + const searchAuth = await tester.get('search'); + const catalogAuth = await tester.get('catalog'); + + const { token: searchToken } = await searchAuth.issueServiceToken(); + + await expect(searchAuth.authenticate(searchToken)).resolves.toEqual( + expect.objectContaining({ + type: 'service', + subject: 'external:backstage-plugin', + }), + ); + await expect(catalogAuth.authenticate(searchToken)).resolves.toEqual( + expect.objectContaining({ + type: 'service', + subject: 'external:backstage-plugin', + }), + ); + }); + + it('should forward user tokens', async () => { + const tester = ServiceFactoryTester.from(authServiceFactory, { + dependencies: mockDeps, + }); + + const catalogAuth = await tester.get('catalog'); + + await expect( + catalogAuth.issueServiceToken({ + forward: { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + type: 'user', + userEntityRef: 'user:default/alice', + token: 'alice-token', + } as InternalBackstageUserCredentials, + }), + ).resolves.toEqual({ token: 'alice-token' }); + }); + + it('should not forward service tokens', async () => { + const tester = ServiceFactoryTester.from(authServiceFactory, { + dependencies: mockDeps, + }); + + const catalogAuth = await tester.get('catalog'); + + const { token } = await catalogAuth.issueServiceToken({ + forward: { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + type: 'service', + subject: 'external:backstage-plugin', + token: 'some-upstream-service-token', + } as InternalBackstageServiceCredentials, + }); + + expect(decodeJwt(token)).toEqual( + expect.objectContaining({ + sub: 'backstage-server', + }), + ); + }); +}); diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts new file mode 100644 index 0000000000..a21829b228 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -0,0 +1,157 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; +import { + AuthService, + BackstageCredentials, + BackstageServiceCredentials, + BackstageUserCredentials, + IdentityService, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { AuthenticationError } from '@backstage/errors'; +import { + DefaultIdentityClient, + IdentityApiGetIdentityRequest, +} from '@backstage/plugin-auth-node'; +import { decodeJwt } from 'jose'; + +/** @internal */ +export type InternalBackstageServiceCredentials = + BackstageServiceCredentials & { + version: string; + token: string; + }; + +function createServiceCredentials( + sub: string, + token: string, +): BackstageServiceCredentials { + return { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + token, + type: 'service', + subject: sub, + } as InternalBackstageServiceCredentials; +} + +/** @internal */ +export type InternalBackstageUserCredentials = BackstageUserCredentials & { + version: string; + token: string; +}; + +function createUserCredentials( + sub: string, + token: string, +): BackstageUserCredentials { + return { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + token, + type: 'user', + userEntityRef: sub, + } as InternalBackstageUserCredentials; +} + +export function toInternalBackstageCredentials( + credentials: BackstageCredentials, +): InternalBackstageServiceCredentials | InternalBackstageUserCredentials { + if (credentials.$$type !== '@backstage/BackstageCredentials') { + throw new Error('Invalid credential type'); + } + const internalCredentials = credentials as + | InternalBackstageServiceCredentials + | InternalBackstageUserCredentials; + if (internalCredentials.version !== 'v1') { + throw new Error( + `Invalid credential version ${internalCredentials.version}`, + ); + } + return internalCredentials; +} + +/** @internal */ +class DefaultAuthService implements AuthService { + constructor( + private readonly tokenManager: TokenManager, + private readonly identity: IdentityService, + ) {} + + async authenticate(token: string): Promise { + const { sub, aud } = decodeJwt(token); + + // Legacy service-to-service token + if (sub === 'backstage-server' && !aud) { + await this.tokenManager.authenticate(token); + return createServiceCredentials('external:backstage-plugin', token); + } + + // User Backstage token + const identity = await this.identity.getIdentity({ + request: { + headers: { authorization: `Bearer ${token}` }, + }, + } as IdentityApiGetIdentityRequest); + + if (!identity) { + throw new AuthenticationError('No identity found'); + } + + return createUserCredentials(identity.identity.userEntityRef, token); + } + + async issueServiceToken(options?: { + forward?: BackstageCredentials; + }): Promise<{ token: string }> { + const internalForward = + options?.forward && toInternalBackstageCredentials(options.forward); + + if (internalForward) { + const { type } = internalForward; + if (type === 'user') { + return { token: internalForward.token }; + } else if (type !== 'service') { + throw new AuthenticationError( + `Refused to issue service token for credential type '${type}'`, + ); + } + } + + const { token } = await this.tokenManager.getToken(); + return { token }; + } +} + +/** @public */ +export const authServiceFactory = createServiceFactory({ + service: coreServices.auth, + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + discovery: coreServices.discovery, + }, + createRootContext({ config, logger }) { + return ServerTokenManager.fromConfig(config, { logger }); + }, + async factory({ discovery }, tokenManager) { + const identity = DefaultIdentityClient.create({ discovery }); + return new DefaultAuthService(tokenManager, identity); + }, +}); diff --git a/packages/backend-app-api/src/services/implementations/auth/index.ts b/packages/backend-app-api/src/services/implementations/auth/index.ts new file mode 100644 index 0000000000..1b55d46a83 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/auth/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { authServiceFactory } from './authServiceFactory'; diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index 57042951d9..9d42dbfef7 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +export * from './auth'; export * from './cache'; export * from './config'; export * from './database'; diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 3b3d28cc27..52f52afaa9 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -15,6 +15,16 @@ import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { Readable } from 'stream'; +// @public (undocumented) +export interface AuthService { + // (undocumented) + authenticate(token: string): Promise; + // (undocumented) + issueServiceToken(options?: { forward?: BackstageCredentials }): Promise<{ + token: string; + }>; +} + // @public (undocumented) export interface BackendFeature { // (undocumented) @@ -76,6 +86,25 @@ export interface BackendPluginRegistrationPoints { }): void; } +// @public (undocumented) +export type BackstageCredentials = + | BackstageUserCredentials + | BackstageServiceCredentials; + +// @public (undocumented) +export type BackstageServiceCredentials = { + $$type: '@backstage/BackstageCredentials'; + type: 'service'; + subject: string; +}; + +// @public (undocumented) +export type BackstageUserCredentials = { + $$type: '@backstage/BackstageCredentials'; + type: 'user'; + userEntityRef: string; +}; + // @public export interface CacheService { delete(key: string): Promise; @@ -100,6 +129,7 @@ export type CacheServiceSetOptions = { // @public export namespace coreServices { + const auth: ServiceRef; const cache: ServiceRef; const rootConfig: ServiceRef; const database: ServiceRef; diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts new file mode 100644 index 0000000000..d4ab8456a8 --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @public + */ +export type BackstageUserCredentials = { + $$type: '@backstage/BackstageCredentials'; + + type: 'user'; + + userEntityRef: string; +}; + +/** + * @public + */ +export type BackstageServiceCredentials = { + $$type: '@backstage/BackstageCredentials'; + + type: 'service'; + + subject: string; +}; + +/** + * @public + */ +export type BackstageCredentials = + | BackstageUserCredentials + | BackstageServiceCredentials; + +/** + * @public + */ +export interface AuthService { + authenticate(token: string): Promise; + issueServiceToken(options?: { + forward?: BackstageCredentials; + }): Promise<{ token: string }>; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index b42795d052..561a587e5e 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -22,6 +22,15 @@ import { createServiceRef } from '../system'; * @public */ export namespace coreServices { + /** + * The service reference for the plugin scoped {@link IdentityService}. + * + * @public + */ + export const auth = createServiceRef({ + id: 'core.auth', + }); + /** * The service reference for the plugin scoped {@link CacheService}. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 98be8211db..8a53399be6 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -15,6 +15,12 @@ */ export { coreServices } from './coreServices'; +export type { + AuthService, + BackstageCredentials, + BackstageServiceCredentials, + BackstageUserCredentials, +} from './AuthService'; export type { CacheService, CacheServiceOptions, diff --git a/yarn.lock b/yarn.lock index ef624e232e..555b683cd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3250,6 +3250,7 @@ __metadata: fs-extra: ^11.2.0 helmet: ^6.0.0 http-errors: ^2.0.0 + jose: ^4.6.0 lodash: ^4.17.21 logform: ^2.3.2 minimatch: ^5.0.0 From 9e45e2af6da0c2e4401f689f6cf20afc9f4569fe Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 9 Feb 2024 13:02:13 +0100 Subject: [PATCH 03/76] backend-{plugin,app}-api: add HttpAuthService + initial implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-app-api/api-report.md | 7 + packages/backend-app-api/package.json | 1 + .../httpAuth/httpAuthServiceFactory.ts | 176 ++++++++++++++++++ .../implementations/httpAuth/index.ts | 17 ++ .../httpRouter/httpRouterServiceFactory.ts | 14 +- .../src/services/implementations/index.ts | 1 + packages/backend-plugin-api/api-report.md | 36 ++++ .../services/definitions/HttpAuthService.ts | 56 ++++++ .../src/services/definitions/coreServices.ts | 9 + .../src/services/definitions/index.ts | 5 + yarn.lock | 3 +- 11 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts create mode 100644 packages/backend-app-api/src/services/implementations/httpAuth/index.ts create mode 100644 packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 6836ec40a0..e4a3d3d6de 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -19,6 +19,7 @@ import { Format } from 'logform'; import { Handler } from 'express'; import { HelmetOptions } from 'helmet'; import * as http from 'http'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { HumanDuration } from '@backstage/types'; import { IdentityService } from '@backstage/backend-plugin-api'; @@ -148,6 +149,12 @@ export class HostDiscovery implements DiscoveryService { getExternalBaseUrl(pluginId: string): Promise; } +// @public (undocumented) +export const httpAuthServiceFactory: () => ServiceFactory< + HttpAuthService, + 'plugin' +>; + // @public (undocumented) export interface HttpRouterFactoryOptions { getPath?(pluginId: string): string; diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index e899e5a075..52378fef37 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -60,6 +60,7 @@ "@types/cors": "^2.8.6", "@types/express": "^4.17.6", "compression": "^1.7.4", + "cookie": "^0.6.0", "cors": "^2.8.5", "express": "^4.17.1", "express-promise-router": "^4.1.0", diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts new file mode 100644 index 0000000000..e2b60e31b2 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -0,0 +1,176 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AuthService, + BackstageCredentialTypes, + BackstageCredentials, + BackstageUnauthorizedCredentials, + DiscoveryService, + HttpAuthService, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { NotAllowedError } from '@backstage/errors'; +import { parse as parseCookie } from 'cookie'; +import { Handler, Request, Response } from 'express'; +import { decodeJwt } from 'jose'; +import { toInternalBackstageCredentials } from '../auth/authServiceFactory'; + +const BACKSTAGE_AUTH_COOKIE = 'backstage-auth'; + +function getTokenFromRequest(req: Request) { + // TODO: support multiple auth headers (iterate rawHeaders) + const authHeader = req.headers.authorization; + if (typeof authHeader === 'string') { + const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i); + const token = matches?.[1]; + if (token) { + return { token, isCookie: false }; + } + } + + const cookieHeader = req.headers.cookie; + if (cookieHeader) { + const cookies = parseCookie(cookieHeader); + const token = cookies[BACKSTAGE_AUTH_COOKIE]; + if (token) { + return { token, isCookie: true }; + } + } + + return { token: undefined, isCookie: false }; +} + +const credentialsSymbol = Symbol('backstage-credentials'); +// TODO: This is temporary and should be removed once we have proper cookie handling in place +const isCookieSymbol = Symbol('backstage-is-cookie-credentials'); + +type RequestWithCredentials = Request & { + [credentialsSymbol]?: BackstageCredentials | BackstageUnauthorizedCredentials; + [isCookieSymbol]?: boolean; +}; + +function createUnauthorizedCredentials(): BackstageUnauthorizedCredentials { + return { + $$type: '@backstage/BackstageCredentials', + type: 'unauthorized', + }; +} + +class DefaultHttpAuthService implements HttpAuthService { + constructor( + private readonly auth: AuthService, + private readonly discovery: DiscoveryService, + private readonly pluginId: string, + ) {} + + createHttpPluginRouterMiddleware(): Handler { + return async (req: RequestWithCredentials, _res, next) => { + try { + const { token, isCookie } = getTokenFromRequest(req); + // TODO: Is this where we match against configured rules? + if (!token) { + req[credentialsSymbol] = createUnauthorizedCredentials(); + } else { + req[credentialsSymbol] = await this.auth.authenticate(token); + req[isCookieSymbol] = isCookie; + } + next(); + } catch (e) { + next(e); + } + }; + } + + async credentials( + req: RequestWithCredentials, + options: { + allow: TAllowed[]; + }, + ): Promise { + const credentials = req[credentialsSymbol]; + if (!credentials) { + throw new Error('Internal error, no credentials found on request'); + } + + if (credentials.type === 'user' && req[isCookieSymbol]) { + if (options.allow.includes('user-cookie' as TAllowed)) { + return credentials as BackstageCredentialTypes[TAllowed]; + } + throw new NotAllowedError( + `This endpoint does not allow 'user-cookie' credentials`, + ); + } + + if (!options.allow.includes(credentials.type as TAllowed)) { + throw new NotAllowedError( + `This endpoint does not allow '${credentials.type}' credentials`, + ); + } + + return credentials as BackstageCredentialTypes[TAllowed]; + } + + async requestHeaders(options?: { + forward?: BackstageCredentials; + }): Promise> { + return { + Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, + }; + } + + async issueUserCookie(res: Response): Promise { + const credentials = await this.credentials(res.req, { allow: ['user'] }); + + // https://backstage.spotify.net/api/catalog + const externalBaseUrlStr = await this.discovery.getExternalBaseUrl( + this.pluginId, + ); + const externalBaseUrl = new URL(externalBaseUrlStr); + + const { token } = toInternalBackstageCredentials(credentials); + + // TODO: Proper refresh and expiration handling + const expires = decodeJwt(token).exp!; + + // TODO: refresh this thing + res.cookie(BACKSTAGE_AUTH_COOKIE, token, { + domain: externalBaseUrl.hostname, + httpOnly: true, + expires: new Date(expires * 1000), + path: externalBaseUrl.pathname, + priority: 'high', + sameSite: 'lax', // TBD + }); + throw new Error('Method not implemented.'); + } +} + +/** @public */ +export const httpAuthServiceFactory = createServiceFactory({ + service: coreServices.httpAuth, + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + discovery: coreServices.discovery, + auth: coreServices.auth, + plugin: coreServices.pluginMetadata, + }, + async factory({ auth, discovery, plugin }) { + return new DefaultHttpAuthService(auth, discovery, plugin.getId()); + }, +}); diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/index.ts b/packages/backend-app-api/src/services/implementations/httpAuth/index.ts new file mode 100644 index 0000000000..edd7e53026 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/httpAuth/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { httpAuthServiceFactory } from './httpAuthServiceFactory'; diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts index 2ecdeffd77..710accbadb 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts @@ -17,10 +17,12 @@ import { coreServices, createServiceFactory, + HttpRouterServiceAuthPolicy, } from '@backstage/backend-plugin-api'; import { Handler } from 'express'; import PromiseRouter from 'express-promise-router'; import { createLifecycleMiddleware } from './createLifecycleMiddleware'; +import { createCredentialsBarrier } from './createCredentialsBarrier'; /** * @public @@ -40,20 +42,28 @@ export const httpRouterServiceFactory = createServiceFactory( plugin: coreServices.pluginMetadata, lifecycle: coreServices.lifecycle, rootHttpRouter: coreServices.rootHttpRouter, + httpAuth: coreServices.httpAuth, }, - async factory({ plugin, rootHttpRouter, lifecycle }) { + async factory({ httpAuth, plugin, rootHttpRouter, lifecycle }) { const getPath = options?.getPath ?? (id => `/api/${id}`); const path = getPath(plugin.getId()); const router = PromiseRouter(); rootHttpRouter.use(path, router); + const credentialsBarrier = createCredentialsBarrier({ httpAuth }); + router.use(createLifecycleMiddleware({ lifecycle })); + router.use(httpAuth.createHttpPluginRouterMiddleware()); + router.use(credentialsBarrier.middleware); return { - use(handler: Handler) { + use(handler: Handler): void { router.use(handler); }, + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { + credentialsBarrier.addAuthPolicy(policy); + }, }; }, }), diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index 9d42dbfef7..e038a13224 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -19,6 +19,7 @@ export * from './cache'; export * from './config'; export * from './database'; export * from './discovery'; +export * from './httpAuth'; export * from './httpRouter'; export * from './identity'; export * from './lifecycle'; diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 52f52afaa9..68dff04e48 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -14,6 +14,8 @@ import { Knex } from 'knex'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { Readable } from 'stream'; +import { Request as Request_2 } from 'express'; +import { Response as Response_2 } from 'express'; // @public (undocumented) export interface AuthService { @@ -91,6 +93,14 @@ export type BackstageCredentials = | BackstageUserCredentials | BackstageServiceCredentials; +// @public (undocumented) +export type BackstageCredentialTypes = { + user: BackstageUserCredentials; + 'user-cookie': BackstageUserCredentials; + service: BackstageServiceCredentials; + unauthorized: BackstageUnauthorizedCredentials; +}; + // @public (undocumented) export type BackstageServiceCredentials = { $$type: '@backstage/BackstageCredentials'; @@ -98,6 +108,12 @@ export type BackstageServiceCredentials = { subject: string; }; +// @public (undocumented) +export type BackstageUnauthorizedCredentials = { + $$type: '@backstage/BackstageCredentials'; + type: 'unauthorized'; +}; + // @public (undocumented) export type BackstageUserCredentials = { $$type: '@backstage/BackstageCredentials'; @@ -134,6 +150,7 @@ export namespace coreServices { const rootConfig: ServiceRef; const database: ServiceRef; const discovery: ServiceRef; + const httpAuth: ServiceRef; const httpRouter: ServiceRef; const lifecycle: ServiceRef; const logger: ServiceRef; @@ -252,6 +269,25 @@ export interface ExtensionPointConfig { id: string; } +// @public (undocumented) +export interface HttpAuthService { + // (undocumented) + createHttpPluginRouterMiddleware(): Handler; + // (undocumented) + credentials( + req: Request_2, + options: { + allow: Array; + }, + ): Promise; + // (undocumented) + issueUserCookie(res: Response_2): Promise; + // (undocumented) + requestHeaders(options?: { + forward?: BackstageCredentials; + }): Promise>; +} + // @public (undocumented) export interface HttpRouterService { // (undocumented) diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts new file mode 100644 index 0000000000..817ca8691b --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Request, Response, Handler } from 'express'; +import { + BackstageUserCredentials, + BackstageServiceCredentials, + BackstageCredentials, +} from './AuthService'; + +/** @public */ +export type BackstageUnauthorizedCredentials = { + $$type: '@backstage/BackstageCredentials'; + + type: 'unauthorized'; +}; + +/** @public */ +export type BackstageCredentialTypes = { + user: BackstageUserCredentials; + 'user-cookie': BackstageUserCredentials; + service: BackstageServiceCredentials; + unauthorized: BackstageUnauthorizedCredentials; +}; + +/** @public */ +export interface HttpAuthService { + createHttpPluginRouterMiddleware(): Handler; + + credentials( + req: Request, + options: { + allow: Array; + }, + ): Promise; + + // TODO: Keep an eye on this, might not be needed + requestHeaders(options?: { + forward?: BackstageCredentials; + }): Promise>; + + issueUserCookie(res: Response): Promise; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index 561a587e5e..c9cadd84c8 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -67,6 +67,15 @@ export namespace coreServices { import('./DiscoveryService').DiscoveryService >({ id: 'core.discovery' }); + /** + * The service reference for the plugin scoped {@link HttpAuthService}. + * + * @public + */ + export const httpAuth = createServiceRef< + import('./HttpAuthService').HttpAuthService + >({ id: 'core.httpAuth' }); + /** * The service reference for the plugin scoped {@link HttpRouterService}. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 8a53399be6..843269c3ee 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -30,6 +30,11 @@ export type { RootConfigService } from './RootConfigService'; export type { DatabaseService } from './DatabaseService'; export type { DiscoveryService } from './DiscoveryService'; export type { HttpRouterService } from './HttpRouterService'; +export type { + HttpAuthService, + BackstageCredentialTypes, + BackstageUnauthorizedCredentials, +} from './HttpAuthService'; export type { LifecycleService, LifecycleServiceStartupHook, diff --git a/yarn.lock b/yarn.lock index 555b683cd0..202aa50d88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3244,6 +3244,7 @@ __metadata: "@types/node-forge": ^1.3.0 "@types/stoppable": ^1.1.0 compression: ^1.7.4 + cookie: ^0.6.0 cors: ^2.8.5 express: ^4.17.1 express-promise-router: ^4.1.0 @@ -23958,7 +23959,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0, cookie@npm:~0.6.0": +"cookie@npm:0.6.0, cookie@npm:^0.6.0, cookie@npm:~0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 From 746701e094f341b47732a9f8ddbacd5dba3dd70e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 9 Feb 2024 13:03:06 +0100 Subject: [PATCH 04/76] backend-{plugin,app}-api: add UserInfoService + initial implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-app-api/api-report.md | 7 +++ .../src/services/implementations/index.ts | 1 + .../implementations/userInfo/index.ts | 17 ++++++ .../userInfo/userInfoServiceFactory.ts | 58 +++++++++++++++++++ packages/backend-plugin-api/api-report.md | 17 ++++++ .../services/definitions/UserInfoService.ts | 30 ++++++++++ .../src/services/definitions/coreServices.ts | 11 ++++ .../src/services/definitions/index.ts | 1 + 8 files changed, 142 insertions(+) create mode 100644 packages/backend-app-api/src/services/implementations/userInfo/index.ts create mode 100644 packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts create mode 100644 packages/backend-plugin-api/src/services/definitions/UserInfoService.ts diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index e4a3d3d6de..52780c6729 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -42,6 +42,7 @@ import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; import { UrlReader } from '@backstage/backend-common'; +import { UserInfoService } from '@backstage/backend-plugin-api'; // @public (undocumented) export const authServiceFactory: () => ServiceFactory; @@ -333,6 +334,12 @@ export const tokenManagerServiceFactory: () => ServiceFactory< // @public (undocumented) export const urlReaderServiceFactory: () => ServiceFactory; +// @public (undocumented) +export const userInfoServiceFactory: () => ServiceFactory< + UserInfoService, + 'plugin' +>; + // @public export class WinstonLogger implements RootLoggerService { // (undocumented) diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index e038a13224..a1114ab3e3 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -31,3 +31,4 @@ export * from './rootLogger'; export * from './scheduler'; export * from './tokenManager'; export * from './urlReader'; +export * from './userInfo'; diff --git a/packages/backend-app-api/src/services/implementations/userInfo/index.ts b/packages/backend-app-api/src/services/implementations/userInfo/index.ts new file mode 100644 index 0000000000..13b42f053c --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/userInfo/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { userInfoServiceFactory } from './userInfoServiceFactory'; diff --git a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts new file mode 100644 index 0000000000..a177f2442b --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BackstageUserCredentials, + UserInfoService, + BackstageUserInfo, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { toInternalBackstageCredentials } from '../auth/authServiceFactory'; +import { decodeJwt } from 'jose'; + +// TODO: The intention is for this to eventually be replaced by a call to the auth-backend +export class DefaultUserInfoService implements UserInfoService { + async getUserInfo( + credentials: BackstageUserCredentials, + ): Promise { + const internalCredentials = toInternalBackstageCredentials(credentials); + if (internalCredentials.type !== 'user') { + throw new Error('Only user credentials are supported'); + } + const { sub: userEntityRef, ent: ownershipEntityRefs = [] } = decodeJwt( + internalCredentials.token, + ); + + if (typeof userEntityRef !== 'string') { + throw new Error('User entity ref must be a string'); + } + if (!Array.isArray(ownershipEntityRefs)) { + throw new Error('Ownership entity refs must be an array'); + } + + return { userEntityRef, ownershipEntityRefs }; + } +} + +/** @public */ +export const userInfoServiceFactory = createServiceFactory({ + service: coreServices.userInfo, + deps: {}, + async factory() { + return new DefaultUserInfoService(); + }, +}); diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 68dff04e48..d49eefd8f2 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -121,6 +121,14 @@ export type BackstageUserCredentials = { userEntityRef: string; }; +// @public (undocumented) +export interface BackstageUserInfo { + // (undocumented) + ownershipEntityRefs: string[]; + // (undocumented) + userEntityRef: string; +} + // @public export interface CacheService { delete(key: string): Promise; @@ -146,6 +154,7 @@ export type CacheServiceSetOptions = { // @public export namespace coreServices { const auth: ServiceRef; + const userInfo: ServiceRef; const cache: ServiceRef; const rootConfig: ServiceRef; const database: ServiceRef; @@ -524,4 +533,12 @@ export interface UrlReaderService { readUrl(url: string, options?: ReadUrlOptions): Promise; search(url: string, options?: SearchOptions): Promise; } + +// @public (undocumented) +export interface UserInfoService { + // (undocumented) + getUserInfo( + credentials: BackstageUserCredentials, + ): Promise; +} ``` diff --git a/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts new file mode 100644 index 0000000000..b789116ffb --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BackstageUserCredentials } from './AuthService'; + +/** @public */ +export interface BackstageUserInfo { + userEntityRef: string; + ownershipEntityRefs: string[]; +} + +/** @public */ +export interface UserInfoService { + getUserInfo( + credentials: BackstageUserCredentials, + ): Promise; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index c9cadd84c8..a7c9d09445 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -31,6 +31,17 @@ export namespace coreServices { id: 'core.auth', }); + /** + * The service reference for the plugin scoped {@link UserInfoService}. + * + * @public + */ + export const userInfo = createServiceRef< + import('./UserInfoService').UserInfoService + >({ + id: 'core.userInfo', + }); + /** * The service reference for the plugin scoped {@link CacheService}. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 843269c3ee..294bed1eb1 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -62,4 +62,5 @@ export type { SearchResponseFile, UrlReaderService, } from './UrlReaderService'; +export type { BackstageUserInfo, UserInfoService } from './UserInfoService'; export type { IdentityService } from './IdentityService'; From 344a82b4e5d52afba86a661f7133b035b4c8bd23 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 9 Feb 2024 13:04:48 +0100 Subject: [PATCH 05/76] backend-{plugin,app}-api: added addAuthPolicy to HttpRouterService + implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-app-api/package.json | 1 + .../httpRouter/createCredentialsBarrier.ts | 89 +++++++++++++++++++ packages/backend-plugin-api/api-report.md | 10 +++ .../services/definitions/HttpRouterService.ts | 8 ++ .../src/services/definitions/index.ts | 5 +- .../src/next/services/mockServices.ts | 1 + yarn.lock | 9 +- 7 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 52378fef37..d5985d1172 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -73,6 +73,7 @@ "minimist": "^1.2.5", "morgan": "^1.10.0", "node-forge": "^1.3.1", + "path-to-regexp": "^6.2.1", "selfsigned": "^2.0.0", "stoppable": "^1.1.0", "winston": "^3.2.1", diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts new file mode 100644 index 0000000000..c502dc25e5 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts @@ -0,0 +1,89 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + HttpAuthService, + HttpRouterServiceAuthPolicy, +} from '@backstage/backend-plugin-api'; +import { RequestHandler } from 'express'; +import { pathToRegexp } from 'path-to-regexp'; + +export function createPathPolicyPredicate(policyPath: string) { + if (policyPath === '/' || policyPath === '*') { + return () => true; + } + + const pathRegex = pathToRegexp(policyPath, undefined, { + end: false, + }); + + return (path: string): boolean => { + return pathRegex.test(path); + }; +} + +export function createCredentialsBarrier(options: { + httpAuth: HttpAuthService; +}): { + middleware: RequestHandler; + addAuthPolicy: (policy: HttpRouterServiceAuthPolicy) => void; +} { + const { httpAuth } = options; + + const unauthenticatedPredicates = new Array<(path: string) => boolean>(); + const cookiePredicates = new Array<(path: string) => boolean>(); + + const middleware: RequestHandler = async (req, _, next) => { + const allowsUnauthenticated = unauthenticatedPredicates.some(predicate => + predicate(req.path), + ); + + if (allowsUnauthenticated) { + next(); + return; + } + + const allowsCookie = cookiePredicates.some(predicate => + predicate(req.path), + ); + + if (allowsCookie) { + // don't we need a user-cookie allow type here? + await httpAuth.credentials(req, { + allow: ['user-cookie', 'user', 'service'], + }); + next(); + return; + } + + await httpAuth.credentials(req, { + allow: ['user', 'service'], + }); + next(); + }; + + const addAuthPolicy = (policy: HttpRouterServiceAuthPolicy) => { + if (policy.allow === 'unauthenticated') { + unauthenticatedPredicates.push(createPathPolicyPredicate(policy.path)); + } else if (policy.allow === 'user-cookie') { + cookiePredicates.push(createPathPolicyPredicate(policy.path)); + } + + throw new Error('Invalid auth policy'); + }; + + return { middleware, addAuthPolicy }; +} diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index d49eefd8f2..302a3d37d4 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -299,10 +299,20 @@ export interface HttpAuthService { // @public (undocumented) export interface HttpRouterService { + // (undocumented) + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void; // (undocumented) use(handler: Handler): void; } +// @public (undocumented) +export interface HttpRouterServiceAuthPolicy { + // (undocumented) + allow: 'unauthenticated' | 'user-cookie'; + // (undocumented) + path: string; +} + // @public (undocumented) export interface IdentityService extends IdentityApi {} diff --git a/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts b/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts index 3c45ef1da1..695b337754 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts @@ -16,9 +16,17 @@ import { Handler } from 'express'; +/** @public */ +export interface HttpRouterServiceAuthPolicy { + path: string; + allow: 'unauthenticated' | 'user-cookie'; +} + /** * @public */ export interface HttpRouterService { use(handler: Handler): void; + + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void; } diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 294bed1eb1..420c722a4d 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -29,7 +29,10 @@ export type { export type { RootConfigService } from './RootConfigService'; export type { DatabaseService } from './DatabaseService'; export type { DiscoveryService } from './DiscoveryService'; -export type { HttpRouterService } from './HttpRouterService'; +export type { + HttpRouterService, + HttpRouterServiceAuthPolicy, +} from './HttpRouterService'; export type { HttpAuthService, BackstageCredentialTypes, diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index bd684f7560..78f59b53c4 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -182,6 +182,7 @@ export namespace mockServices { export const factory = httpRouterServiceFactory; export const mock = simpleMock(coreServices.httpRouter, () => ({ use: jest.fn(), + addAuthPolicy: jest.fn(), })); } export namespace rootHttpRouter { diff --git a/yarn.lock b/yarn.lock index 202aa50d88..6d841a09db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3258,6 +3258,7 @@ __metadata: minimist: ^1.2.5 morgan: ^1.10.0 node-forge: ^1.3.1 + path-to-regexp: ^6.2.1 selfsigned: ^2.0.0 stoppable: ^1.1.0 supertest: ^6.1.3 @@ -37508,10 +37509,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0": - version: 6.2.0 - resolution: "path-to-regexp@npm:6.2.0" - checksum: a6aca74d2d6e2e7594d812f653cf85e9cb5054d3a8d80f099722a44ef6ad22639b02078e5ea83d11db16321c3e4359e3f1ab0274fa78dad0754a6e53f630b0fc +"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.2.1": + version: 6.2.1 + resolution: "path-to-regexp@npm:6.2.1" + checksum: f0227af8284ea13300f4293ba111e3635142f976d4197f14d5ad1f124aebd9118783dd2e5f1fe16f7273743cc3dbeddfb7493f237bb27c10fdae07020cc9b698 languageName: node linkType: hard From 6a685868ffd6dc11dd10c46bd554e3c34caa8386 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 9 Feb 2024 11:16:25 +0100 Subject: [PATCH 06/76] backend-plugin-api: refactor to remove createHttpPluginRouterMiddleware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../httpAuth/httpAuthServiceFactory.ts | 45 ++++++++----------- .../httpRouter/httpRouterServiceFactory.ts | 1 - .../services/definitions/HttpAuthService.ts | 4 +- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index e2b60e31b2..02b9975a47 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -26,7 +26,7 @@ import { } from '@backstage/backend-plugin-api'; import { NotAllowedError } from '@backstage/errors'; import { parse as parseCookie } from 'cookie'; -import { Handler, Request, Response } from 'express'; +import { Request, Response } from 'express'; import { decodeJwt } from 'jose'; import { toInternalBackstageCredentials } from '../auth/authServiceFactory'; @@ -56,12 +56,13 @@ function getTokenFromRequest(req: Request) { } const credentialsSymbol = Symbol('backstage-credentials'); -// TODO: This is temporary and should be removed once we have proper cookie handling in place -const isCookieSymbol = Symbol('backstage-is-cookie-credentials'); type RequestWithCredentials = Request & { - [credentialsSymbol]?: BackstageCredentials | BackstageUnauthorizedCredentials; - [isCookieSymbol]?: boolean; + [credentialsSymbol]?: Promise<{ + credentials: BackstageCredentials | BackstageUnauthorizedCredentials; + // TODO: This is temporary and should be removed once we have proper cookie handling in place + isCookie: boolean; + }>; }; function createUnauthorizedCredentials(): BackstageUnauthorizedCredentials { @@ -78,22 +79,17 @@ class DefaultHttpAuthService implements HttpAuthService { private readonly pluginId: string, ) {} - createHttpPluginRouterMiddleware(): Handler { - return async (req: RequestWithCredentials, _res, next) => { - try { - const { token, isCookie } = getTokenFromRequest(req); - // TODO: Is this where we match against configured rules? - if (!token) { - req[credentialsSymbol] = createUnauthorizedCredentials(); - } else { - req[credentialsSymbol] = await this.auth.authenticate(token); - req[isCookieSymbol] = isCookie; - } - next(); - } catch (e) { - next(e); - } - }; + async #getCredentials(req: Request) { + const { token, isCookie } = getTokenFromRequest(req); + // TODO: Is this where we match against configured rules? + if (!token) { + return { credentials: createUnauthorizedCredentials(), isCookie }; + } + return { credentials: await this.auth.authenticate(token), isCookie }; + } + + async #getCredentialsCached(req: /* */ RequestWithCredentials) { + return (req[credentialsSymbol] ??= this.#getCredentials(req)); } async credentials( @@ -102,12 +98,9 @@ class DefaultHttpAuthService implements HttpAuthService { allow: TAllowed[]; }, ): Promise { - const credentials = req[credentialsSymbol]; - if (!credentials) { - throw new Error('Internal error, no credentials found on request'); - } + const { credentials, isCookie } = await this.#getCredentialsCached(req); - if (credentials.type === 'user' && req[isCookieSymbol]) { + if (credentials.type === 'user' && isCookie) { if (options.allow.includes('user-cookie' as TAllowed)) { return credentials as BackstageCredentialTypes[TAllowed]; } diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts index 710accbadb..6c89834f2b 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts @@ -54,7 +54,6 @@ export const httpRouterServiceFactory = createServiceFactory( const credentialsBarrier = createCredentialsBarrier({ httpAuth }); router.use(createLifecycleMiddleware({ lifecycle })); - router.use(httpAuth.createHttpPluginRouterMiddleware()); router.use(credentialsBarrier.middleware); return { diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index 817ca8691b..d5c5cb9613 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Request, Response, Handler } from 'express'; +import { Request, Response } from 'express'; import { BackstageUserCredentials, BackstageServiceCredentials, @@ -38,8 +38,6 @@ export type BackstageCredentialTypes = { /** @public */ export interface HttpAuthService { - createHttpPluginRouterMiddleware(): Handler; - credentials( req: Request, options: { From a19ef483f14a8930c130c493d10788ab1004d4c4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 10 Feb 2024 09:53:37 +0100 Subject: [PATCH 07/76] backend-{plugin,app}-api: refactored auth APIs to use principals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../auth/authServiceFactory.test.ts | 43 ++++--- .../auth/authServiceFactory.ts | 104 ++++++++++----- .../httpAuth/httpAuthServiceFactory.ts | 121 +++++++++++------- .../userInfo/userInfoServiceFactory.ts | 9 +- packages/backend-plugin-api/api-report.md | 84 +++++++----- .../src/services/definitions/AuthService.ts | 51 ++++++-- .../services/definitions/HttpAuthService.ts | 39 +++--- .../services/definitions/UserInfoService.ts | 6 +- .../src/services/definitions/index.ts | 9 +- 9 files changed, 296 insertions(+), 170 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts index 9dc64212de..64c2bed2a9 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts @@ -19,12 +19,15 @@ import { mockServices, } from '@backstage/backend-test-utils'; import { - InternalBackstageServiceCredentials, - InternalBackstageUserCredentials, + InternalBackstageCredentials, authServiceFactory, } from './authServiceFactory'; import { decodeJwt } from 'jose'; import { discoveryServiceFactory } from '../discovery'; +import { + BackstageServicePrincipal, + BackstageUserPrincipal, +} from '@backstage/backend-plugin-api'; // TODO: Ship discovery mock service in the service factory tester const mockDeps = [ @@ -48,18 +51,22 @@ describe('authServiceFactory', () => { const searchAuth = await tester.get('search'); const catalogAuth = await tester.get('catalog'); - const { token: searchToken } = await searchAuth.issueServiceToken(); + const { token: searchToken } = await searchAuth.issueToken({}); await expect(searchAuth.authenticate(searchToken)).resolves.toEqual( expect.objectContaining({ - type: 'service', - subject: 'external:backstage-plugin', + principal: { + type: 'service', + subject: 'external:backstage-plugin', + }, }), ); await expect(catalogAuth.authenticate(searchToken)).resolves.toEqual( expect.objectContaining({ - type: 'service', - subject: 'external:backstage-plugin', + principal: { + type: 'service', + subject: 'external:backstage-plugin', + }, }), ); }); @@ -72,14 +79,17 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); await expect( - catalogAuth.issueServiceToken({ + catalogAuth.issueToken({ forward: { $$type: '@backstage/BackstageCredentials', version: 'v1', - type: 'user', - userEntityRef: 'user:default/alice', + authMethod: 'token', token: 'alice-token', - } as InternalBackstageUserCredentials, + principal: { + type: 'user', + userEntityRef: 'user:default/alice', + }, + } as InternalBackstageCredentials, }), ).resolves.toEqual({ token: 'alice-token' }); }); @@ -91,14 +101,17 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); - const { token } = await catalogAuth.issueServiceToken({ + const { token } = await catalogAuth.issueToken({ forward: { $$type: '@backstage/BackstageCredentials', version: 'v1', - type: 'service', - subject: 'external:backstage-plugin', + authMethod: 'token', token: 'some-upstream-service-token', - } as InternalBackstageServiceCredentials, + principal: { + type: 'service', + subject: 'external:upstream-service', + }, + } as InternalBackstageCredentials, }); expect(decodeJwt(token)).toEqual( diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index a21829b228..5190b90e7e 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -18,8 +18,10 @@ import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; import { AuthService, BackstageCredentials, - BackstageServiceCredentials, - BackstageUserCredentials, + BackstagePrincipalTypes, + BackstageServicePrincipal, + BackstageNonePrincipal, + BackstageUserPrincipal, IdentityService, coreServices, createServiceFactory, @@ -32,58 +34,76 @@ import { import { decodeJwt } from 'jose'; /** @internal */ -export type InternalBackstageServiceCredentials = - BackstageServiceCredentials & { +export type InternalBackstageCredentials = + BackstageCredentials & { version: string; - token: string; + token?: string; + authMethod: 'token' | 'cookie' | 'none'; }; -function createServiceCredentials( +export function createCredentialsWithServicePrincipal( sub: string, token: string, -): BackstageServiceCredentials { +): InternalBackstageCredentials { return { $$type: '@backstage/BackstageCredentials', version: 'v1', token, - type: 'service', - subject: sub, - } as InternalBackstageServiceCredentials; + principal: { + type: 'service', + subject: sub, + }, + authMethod: 'token', + }; } -/** @internal */ -export type InternalBackstageUserCredentials = BackstageUserCredentials & { - version: string; - token: string; -}; - -function createUserCredentials( +export function createCredentialsWithUserPrincipal( sub: string, token: string, -): BackstageUserCredentials { + authMethod: 'token' | 'cookie' = 'token', +): InternalBackstageCredentials { return { $$type: '@backstage/BackstageCredentials', version: 'v1', token, - type: 'user', - userEntityRef: sub, - } as InternalBackstageUserCredentials; + principal: { + type: 'user', + userEntityRef: sub, + }, + authMethod, + }; +} + +export function createCredentialsWithNonePrincipal(): InternalBackstageCredentials { + return { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + principal: { + type: 'none', + }, + authMethod: 'none', + }; } export function toInternalBackstageCredentials( credentials: BackstageCredentials, -): InternalBackstageServiceCredentials | InternalBackstageUserCredentials { +): InternalBackstageCredentials< + BackstageUserPrincipal | BackstageServicePrincipal | BackstageNonePrincipal +> { if (credentials.$$type !== '@backstage/BackstageCredentials') { throw new Error('Invalid credential type'); } - const internalCredentials = credentials as - | InternalBackstageServiceCredentials - | InternalBackstageUserCredentials; + + const internalCredentials = credentials as InternalBackstageCredentials< + BackstageUserPrincipal | BackstageServicePrincipal | BackstageNonePrincipal + >; + if (internalCredentials.version !== 'v1') { throw new Error( `Invalid credential version ${internalCredentials.version}`, ); } + return internalCredentials; } @@ -100,7 +120,10 @@ class DefaultAuthService implements AuthService { // Legacy service-to-service token if (sub === 'backstage-server' && !aud) { await this.tokenManager.authenticate(token); - return createServiceCredentials('external:backstage-plugin', token); + return createCredentialsWithServicePrincipal( + 'external:backstage-plugin', + token, + ); } // User Backstage token @@ -111,21 +134,42 @@ class DefaultAuthService implements AuthService { } as IdentityApiGetIdentityRequest); if (!identity) { - throw new AuthenticationError('No identity found'); + throw new AuthenticationError('Invalid user token'); } - return createUserCredentials(identity.identity.userEntityRef, token); + return createCredentialsWithUserPrincipal( + identity.identity.userEntityRef, + token, + ); } - async issueServiceToken(options?: { + isPrincipal( + credentials: BackstageCredentials, + type: TType, + ): credentials is BackstageCredentials { + const principal = credentials.principal as + | BackstageUserPrincipal + | BackstageServicePrincipal; + + if (principal.type !== type) { + return false; + } + + return true; + } + + async issueToken(options?: { forward?: BackstageCredentials; }): Promise<{ token: string }> { const internalForward = options?.forward && toInternalBackstageCredentials(options.forward); if (internalForward) { - const { type } = internalForward; + const { type } = internalForward.principal; if (type === 'user') { + if (!internalForward.token) { + throw new Error('User credentials is unexpectedly missing token'); + } return { token: internalForward.token }; } else if (type !== 'service') { throw new AuthenticationError( diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 02b9975a47..c7525acebb 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -16,19 +16,21 @@ import { AuthService, - BackstageCredentialTypes, BackstageCredentials, - BackstageUnauthorizedCredentials, + BackstageHttpAccessToPrincipalTypesMapping, DiscoveryService, HttpAuthService, coreServices, createServiceFactory, } from '@backstage/backend-plugin-api'; -import { NotAllowedError } from '@backstage/errors'; +import { AuthenticationError, NotAllowedError } from '@backstage/errors'; import { parse as parseCookie } from 'cookie'; import { Request, Response } from 'express'; import { decodeJwt } from 'jose'; -import { toInternalBackstageCredentials } from '../auth/authServiceFactory'; +import { + createCredentialsWithNonePrincipal, + toInternalBackstageCredentials, +} from '../auth/authServiceFactory'; const BACKSTAGE_AUTH_COOKIE = 'backstage-auth'; @@ -58,20 +60,9 @@ function getTokenFromRequest(req: Request) { const credentialsSymbol = Symbol('backstage-credentials'); type RequestWithCredentials = Request & { - [credentialsSymbol]?: Promise<{ - credentials: BackstageCredentials | BackstageUnauthorizedCredentials; - // TODO: This is temporary and should be removed once we have proper cookie handling in place - isCookie: boolean; - }>; + [credentialsSymbol]?: Promise; }; -function createUnauthorizedCredentials(): BackstageUnauthorizedCredentials { - return { - $$type: '@backstage/BackstageCredentials', - type: 'unauthorized', - }; -} - class DefaultHttpAuthService implements HttpAuthService { constructor( private readonly auth: AuthService, @@ -79,63 +70,94 @@ class DefaultHttpAuthService implements HttpAuthService { private readonly pluginId: string, ) {} - async #getCredentials(req: Request) { + async #extractCredentialsFromRequest(req: Request) { const { token, isCookie } = getTokenFromRequest(req); - // TODO: Is this where we match against configured rules? if (!token) { - return { credentials: createUnauthorizedCredentials(), isCookie }; + return createCredentialsWithNonePrincipal(); } - return { credentials: await this.auth.authenticate(token), isCookie }; - } - async #getCredentialsCached(req: /* */ RequestWithCredentials) { - return (req[credentialsSymbol] ??= this.#getCredentials(req)); - } - - async credentials( - req: RequestWithCredentials, - options: { - allow: TAllowed[]; - }, - ): Promise { - const { credentials, isCookie } = await this.#getCredentialsCached(req); - - if (credentials.type === 'user' && isCookie) { - if (options.allow.includes('user-cookie' as TAllowed)) { - return credentials as BackstageCredentialTypes[TAllowed]; + const credentials = toInternalBackstageCredentials( + await this.auth.authenticate(token), + ); + if (isCookie) { + if (credentials.principal.type !== 'user') { + throw new AuthenticationError( + 'Refusing to authenticate non-user principal with cookie auth', + ); } - throw new NotAllowedError( - `This endpoint does not allow 'user-cookie' credentials`, - ); + credentials.authMethod = 'cookie'; } - if (!options.allow.includes(credentials.type as TAllowed)) { - throw new NotAllowedError( - `This endpoint does not allow '${credentials.type}' credentials`, - ); - } - - return credentials as BackstageCredentialTypes[TAllowed]; + return credentials; } - async requestHeaders(options?: { + async #getCredentials(req: /* */ RequestWithCredentials) { + return (req[credentialsSymbol] ??= + this.#extractCredentialsFromRequest(req)); + } + + async credentials< + TAllowed extends + | keyof BackstageHttpAccessToPrincipalTypesMapping + | undefined = undefined, + >( + req: Request, + options?: { + allow: Array; + }, + ): Promise< + BackstageCredentials< + TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping + ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] + : unknown + > + > { + const credentials = toInternalBackstageCredentials( + await this.#getCredentials(req), + ); + + // TODO break out into more readable function as we always + // want to check cookie regardless if options are set or not + // Probably asserts function that ensures authMethod = 'token' after cookie check + if (credentials.authMethod === 'cookie') { + if (options && !options.allow.includes('user-cookie' as TAllowed)) { + throw new NotAllowedError( + `This endpoint does not allow 'user-cookie' credentials`, + ); + } + } else if ( + options && + !options.allow.includes(credentials.principal.type as TAllowed) + ) { + throw new NotAllowedError( + `This endpoint does not allow '${credentials.principal.type}' credentials`, + ); + } + + return credentials as any; + } + + async requestHeaders(options: { forward?: BackstageCredentials; }): Promise> { return { - Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, + Authorization: `Bearer ${await this.auth.issueToken(options)}`, }; } async issueUserCookie(res: Response): Promise { const credentials = await this.credentials(res.req, { allow: ['user'] }); - // https://backstage.spotify.net/api/catalog + // https://backstage.example.com/api/catalog const externalBaseUrlStr = await this.discovery.getExternalBaseUrl( this.pluginId, ); const externalBaseUrl = new URL(externalBaseUrlStr); const { token } = toInternalBackstageCredentials(credentials); + if (!token) { + throw new Error('User credentials is unexpectedly missing token'); + } // TODO: Proper refresh and expiration handling const expires = decodeJwt(token).exp!; @@ -149,6 +171,7 @@ class DefaultHttpAuthService implements HttpAuthService { priority: 'high', sameSite: 'lax', // TBD }); + throw new Error('Method not implemented.'); } } diff --git a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts index a177f2442b..a74b8b7002 100644 --- a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts @@ -15,11 +15,11 @@ */ import { - BackstageUserCredentials, UserInfoService, BackstageUserInfo, coreServices, createServiceFactory, + BackstageCredentials, } from '@backstage/backend-plugin-api'; import { toInternalBackstageCredentials } from '../auth/authServiceFactory'; import { decodeJwt } from 'jose'; @@ -27,12 +27,15 @@ import { decodeJwt } from 'jose'; // TODO: The intention is for this to eventually be replaced by a call to the auth-backend export class DefaultUserInfoService implements UserInfoService { async getUserInfo( - credentials: BackstageUserCredentials, + credentials: BackstageCredentials, ): Promise { const internalCredentials = toInternalBackstageCredentials(credentials); - if (internalCredentials.type !== 'user') { + if (internalCredentials.principal.type !== 'user') { throw new Error('Only user credentials are supported'); } + if (!internalCredentials.token) { + throw new Error('User credentials is unexpectedly missing token'); + } const { sub: userEntityRef, ent: ownershipEntityRefs = [] } = decodeJwt( internalCredentials.token, ); diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 302a3d37d4..81579fb0e9 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -22,7 +22,12 @@ export interface AuthService { // (undocumented) authenticate(token: string): Promise; // (undocumented) - issueServiceToken(options?: { forward?: BackstageCredentials }): Promise<{ + isPrincipal( + credentials: BackstageCredentials, + type: TType, + ): credentials is BackstageCredentials; + // (undocumented) + issueToken(options: { forward?: BackstageCredentials }): Promise<{ token: string; }>; } @@ -89,36 +94,35 @@ export interface BackendPluginRegistrationPoints { } // @public (undocumented) -export type BackstageCredentials = - | BackstageUserCredentials - | BackstageServiceCredentials; - -// @public (undocumented) -export type BackstageCredentialTypes = { - user: BackstageUserCredentials; - 'user-cookie': BackstageUserCredentials; - service: BackstageServiceCredentials; - unauthorized: BackstageUnauthorizedCredentials; +export type BackstageCredentials = { + $$type: '@backstage/BackstageCredentials'; + principal: TPrincipal; }; // @public (undocumented) -export type BackstageServiceCredentials = { - $$type: '@backstage/BackstageCredentials'; +export type BackstageHttpAccessToPrincipalTypesMapping = { + user: BackstageUserPrincipal; + 'user-cookie': BackstageUserPrincipal; + service: BackstageServicePrincipal; + unauthenticated: BackstageNonePrincipal; +}; + +// @public (undocumented) +export type BackstageNonePrincipal = { + type: 'none'; +}; + +// @public (undocumented) +export type BackstagePrincipalTypes = { + user: BackstageUserPrincipal; + service: BackstageServicePrincipal; +}; + +// @public (undocumented) +export type BackstageServicePrincipal = { type: 'service'; subject: string; -}; - -// @public (undocumented) -export type BackstageUnauthorizedCredentials = { - $$type: '@backstage/BackstageCredentials'; - type: 'unauthorized'; -}; - -// @public (undocumented) -export type BackstageUserCredentials = { - $$type: '@backstage/BackstageCredentials'; - type: 'user'; - userEntityRef: string; + permissions?: string[]; }; // @public (undocumented) @@ -129,6 +133,12 @@ export interface BackstageUserInfo { userEntityRef: string; } +// @public (undocumented) +export type BackstageUserPrincipal = { + type: 'user'; + userEntityRef: string; +}; + // @public export interface CacheService { delete(key: string): Promise; @@ -281,14 +291,22 @@ export interface ExtensionPointConfig { // @public (undocumented) export interface HttpAuthService { // (undocumented) - createHttpPluginRouterMiddleware(): Handler; - // (undocumented) - credentials( + credentials< + TAllowed extends + | keyof BackstageHttpAccessToPrincipalTypesMapping + | undefined = undefined, + >( req: Request_2, - options: { + options?: { allow: Array; }, - ): Promise; + ): Promise< + BackstageCredentials< + TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping + ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] + : unknown + > + >; // (undocumented) issueUserCookie(res: Response_2): Promise; // (undocumented) @@ -547,8 +565,6 @@ export interface UrlReaderService { // @public (undocumented) export interface UserInfoService { // (undocumented) - getUserInfo( - credentials: BackstageUserCredentials, - ): Promise; + getUserInfo(credentials: BackstageCredentials): Promise; } ``` diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index d4ab8456a8..8a946e5c91 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -17,9 +17,7 @@ /** * @public */ -export type BackstageUserCredentials = { - $$type: '@backstage/BackstageCredentials'; - +export type BackstageUserPrincipal = { type: 'user'; userEntityRef: string; @@ -28,27 +26,54 @@ export type BackstageUserCredentials = { /** * @public */ -export type BackstageServiceCredentials = { - $$type: '@backstage/BackstageCredentials'; - - type: 'service'; - - subject: string; +export type BackstageNonePrincipal = { + type: 'none'; }; /** * @public */ -export type BackstageCredentials = - | BackstageUserCredentials - | BackstageServiceCredentials; +export type BackstageServicePrincipal = { + type: 'service'; + + // Exact format TBD, possibly 'plugin:' or 'external:' + subject: string; + + // Not implemented in the first iteration, but this is how we might extend this in the future + permissions?: string[]; +}; + +/** + * @public + */ +export type BackstageCredentials = { + $$type: '@backstage/BackstageCredentials'; + + principal: TPrincipal; +}; + +/** + * @public + */ +export type BackstagePrincipalTypes = { + user: BackstageUserPrincipal; + service: BackstageServicePrincipal; +}; /** * @public */ export interface AuthService { authenticate(token: string): Promise; - issueServiceToken(options?: { + + isPrincipal( + credentials: BackstageCredentials, + type: TType, + ): credentials is BackstageCredentials; + + // TODO: should the caller provide the target plugin ID? + // TODO: how can we make it very difficult to forget to forward credentials + issueToken(options: { forward?: BackstageCredentials; }): Promise<{ token: string }>; } diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index d5c5cb9613..f84234932b 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -16,36 +16,39 @@ import { Request, Response } from 'express'; import { - BackstageUserCredentials, - BackstageServiceCredentials, BackstageCredentials, + BackstageServicePrincipal, + BackstageNonePrincipal, + BackstageUserPrincipal, } from './AuthService'; /** @public */ -export type BackstageUnauthorizedCredentials = { - $$type: '@backstage/BackstageCredentials'; - - type: 'unauthorized'; -}; - -/** @public */ -export type BackstageCredentialTypes = { - user: BackstageUserCredentials; - 'user-cookie': BackstageUserCredentials; - service: BackstageServiceCredentials; - unauthorized: BackstageUnauthorizedCredentials; +export type BackstageHttpAccessToPrincipalTypesMapping = { + user: BackstageUserPrincipal; + 'user-cookie': BackstageUserPrincipal; + service: BackstageServicePrincipal; + unauthenticated: BackstageNonePrincipal; }; /** @public */ export interface HttpAuthService { - credentials( + credentials< + TAllowed extends + | keyof BackstageHttpAccessToPrincipalTypesMapping + | undefined = undefined, + >( req: Request, - options: { + options?: { allow: Array; }, - ): Promise; + ): Promise< + BackstageCredentials< + TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping + ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] + : unknown + > + >; - // TODO: Keep an eye on this, might not be needed requestHeaders(options?: { forward?: BackstageCredentials; }): Promise>; diff --git a/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts index b789116ffb..90f5306a58 100644 --- a/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts +++ b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BackstageUserCredentials } from './AuthService'; +import { BackstageCredentials } from './AuthService'; /** @public */ export interface BackstageUserInfo { @@ -24,7 +24,5 @@ export interface BackstageUserInfo { /** @public */ export interface UserInfoService { - getUserInfo( - credentials: BackstageUserCredentials, - ): Promise; + getUserInfo(credentials: BackstageCredentials): Promise; } diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 420c722a4d..810f1754b7 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -18,8 +18,10 @@ export { coreServices } from './coreServices'; export type { AuthService, BackstageCredentials, - BackstageServiceCredentials, - BackstageUserCredentials, + BackstageUserPrincipal, + BackstageServicePrincipal, + BackstagePrincipalTypes, + BackstageNonePrincipal, } from './AuthService'; export type { CacheService, @@ -35,8 +37,7 @@ export type { } from './HttpRouterService'; export type { HttpAuthService, - BackstageCredentialTypes, - BackstageUnauthorizedCredentials, + BackstageHttpAccessToPrincipalTypesMapping, } from './HttpAuthService'; export type { LifecycleService, From 9ae4b9b6c2c2683889bf3fbaf9c77224e380677b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 10 Feb 2024 11:41:17 +0100 Subject: [PATCH 08/76] backend-plugin-api: simplify auth.credentials() types Signed-off-by: Patrik Oldsberg --- .../httpAuth/httpAuthServiceFactory.ts | 9 ++------- packages/backend-plugin-api/api-report.md | 11 +++-------- .../src/services/definitions/HttpAuthService.ts | 14 ++++---------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index c7525acebb..79c74ffa9f 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -98,19 +98,14 @@ class DefaultHttpAuthService implements HttpAuthService { async credentials< TAllowed extends - | keyof BackstageHttpAccessToPrincipalTypesMapping - | undefined = undefined, + | keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', >( req: Request, options?: { allow: Array; }, ): Promise< - BackstageCredentials< - TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping - ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] - : unknown - > + BackstageCredentials > { const credentials = toInternalBackstageCredentials( await this.#getCredentials(req), diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 81579fb0e9..a3e5930375 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -105,6 +105,7 @@ export type BackstageHttpAccessToPrincipalTypesMapping = { 'user-cookie': BackstageUserPrincipal; service: BackstageServicePrincipal; unauthenticated: BackstageNonePrincipal; + unknown: unknown; }; // @public (undocumented) @@ -292,20 +293,14 @@ export interface ExtensionPointConfig { export interface HttpAuthService { // (undocumented) credentials< - TAllowed extends - | keyof BackstageHttpAccessToPrincipalTypesMapping - | undefined = undefined, + TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', >( req: Request_2, options?: { allow: Array; }, ): Promise< - BackstageCredentials< - TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping - ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] - : unknown - > + BackstageCredentials >; // (undocumented) issueUserCookie(res: Response_2): Promise; diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index f84234932b..949ca1af0a 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -28,25 +28,19 @@ export type BackstageHttpAccessToPrincipalTypesMapping = { 'user-cookie': BackstageUserPrincipal; service: BackstageServicePrincipal; unauthenticated: BackstageNonePrincipal; + unknown: unknown; }; /** @public */ export interface HttpAuthService { credentials< TAllowed extends - | keyof BackstageHttpAccessToPrincipalTypesMapping - | undefined = undefined, + | keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', >( req: Request, - options?: { - allow: Array; - }, + options?: { allow: Array }, ): Promise< - BackstageCredentials< - TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping - ? BackstageHttpAccessToPrincipalTypesMapping[TAllowed] - : unknown - > + BackstageCredentials >; requestHeaders(options?: { From c599fe1f7ba752d481809fffe7f82baffd91c615 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 10 Feb 2024 12:04:11 +0100 Subject: [PATCH 09/76] backend-plugin-api: auth refactor to issueServiceToken with required credentials + getOwnCredentials Signed-off-by: Patrik Oldsberg --- .../auth/authServiceFactory.test.ts | 8 ++-- .../auth/authServiceFactory.ts | 42 +++++++++---------- .../httpAuth/httpAuthServiceFactory.ts | 4 +- packages/backend-plugin-api/api-report.md | 8 ++-- .../src/services/definitions/AuthService.ts | 7 ++-- .../services/definitions/HttpAuthService.ts | 4 +- 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts index 64c2bed2a9..16f05ef9d0 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts @@ -51,7 +51,9 @@ describe('authServiceFactory', () => { const searchAuth = await tester.get('search'); const catalogAuth = await tester.get('catalog'); - const { token: searchToken } = await searchAuth.issueToken({}); + const { token: searchToken } = await searchAuth.issueServiceToken({ + forward: await searchAuth.getOwnCredentials(), + }); await expect(searchAuth.authenticate(searchToken)).resolves.toEqual( expect.objectContaining({ @@ -79,7 +81,7 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); await expect( - catalogAuth.issueToken({ + catalogAuth.issueServiceToken({ forward: { $$type: '@backstage/BackstageCredentials', version: 'v1', @@ -101,7 +103,7 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); - const { token } = await catalogAuth.issueToken({ + const { token } = await catalogAuth.issueServiceToken({ forward: { $$type: '@backstage/BackstageCredentials', version: 'v1', diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index 5190b90e7e..c2b4236f45 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -43,12 +43,10 @@ export type InternalBackstageCredentials = export function createCredentialsWithServicePrincipal( sub: string, - token: string, ): InternalBackstageCredentials { return { $$type: '@backstage/BackstageCredentials', version: 'v1', - token, principal: { type: 'service', subject: sub, @@ -112,6 +110,7 @@ class DefaultAuthService implements AuthService { constructor( private readonly tokenManager: TokenManager, private readonly identity: IdentityService, + private readonly pluginId: string, ) {} async authenticate(token: string): Promise { @@ -120,10 +119,7 @@ class DefaultAuthService implements AuthService { // Legacy service-to-service token if (sub === 'backstage-server' && !aud) { await this.tokenManager.authenticate(token); - return createCredentialsWithServicePrincipal( - 'external:backstage-plugin', - token, - ); + return createCredentialsWithServicePrincipal('external:backstage-plugin'); } // User Backstage token @@ -158,28 +154,31 @@ class DefaultAuthService implements AuthService { return true; } - async issueToken(options?: { - forward?: BackstageCredentials; - }): Promise<{ token: string }> { - const internalForward = - options?.forward && toInternalBackstageCredentials(options.forward); + async getOwnCredentials(): Promise< + BackstageCredentials + > { + return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`); + } - if (internalForward) { - const { type } = internalForward.principal; - if (type === 'user') { + async issueServiceToken(options: { + forward: BackstageCredentials; + }): Promise<{ token: string }> { + const internalForward = toInternalBackstageCredentials(options.forward); + const { type } = internalForward.principal; + + switch (type) { + case 'service': + return this.tokenManager.getToken(); + case 'user': if (!internalForward.token) { throw new Error('User credentials is unexpectedly missing token'); } return { token: internalForward.token }; - } else if (type !== 'service') { + default: throw new AuthenticationError( `Refused to issue service token for credential type '${type}'`, ); - } } - - const { token } = await this.tokenManager.getToken(); - return { token }; } } @@ -190,12 +189,13 @@ export const authServiceFactory = createServiceFactory({ config: coreServices.rootConfig, logger: coreServices.rootLogger, discovery: coreServices.discovery, + plugin: coreServices.pluginMetadata, }, createRootContext({ config, logger }) { return ServerTokenManager.fromConfig(config, { logger }); }, - async factory({ discovery }, tokenManager) { + async factory({ discovery, plugin }, tokenManager) { const identity = DefaultIdentityClient.create({ discovery }); - return new DefaultAuthService(tokenManager, identity); + return new DefaultAuthService(tokenManager, identity, plugin.getId()); }, }); diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 79c74ffa9f..d23c35fb43 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -133,10 +133,10 @@ class DefaultHttpAuthService implements HttpAuthService { } async requestHeaders(options: { - forward?: BackstageCredentials; + forward: BackstageCredentials; }): Promise> { return { - Authorization: `Bearer ${await this.auth.issueToken(options)}`, + Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, }; } diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index a3e5930375..23e9172bee 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -22,12 +22,14 @@ export interface AuthService { // (undocumented) authenticate(token: string): Promise; // (undocumented) + getOwnCredentials(): Promise>; + // (undocumented) isPrincipal( credentials: BackstageCredentials, type: TType, ): credentials is BackstageCredentials; // (undocumented) - issueToken(options: { forward?: BackstageCredentials }): Promise<{ + issueServiceToken(options: { forward: BackstageCredentials }): Promise<{ token: string; }>; } @@ -305,8 +307,8 @@ export interface HttpAuthService { // (undocumented) issueUserCookie(res: Response_2): Promise; // (undocumented) - requestHeaders(options?: { - forward?: BackstageCredentials; + requestHeaders(options: { + forward: BackstageCredentials; }): Promise>; } diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index 8a946e5c91..8eeb40a5ca 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -71,9 +71,10 @@ export interface AuthService { type: TType, ): credentials is BackstageCredentials; + getOwnCredentials(): Promise>; + // TODO: should the caller provide the target plugin ID? - // TODO: how can we make it very difficult to forget to forward credentials - issueToken(options: { - forward?: BackstageCredentials; + issueServiceToken(options: { + forward: BackstageCredentials; }): Promise<{ token: string }>; } diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index 949ca1af0a..937bb1ee82 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -43,8 +43,8 @@ export interface HttpAuthService { BackstageCredentials >; - requestHeaders(options?: { - forward?: BackstageCredentials; + requestHeaders(options: { + forward: BackstageCredentials; }): Promise>; issueUserCookie(res: Response): Promise; From 99dadac0af4370a73ce90de1cedad4430f9d90df Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 10 Feb 2024 12:04:39 +0100 Subject: [PATCH 10/76] backend-plugin-api: remove WIP permissions from service principal Signed-off-by: Patrik Oldsberg --- packages/backend-plugin-api/api-report.md | 1 - .../backend-plugin-api/src/services/definitions/AuthService.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 23e9172bee..a798f1b1f7 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -125,7 +125,6 @@ export type BackstagePrincipalTypes = { export type BackstageServicePrincipal = { type: 'service'; subject: string; - permissions?: string[]; }; // @public (undocumented) diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index 8eeb40a5ca..a35d5a5160 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -38,9 +38,6 @@ export type BackstageServicePrincipal = { // Exact format TBD, possibly 'plugin:' or 'external:' subject: string; - - // Not implemented in the first iteration, but this is how we might extend this in the future - permissions?: string[]; }; /** From 6b19a73abc5c0320ac483dcfe3aa4b9bf40faaa2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 12 Feb 2024 16:28:16 +0100 Subject: [PATCH 11/76] backend-{plugin,app}-api: refactored HttpAuth to separate allowing principals from auth method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../httpAuth/httpAuthServiceFactory.ts | 46 +++++++++---------- .../httpRouter/createCredentialsBarrier.ts | 11 +---- packages/backend-plugin-api/api-report.md | 22 +++------ .../src/services/definitions/AuthService.ts | 2 + .../services/definitions/HttpAuthService.ts | 30 +++--------- .../src/services/definitions/index.ts | 5 +- 6 files changed, 40 insertions(+), 76 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index d23c35fb43..1723e3b76c 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -17,7 +17,7 @@ import { AuthService, BackstageCredentials, - BackstageHttpAccessToPrincipalTypesMapping, + BackstagePrincipalTypes, DiscoveryService, HttpAuthService, coreServices, @@ -96,33 +96,33 @@ class DefaultHttpAuthService implements HttpAuthService { this.#extractCredentialsFromRequest(req)); } - async credentials< - TAllowed extends - | keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', - >( + async credentials( req: Request, options?: { - allow: Array; + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; }, - ): Promise< - BackstageCredentials - > { + ): Promise> { const credentials = toInternalBackstageCredentials( await this.#getCredentials(req), ); - // TODO break out into more readable function as we always - // want to check cookie regardless if options are set or not - // Probably asserts function that ensures authMethod = 'token' after cookie check - if (credentials.authMethod === 'cookie') { - if (options && !options.allow.includes('user-cookie' as TAllowed)) { - throw new NotAllowedError( - `This endpoint does not allow 'user-cookie' credentials`, - ); - } - } else if ( - options && - !options.allow.includes(credentials.principal.type as TAllowed) + const allowedPrincipalTypes = options?.allow; + const allowedAuthMethods: Array<'token' | 'cookie' | 'none'> = + options?.allowedAuthMethods ?? ['token']; + + if ( + credentials.authMethod !== 'none' && + !allowedAuthMethods.includes(credentials.authMethod) + ) { + throw new NotAllowedError( + `This endpoint does not allow the '${credentials.authMethod}' auth method`, + ); + } + + if ( + allowedPrincipalTypes && + !allowedPrincipalTypes.includes(credentials.principal.type as TAllowed) ) { throw new NotAllowedError( `This endpoint does not allow '${credentials.principal.type}' credentials`, @@ -175,10 +175,8 @@ class DefaultHttpAuthService implements HttpAuthService { export const httpAuthServiceFactory = createServiceFactory({ service: coreServices.httpAuth, deps: { - config: coreServices.rootConfig, - logger: coreServices.rootLogger, - discovery: coreServices.discovery, auth: coreServices.auth, + discovery: coreServices.discovery, plugin: coreServices.pluginMetadata, }, async factory({ auth, discovery, plugin }) { diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts index c502dc25e5..6cdff9d32c 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts @@ -60,18 +60,11 @@ export function createCredentialsBarrier(options: { predicate(req.path), ); - if (allowsCookie) { - // don't we need a user-cookie allow type here? - await httpAuth.credentials(req, { - allow: ['user-cookie', 'user', 'service'], - }); - next(); - return; - } - await httpAuth.credentials(req, { allow: ['user', 'service'], + allowedAuthMethods: allowsCookie ? ['token', 'cookie'] : ['token'], }); + next(); }; diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index a798f1b1f7..27dfeb13b6 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -101,15 +101,6 @@ export type BackstageCredentials = { principal: TPrincipal; }; -// @public (undocumented) -export type BackstageHttpAccessToPrincipalTypesMapping = { - user: BackstageUserPrincipal; - 'user-cookie': BackstageUserPrincipal; - service: BackstageServicePrincipal; - unauthenticated: BackstageNonePrincipal; - unknown: unknown; -}; - // @public (undocumented) export type BackstageNonePrincipal = { type: 'none'; @@ -119,6 +110,8 @@ export type BackstageNonePrincipal = { export type BackstagePrincipalTypes = { user: BackstageUserPrincipal; service: BackstageServicePrincipal; + unauthenticated: BackstageNonePrincipal; + unknown: unknown; }; // @public (undocumented) @@ -293,16 +286,13 @@ export interface ExtensionPointConfig { // @public (undocumented) export interface HttpAuthService { // (undocumented) - credentials< - TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', - >( + credentials( req: Request_2, options?: { - allow: Array; + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; }, - ): Promise< - BackstageCredentials - >; + ): Promise>; // (undocumented) issueUserCookie(res: Response_2): Promise; // (undocumented) diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index a35d5a5160..4566d4a3fa 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -55,6 +55,8 @@ export type BackstageCredentials = { export type BackstagePrincipalTypes = { user: BackstageUserPrincipal; service: BackstageServicePrincipal; + unauthenticated: BackstageNonePrincipal; + unknown: unknown; }; /** diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index 937bb1ee82..cc8aace8ba 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -15,33 +15,17 @@ */ import { Request, Response } from 'express'; -import { - BackstageCredentials, - BackstageServicePrincipal, - BackstageNonePrincipal, - BackstageUserPrincipal, -} from './AuthService'; - -/** @public */ -export type BackstageHttpAccessToPrincipalTypesMapping = { - user: BackstageUserPrincipal; - 'user-cookie': BackstageUserPrincipal; - service: BackstageServicePrincipal; - unauthenticated: BackstageNonePrincipal; - unknown: unknown; -}; +import { BackstageCredentials, BackstagePrincipalTypes } from './AuthService'; /** @public */ export interface HttpAuthService { - credentials< - TAllowed extends - | keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', - >( + credentials( req: Request, - options?: { allow: Array }, - ): Promise< - BackstageCredentials - >; + options?: { + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; + }, + ): Promise>; requestHeaders(options: { forward: BackstageCredentials; diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 810f1754b7..5955c4cbb1 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -35,10 +35,7 @@ export type { HttpRouterService, HttpRouterServiceAuthPolicy, } from './HttpRouterService'; -export type { - HttpAuthService, - BackstageHttpAccessToPrincipalTypesMapping, -} from './HttpAuthService'; +export type { HttpAuthService } from './HttpAuthService'; export type { LifecycleService, LifecycleServiceStartupHook, From 3444a2c7c96123e43719f5205fbcdc2139d07f0d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 12 Feb 2024 16:33:53 +0100 Subject: [PATCH 12/76] backend-common: add createLegacyAuthAdapters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-common/api-report.md | 14 + packages/backend-common/package.json | 1 + .../src/auth/createLegacyAuthAdapters.ts | 249 ++++++++++++++++++ packages/backend-common/src/auth/index.ts | 17 ++ packages/backend-common/src/index.ts | 1 + 5 files changed, 282 insertions(+) create mode 100644 packages/backend-common/src/auth/createLegacyAuthAdapters.ts create mode 100644 packages/backend-common/src/auth/index.ts diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 6c9b63ae11..8740910449 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -8,6 +8,7 @@ import { AppConfig } from '@backstage/config'; import { AuthCallback } from 'isomorphic-git'; +import { AuthService } from '@backstage/backend-plugin-api'; import { AwsCredentialsManager } from '@backstage/integration-aws-node'; import { AwsS3Integration } from '@backstage/integration'; import { AzureDevOpsCredentialsProvider } from '@backstage/integration'; @@ -30,6 +31,7 @@ import { GithubCredentialsProvider } from '@backstage/integration'; import { GithubIntegration } from '@backstage/integration'; import { GitLabIntegration } from '@backstage/integration'; import { HostDiscovery as HostDiscovery_2 } from '@backstage/backend-app-api'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { IdentityService } from '@backstage/backend-plugin-api'; import { isChildPath } from '@backstage/cli-common'; import { Knex } from 'knex'; @@ -232,6 +234,18 @@ export function createDatabaseClient( }, ): knexFactory.Knex; +// @public (undocumented) +export function createLegacyAuthAdapters(options: { + auth?: AuthService; + httpAuth?: HttpAuthService; + identity?: IdentityService; + tokenManager?: TokenManager; + discovery: PluginEndpointDiscovery; +}): { + auth: AuthService; + httpAuth: HttpAuthService; +}; + // @public export function createRootLogger( options?: winston.LoggerOptions, diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index d202b19040..bfe8fd09fc 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -63,6 +63,7 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/integration-aws-node": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", "@backstage/types": "workspace:^", "@google-cloud/storage": "^7.0.0", "@keyv/memcache": "^1.3.5", diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts new file mode 100644 index 0000000000..f0c259ad08 --- /dev/null +++ b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts @@ -0,0 +1,249 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AuthService, + BackstageCredentials, + BackstagePrincipalTypes, + BackstageServicePrincipal, + BackstageUserPrincipal, + HttpAuthService, + IdentityService, + TokenManagerService, +} from '@backstage/backend-plugin-api'; +import { ServerTokenManager, TokenManager } from '../tokens'; +import { AuthenticationError, NotAllowedError } from '@backstage/errors'; +import type { Request, Response } from 'express'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + createCredentialsWithServicePrincipal, + createCredentialsWithUserPrincipal, + createCredentialsWithNonePrincipal, + toInternalBackstageCredentials, +} from '../../../backend-app-api/src/services/implementations/auth/authServiceFactory'; +// TODO is this circular thingy a problem? Test in e2e +import { + type IdentityApiGetIdentityRequest, + DefaultIdentityClient, +} from '@backstage/plugin-auth-node'; +import { decodeJwt } from 'jose'; +import { PluginEndpointDiscovery } from '../discovery'; + +class AuthCompat implements AuthService { + constructor( + private readonly identity: IdentityService, + private readonly tokenManager: TokenManagerService, + ) {} + + isPrincipal( + credentials: BackstageCredentials, + type: TType, + ): credentials is BackstageCredentials { + const principal = credentials.principal as + | BackstageUserPrincipal + | BackstageServicePrincipal; + + if (principal.type !== type) { + return false; + } + + return true; + } + + async getOwnCredentials(): Promise< + BackstageCredentials + > { + return createCredentialsWithServicePrincipal('external:backstage-plugin'); + } + + async authenticate(token: string): Promise { + const { sub, aud } = decodeJwt(token); + + // Legacy service-to-service token + if (sub === 'backstage-server' && !aud) { + await this.tokenManager.authenticate(token); + return createCredentialsWithServicePrincipal('external:backstage-plugin'); + } + + // User Backstage token + const identity = await this.identity.getIdentity({ + request: { + headers: { authorization: `Bearer ${token}` }, + }, + } as IdentityApiGetIdentityRequest); + + if (!identity) { + throw new AuthenticationError('Invalid user token'); + } + + return createCredentialsWithUserPrincipal( + identity.identity.userEntityRef, + token, + ); + } + + async issueServiceToken(options: { + forward: BackstageCredentials; + }): Promise<{ token: string }> { + const internalForward = toInternalBackstageCredentials(options.forward); + const { type } = internalForward.principal; + + switch (type) { + // TODO: Check whether the principal is ourselves + case 'service': + return this.tokenManager.getToken(); + case 'user': + if (!internalForward.token) { + throw new Error('User credentials is unexpectedly missing token'); + } + return { token: internalForward.token }; + // NOTE: this is not the behavior of this service in the new backend system, it only applies + // here since we'll need to accept and forward requests without authentication. + case 'none': + return { token: '' }; + default: + throw new AuthenticationError( + `Refused to issue service token for credential type '${type}'`, + ); + } + } +} + +function getTokenFromRequest(req: Request) { + // TODO: support multiple auth headers (iterate rawHeaders) + const authHeader = req.headers.authorization; + if (typeof authHeader === 'string') { + const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i); + const token = matches?.[1]; + if (token) { + return token; + } + } + + return undefined; +} + +const credentialsSymbol = Symbol('backstage-credentials'); + +type RequestWithCredentials = Request & { + [credentialsSymbol]?: Promise; +}; + +class HttpAuthCompat implements HttpAuthService { + constructor(private readonly auth: AuthService) {} + + async #extractCredentialsFromRequest(req: Request) { + const token = getTokenFromRequest(req); + if (!token) { + return createCredentialsWithNonePrincipal(); + } + + const credentials = toInternalBackstageCredentials( + await this.auth.authenticate(token), + ); + + return credentials; + } + + async #getCredentials(req: /* */ RequestWithCredentials) { + return (req[credentialsSymbol] ??= + this.#extractCredentialsFromRequest(req)); + } + + async credentials( + req: Request, + options?: { + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; + }, + ): Promise> { + const credentials = toInternalBackstageCredentials( + await this.#getCredentials(req), + ); + + const allowedPrincipalTypes = options?.allow; + const allowedAuthMethods: Array<'token' | 'cookie' | 'none'> = + options?.allowedAuthMethods ?? ['token']; + + if ( + credentials.authMethod !== 'none' && + !allowedAuthMethods.includes(credentials.authMethod) + ) { + throw new NotAllowedError( + `This endpoint does not allow the '${credentials.authMethod}' auth method`, + ); + } + + if ( + allowedPrincipalTypes && + !allowedPrincipalTypes.includes(credentials.principal.type as TAllowed) + ) { + throw new NotAllowedError( + `This endpoint does not allow '${credentials.principal.type}' credentials`, + ); + } + + return credentials as any; + } + + async requestHeaders(options: { + forward: BackstageCredentials; + }): Promise> { + return { + Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, + }; + } + + async issueUserCookie(_res: Response): Promise {} +} + +/** @public */ +export function createLegacyAuthAdapters(options: { + auth?: AuthService; + httpAuth?: HttpAuthService; + identity?: IdentityService; + tokenManager?: TokenManager; + discovery: PluginEndpointDiscovery; +}): { + auth: AuthService; + httpAuth: HttpAuthService; +} { + const { auth, httpAuth, discovery } = options; + + if (auth || httpAuth) { + // TODO: Is this sensible? Could be that a lot of plugins only want one of them and in + // that case overloads might be better, so that it's possible to only provide one of them. + if (!(auth && httpAuth)) { + throw new Error('Both auth and httpAuth must be provided'); + } + return { + auth, + httpAuth, + }; + } + + const identity = + options.identity ?? DefaultIdentityClient.create({ discovery }); + const tokenManager = options.tokenManager ?? ServerTokenManager.noop(); + + const authImpl = new AuthCompat(identity, tokenManager); + const httpAuthImpl = new HttpAuthCompat(authImpl); + + return { + auth: authImpl, + httpAuth: httpAuthImpl, + }; +} diff --git a/packages/backend-common/src/auth/index.ts b/packages/backend-common/src/auth/index.ts new file mode 100644 index 0000000000..c92ecdce25 --- /dev/null +++ b/packages/backend-common/src/auth/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { createLegacyAuthAdapters } from './createLegacyAuthAdapters'; diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts index afb12115b2..4b1314b7d2 100644 --- a/packages/backend-common/src/index.ts +++ b/packages/backend-common/src/index.ts @@ -22,6 +22,7 @@ export { legacyPlugin, makeLegacyPlugin } from './legacy'; export type { LegacyCreateRouter } from './legacy'; +export * from './auth'; export * from './cache'; export { loadBackendConfig } from './config'; export * from './database'; From 54fa4997ee5488b42fe84d2144c2b1412b4c06b6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 00:13:36 +0100 Subject: [PATCH 13/76] backend-common: update createLegacyAuthAdapters to work with a single service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-common/api-report.md | 39 +++++++--- .../src/auth/createLegacyAuthAdapters.test.ts | 73 +++++++++++++++++++ .../src/auth/createLegacyAuthAdapters.ts | 57 ++++++++++----- 3 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 8740910449..cd4d5ab309 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -235,16 +235,35 @@ export function createDatabaseClient( ): knexFactory.Knex; // @public (undocumented) -export function createLegacyAuthAdapters(options: { - auth?: AuthService; - httpAuth?: HttpAuthService; - identity?: IdentityService; - tokenManager?: TokenManager; - discovery: PluginEndpointDiscovery; -}): { - auth: AuthService; - httpAuth: HttpAuthService; -}; +export function createLegacyAuthAdapters< + TOptions extends { + auth?: AuthService; + httpAuth?: HttpAuthService; + identity?: IdentityService; + tokenManager?: TokenManager; + discovery: PluginEndpointDiscovery; + }, + TAdapters = TOptions extends { + auth?: AuthService; + } + ? TOptions extends { + httpAuth?: HttpAuthService; + } + ? { + auth: AuthService; + httpAuth: HttpAuthService; + } + : { + auth: AuthService; + } + : TOptions extends { + httpAuth?: HttpAuthService; + } + ? { + httpAuth: HttpAuthService; + } + : 'error: at least one of auth and/or httpAuth must be provided', +>(options: TOptions): TAdapters; // @public export function createRootLogger( diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts b/packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts new file mode 100644 index 0000000000..7e1f1be858 --- /dev/null +++ b/packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { mockServices } from '@backstage/backend-test-utils'; +import { createLegacyAuthAdapters } from './createLegacyAuthAdapters'; + +describe('createLegacyAuthAdapters', () => { + it('should pass through auth if only auth is provided', () => { + const auth = {}; + const ret = createLegacyAuthAdapters({ + auth: auth as any, + tokenManager: mockServices.tokenManager(), + discovery: {} as any, + identity: mockServices.identity(), + }); + + expect(ret.auth).toBe(auth); + }); + + it('should pass through httpAuth if only httpAuth is provided', () => { + const httpAuth = {}; + const ret = createLegacyAuthAdapters({ + httpAuth: httpAuth as any, + tokenManager: mockServices.tokenManager(), + discovery: {} as any, + identity: mockServices.identity(), + }); + + expect(ret.httpAuth).toBe(httpAuth); + }); + + it('should pass through both auth and httpAuth if both are provided', () => { + const auth = {}; + const httpAuth = {}; + const ret = createLegacyAuthAdapters({ + auth: auth as any, + httpAuth: httpAuth as any, + tokenManager: mockServices.tokenManager(), + discovery: {} as any, + identity: mockServices.identity(), + }); + + expect(ret.auth).toBe(auth); + expect(ret.httpAuth).toBe(httpAuth); + }); + + it('should adapt both auth and httpAuth if neither are provided', () => { + const ret = createLegacyAuthAdapters({ + auth: undefined, + httpAuth: undefined, + tokenManager: mockServices.tokenManager(), + discovery: {} as any, + identity: mockServices.identity(), + }); + + expect(ret).toEqual({ + auth: expect.any(Object), + httpAuth: expect.any(Object), + }); + }); +}); diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts index f0c259ad08..932c8c421a 100644 --- a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts +++ b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts @@ -210,29 +210,47 @@ class HttpAuthCompat implements HttpAuthService { async issueUserCookie(_res: Response): Promise {} } -/** @public */ -export function createLegacyAuthAdapters(options: { - auth?: AuthService; - httpAuth?: HttpAuthService; - identity?: IdentityService; - tokenManager?: TokenManager; - discovery: PluginEndpointDiscovery; -}): { - auth: AuthService; - httpAuth: HttpAuthService; -} { +/** + * An adapter that ensures presence of the auth and/or httpAuth services. + * @public + */ +export function createLegacyAuthAdapters< + TOptions extends { + auth?: AuthService; + httpAuth?: HttpAuthService; + identity?: IdentityService; + tokenManager?: TokenManager; + discovery: PluginEndpointDiscovery; + }, + TAdapters = TOptions extends { + auth?: AuthService; + } + ? TOptions extends { httpAuth?: HttpAuthService } + ? { auth: AuthService; httpAuth: HttpAuthService } + : { auth: AuthService } + : TOptions extends { httpAuth?: HttpAuthService } + ? { httpAuth: HttpAuthService } + : 'error: at least one of auth and/or httpAuth must be provided', +>(options: TOptions): TAdapters { const { auth, httpAuth, discovery } = options; - if (auth || httpAuth) { - // TODO: Is this sensible? Could be that a lot of plugins only want one of them and in - // that case overloads might be better, so that it's possible to only provide one of them. - if (!(auth && httpAuth)) { - throw new Error('Both auth and httpAuth must be provided'); - } + if (auth && httpAuth) { return { auth, httpAuth, - }; + } as TAdapters; + } + + if (auth) { + return { + auth, + } as TAdapters; + } + + if (httpAuth) { + return { + httpAuth, + } as TAdapters; } const identity = @@ -240,10 +258,11 @@ export function createLegacyAuthAdapters(options: { const tokenManager = options.tokenManager ?? ServerTokenManager.noop(); const authImpl = new AuthCompat(identity, tokenManager); + const httpAuthImpl = new HttpAuthCompat(authImpl); return { auth: authImpl, httpAuth: httpAuthImpl, - }; + } as TAdapters; } From abaaf4970a9997f5f2f7d2cf7d33edeec22ec59b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 00:38:58 +0100 Subject: [PATCH 14/76] backend-test-utils: add mocks for AuthService and HttpAuthService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 22 +++++ .../src/next/services/MockAuthService.ts | 90 +++++++++++++++++++ .../src/next/services/mockServices.ts | 28 ++++++ .../src/next/wiring/TestBackend.ts | 2 + 4 files changed, 142 insertions(+) create mode 100644 packages/backend-test-utils/src/next/services/MockAuthService.ts diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 204e5dc84a..a29a782af0 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -6,12 +6,14 @@ /// /// +import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CacheService } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HttpRouterFactoryOptions } from '@backstage/backend-app-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { IdentityService } from '@backstage/backend-plugin-api'; @@ -86,6 +88,17 @@ export interface MockDirectoryOptions { // @public (undocumented) export namespace mockServices { + // (undocumented) + export function auth(options?: { pluginId?: string }): AuthService; + // (undocumented) + export namespace auth { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + } // (undocumented) export namespace cache { const // (undocumented) @@ -105,6 +118,15 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) + export namespace httpAuth { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + } + // (undocumented) export namespace httpRouter { const // (undocumented) factory: ( diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts new file mode 100644 index 0000000000..9af9be4818 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BackstageCredentials, + BackstageServicePrincipal, + BackstagePrincipalTypes, + BackstageUserPrincipal, + BackstageNonePrincipal, + AuthService, +} from '@backstage/backend-plugin-api'; +import { AuthenticationError } from '@backstage/errors'; + +/** @internal */ +export class MockAuthService implements AuthService { + constructor(private readonly pluginId: string) {} + + async authenticate(token: string): Promise { + if (token === 'mock-user-token') { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'user', userEntityRef: 'user:default/mock' }, + }; + } else if (token === 'mock-service-token') { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'service', subject: 'external:test-service' }, + }; + } + + throw new AuthenticationError('Invalid token'); + } + + async getOwnCredentials(): Promise< + BackstageCredentials + > { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'service', subject: `plugin:${this.pluginId}` }, + }; + } + + isPrincipal( + credentials: BackstageCredentials, + type: TType, + ): credentials is BackstageCredentials { + const principal = credentials.principal as + | BackstageUserPrincipal + | BackstageServicePrincipal + | BackstageNonePrincipal; + if (principal.type !== type) { + return false; + } + + return true; + } + + async issueServiceToken(options: { + forward: BackstageCredentials; + }): Promise<{ token: string }> { + const principal = options.forward.principal as + | BackstageUserPrincipal + | BackstageServicePrincipal + | BackstageNonePrincipal; + + switch (principal.type) { + case 'user': + return { token: 'mock-user-token' }; + case 'service': + return { token: 'mock-service-token' }; + default: + throw new AuthenticationError( + `Refused to issue service token for credential type '${principal.type}'`, + ); + } + } +} diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 78f59b53c4..58a6f7c421 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -23,6 +23,7 @@ import { ServiceFactory, ServiceRef, TokenManagerService, + AuthService, } from '@backstage/backend-plugin-api'; import { cacheServiceFactory, @@ -35,11 +36,13 @@ import { rootLifecycleServiceFactory, schedulerServiceFactory, urlReaderServiceFactory, + httpAuthServiceFactory, } from '@backstage/backend-app-api'; import { ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { MockIdentityService } from './MockIdentityService'; import { MockRootLoggerService } from './MockRootLoggerService'; +import { MockAuthService } from './MockAuthService'; /** @internal */ function simpleFactory< @@ -160,6 +163,23 @@ export namespace mockServices { })); } + export function auth(options?: { pluginId?: string }): AuthService { + return new MockAuthService(options?.pluginId ?? 'test'); + } + export namespace auth { + export const factory = createServiceFactory({ + service: coreServices.auth, + deps: { plugin: coreServices.pluginMetadata }, + factory: ({ plugin }) => new MockAuthService(plugin.getId()), + }); + export const mock = simpleMock(coreServices.auth, () => ({ + authenticate: jest.fn(), + getOwnCredentials: jest.fn(), + isPrincipal: jest.fn() as any, + issueServiceToken: jest.fn(), + })); + } + // TODO(Rugvip): Not all core services have implementations available here yet. // some may need a bit more refactoring for it to be simpler to // re-implement functioning mock versions here. @@ -185,6 +205,14 @@ export namespace mockServices { addAuthPolicy: jest.fn(), })); } + export namespace httpAuth { + export const factory = httpAuthServiceFactory; + export const mock = simpleMock(coreServices.httpAuth, () => ({ + credentials: jest.fn(), + issueUserCookie: jest.fn(), + requestHeaders: jest.fn(), + })); + } export namespace rootHttpRouter { export const factory = rootHttpRouterServiceFactory; export const mock = simpleMock(coreServices.rootHttpRouter, () => ({ diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index 14e8920390..72a2ed8edb 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -66,9 +66,11 @@ export interface TestBackend extends Backend { } export const defaultServiceFactories = [ + mockServices.auth.factory(), mockServices.cache.factory(), mockServices.rootConfig.factory(), mockServices.database.factory(), + mockServices.httpAuth.factory(), mockServices.httpRouter.factory(), mockServices.identity.factory(), mockServices.lifecycle.factory(), From bfc63fdf378a496bfdca71f820c7fe0360e10842 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 00:39:54 +0100 Subject: [PATCH 15/76] backend-app-api: add TODO for authServiceFactory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../src/services/implementations/auth/authServiceFactory.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index c2b4236f45..7e9ad3077f 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -167,6 +167,7 @@ class DefaultAuthService implements AuthService { const { type } = internalForward.principal; switch (type) { + // TODO: Check whether the principal is ourselves case 'service': return this.tokenManager.getToken(); case 'user': From 05b7e918612ec41a151f2c5d4e91915d066c429b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 12:32:38 +0100 Subject: [PATCH 16/76] backend-test-utils: add httpAuth instance mock + discovery mock Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 14 ++++++ .../src/next/services/mockServices.ts | 49 ++++++++++++++++--- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index a29a782af0..cff8a8fda9 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -11,6 +11,7 @@ import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CacheService } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { HttpAuthService } from '@backstage/backend-plugin-api'; @@ -118,6 +119,19 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) + export function discovery(): DiscoveryService; + // (undocumented) + export namespace discovery { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + } + // (undocumented) + export function httpAuth(options?: { pluginId?: string }): HttpAuthService; + // (undocumented) export namespace httpAuth { const // (undocumented) factory: () => ServiceFactory; diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 58a6f7c421..ba43aff008 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -24,6 +24,8 @@ import { ServiceRef, TokenManagerService, AuthService, + DiscoveryService, + HttpAuthService, } from '@backstage/backend-plugin-api'; import { cacheServiceFactory, @@ -37,12 +39,16 @@ import { schedulerServiceFactory, urlReaderServiceFactory, httpAuthServiceFactory, + discoveryServiceFactory, + HostDiscovery, } from '@backstage/backend-app-api'; import { ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { MockIdentityService } from './MockIdentityService'; import { MockRootLoggerService } from './MockRootLoggerService'; import { MockAuthService } from './MockAuthService'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { DefaultHttpAuthService } from '../../../../backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory'; /** @internal */ function simpleFactory< @@ -180,6 +186,41 @@ export namespace mockServices { })); } + export function discovery(): DiscoveryService { + return HostDiscovery.fromConfig( + new ConfigReader({ + backend: { + // Invalid port to make sure that requests are always mocked + baseUrl: 'http://localhost:0', + listen: { port: 0 }, + }, + }), + ); + } + export namespace discovery { + export const factory = discoveryServiceFactory; + export const mock = simpleMock(coreServices.discovery, () => ({ + getBaseUrl: jest.fn(), + getExternalBaseUrl: jest.fn(), + })); + } + + export function httpAuth(options?: { pluginId?: string }): HttpAuthService { + return new DefaultHttpAuthService( + auth(), + discovery(), + options?.pluginId ?? 'test', + ); + } + export namespace httpAuth { + export const factory = httpAuthServiceFactory; + export const mock = simpleMock(coreServices.httpAuth, () => ({ + credentials: jest.fn(), + issueUserCookie: jest.fn(), + requestHeaders: jest.fn(), + })); + } + // TODO(Rugvip): Not all core services have implementations available here yet. // some may need a bit more refactoring for it to be simpler to // re-implement functioning mock versions here. @@ -205,14 +246,6 @@ export namespace mockServices { addAuthPolicy: jest.fn(), })); } - export namespace httpAuth { - export const factory = httpAuthServiceFactory; - export const mock = simpleMock(coreServices.httpAuth, () => ({ - credentials: jest.fn(), - issueUserCookie: jest.fn(), - requestHeaders: jest.fn(), - })); - } export namespace rootHttpRouter { export const factory = rootHttpRouterServiceFactory; export const mock = simpleMock(coreServices.rootHttpRouter, () => ({ From 413a9e7de86f513e6c5495a6fa5e8c5b4a6d8793 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 14:45:08 +0100 Subject: [PATCH 17/76] backend-*-api: updates auth APIs for BEP changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .../auth/authServiceFactory.test.ts | 15 +++-- .../auth/authServiceFactory.ts | 9 +-- .../httpAuth/httpAuthServiceFactory.ts | 10 +--- packages/backend-common/api-report.md | 2 +- .../src/auth/createLegacyAuthAdapters.ts | 55 ++++++++----------- packages/backend-plugin-api/api-report.md | 19 ++++--- .../src/services/definitions/AuthService.ts | 10 ++-- .../services/definitions/HttpAuthService.ts | 4 -- .../src/next/services/MockAuthService.ts | 11 ++-- .../src/next/services/mockServices.ts | 5 +- yarn.lock | 1 + 11 files changed, 65 insertions(+), 76 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts index 16f05ef9d0..f24264930a 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts @@ -51,8 +51,9 @@ describe('authServiceFactory', () => { const searchAuth = await tester.get('search'); const catalogAuth = await tester.get('catalog'); - const { token: searchToken } = await searchAuth.issueServiceToken({ - forward: await searchAuth.getOwnCredentials(), + const { token: searchToken } = await searchAuth.getPluginRequestToken({ + onBehalfOf: await searchAuth.getOwnServiceCredentials(), + targetPluginId: 'catalog', }); await expect(searchAuth.authenticate(searchToken)).resolves.toEqual( @@ -81,8 +82,8 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); await expect( - catalogAuth.issueServiceToken({ - forward: { + catalogAuth.getPluginRequestToken({ + onBehalfOf: { $$type: '@backstage/BackstageCredentials', version: 'v1', authMethod: 'token', @@ -92,6 +93,7 @@ describe('authServiceFactory', () => { userEntityRef: 'user:default/alice', }, } as InternalBackstageCredentials, + targetPluginId: 'catalog', }), ).resolves.toEqual({ token: 'alice-token' }); }); @@ -103,8 +105,8 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); - const { token } = await catalogAuth.issueServiceToken({ - forward: { + const { token } = await catalogAuth.getPluginRequestToken({ + onBehalfOf: { $$type: '@backstage/BackstageCredentials', version: 'v1', authMethod: 'token', @@ -114,6 +116,7 @@ describe('authServiceFactory', () => { subject: 'external:upstream-service', }, } as InternalBackstageCredentials, + targetPluginId: 'catalog', }); expect(decodeJwt(token)).toEqual( diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index 7e9ad3077f..dac8ae6d9e 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -154,16 +154,17 @@ class DefaultAuthService implements AuthService { return true; } - async getOwnCredentials(): Promise< + async getOwnServiceCredentials(): Promise< BackstageCredentials > { return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`); } - async issueServiceToken(options: { - forward: BackstageCredentials; + async getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }): Promise<{ token: string }> { - const internalForward = toInternalBackstageCredentials(options.forward); + const internalForward = toInternalBackstageCredentials(options.onBehalfOf); const { type } = internalForward.principal; switch (type) { diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 1723e3b76c..2182e94684 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -63,7 +63,7 @@ type RequestWithCredentials = Request & { [credentialsSymbol]?: Promise; }; -class DefaultHttpAuthService implements HttpAuthService { +export class DefaultHttpAuthService implements HttpAuthService { constructor( private readonly auth: AuthService, private readonly discovery: DiscoveryService, @@ -132,14 +132,6 @@ class DefaultHttpAuthService implements HttpAuthService { return credentials as any; } - async requestHeaders(options: { - forward: BackstageCredentials; - }): Promise> { - return { - Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, - }; - } - async issueUserCookie(res: Response): Promise { const credentials = await this.credentials(res.req, { allow: ['user'] }); diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index cd4d5ab309..1940a79b78 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -234,7 +234,7 @@ export function createDatabaseClient( }, ): knexFactory.Knex; -// @public (undocumented) +// @public export function createLegacyAuthAdapters< TOptions extends { auth?: AuthService; diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts index 932c8c421a..98d21ba559 100644 --- a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts +++ b/packages/backend-common/src/auth/createLegacyAuthAdapters.ts @@ -63,42 +63,43 @@ class AuthCompat implements AuthService { return true; } - async getOwnCredentials(): Promise< + async getOwnServiceCredentials(): Promise< BackstageCredentials > { return createCredentialsWithServicePrincipal('external:backstage-plugin'); } async authenticate(token: string): Promise { - const { sub, aud } = decodeJwt(token); + const { aud } = decodeJwt(token); - // Legacy service-to-service token - if (sub === 'backstage-server' && !aud) { - await this.tokenManager.authenticate(token); - return createCredentialsWithServicePrincipal('external:backstage-plugin'); + if (aud === 'backstage') { + // User Backstage token + const identity = await this.identity.getIdentity({ + request: { + headers: { authorization: `Bearer ${token}` }, + }, + } as IdentityApiGetIdentityRequest); + + if (!identity) { + throw new AuthenticationError('Invalid user token'); + } + + return createCredentialsWithUserPrincipal( + identity.identity.userEntityRef, + token, + ); } - // User Backstage token - const identity = await this.identity.getIdentity({ - request: { - headers: { authorization: `Bearer ${token}` }, - }, - } as IdentityApiGetIdentityRequest); + await this.tokenManager.authenticate(token); - if (!identity) { - throw new AuthenticationError('Invalid user token'); - } - - return createCredentialsWithUserPrincipal( - identity.identity.userEntityRef, - token, - ); + return createCredentialsWithServicePrincipal('external:backstage-plugin'); } - async issueServiceToken(options: { - forward: BackstageCredentials; + async getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }): Promise<{ token: string }> { - const internalForward = toInternalBackstageCredentials(options.forward); + const internalForward = toInternalBackstageCredentials(options.onBehalfOf); const { type } = internalForward.principal; switch (type) { @@ -199,14 +200,6 @@ class HttpAuthCompat implements HttpAuthService { return credentials as any; } - async requestHeaders(options: { - forward: BackstageCredentials; - }): Promise> { - return { - Authorization: `Bearer ${await this.auth.issueServiceToken(options)}`, - }; - } - async issueUserCookie(_res: Response): Promise {} } diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 27dfeb13b6..537e7a8a15 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -22,16 +22,21 @@ export interface AuthService { // (undocumented) authenticate(token: string): Promise; // (undocumented) - getOwnCredentials(): Promise>; + getOwnServiceCredentials(): Promise< + BackstageCredentials + >; + // (undocumented) + getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; + }): Promise<{ + token: string; + }>; // (undocumented) isPrincipal( credentials: BackstageCredentials, type: TType, ): credentials is BackstageCredentials; - // (undocumented) - issueServiceToken(options: { forward: BackstageCredentials }): Promise<{ - token: string; - }>; } // @public (undocumented) @@ -295,10 +300,6 @@ export interface HttpAuthService { ): Promise>; // (undocumented) issueUserCookie(res: Response_2): Promise; - // (undocumented) - requestHeaders(options: { - forward: BackstageCredentials; - }): Promise>; } // @public (undocumented) diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index 4566d4a3fa..dc38b572c5 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -70,10 +70,12 @@ export interface AuthService { type: TType, ): credentials is BackstageCredentials; - getOwnCredentials(): Promise>; + getOwnServiceCredentials(): Promise< + BackstageCredentials + >; - // TODO: should the caller provide the target plugin ID? - issueServiceToken(options: { - forward: BackstageCredentials; + getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }): Promise<{ token: string }>; } diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index cc8aace8ba..bcc31880b3 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -27,9 +27,5 @@ export interface HttpAuthService { }, ): Promise>; - requestHeaders(options: { - forward: BackstageCredentials; - }): Promise>; - issueUserCookie(res: Response): Promise; } diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 9af9be4818..925ee1bb6d 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -44,7 +44,7 @@ export class MockAuthService implements AuthService { throw new AuthenticationError('Invalid token'); } - async getOwnCredentials(): Promise< + async getOwnServiceCredentials(): Promise< BackstageCredentials > { return { @@ -68,10 +68,11 @@ export class MockAuthService implements AuthService { return true; } - async issueServiceToken(options: { - forward: BackstageCredentials; + async getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }): Promise<{ token: string }> { - const principal = options.forward.principal as + const principal = options.onBehalfOf.principal as | BackstageUserPrincipal | BackstageServicePrincipal | BackstageNonePrincipal; @@ -80,7 +81,7 @@ export class MockAuthService implements AuthService { case 'user': return { token: 'mock-user-token' }; case 'service': - return { token: 'mock-service-token' }; + return { token: `mock-service-token-for-${options.targetPluginId}` }; default: throw new AuthenticationError( `Refused to issue service token for credential type '${principal.type}'`, diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index ba43aff008..63f8ffbd93 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -180,9 +180,9 @@ export namespace mockServices { }); export const mock = simpleMock(coreServices.auth, () => ({ authenticate: jest.fn(), - getOwnCredentials: jest.fn(), + getOwnServiceCredentials: jest.fn(), isPrincipal: jest.fn() as any, - issueServiceToken: jest.fn(), + getPluginRequestToken: jest.fn(), })); } @@ -217,7 +217,6 @@ export namespace mockServices { export const mock = simpleMock(coreServices.httpAuth, () => ({ credentials: jest.fn(), issueUserCookie: jest.fn(), - requestHeaders: jest.fn(), })); } diff --git a/yarn.lock b/yarn.lock index 6d841a09db..218faf39a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3287,6 +3287,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/integration-aws-node": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" "@backstage/types": "workspace:^" "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^1.3.5 From f52a439239f6d752427631a4a30814cd5cef6e04 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 19:47:48 +0100 Subject: [PATCH 18/76] backend-plugin-api: fix HttpAuthService Request type parameters Signed-off-by: Patrik Oldsberg --- packages/backend-plugin-api/api-report.md | 2 +- .../src/services/definitions/HttpAuthService.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 537e7a8a15..320e05dd3d 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -292,7 +292,7 @@ export interface ExtensionPointConfig { export interface HttpAuthService { // (undocumented) credentials( - req: Request_2, + req: Request_2, options?: { allow?: Array; allowedAuthMethods?: Array<'token' | 'cookie'>; diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index bcc31880b3..44696bd777 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -20,7 +20,7 @@ import { BackstageCredentials, BackstagePrincipalTypes } from './AuthService'; /** @public */ export interface HttpAuthService { credentials( - req: Request, + req: Request, options?: { allow?: Array; allowedAuthMethods?: Array<'token' | 'cookie'>; From de0244f538b8b9559be2181e396fa1c5dcbc54aa Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 19:48:19 +0100 Subject: [PATCH 19/76] backend-test-utils: add mockCredentials and use them to implement MockAuthService Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 28 ++++ .../src/next/services/MockAuthService.ts | 66 ++++++++-- .../src/next/services/index.ts | 1 + .../src/next/services/mockCredentials.ts | 120 ++++++++++++++++++ 4 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 packages/backend-test-utils/src/next/services/mockCredentials.ts diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index cff8a8fda9..05074c7f60 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -9,6 +9,10 @@ import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { BackstageNonePrincipal } from '@backstage/backend-plugin-api'; +import { BackstageServicePrincipal } from '@backstage/backend-plugin-api'; +import { BackstageUserPrincipal } from '@backstage/backend-plugin-api'; import { CacheService } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; @@ -42,6 +46,30 @@ export function createMockDirectory( // @public (undocumented) export function isDockerDisabledForTests(): boolean; +// @public (undocumented) +export namespace mockCredentials { + export function none(): BackstageCredentials; + export function service( + subject?: string, + ): BackstageCredentials; + export namespace service { + export function token(payload?: TokenPayload): string; + export type TokenPayload = { + subject?: string; + targetPluginId?: string; + }; + } + export function user( + userEntityRef?: string, + ): BackstageCredentials; + export namespace user { + export function token(payload?: TokenPayload): string; + export type TokenPayload = { + userEntityRef: string; + }; + } +} + // @public export interface MockDirectory { addContent(root: MockDirectoryContent): void; diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 925ee1bb6d..b73bb7875f 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -23,25 +23,50 @@ import { AuthService, } from '@backstage/backend-plugin-api'; import { AuthenticationError } from '@backstage/errors'; +import { + mockCredentials, + MOCK_USER_TOKEN, + MOCK_USER_TOKEN_PREFIX, + MOCK_SERVICE_TOKEN, + MOCK_SERVICE_TOKEN_PREFIX, + DEFAULT_MOCK_USER_ENTITY_REF, + DEFAULT_MOCK_SERVICE_SUBJECT, +} from './mockCredentials'; /** @internal */ export class MockAuthService implements AuthService { constructor(private readonly pluginId: string) {} async authenticate(token: string): Promise { - if (token === 'mock-user-token') { - return { - $$type: '@backstage/BackstageCredentials', - principal: { type: 'user', userEntityRef: 'user:default/mock' }, - }; - } else if (token === 'mock-service-token') { - return { - $$type: '@backstage/BackstageCredentials', - principal: { type: 'service', subject: 'external:test-service' }, - }; + if (token === MOCK_USER_TOKEN) { + return mockCredentials.user(); + } + if (token === MOCK_SERVICE_TOKEN) { + return mockCredentials.service(); } - throw new AuthenticationError('Invalid token'); + if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) { + const { userEntityRef }: mockCredentials.user.TokenPayload = JSON.parse( + token.slice(MOCK_USER_TOKEN_PREFIX.length), + ); + + return mockCredentials.user(userEntityRef); + } + + if (token.startsWith(MOCK_SERVICE_TOKEN_PREFIX)) { + const { targetPluginId, subject }: mockCredentials.service.TokenPayload = + JSON.parse(token.slice(MOCK_SERVICE_TOKEN_PREFIX.length)); + + if (targetPluginId && targetPluginId !== this.pluginId) { + throw new AuthenticationError( + `Invalid mock token target, got ${targetPluginId} but expected ${this.pluginId}`, + ); + } + + return mockCredentials.service(subject); + } + + throw new AuthenticationError('Invalid mock token'); } async getOwnServiceCredentials(): Promise< @@ -79,9 +104,24 @@ export class MockAuthService implements AuthService { switch (principal.type) { case 'user': - return { token: 'mock-user-token' }; + if (principal.userEntityRef === DEFAULT_MOCK_USER_ENTITY_REF) { + return { token: mockCredentials.user.token() }; + } + return { + token: mockCredentials.user.token({ + userEntityRef: principal.userEntityRef, + }), + }; case 'service': - return { token: `mock-service-token-for-${options.targetPluginId}` }; + return { + token: mockCredentials.service.token({ + targetPluginId: options.targetPluginId, + subject: + principal.subject === DEFAULT_MOCK_SERVICE_SUBJECT + ? undefined + : principal.subject, + }), + }; default: throw new AuthenticationError( `Refused to issue service token for credential type '${principal.type}'`, diff --git a/packages/backend-test-utils/src/next/services/index.ts b/packages/backend-test-utils/src/next/services/index.ts index 97a22567fd..7c3949e207 100644 --- a/packages/backend-test-utils/src/next/services/index.ts +++ b/packages/backend-test-utils/src/next/services/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { mockServices, type ServiceMock } from './mockServices'; +export { mockCredentials } from './mockCredentials'; diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts new file mode 100644 index 0000000000..3b77cee9a5 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -0,0 +1,120 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BackstageCredentials, + BackstageNonePrincipal, + BackstageServicePrincipal, + BackstageUserPrincipal, +} from '@backstage/backend-plugin-api'; + +export const DEFAULT_MOCK_USER_ENTITY_REF = 'user:default/mock'; +export const DEFAULT_MOCK_SERVICE_SUBJECT = 'external:test-service'; + +export const MOCK_USER_TOKEN = 'mock-user-token'; +export const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:'; +export const MOCK_SERVICE_TOKEN = 'mock-service-token'; +export const MOCK_SERVICE_TOKEN_PREFIX = 'mock-service-token:'; + +/** + * @public + */ +export namespace mockCredentials { + /** + * Creates a mocked credentials object for a unauthenticated principal. + */ + export function none(): BackstageCredentials { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'none' }, + }; + } + + /** + * Creates a mocked credentials object for a user principal. + * + * The default user entity reference is 'user:default/mock'. + */ + export function user( + userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF, + ): BackstageCredentials { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'user', userEntityRef }, + }; + } + + /** + * Utilities related to user credentials. + */ + export namespace user { + /** + * The payload that can be encoded into a mock user token. + */ + export type TokenPayload = { userEntityRef?: string }; + + /** + * Creates a mocked user token. If a payload is provided it will be encoded + * into the token and forwarded to the credentials object when authenticated + * by the mock auth service. + */ + export function token(payload?: TokenPayload): string { + if (payload) { + return `${MOCK_USER_TOKEN_PREFIX}:${JSON.stringify(payload)}`; + } + return MOCK_USER_TOKEN; + } + } + + /** + * Creates a mocked credentials object for a service principal. + * + * The default subject is 'external:test-service'. + */ + export function service( + subject: string = DEFAULT_MOCK_SERVICE_SUBJECT, + ): BackstageCredentials { + return { + $$type: '@backstage/BackstageCredentials', + principal: { type: 'service', subject }, + }; + } + + /** + * Utilities related to service credentials. + */ + export namespace service { + /** + * The payload that can be encoded into a mock service token. + */ + export type TokenPayload = { + subject?: string; + targetPluginId?: string; + }; + + /** + * Creates a mocked service token. If a payload is provided it will be + * encoded into the token and forwarded to the credentials object when + * authenticated by the mock auth service. + */ + export function token(payload?: TokenPayload): string { + if (payload) { + return `${MOCK_SERVICE_TOKEN_PREFIX}:${payload}`; + } + return MOCK_SERVICE_TOKEN; + } + } +} From 25609ed6623226592dbfc72f9fb589b923c90454 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 11:47:37 +0100 Subject: [PATCH 20/76] backend-test-utils: add MockHttpAuthService Signed-off-by: Patrik Oldsberg --- .../httpAuth/httpAuthServiceFactory.ts | 2 +- .../src/next/services/MockHttpAuthService.ts | 97 +++++++++++++++++++ .../src/next/services/mockServices.ts | 16 ++- 3 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 packages/backend-test-utils/src/next/services/MockHttpAuthService.ts diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 2182e94684..393991c6d0 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -63,7 +63,7 @@ type RequestWithCredentials = Request & { [credentialsSymbol]?: Promise; }; -export class DefaultHttpAuthService implements HttpAuthService { +class DefaultHttpAuthService implements HttpAuthService { constructor( private readonly auth: AuthService, private readonly discovery: DiscoveryService, diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts new file mode 100644 index 0000000000..d63d8a1769 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts @@ -0,0 +1,97 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AuthService, + BackstageCredentials, + BackstagePrincipalTypes, + HttpAuthService, +} from '@backstage/backend-plugin-api'; +import { Request, Response } from 'express'; +import { mockCredentials } from './mockCredentials'; +import { MockAuthService } from './MockAuthService'; +import { NotAllowedError, NotImplementedError } from '@backstage/errors'; + +// TODO: support mock cookie auth? +export class MockHttpAuthService implements HttpAuthService { + #auth: AuthService; + + constructor(pluginId: string) { + this.#auth = new MockAuthService(pluginId); + } + + async #getCredentials(req: Request) { + const header = req.headers.authorization; + const token = + typeof header === 'string' + ? header.match(/^Bearer[ ]+(\S+)$/i)?.[1] + : undefined; + if (!token) { + return mockCredentials.none(); + } + + return await this.#auth.authenticate(token); + } + + async credentials( + req: Request, + options?: { + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; + }, + ): Promise> { + const credentials = await this.#getCredentials(req); + + const allowedPrincipalTypes = options?.allow; + if (!allowedPrincipalTypes) { + return credentials as any; + } + + if (this.#auth.isPrincipal(credentials, 'unauthenticated')) { + if (allowedPrincipalTypes.includes('none' as TAllowed)) { + return credentials as any; + } + + throw new NotAllowedError( + `This endpoint does not allow 'unauthenticated' credentials`, + ); + } else if (this.#auth.isPrincipal(credentials, 'user')) { + if (allowedPrincipalTypes.includes('user' as TAllowed)) { + return credentials as any; + } + + throw new NotAllowedError( + `This endpoint does not allow 'user' credentials`, + ); + } else if (this.#auth.isPrincipal(credentials, 'service')) { + if (allowedPrincipalTypes.includes('service' as TAllowed)) { + return credentials as any; + } + + throw new NotAllowedError( + `This endpoint does not allow 'service' credentials`, + ); + } + + throw new NotAllowedError( + 'Unknown principal type, this should never happen', + ); + } + + async issueUserCookie(_res: Response): Promise { + throw new NotImplementedError('Not implemented'); + } +} diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 63f8ffbd93..0d88c6b377 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -38,7 +38,6 @@ import { rootLifecycleServiceFactory, schedulerServiceFactory, urlReaderServiceFactory, - httpAuthServiceFactory, discoveryServiceFactory, HostDiscovery, } from '@backstage/backend-app-api'; @@ -47,8 +46,7 @@ import { JsonObject } from '@backstage/types'; import { MockIdentityService } from './MockIdentityService'; import { MockRootLoggerService } from './MockRootLoggerService'; import { MockAuthService } from './MockAuthService'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { DefaultHttpAuthService } from '../../../../backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory'; +import { MockHttpAuthService } from './MockHttpAuthService'; /** @internal */ function simpleFactory< @@ -206,14 +204,14 @@ export namespace mockServices { } export function httpAuth(options?: { pluginId?: string }): HttpAuthService { - return new DefaultHttpAuthService( - auth(), - discovery(), - options?.pluginId ?? 'test', - ); + return new MockHttpAuthService(options?.pluginId ?? 'test'); } export namespace httpAuth { - export const factory = httpAuthServiceFactory; + export const factory = createServiceFactory({ + service: coreServices.httpAuth, + deps: { plugin: coreServices.pluginMetadata }, + factory: ({ plugin }) => new MockHttpAuthService(plugin.getId()), + }); export const mock = simpleMock(coreServices.httpAuth, () => ({ credentials: jest.fn(), issueUserCookie: jest.fn(), From 4c72edd4c03cc19f719dbd54b0ac9b1ad0362001 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 12:17:06 +0100 Subject: [PATCH 21/76] backend-app-api: always return true from auth.isPrincipal for unknown checks Signed-off-by: Patrik Oldsberg --- .../src/services/implementations/auth/authServiceFactory.ts | 4 ++++ .../backend-test-utils/src/next/services/MockAuthService.ts | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index dac8ae6d9e..86aeeea74d 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -147,6 +147,10 @@ class DefaultAuthService implements AuthService { | BackstageUserPrincipal | BackstageServicePrincipal; + if (type === 'unknown') { + return true; + } + if (principal.type !== type) { return false; } diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index b73bb7875f..6be358b83a 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -86,6 +86,11 @@ export class MockAuthService implements AuthService { | BackstageUserPrincipal | BackstageServicePrincipal | BackstageNonePrincipal; + + if (type === 'unknown') { + return true; + } + if (principal.type !== type) { return false; } From ddb7060e081d54019dfbded8227b5fd8ac862e48 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 12:18:35 +0100 Subject: [PATCH 22/76] backend-plugin-api: switch principal mapping to use none instead of unauthenticated Signed-off-by: Patrik Oldsberg --- packages/backend-plugin-api/api-report.md | 2 +- .../src/services/definitions/AuthService.ts | 2 +- .../src/next/services/MockHttpAuthService.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 320e05dd3d..d676de2fce 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -115,7 +115,7 @@ export type BackstageNonePrincipal = { export type BackstagePrincipalTypes = { user: BackstageUserPrincipal; service: BackstageServicePrincipal; - unauthenticated: BackstageNonePrincipal; + none: BackstageNonePrincipal; unknown: unknown; }; diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index dc38b572c5..eab0a7fac7 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -55,7 +55,7 @@ export type BackstageCredentials = { export type BackstagePrincipalTypes = { user: BackstageUserPrincipal; service: BackstageServicePrincipal; - unauthenticated: BackstageNonePrincipal; + none: BackstageNonePrincipal; unknown: unknown; }; diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts index d63d8a1769..02eb305915 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts @@ -60,13 +60,13 @@ export class MockHttpAuthService implements HttpAuthService { return credentials as any; } - if (this.#auth.isPrincipal(credentials, 'unauthenticated')) { + if (this.#auth.isPrincipal(credentials, 'none')) { if (allowedPrincipalTypes.includes('none' as TAllowed)) { return credentials as any; } throw new NotAllowedError( - `This endpoint does not allow 'unauthenticated' credentials`, + `This endpoint does not allow 'none' credentials`, ); } else if (this.#auth.isPrincipal(credentials, 'user')) { if (allowedPrincipalTypes.includes('user' as TAllowed)) { From f69b9dadf96a2b089632a9a900863bd6eae72e9f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 12:19:09 +0100 Subject: [PATCH 23/76] backend-test-utils: add MockServiceAuth tests + fixes Signed-off-by: Patrik Oldsberg --- .../src/next/services/MockAuthService.test.ts | 169 ++++++++++++++++++ .../src/next/services/MockAuthService.ts | 7 +- .../src/next/services/mockCredentials.ts | 9 +- 3 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 packages/backend-test-utils/src/next/services/MockAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts new file mode 100644 index 0000000000..e94f944d8b --- /dev/null +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -0,0 +1,169 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { MockAuthService } from './MockAuthService'; +import { + DEFAULT_MOCK_SERVICE_SUBJECT, + DEFAULT_MOCK_USER_ENTITY_REF, + MOCK_SERVICE_TOKEN_PREFIX, + MOCK_USER_TOKEN_PREFIX, + mockCredentials, +} from './mockCredentials'; + +describe('MockAuthService', () => { + const auth = new MockAuthService('test'); + + it('should reject invalid tokens', async () => { + await expect(auth.authenticate('')).rejects.toThrow('Invalid mock token'); + await expect(auth.authenticate('not-a-mock-token')).rejects.toThrow( + 'Invalid mock token', + ); + await expect(auth.authenticate(MOCK_USER_TOKEN_PREFIX)).rejects.toThrow( + 'Unexpected end of JSON input', + ); + await expect( + auth.authenticate(`${MOCK_USER_TOKEN_PREFIX}{"invalid":json}`), + ).rejects.toThrow('Unexpected token'); + await expect(auth.authenticate(MOCK_SERVICE_TOKEN_PREFIX)).rejects.toThrow( + 'Unexpected end of JSON input', + ); + await expect( + auth.authenticate(`${MOCK_SERVICE_TOKEN_PREFIX}{"invalid":json}`), + ).rejects.toThrow('Unexpected token'); + }); + + it('should authenticate mock user tokens', async () => { + await expect( + auth.authenticate(mockCredentials.user.token()), + ).resolves.toEqual(mockCredentials.user()); + + await expect( + auth.authenticate(mockCredentials.user.token()), + ).resolves.toEqual(mockCredentials.user(DEFAULT_MOCK_USER_ENTITY_REF)); + + await expect( + auth.authenticate( + mockCredentials.user.token({ userEntityRef: 'user:default/other' }), + ), + ).resolves.toEqual(mockCredentials.user('user:default/other')); + }); + + it('should authenticate mock service tokens', async () => { + await expect( + auth.authenticate(mockCredentials.service.token()), + ).resolves.toEqual(mockCredentials.service()); + + await expect( + auth.authenticate(mockCredentials.service.token()), + ).resolves.toEqual(mockCredentials.service(DEFAULT_MOCK_SERVICE_SUBJECT)); + + await expect( + auth.authenticate( + mockCredentials.service.token({ subject: 'plugin:catalog' }), + ), + ).resolves.toEqual(mockCredentials.service('plugin:catalog')); + + await expect( + auth.authenticate( + mockCredentials.service.token({ + targetPluginId: 'test', + }), + ), + ).resolves.toEqual(mockCredentials.service()); + + await expect( + auth.authenticate( + mockCredentials.service.token({ + targetPluginId: 'other', + }), + ), + ).rejects.toThrow( + "Invalid mock token target plugin ID, got 'other' but expected 'test'", + ); + }); + + it('should return own service credentials', async () => { + await expect(auth.getOwnServiceCredentials()).resolves.toEqual( + mockCredentials.service('plugin:test'), + ); + }); + + it('should check principal types', () => { + const none = mockCredentials.none(); + const user = mockCredentials.user(); + const service = mockCredentials.service(); + + expect(auth.isPrincipal(none, 'unknown')).toBe(true); + expect(auth.isPrincipal(user, 'unknown')).toBe(true); + expect(auth.isPrincipal(service, 'unknown')).toBe(true); + + expect(auth.isPrincipal(none, 'none')).toBe(true); + expect(auth.isPrincipal(user, 'none')).toBe(false); + expect(auth.isPrincipal(service, 'none')).toBe(false); + + expect(auth.isPrincipal(none, 'user')).toBe(false); + expect(auth.isPrincipal(user, 'user')).toBe(true); + expect(auth.isPrincipal(service, 'user')).toBe(false); + + expect(auth.isPrincipal(none, 'service')).toBe(false); + expect(auth.isPrincipal(user, 'service')).toBe(false); + expect(auth.isPrincipal(service, 'service')).toBe(true); + }); + + it('should issue plugin request tokens', async () => { + await expect( + auth.getPluginRequestToken({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'test', + }), + ).resolves.toEqual({ token: mockCredentials.user.token() }); + + await expect( + auth.getPluginRequestToken({ + onBehalfOf: mockCredentials.service(), + targetPluginId: 'test', + }), + ).resolves.toEqual({ + token: mockCredentials.service.token({ + targetPluginId: 'test', + }), + }); + + await expect( + auth.getPluginRequestToken({ + onBehalfOf: mockCredentials.service('external:other'), + targetPluginId: 'test', + }), + ).resolves.toEqual({ + token: mockCredentials.service.token({ + subject: 'external:other', + targetPluginId: 'test', + }), + }); + + await expect( + auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'other', + }), + ).resolves.toEqual({ + token: mockCredentials.service.token({ + subject: 'plugin:test', + targetPluginId: 'other', + }), + }); + }); +}); diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 6be358b83a..2ac7fff3a1 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -59,7 +59,7 @@ export class MockAuthService implements AuthService { if (targetPluginId && targetPluginId !== this.pluginId) { throw new AuthenticationError( - `Invalid mock token target, got ${targetPluginId} but expected ${this.pluginId}`, + `Invalid mock token target plugin ID, got '${targetPluginId}' but expected '${this.pluginId}'`, ); } @@ -72,10 +72,7 @@ export class MockAuthService implements AuthService { async getOwnServiceCredentials(): Promise< BackstageCredentials > { - return { - $$type: '@backstage/BackstageCredentials', - principal: { type: 'service', subject: `plugin:${this.pluginId}` }, - }; + return mockCredentials.service(`plugin:${this.pluginId}`); } isPrincipal( diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index 3b77cee9a5..2e7a4933a6 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -73,7 +73,8 @@ export namespace mockCredentials { */ export function token(payload?: TokenPayload): string { if (payload) { - return `${MOCK_USER_TOKEN_PREFIX}:${JSON.stringify(payload)}`; + const { userEntityRef } = payload; // for fixed ordering + return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({ userEntityRef })}`; } return MOCK_USER_TOKEN; } @@ -112,7 +113,11 @@ export namespace mockCredentials { */ export function token(payload?: TokenPayload): string { if (payload) { - return `${MOCK_SERVICE_TOKEN_PREFIX}:${payload}`; + const { subject, targetPluginId } = payload; // for fixed ordering + return `${MOCK_SERVICE_TOKEN_PREFIX}${JSON.stringify({ + subject, + targetPluginId, + })}`; } return MOCK_SERVICE_TOKEN; } From 67e53eb38feb6c640acb7463bec84935cf368926 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 14:13:10 +0100 Subject: [PATCH 24/76] backend-test-utils: added header utils to mockCredentials Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 4 +++- .../src/next/services/mockCredentials.ts | 18 ++++++++++++++++++ .../src/next/wiring/TestBackend.test.ts | 9 +++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 05074c7f60..5c22cfb149 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -53,6 +53,7 @@ export namespace mockCredentials { subject?: string, ): BackstageCredentials; export namespace service { + export function header(payload?: TokenPayload): string; export function token(payload?: TokenPayload): string; export type TokenPayload = { subject?: string; @@ -63,9 +64,10 @@ export namespace mockCredentials { userEntityRef?: string, ): BackstageCredentials; export namespace user { + export function header(payload?: TokenPayload): string; export function token(payload?: TokenPayload): string; export type TokenPayload = { - userEntityRef: string; + userEntityRef?: string; }; } } diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index 2e7a4933a6..7eda645150 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -78,6 +78,15 @@ export namespace mockCredentials { } return MOCK_USER_TOKEN; } + + /** + * Returns an authorization header with a mocked user token. If a payload is + * provided it will be encoded into the token and forwarded to the + * credentials object when authenticated by the mock auth service. + */ + export function header(payload?: TokenPayload): string { + return `Bearer ${token(payload)}`; + } } /** @@ -121,5 +130,14 @@ export namespace mockCredentials { } return MOCK_SERVICE_TOKEN; } + + /** + * Returns an authorization header with a mocked service token. If a + * payload is provided it will be encoded into the token and forwarded to + * the credentials object when authenticated by the mock auth service. + */ + export function header(payload?: TokenPayload): string { + return `Bearer ${token(payload)}`; + } } } diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index 968237f11d..a4b74b5ffa 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -26,6 +26,7 @@ import { Router } from 'express'; import request from 'supertest'; import { startTestBackend } from './TestBackend'; +import { mockCredentials } from '../services'; // This bit makes sure that test backends are cleaned up properly let globalTestBackendHasBeenStopped = false; @@ -199,9 +200,11 @@ describe('TestBackend', () => { scheduler: coreServices.scheduler, tokenManager: coreServices.tokenManager, urlReader: coreServices.urlReader, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, }, async init(deps) { - expect(Object.keys(deps)).toHaveLength(15); + expect(Object.keys(deps)).toHaveLength(17); expect(Object.values(deps)).not.toContain(undefined); }, }); @@ -232,7 +235,9 @@ describe('TestBackend', () => { const { server } = await startTestBackend({ features: [testPlugin()] }); - const res = await request(server).get('/api/test/ping-me'); + const res = await request(server) + .get('/api/test/ping-me') + .set('authorization', mockCredentials.user.header()); expect(res.status).toEqual(200); expect(res.body).toEqual({ message: 'pong' }); }); From f3e11ff0ccc117d43e7da8f65f692e0a20fb92ca Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 14:36:25 +0100 Subject: [PATCH 25/76] backend-test-utils: mockCredentials refactor for ref validation, header, inline payload + tests Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 4 +- .../src/next/services/MockAuthService.test.ts | 4 +- .../src/next/services/MockAuthService.ts | 4 +- .../src/next/services/mockCredentials.test.ts | 142 ++++++++++++++++++ .../src/next/services/mockCredentials.ts | 19 ++- 5 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 packages/backend-test-utils/src/next/services/mockCredentials.test.ts diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 5c22cfb149..b553d20e48 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -64,8 +64,8 @@ export namespace mockCredentials { userEntityRef?: string, ): BackstageCredentials; export namespace user { - export function header(payload?: TokenPayload): string; - export function token(payload?: TokenPayload): string; + export function header(userEntityRef?: string): string; + export function token(userEntityRef?: string): string; export type TokenPayload = { userEntityRef?: string; }; diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index e94f944d8b..b354301c53 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -55,9 +55,7 @@ describe('MockAuthService', () => { ).resolves.toEqual(mockCredentials.user(DEFAULT_MOCK_USER_ENTITY_REF)); await expect( - auth.authenticate( - mockCredentials.user.token({ userEntityRef: 'user:default/other' }), - ), + auth.authenticate(mockCredentials.user.token('user:default/other')), ).resolves.toEqual(mockCredentials.user('user:default/other')); }); diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 2ac7fff3a1..38a068adeb 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -110,9 +110,7 @@ export class MockAuthService implements AuthService { return { token: mockCredentials.user.token() }; } return { - token: mockCredentials.user.token({ - userEntityRef: principal.userEntityRef, - }), + token: mockCredentials.user.token(principal.userEntityRef), }; case 'service': return { diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts new file mode 100644 index 0000000000..aaa2626309 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts @@ -0,0 +1,142 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockCredentials } from './mockCredentials'; + +describe('mockCredentials', () => { + it('creates a mocked credentials object for a none principal', () => { + expect(mockCredentials.none()).toEqual({ + $$type: '@backstage/BackstageCredentials', + principal: { type: 'none' }, + }); + }); + + it('creates a mocked credentials object for a user principal', () => { + expect(mockCredentials.user()).toEqual({ + $$type: '@backstage/BackstageCredentials', + principal: { type: 'user', userEntityRef: 'user:default/mock' }, + }); + + expect(mockCredentials.user('user:default/other')).toEqual({ + $$type: '@backstage/BackstageCredentials', + principal: { type: 'user', userEntityRef: 'user:default/other' }, + }); + }); + + it('creates a mocked credentials object for a service principal', () => { + expect(mockCredentials.service()).toEqual({ + $$type: '@backstage/BackstageCredentials', + principal: { type: 'service', subject: 'external:test-service' }, + }); + + expect(mockCredentials.service('plugin:other')).toEqual({ + $$type: '@backstage/BackstageCredentials', + principal: { type: 'service', subject: 'plugin:other' }, + }); + }); + + it('creates user tokens and headers', () => { + expect(mockCredentials.user.token()).toBe('mock-user-token'); + expect(mockCredentials.user.token('user:default/other')).toBe( + 'mock-user-token:{"userEntityRef":"user:default/other"}', + ); + expect(mockCredentials.user.header()).toBe('Bearer mock-user-token'); + expect(mockCredentials.user.header('user:default/other')).toBe( + 'Bearer mock-user-token:{"userEntityRef":"user:default/other"}', + ); + }); + + it('creates service tokens and headers', () => { + expect(mockCredentials.service.token()).toBe('mock-service-token'); + expect(mockCredentials.service.token({ subject: 'external:other' })).toBe( + 'mock-service-token:{"subject":"external:other"}', + ); + expect( + mockCredentials.service.token({ + targetPluginId: 'other', + }), + ).toBe('mock-service-token:{"targetPluginId":"other"}'); + expect( + mockCredentials.service.token({ + subject: 'external:other', + targetPluginId: 'other', + }), + ).toBe( + 'mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + ); + // Object keys are reordered, ordering in the token should be stable + expect( + mockCredentials.service.token({ + targetPluginId: 'other', + subject: 'external:other', + }), + ).toBe( + 'mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + ); + + expect(mockCredentials.service.header()).toBe('Bearer mock-service-token'); + expect(mockCredentials.service.header({ subject: 'external:other' })).toBe( + 'Bearer mock-service-token:{"subject":"external:other"}', + ); + expect( + mockCredentials.service.header({ + targetPluginId: 'other', + }), + ).toBe('Bearer mock-service-token:{"targetPluginId":"other"}'); + expect( + mockCredentials.service.header({ + subject: 'external:other', + targetPluginId: 'other', + }), + ).toBe( + 'Bearer mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + ); + // Object keys are reordered, ordering in the token should be stable + expect( + mockCredentials.service.header({ + targetPluginId: 'other', + subject: 'external:other', + }), + ).toBe( + 'Bearer mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + ); + }); + + it('should throw on invalid user entity refs', () => { + expect(() => mockCredentials.user('wrong')).toThrow( + "Invalid user entity reference 'wrong', expected :/", + ); + expect(() => mockCredentials.user('wr:ong')).toThrow( + "Invalid user entity reference 'wr:ong', expected :/", + ); + expect(() => mockCredentials.user('wr/ong')).toThrow( + "Invalid user entity reference 'wr/ong', expected :/", + ); + expect(() => mockCredentials.user('wr/o:ng')).toThrow( + "Invalid user entity reference 'wr/o:ng', expected :/", + ); + expect(() => mockCredentials.user('wr:/ong')).toThrow( + "Invalid user entity reference 'wr:/ong', expected :/", + ); + + expect(() => mockCredentials.user.token('wrong')).toThrow( + "Invalid user entity reference 'wrong', expected :/", + ); + expect(() => mockCredentials.user.header('wrong')).toThrow( + "Invalid user entity reference 'wrong', expected :/", + ); + }); +}); diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index 7eda645150..e86916db3b 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -29,6 +29,14 @@ export const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:'; export const MOCK_SERVICE_TOKEN = 'mock-service-token'; export const MOCK_SERVICE_TOKEN_PREFIX = 'mock-service-token:'; +function validateUserEntityRef(ref: string) { + if (!ref.match(/^.+:.+\/.+$/)) { + throw new TypeError( + `Invalid user entity reference '${ref}', expected :/`, + ); + } +} + /** * @public */ @@ -51,6 +59,7 @@ export namespace mockCredentials { export function user( userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF, ): BackstageCredentials { + validateUserEntityRef(userEntityRef); return { $$type: '@backstage/BackstageCredentials', principal: { type: 'user', userEntityRef }, @@ -71,9 +80,9 @@ export namespace mockCredentials { * into the token and forwarded to the credentials object when authenticated * by the mock auth service. */ - export function token(payload?: TokenPayload): string { - if (payload) { - const { userEntityRef } = payload; // for fixed ordering + export function token(userEntityRef?: string): string { + if (userEntityRef) { + validateUserEntityRef(userEntityRef); return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({ userEntityRef })}`; } return MOCK_USER_TOKEN; @@ -84,8 +93,8 @@ export namespace mockCredentials { * provided it will be encoded into the token and forwarded to the * credentials object when authenticated by the mock auth service. */ - export function header(payload?: TokenPayload): string { - return `Bearer ${token(payload)}`; + export function header(userEntityRef?: string): string { + return `Bearer ${token(userEntityRef)}`; } } From 74fb755273290021653f0e4dfe8e3d8cd569562e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 15:00:37 +0100 Subject: [PATCH 26/76] backend-test-utils: added mockCredentials utils for invalid credentials Signed-off-by: Patrik Oldsberg --- .../src/next/services/MockAuthService.test.ts | 8 ++++++++ .../src/next/services/MockAuthService.ts | 17 ++++++++++++----- .../src/next/services/mockCredentials.test.ts | 11 +++++++++++ .../src/next/services/mockCredentials.ts | 18 ++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index b354301c53..7a6e562c98 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -57,6 +57,10 @@ describe('MockAuthService', () => { await expect( auth.authenticate(mockCredentials.user.token('user:default/other')), ).resolves.toEqual(mockCredentials.user('user:default/other')); + + await expect( + auth.authenticate(mockCredentials.user.invalidToken()), + ).rejects.toThrow('User token is invalid'); }); it('should authenticate mock service tokens', async () => { @@ -91,6 +95,10 @@ describe('MockAuthService', () => { ).rejects.toThrow( "Invalid mock token target plugin ID, got 'other' but expected 'test'", ); + + await expect( + auth.authenticate(mockCredentials.service.invalidToken()), + ).rejects.toThrow('Service token is invalid'); }); it('should return own service credentials', async () => { diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 38a068adeb..7d1bbc0733 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -31,6 +31,8 @@ import { MOCK_SERVICE_TOKEN_PREFIX, DEFAULT_MOCK_USER_ENTITY_REF, DEFAULT_MOCK_SERVICE_SUBJECT, + MOCK_INVALID_USER_TOKEN, + MOCK_INVALID_SERVICE_TOKEN, } from './mockCredentials'; /** @internal */ @@ -38,11 +40,16 @@ export class MockAuthService implements AuthService { constructor(private readonly pluginId: string) {} async authenticate(token: string): Promise { - if (token === MOCK_USER_TOKEN) { - return mockCredentials.user(); - } - if (token === MOCK_SERVICE_TOKEN) { - return mockCredentials.service(); + switch (token) { + case MOCK_USER_TOKEN: + return mockCredentials.user(); + case MOCK_SERVICE_TOKEN: + return mockCredentials.service(); + case MOCK_INVALID_USER_TOKEN: + throw new AuthenticationError('User token is invalid'); + case MOCK_INVALID_SERVICE_TOKEN: + throw new AuthenticationError('Service token is invalid'); + default: } if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) { diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts index aaa2626309..3d7540a0ee 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts @@ -53,10 +53,15 @@ describe('mockCredentials', () => { expect(mockCredentials.user.token('user:default/other')).toBe( 'mock-user-token:{"userEntityRef":"user:default/other"}', ); + expect(mockCredentials.user.invalidToken()).toBe('mock-invalid-user-token'); + expect(mockCredentials.user.header()).toBe('Bearer mock-user-token'); expect(mockCredentials.user.header('user:default/other')).toBe( 'Bearer mock-user-token:{"userEntityRef":"user:default/other"}', ); + expect(mockCredentials.user.invalidHeader()).toBe( + 'Bearer mock-invalid-user-token', + ); }); it('creates service tokens and headers', () => { @@ -86,6 +91,9 @@ describe('mockCredentials', () => { ).toBe( 'mock-service-token:{"subject":"external:other","targetPluginId":"other"}', ); + expect(mockCredentials.service.invalidToken()).toBe( + 'mock-invalid-service-token', + ); expect(mockCredentials.service.header()).toBe('Bearer mock-service-token'); expect(mockCredentials.service.header({ subject: 'external:other' })).toBe( @@ -113,6 +121,9 @@ describe('mockCredentials', () => { ).toBe( 'Bearer mock-service-token:{"subject":"external:other","targetPluginId":"other"}', ); + expect(mockCredentials.service.invalidHeader()).toBe( + 'Bearer mock-invalid-service-token', + ); }); it('should throw on invalid user entity refs', () => { diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index e86916db3b..cf516c403a 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -26,8 +26,10 @@ export const DEFAULT_MOCK_SERVICE_SUBJECT = 'external:test-service'; export const MOCK_USER_TOKEN = 'mock-user-token'; export const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:'; +export const MOCK_INVALID_USER_TOKEN = 'mock-invalid-user-token'; export const MOCK_SERVICE_TOKEN = 'mock-service-token'; export const MOCK_SERVICE_TOKEN_PREFIX = 'mock-service-token:'; +export const MOCK_INVALID_SERVICE_TOKEN = 'mock-invalid-service-token'; function validateUserEntityRef(ref: string) { if (!ref.match(/^.+:.+\/.+$/)) { @@ -96,6 +98,14 @@ export namespace mockCredentials { export function header(userEntityRef?: string): string { return `Bearer ${token(userEntityRef)}`; } + + export function invalidToken(): string { + return MOCK_INVALID_USER_TOKEN; + } + + export function invalidHeader(): string { + return `Bearer ${invalidToken()}`; + } } /** @@ -148,5 +158,13 @@ export namespace mockCredentials { export function header(payload?: TokenPayload): string { return `Bearer ${token(payload)}`; } + + export function invalidToken(): string { + return MOCK_INVALID_SERVICE_TOKEN; + } + + export function invalidHeader(): string { + return `Bearer ${invalidToken()}`; + } } } From fe78da86f443e050528b2cd4cd6a389fcea905ec Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 15:23:01 +0100 Subject: [PATCH 27/76] backend-test-utils: added tests for MockHttpAuthService + fixes Signed-off-by: Patrik Oldsberg --- .../src/next/services/MockAuthService.test.ts | 4 +- .../src/next/services/MockAuthService.ts | 4 +- .../next/services/MockHttpAuthService.test.ts | 91 +++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index 7a6e562c98..cf7b23e999 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -27,9 +27,9 @@ describe('MockAuthService', () => { const auth = new MockAuthService('test'); it('should reject invalid tokens', async () => { - await expect(auth.authenticate('')).rejects.toThrow('Invalid mock token'); + await expect(auth.authenticate('')).rejects.toThrow('Token is empty'); await expect(auth.authenticate('not-a-mock-token')).rejects.toThrow( - 'Invalid mock token', + "Unknown mock token 'not-a-mock-token'", ); await expect(auth.authenticate(MOCK_USER_TOKEN_PREFIX)).rejects.toThrow( 'Unexpected end of JSON input', diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 7d1bbc0733..b5debd5c7d 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -49,6 +49,8 @@ export class MockAuthService implements AuthService { throw new AuthenticationError('User token is invalid'); case MOCK_INVALID_SERVICE_TOKEN: throw new AuthenticationError('Service token is invalid'); + case '': + throw new AuthenticationError('Token is empty'); default: } @@ -73,7 +75,7 @@ export class MockAuthService implements AuthService { return mockCredentials.service(subject); } - throw new AuthenticationError('Invalid mock token'); + throw new AuthenticationError(`Unknown mock token '${token}'`); } async getOwnServiceCredentials(): Promise< diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts new file mode 100644 index 0000000000..84d7c84ec3 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Request } from 'express'; +import { MockHttpAuthService } from './MockHttpAuthService'; +import { mockCredentials } from './mockCredentials'; + +describe('MockHttpAuthService', () => { + const httpAuth = new MockHttpAuthService('test'); + + it('should authenticate requests', async () => { + await expect( + httpAuth.credentials({ + headers: {}, + } as Request), + ).resolves.toEqual(mockCredentials.none()); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.user.header(), + }, + } as Request), + ).resolves.toEqual(mockCredentials.user()); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.user.header('user:default/other'), + }, + } as Request), + ).resolves.toEqual(mockCredentials.user('user:default/other')); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.service.header(), + }, + } as Request), + ).resolves.toEqual(mockCredentials.service()); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.service.header({ + subject: 'plugin:other', + }), + }, + } as Request), + ).resolves.toEqual(mockCredentials.service('plugin:other')); + }); + + it('should reject invalid credentials', async () => { + await expect( + httpAuth.credentials({ + headers: { + authorization: 'Bearer bad', + }, + } as Request), + ).rejects.toThrow("Unknown mock token 'bad'"); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.user.invalidHeader(), + }, + } as Request), + ).rejects.toThrow('User token is invalid'); + + await expect( + httpAuth.credentials({ + headers: { + authorization: mockCredentials.service.invalidHeader(), + }, + } as Request), + ).rejects.toThrow('Service token is invalid'); + }); +}); From cacf422f1f4c29fb016aea8d18c94b72657e534d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 16:55:39 +0100 Subject: [PATCH 28/76] backend-test-utils: more test coverage for mock auth services Signed-off-by: Patrik Oldsberg --- .../src/next/services/MockAuthService.test.ts | 18 +++ .../next/services/MockHttpAuthService.test.ts | 110 +++++++++++------- 2 files changed, 86 insertions(+), 42 deletions(-) diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index cf7b23e999..63a3e83c89 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -137,6 +137,15 @@ describe('MockAuthService', () => { }), ).resolves.toEqual({ token: mockCredentials.user.token() }); + await expect( + auth.getPluginRequestToken({ + onBehalfOf: mockCredentials.user('user:default/other'), + targetPluginId: 'test', + }), + ).resolves.toEqual({ + token: mockCredentials.user.token('user:default/other'), + }); + await expect( auth.getPluginRequestToken({ onBehalfOf: mockCredentials.service(), @@ -171,5 +180,14 @@ describe('MockAuthService', () => { targetPluginId: 'other', }), }); + + await expect( + auth.getPluginRequestToken({ + onBehalfOf: await mockCredentials.none(), + targetPluginId: 'other', + }), + ).rejects.toThrow( + `Refused to issue service token for credential type 'none'`, + ); }); }); diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts index 84d7c84ec3..62810604a6 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts @@ -21,71 +21,97 @@ import { mockCredentials } from './mockCredentials'; describe('MockHttpAuthService', () => { const httpAuth = new MockHttpAuthService('test'); - it('should authenticate requests', async () => { + function makeAuthReq(header?: string) { + return { headers: { authorization: header } } as Request; + } + + it('should authenticate unauthenticated requests', async () => { + await expect(httpAuth.credentials(makeAuthReq())).resolves.toEqual( + mockCredentials.none(), + ); + await expect( - httpAuth.credentials({ - headers: {}, - } as Request), + httpAuth.credentials(makeAuthReq(), { allow: ['none'] }), ).resolves.toEqual(mockCredentials.none()); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.user.header(), - }, - } as Request), + httpAuth.credentials(makeAuthReq(), { allow: ['user'] }), + ).rejects.toThrow("This endpoint does not allow 'none' credentials"); + + await expect(httpAuth.credentials(makeAuthReq())).resolves.toEqual( + mockCredentials.none(), + ); + }); + + it('should authenticate user requests', async () => { + await expect( + httpAuth.credentials(makeAuthReq(mockCredentials.user.header())), ).resolves.toEqual(mockCredentials.user()); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.user.header('user:default/other'), - }, - } as Request), - ).resolves.toEqual(mockCredentials.user('user:default/other')); + httpAuth.credentials(makeAuthReq(mockCredentials.user.header()), { + allow: ['user'], + }), + ).resolves.toEqual(mockCredentials.user()); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.service.header(), - }, - } as Request), + httpAuth.credentials(makeAuthReq(mockCredentials.user.header()), { + allow: ['none', 'service'], + }), + ).rejects.toThrow("This endpoint does not allow 'user' credentials"); + + await expect( + httpAuth.credentials( + makeAuthReq(mockCredentials.user.header('user:default/other')), + ), + ).resolves.toEqual(mockCredentials.user('user:default/other')); + }); + + it('should authenticate service requests', async () => { + await expect( + httpAuth.credentials(makeAuthReq(mockCredentials.service.header())), ).resolves.toEqual(mockCredentials.service()); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.service.header({ - subject: 'plugin:other', - }), - }, - } as Request), + httpAuth.credentials(makeAuthReq(mockCredentials.service.header()), { + allow: ['none', 'service'], + }), + ).resolves.toEqual(mockCredentials.service()); + + await expect( + httpAuth.credentials( + makeAuthReq( + mockCredentials.service.header({ subject: 'plugin:other' }), + ), + ), ).resolves.toEqual(mockCredentials.service('plugin:other')); + + await expect( + httpAuth.credentials(makeAuthReq(mockCredentials.service.header()), { + allow: ['user'], + }), + ).rejects.toThrow("This endpoint does not allow 'service' credentials"); }); it('should reject invalid credentials', async () => { await expect( - httpAuth.credentials({ - headers: { - authorization: 'Bearer bad', - }, - } as Request), + httpAuth.credentials(makeAuthReq('Bearer bad')), ).rejects.toThrow("Unknown mock token 'bad'"); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.user.invalidHeader(), - }, - } as Request), + httpAuth.credentials(makeAuthReq(mockCredentials.user.invalidHeader())), ).rejects.toThrow('User token is invalid'); await expect( - httpAuth.credentials({ - headers: { - authorization: mockCredentials.service.invalidHeader(), - }, - } as Request), + httpAuth.credentials( + makeAuthReq(mockCredentials.service.invalidHeader()), + ), ).rejects.toThrow('Service token is invalid'); }); + + it('does not implement .issueUserCookie', async () => { + await expect(httpAuth.issueUserCookie({} as any)).rejects.toThrow( + 'Not implemented', + ); + }); }); From 663fce7457d911fc724900a1d6186747a15499fd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 17 Feb 2024 01:16:22 +0100 Subject: [PATCH 29/76] backend-app-api: fix HttpRouter credentials barrier Signed-off-by: Patrik Oldsberg --- .../implementations/httpRouter/createCredentialsBarrier.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts index 6cdff9d32c..d786df1ecc 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts @@ -73,9 +73,9 @@ export function createCredentialsBarrier(options: { unauthenticatedPredicates.push(createPathPolicyPredicate(policy.path)); } else if (policy.allow === 'user-cookie') { cookiePredicates.push(createPathPolicyPredicate(policy.path)); + } else { + throw new Error('Invalid auth policy'); } - - throw new Error('Invalid auth policy'); }; return { middleware, addAuthPolicy }; From caf1af65415adc77ad6a8fc14096bc82094a5d14 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 17 Feb 2024 12:57:39 +0100 Subject: [PATCH 30/76] backend-test-utils: add default credentials for mock http auth + explicit none credentials header Signed-off-by: Patrik Oldsberg --- .../next/services/MockHttpAuthService.test.ts | 50 ++++++++++++++++++- .../src/next/services/MockHttpAuthService.ts | 14 ++++-- .../src/next/services/mockCredentials.test.ts | 4 ++ .../src/next/services/mockCredentials.ts | 20 ++++++++ .../src/next/services/mockServices.ts | 49 +++++++++++++++--- 5 files changed, 126 insertions(+), 11 deletions(-) diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts index 62810604a6..d441fd0108 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts @@ -19,7 +19,7 @@ import { MockHttpAuthService } from './MockHttpAuthService'; import { mockCredentials } from './mockCredentials'; describe('MockHttpAuthService', () => { - const httpAuth = new MockHttpAuthService('test'); + const httpAuth = new MockHttpAuthService('test', mockCredentials.none()); function makeAuthReq(header?: string) { return { headers: { authorization: header } } as Request; @@ -93,6 +93,54 @@ describe('MockHttpAuthService', () => { ).rejects.toThrow("This endpoint does not allow 'service' credentials"); }); + it('should default to different credential types', async () => { + const noneAuth = new MockHttpAuthService('test', mockCredentials.none()); + const userAuth = new MockHttpAuthService('test', mockCredentials.user()); + const serviceAuth = new MockHttpAuthService( + 'test', + mockCredentials.service(), + ); + + await expect(noneAuth.credentials(makeAuthReq())).resolves.toEqual( + mockCredentials.none(), + ); + await expect( + noneAuth.credentials(makeAuthReq(mockCredentials.none.header())), + ).resolves.toEqual(mockCredentials.none()); + await expect( + noneAuth.credentials(makeAuthReq(mockCredentials.user.header())), + ).resolves.toEqual(mockCredentials.user()); + await expect( + noneAuth.credentials(makeAuthReq(mockCredentials.service.header())), + ).resolves.toEqual(mockCredentials.service()); + + await expect(userAuth.credentials(makeAuthReq())).resolves.toEqual( + mockCredentials.user(), + ); + await expect( + userAuth.credentials(makeAuthReq(mockCredentials.none.header())), + ).resolves.toEqual(mockCredentials.none()); + await expect( + userAuth.credentials(makeAuthReq(mockCredentials.user.header())), + ).resolves.toEqual(mockCredentials.user()); + await expect( + userAuth.credentials(makeAuthReq(mockCredentials.service.header())), + ).resolves.toEqual(mockCredentials.service()); + + await expect(serviceAuth.credentials(makeAuthReq())).resolves.toEqual( + mockCredentials.service(), + ); + await expect( + serviceAuth.credentials(makeAuthReq(mockCredentials.none.header())), + ).resolves.toEqual(mockCredentials.none()); + await expect( + serviceAuth.credentials(makeAuthReq(mockCredentials.user.header())), + ).resolves.toEqual(mockCredentials.user()); + await expect( + serviceAuth.credentials(makeAuthReq(mockCredentials.service.header())), + ).resolves.toEqual(mockCredentials.service()); + }); + it('should reject invalid credentials', async () => { await expect( httpAuth.credentials(makeAuthReq('Bearer bad')), diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts index 02eb305915..79a940789a 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts @@ -21,26 +21,34 @@ import { HttpAuthService, } from '@backstage/backend-plugin-api'; import { Request, Response } from 'express'; -import { mockCredentials } from './mockCredentials'; import { MockAuthService } from './MockAuthService'; import { NotAllowedError, NotImplementedError } from '@backstage/errors'; +import { mockCredentials } from './mockCredentials'; // TODO: support mock cookie auth? export class MockHttpAuthService implements HttpAuthService { #auth: AuthService; + #defaultCredentials: BackstageCredentials; - constructor(pluginId: string) { + constructor(pluginId: string, defaultCredentials: BackstageCredentials) { this.#auth = new MockAuthService(pluginId); + this.#defaultCredentials = defaultCredentials; } async #getCredentials(req: Request) { const header = req.headers.authorization; + + if (header === mockCredentials.none.header()) { + return mockCredentials.none(); + } + const token = typeof header === 'string' ? header.match(/^Bearer[ ]+(\S+)$/i)?.[1] : undefined; + if (!token) { - return mockCredentials.none(); + return this.#defaultCredentials; } return await this.#auth.authenticate(token); diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts index 3d7540a0ee..7b0ff1e9be 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts @@ -48,6 +48,10 @@ describe('mockCredentials', () => { }); }); + it('creates unauthenticated tokens and headers', () => { + expect(mockCredentials.none.header()).toBe('Bearer mock-none-token'); + }); + it('creates user tokens and headers', () => { expect(mockCredentials.user.token()).toBe('mock-user-token'); expect(mockCredentials.user.token('user:default/other')).toBe( diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index cf516c403a..3b440b3a31 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -24,6 +24,7 @@ import { export const DEFAULT_MOCK_USER_ENTITY_REF = 'user:default/mock'; export const DEFAULT_MOCK_SERVICE_SUBJECT = 'external:test-service'; +export const MOCK_NONE_TOKEN = 'mock-none-token'; export const MOCK_USER_TOKEN = 'mock-user-token'; export const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:'; export const MOCK_INVALID_USER_TOKEN = 'mock-invalid-user-token'; @@ -53,6 +54,25 @@ export namespace mockCredentials { }; } + /** + * Utilities related to none credentials. + */ + export namespace none { + /** + * Returns an authorization header that translates to unauthenticated + * credentials. + * + * This is useful when one wants to explicitly test unauthenticated requests + * while still using the default behavior of the mock HttpAuthService where + * it defaults to user credentials. + */ + export function header(): string { + // NOTE: there is no .token() version of this because only the + // HttpAuthService should know about and consume this token + return `Bearer ${MOCK_NONE_TOKEN}`; + } + } + /** * Creates a mocked credentials object for a user principal. * diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 0d88c6b377..e87319c669 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -26,6 +26,7 @@ import { AuthService, DiscoveryService, HttpAuthService, + BackstageCredentials, } from '@backstage/backend-plugin-api'; import { cacheServiceFactory, @@ -47,6 +48,7 @@ import { MockIdentityService } from './MockIdentityService'; import { MockRootLoggerService } from './MockRootLoggerService'; import { MockAuthService } from './MockAuthService'; import { MockHttpAuthService } from './MockHttpAuthService'; +import { mockCredentials } from './mockCredentials'; /** @internal */ function simpleFactory< @@ -203,15 +205,48 @@ export namespace mockServices { })); } - export function httpAuth(options?: { pluginId?: string }): HttpAuthService { - return new MockHttpAuthService(options?.pluginId ?? 'test'); + /** + * Creates a mock implementation of the `HttpAuthService`. + * + * By default all requests without credentials are treated as requests from + * the default mock user principal. This behavior can be configured with the + * `defaultCredentials` option. + */ + export function httpAuth(options?: { + pluginId?: string; + /** + * The default credentials to use if there are no credentials present in the + * incoming request. + * + * By default all requests without credentials are treated as authenticated + * as the default mock user as returned from `mockCredentials.user()`. + */ + defaultCredentials?: BackstageCredentials; + }): HttpAuthService { + return new MockHttpAuthService( + options?.pluginId ?? 'test', + options?.defaultCredentials ?? mockCredentials.user(), + ); } export namespace httpAuth { - export const factory = createServiceFactory({ - service: coreServices.httpAuth, - deps: { plugin: coreServices.pluginMetadata }, - factory: ({ plugin }) => new MockHttpAuthService(plugin.getId()), - }); + /** + * Creates a mock service factory for the `HttpAuthService`. + * + * By default all requests without credentials are treated as requests from + * the default mock user principal. This behavior can be configured with the + * `defaultCredentials` option. + */ + export const factory = createServiceFactory( + (options?: { defaultCredentials?: BackstageCredentials }) => ({ + service: coreServices.httpAuth, + deps: { plugin: coreServices.pluginMetadata }, + factory: ({ plugin }) => + new MockHttpAuthService( + plugin.getId(), + options?.defaultCredentials ?? mockCredentials.user(), + ), + }), + ); export const mock = simpleMock(coreServices.httpAuth, () => ({ credentials: jest.fn(), issueUserCookie: jest.fn(), From faf5190d739c54b11d38a5be3c189e22530a9531 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 17 Feb 2024 18:00:42 +0100 Subject: [PATCH 31/76] backend-test-utils: refactor mock service auth tokens to mirror creation options Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 39 +++++++--- .../src/next/services/MockAuthService.test.ts | 30 ++++++-- .../src/next/services/MockAuthService.ts | 53 ++++++------- .../next/services/MockHttpAuthService.test.ts | 5 +- .../src/next/services/mockCredentials.test.ts | 42 +++-------- .../src/next/services/mockCredentials.ts | 74 +++++++++++++------ 6 files changed, 138 insertions(+), 105 deletions(-) diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index b553d20e48..949caddcfa 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -49,15 +49,22 @@ export function isDockerDisabledForTests(): boolean; // @public (undocumented) export namespace mockCredentials { export function none(): BackstageCredentials; + export namespace none { + export function header(): string; + } export function service( subject?: string, ): BackstageCredentials; export namespace service { - export function header(payload?: TokenPayload): string; - export function token(payload?: TokenPayload): string; - export type TokenPayload = { - subject?: string; - targetPluginId?: string; + export function header(options?: TokenOptions): string; + // (undocumented) + export function invalidHeader(): string; + // (undocumented) + export function invalidToken(): string; + export function token(options?: TokenOptions): string; + export type TokenOptions = { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }; } export function user( @@ -65,10 +72,11 @@ export namespace mockCredentials { ): BackstageCredentials; export namespace user { export function header(userEntityRef?: string): string; + // (undocumented) + export function invalidHeader(): string; + // (undocumented) + export function invalidToken(): string; export function token(userEntityRef?: string): string; - export type TokenPayload = { - userEntityRef?: string; - }; } } @@ -159,12 +167,19 @@ export namespace mockServices { partialImpl?: Partial | undefined, ) => ServiceMock; } - // (undocumented) - export function httpAuth(options?: { pluginId?: string }): HttpAuthService; + export function httpAuth(options?: { + pluginId?: string; + defaultCredentials?: BackstageCredentials; + }): HttpAuthService; // (undocumented) export namespace httpAuth { - const // (undocumented) - factory: () => ServiceFactory; + const factory: ( + options?: + | { + defaultCredentials?: BackstageCredentials | undefined; + } + | undefined, + ) => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index 63a3e83c89..261bc90f77 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -72,23 +72,32 @@ describe('MockAuthService', () => { auth.authenticate(mockCredentials.service.token()), ).resolves.toEqual(mockCredentials.service(DEFAULT_MOCK_SERVICE_SUBJECT)); + await expect( + auth.authenticate(mockCredentials.service.token()), + ).resolves.toEqual(mockCredentials.service()); + await expect( auth.authenticate( - mockCredentials.service.token({ subject: 'plugin:catalog' }), + mockCredentials.service.token({ + onBehalfOf: mockCredentials.service('plugin:catalog'), + targetPluginId: 'test', + }), ), ).resolves.toEqual(mockCredentials.service('plugin:catalog')); await expect( auth.authenticate( mockCredentials.service.token({ + onBehalfOf: await auth.getOwnServiceCredentials(), targetPluginId: 'test', }), ), - ).resolves.toEqual(mockCredentials.service()); + ).resolves.toEqual(mockCredentials.service('plugin:test')); await expect( auth.authenticate( mockCredentials.service.token({ + onBehalfOf: await auth.getOwnServiceCredentials(), targetPluginId: 'other', }), ), @@ -135,7 +144,12 @@ describe('MockAuthService', () => { onBehalfOf: mockCredentials.user(), targetPluginId: 'test', }), - ).resolves.toEqual({ token: mockCredentials.user.token() }); + ).resolves.toEqual({ + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'test', + }), + }); await expect( auth.getPluginRequestToken({ @@ -143,7 +157,10 @@ describe('MockAuthService', () => { targetPluginId: 'test', }), ).resolves.toEqual({ - token: mockCredentials.user.token('user:default/other'), + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user('user:default/other'), + targetPluginId: 'test', + }), }); await expect( @@ -153,6 +170,7 @@ describe('MockAuthService', () => { }), ).resolves.toEqual({ token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.service(), targetPluginId: 'test', }), }); @@ -164,7 +182,7 @@ describe('MockAuthService', () => { }), ).resolves.toEqual({ token: mockCredentials.service.token({ - subject: 'external:other', + onBehalfOf: mockCredentials.service('external:other'), targetPluginId: 'test', }), }); @@ -176,7 +194,7 @@ describe('MockAuthService', () => { }), ).resolves.toEqual({ token: mockCredentials.service.token({ - subject: 'plugin:test', + onBehalfOf: await mockCredentials.service('plugin:test'), targetPluginId: 'other', }), }); diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index b5debd5c7d..5c58240b42 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -29,10 +29,10 @@ import { MOCK_USER_TOKEN_PREFIX, MOCK_SERVICE_TOKEN, MOCK_SERVICE_TOKEN_PREFIX, - DEFAULT_MOCK_USER_ENTITY_REF, - DEFAULT_MOCK_SERVICE_SUBJECT, MOCK_INVALID_USER_TOKEN, MOCK_INVALID_SERVICE_TOKEN, + UserTokenPayload, + ServiceTokenPayload, } from './mockCredentials'; /** @internal */ @@ -55,7 +55,7 @@ export class MockAuthService implements AuthService { } if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) { - const { userEntityRef }: mockCredentials.user.TokenPayload = JSON.parse( + const { sub: userEntityRef }: UserTokenPayload = JSON.parse( token.slice(MOCK_USER_TOKEN_PREFIX.length), ); @@ -63,16 +63,20 @@ export class MockAuthService implements AuthService { } if (token.startsWith(MOCK_SERVICE_TOKEN_PREFIX)) { - const { targetPluginId, subject }: mockCredentials.service.TokenPayload = - JSON.parse(token.slice(MOCK_SERVICE_TOKEN_PREFIX.length)); + const { sub, target, obo }: ServiceTokenPayload = JSON.parse( + token.slice(MOCK_SERVICE_TOKEN_PREFIX.length), + ); - if (targetPluginId && targetPluginId !== this.pluginId) { + if (target && target !== this.pluginId) { throw new AuthenticationError( - `Invalid mock token target plugin ID, got '${targetPluginId}' but expected '${this.pluginId}'`, + `Invalid mock token target plugin ID, got '${target}' but expected '${this.pluginId}'`, ); } + if (obo) { + return mockCredentials.user(obo); + } - return mockCredentials.service(subject); + return mockCredentials.service(sub); } throw new AuthenticationError(`Unknown mock token '${token}'`); @@ -113,28 +117,17 @@ export class MockAuthService implements AuthService { | BackstageServicePrincipal | BackstageNonePrincipal; - switch (principal.type) { - case 'user': - if (principal.userEntityRef === DEFAULT_MOCK_USER_ENTITY_REF) { - return { token: mockCredentials.user.token() }; - } - return { - token: mockCredentials.user.token(principal.userEntityRef), - }; - case 'service': - return { - token: mockCredentials.service.token({ - targetPluginId: options.targetPluginId, - subject: - principal.subject === DEFAULT_MOCK_SERVICE_SUBJECT - ? undefined - : principal.subject, - }), - }; - default: - throw new AuthenticationError( - `Refused to issue service token for credential type '${principal.type}'`, - ); + if (principal.type !== 'user' && principal.type !== 'service') { + throw new AuthenticationError( + `Refused to issue service token for credential type '${principal.type}'`, + ); } + + return { + token: mockCredentials.service.token({ + onBehalfOf: options.onBehalfOf, + targetPluginId: options.targetPluginId, + }), + }; } } diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts index d441fd0108..6f21c709f7 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts @@ -81,7 +81,10 @@ describe('MockHttpAuthService', () => { await expect( httpAuth.credentials( makeAuthReq( - mockCredentials.service.header({ subject: 'plugin:other' }), + mockCredentials.service.header({ + onBehalfOf: mockCredentials.service('plugin:other'), + targetPluginId: 'test', + }), ), ), ).resolves.toEqual(mockCredentials.service('plugin:other')); diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts index 7b0ff1e9be..67cda92be8 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.test.ts @@ -55,13 +55,13 @@ describe('mockCredentials', () => { it('creates user tokens and headers', () => { expect(mockCredentials.user.token()).toBe('mock-user-token'); expect(mockCredentials.user.token('user:default/other')).toBe( - 'mock-user-token:{"userEntityRef":"user:default/other"}', + 'mock-user-token:{"sub":"user:default/other"}', ); expect(mockCredentials.user.invalidToken()).toBe('mock-invalid-user-token'); expect(mockCredentials.user.header()).toBe('Bearer mock-user-token'); expect(mockCredentials.user.header('user:default/other')).toBe( - 'Bearer mock-user-token:{"userEntityRef":"user:default/other"}', + 'Bearer mock-user-token:{"sub":"user:default/other"}', ); expect(mockCredentials.user.invalidHeader()).toBe( 'Bearer mock-invalid-user-token', @@ -70,60 +70,38 @@ describe('mockCredentials', () => { it('creates service tokens and headers', () => { expect(mockCredentials.service.token()).toBe('mock-service-token'); - expect(mockCredentials.service.token({ subject: 'external:other' })).toBe( - 'mock-service-token:{"subject":"external:other"}', - ); expect( mockCredentials.service.token({ + onBehalfOf: mockCredentials.service('external:other'), targetPluginId: 'other', }), - ).toBe('mock-service-token:{"targetPluginId":"other"}'); + ).toBe('mock-service-token:{"sub":"external:other","target":"other"}'); expect( mockCredentials.service.token({ - subject: 'external:other', + onBehalfOf: mockCredentials.user('user:default/other'), targetPluginId: 'other', }), - ).toBe( - 'mock-service-token:{"subject":"external:other","targetPluginId":"other"}', - ); - // Object keys are reordered, ordering in the token should be stable - expect( - mockCredentials.service.token({ - targetPluginId: 'other', - subject: 'external:other', - }), - ).toBe( - 'mock-service-token:{"subject":"external:other","targetPluginId":"other"}', - ); + ).toBe('mock-service-token:{"obo":"user:default/other","target":"other"}'); expect(mockCredentials.service.invalidToken()).toBe( 'mock-invalid-service-token', ); expect(mockCredentials.service.header()).toBe('Bearer mock-service-token'); - expect(mockCredentials.service.header({ subject: 'external:other' })).toBe( - 'Bearer mock-service-token:{"subject":"external:other"}', - ); expect( mockCredentials.service.header({ - targetPluginId: 'other', - }), - ).toBe('Bearer mock-service-token:{"targetPluginId":"other"}'); - expect( - mockCredentials.service.header({ - subject: 'external:other', + onBehalfOf: mockCredentials.service('external:other'), targetPluginId: 'other', }), ).toBe( - 'Bearer mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + 'Bearer mock-service-token:{"sub":"external:other","target":"other"}', ); - // Object keys are reordered, ordering in the token should be stable expect( mockCredentials.service.header({ + onBehalfOf: mockCredentials.user('user:default/other'), targetPluginId: 'other', - subject: 'external:other', }), ).toBe( - 'Bearer mock-service-token:{"subject":"external:other","targetPluginId":"other"}', + 'Bearer mock-service-token:{"obo":"user:default/other","target":"other"}', ); expect(mockCredentials.service.invalidHeader()).toBe( 'Bearer mock-invalid-service-token', diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/next/services/mockCredentials.ts index 3b440b3a31..8dac9c1a4b 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/next/services/mockCredentials.ts @@ -40,6 +40,24 @@ function validateUserEntityRef(ref: string) { } } +/** + * The payload that can be encoded into a mock user token. + * @internal + */ +export type UserTokenPayload = { + sub?: string; +}; + +/** + * The payload that can be encoded into a mock service token. + * @internal + */ +export type ServiceTokenPayload = { + sub?: string; // service subject + obo?: string; // user entity reference + target?: string; // target plugin id +}; + /** * @public */ @@ -92,11 +110,6 @@ export namespace mockCredentials { * Utilities related to user credentials. */ export namespace user { - /** - * The payload that can be encoded into a mock user token. - */ - export type TokenPayload = { userEntityRef?: string }; - /** * Creates a mocked user token. If a payload is provided it will be encoded * into the token and forwarded to the credentials object when authenticated @@ -105,7 +118,9 @@ export namespace mockCredentials { export function token(userEntityRef?: string): string { if (userEntityRef) { validateUserEntityRef(userEntityRef); - return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({ userEntityRef })}`; + return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({ + sub: userEntityRef, + } satisfies UserTokenPayload)}`; } return MOCK_USER_TOKEN; } @@ -147,36 +162,47 @@ export namespace mockCredentials { */ export namespace service { /** - * The payload that can be encoded into a mock service token. + * Options for the creation of mock service tokens. */ - export type TokenPayload = { - subject?: string; - targetPluginId?: string; + export type TokenOptions = { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }; /** - * Creates a mocked service token. If a payload is provided it will be - * encoded into the token and forwarded to the credentials object when - * authenticated by the mock auth service. + * Creates a mocked service token. The provided options will be encoded into + * the token and forwarded to the credentials object when authenticated by + * the mock auth service. */ - export function token(payload?: TokenPayload): string { - if (payload) { - const { subject, targetPluginId } = payload; // for fixed ordering + export function token(options?: TokenOptions): string { + if (options) { + const { targetPluginId, onBehalfOf } = options; // for fixed ordering + + const oboPrincipal = onBehalfOf?.principal as + | BackstageServicePrincipal + | BackstageUserPrincipal + | BackstageNonePrincipal; + const obo = + oboPrincipal.type === 'user' ? oboPrincipal.userEntityRef : undefined; + const subject = + oboPrincipal.type === 'service' ? oboPrincipal.subject : undefined; + return `${MOCK_SERVICE_TOKEN_PREFIX}${JSON.stringify({ - subject, - targetPluginId, - })}`; + sub: subject, + obo, + target: targetPluginId, + } satisfies ServiceTokenPayload)}`; } return MOCK_SERVICE_TOKEN; } /** - * Returns an authorization header with a mocked service token. If a - * payload is provided it will be encoded into the token and forwarded to - * the credentials object when authenticated by the mock auth service. + * Returns an authorization header with a mocked service token. The provided + * options will be encoded into the token and forwarded to the credentials + * object when authenticated by the mock auth service. */ - export function header(payload?: TokenPayload): string { - return `Bearer ${token(payload)}`; + export function header(options?: TokenOptions): string { + return `Bearer ${token(options)}`; } export function invalidToken(): string { From cb993f9dc80b05f662f99bf635d092c2f6387c5d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 19 Feb 2024 16:25:59 +0100 Subject: [PATCH 32/76] backend-app-api: treat rejected none credentials as 401 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .../implementations/httpAuth/httpAuthServiceFactory.ts | 3 +++ .../src/next/services/MockHttpAuthService.test.ts | 3 ++- .../src/next/services/MockHttpAuthService.ts | 10 ++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 393991c6d0..44199f4256 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -124,6 +124,9 @@ class DefaultHttpAuthService implements HttpAuthService { allowedPrincipalTypes && !allowedPrincipalTypes.includes(credentials.principal.type as TAllowed) ) { + if (credentials.authMethod === 'none') { + throw new AuthenticationError(); + } throw new NotAllowedError( `This endpoint does not allow '${credentials.principal.type}' credentials`, ); diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts index 6f21c709f7..922b3daaf4 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts @@ -17,6 +17,7 @@ import { Request } from 'express'; import { MockHttpAuthService } from './MockHttpAuthService'; import { mockCredentials } from './mockCredentials'; +import { AuthenticationError } from '@backstage/errors'; describe('MockHttpAuthService', () => { const httpAuth = new MockHttpAuthService('test', mockCredentials.none()); @@ -36,7 +37,7 @@ describe('MockHttpAuthService', () => { await expect( httpAuth.credentials(makeAuthReq(), { allow: ['user'] }), - ).rejects.toThrow("This endpoint does not allow 'none' credentials"); + ).rejects.toThrow(AuthenticationError); await expect(httpAuth.credentials(makeAuthReq())).resolves.toEqual( mockCredentials.none(), diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts index 79a940789a..2f067e9dcb 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts @@ -22,7 +22,11 @@ import { } from '@backstage/backend-plugin-api'; import { Request, Response } from 'express'; import { MockAuthService } from './MockAuthService'; -import { NotAllowedError, NotImplementedError } from '@backstage/errors'; +import { + AuthenticationError, + NotAllowedError, + NotImplementedError, +} from '@backstage/errors'; import { mockCredentials } from './mockCredentials'; // TODO: support mock cookie auth? @@ -73,9 +77,7 @@ export class MockHttpAuthService implements HttpAuthService { return credentials as any; } - throw new NotAllowedError( - `This endpoint does not allow 'none' credentials`, - ); + throw new AuthenticationError(); } else if (this.#auth.isPrincipal(credentials, 'user')) { if (allowedPrincipalTypes.includes('user' as TAllowed)) { return credentials as any; From a2b90a82d43da4a50aea776b005b293bdd671f8c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 19 Feb 2024 18:46:33 +0100 Subject: [PATCH 33/76] backend-app-api: added backend.auth.dangerouslyDisableDefaultAuthPolicy config + tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- packages/backend-app-api/config.d.ts | 20 ++ .../auth/authServiceFactory.ts | 24 ++- .../httpRouter/createCredentialsBarrier.ts | 15 +- .../httpRouterServiceFactory.test.ts | 194 ++++++++++++++++++ .../httpRouter/httpRouterServiceFactory.ts | 5 +- packages/backend-test-utils/api-report.md | 5 +- .../src/next/services/MockAuthService.test.ts | 5 +- .../src/next/services/MockAuthService.ts | 15 +- .../src/next/services/MockHttpAuthService.ts | 5 +- .../src/next/services/mockServices.ts | 27 ++- 10 files changed, 302 insertions(+), 13 deletions(-) diff --git a/packages/backend-app-api/config.d.ts b/packages/backend-app-api/config.d.ts index 86b63b527a..137615a152 100644 --- a/packages/backend-app-api/config.d.ts +++ b/packages/backend-app-api/config.d.ts @@ -15,6 +15,26 @@ */ export interface Config { + backend?: { + auth?: { + /** + * This disables the otherwise default auth policy, which requires all + * requests to be authenticated with either user or service credentials. + * + * Disabling this check means that the backend will no longer block + * unauthenticated requests, but instead allow them to pass through to + * plugins. + * + * If permissions are enabled, unauthenticated requests will be treated + * exactly as such, leaving it to the permission policy to determine what + * permissions should be allowed for an unauthenticated identity. Note + * that this will also apply to service-to-service calls between plugins + * unless you configure credentials for service calls. + */ + dangerouslyDisableDefaultAuthPolicy?: boolean; + }; + }; + /** Discovery options. */ discovery?: { /** diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index 86aeeea74d..72d5635f61 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -111,6 +111,7 @@ class DefaultAuthService implements AuthService { private readonly tokenManager: TokenManager, private readonly identity: IdentityService, private readonly pluginId: string, + private readonly disableDefaultAuthPolicy: boolean, ) {} async authenticate(token: string): Promise { @@ -171,6 +172,15 @@ class DefaultAuthService implements AuthService { const internalForward = toInternalBackstageCredentials(options.onBehalfOf); const { type } = internalForward.principal; + // Since disabling the default policy means we'll be allowing + // unauthenticated requests through, we might have unauthenticated + // credentials from service calls that reach this point. If that's the case, + // we'll want to keep "forwarding" the unauthenticated credentials, which we + // do by returning an empty token. + if (type === 'none' && this.disableDefaultAuthPolicy) { + return { token: '' }; + } + switch (type) { // TODO: Check whether the principal is ourselves case 'service': @@ -200,8 +210,18 @@ export const authServiceFactory = createServiceFactory({ createRootContext({ config, logger }) { return ServerTokenManager.fromConfig(config, { logger }); }, - async factory({ discovery, plugin }, tokenManager) { + async factory({ discovery, config, plugin }, tokenManager) { const identity = DefaultIdentityClient.create({ discovery }); - return new DefaultAuthService(tokenManager, identity, plugin.getId()); + const disableDefaultAuthPolicy = Boolean( + config.getOptionalBoolean( + 'backend.auth.dangerouslyDisableDefaultAuthPolicy', + ), + ); + return new DefaultAuthService( + tokenManager, + identity, + plugin.getId(), + disableDefaultAuthPolicy, + ); }, }); diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts index d786df1ecc..801c87d430 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts @@ -17,6 +17,7 @@ import { HttpAuthService, HttpRouterServiceAuthPolicy, + RootConfigService, } from '@backstage/backend-plugin-api'; import { RequestHandler } from 'express'; import { pathToRegexp } from 'path-to-regexp'; @@ -37,11 +38,23 @@ export function createPathPolicyPredicate(policyPath: string) { export function createCredentialsBarrier(options: { httpAuth: HttpAuthService; + config: RootConfigService; }): { middleware: RequestHandler; addAuthPolicy: (policy: HttpRouterServiceAuthPolicy) => void; } { - const { httpAuth } = options; + const { httpAuth, config } = options; + + const disableDefaultAuthPolicy = config.getOptionalBoolean( + 'backend.auth.dangerouslyDisableDefaultAuthPolicy', + ); + + if (disableDefaultAuthPolicy) { + return { + middleware: (_req, _res, next) => next(), + addAuthPolicy: () => {}, + }; + } const unauthenticatedPredicates = new Array<(path: string) => boolean>(); const cookiePredicates = new Array<(path: string) => boolean>(); diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts index a6c586d806..58c074f985 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts @@ -16,9 +16,17 @@ import { ServiceFactoryTester, + mockCredentials, mockServices, + startTestBackend, } from '@backstage/backend-test-utils'; import { httpRouterServiceFactory } from './httpRouterServiceFactory'; +import request from 'supertest'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import Router from 'express-promise-router'; describe('httpRouterFactory', () => { it('should register plugin paths', async () => { @@ -69,4 +77,190 @@ describe('httpRouterFactory', () => { expect.any(Function), ); }); + + describe('auth services', () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: { + httpRouter: coreServices.httpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + }, + async init({ httpRouter, auth, httpAuth }) { + const router = Router(); + httpRouter.use(router); + httpRouter.addAuthPolicy({ + path: '/public', + allow: 'unauthenticated', + }); + httpRouter.addAuthPolicy({ + path: '/cookie', + allow: 'user-cookie', + }); + + router.get('/public', (_req, res) => { + res.json({ ok: true }); + }); + router.get('/cookie', (_req, res) => { + res.json({ ok: true }); + }); + router.get('/protected/no-checks', (_req, res) => { + res.json({ ok: true }); + }); + router.get('/protected/only-users', async (req, res) => { + await httpAuth.credentials(req, { allow: ['user'] }); + res.json({ ok: true }); + }); + router.get('/protected/only-services', async (req, res) => { + await httpAuth.credentials(req, { allow: ['service'] }); + res.json({ ok: true }); + }); + router.get('/protected/credentials', async (req, res) => { + res.json({ + credentials: await httpAuth.credentials(req), + }); + }); + router.get('/protected/service-token', async (req, res) => { + res.json( + await auth.getPluginRequestToken({ + onBehalfOf: await httpAuth.credentials(req), + targetPluginId: 'test', + }), + ); + }); + }, + }); + }, + }); + + const defaultServices = [ + httpRouterServiceFactory(), + mockServices.httpAuth.factory({ + defaultCredentials: mockCredentials.none(), + }), + ]; + + it('should block unauthenticated requests by default', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + await expect( + request(server).get('/api/test/public'), + ).resolves.toMatchObject({ + status: 200, + }); + + // TODO: cookie + + await expect( + request(server).get('/api/test/protected/no-checks'), + ).resolves.toMatchObject({ + status: 401, + }); + }); + + it('should not block unauthenticated requests if default policy is disabled', async () => { + const { server } = await startTestBackend({ + features: [ + pluginSubject, + ...defaultServices, + mockServices.rootConfig.factory({ + data: { + backend: { auth: { dangerouslyDisableDefaultAuthPolicy: true } }, + }, + }), + ], + }); + + await expect( + request(server).get('/api/test/public'), + ).resolves.toMatchObject({ + status: 200, + }); + + // TODO: cookie + + await expect( + request(server).get('/api/test/protected/no-checks'), + ).resolves.toMatchObject({ + status: 200, + body: { ok: true }, + }); + + await expect( + request(server).get('/api/test/protected/only-users'), + ).resolves.toMatchObject({ + status: 401, + }); + + await expect( + request(server).get('/api/test/protected/only-services'), + ).resolves.toMatchObject({ + status: 401, + }); + + await expect( + request(server).get('/api/test/protected/credentials'), + ).resolves.toMatchObject({ + status: 200, + body: { credentials: mockCredentials.none() }, + }); + + await expect( + request(server) + .get('/api/test/protected/credentials') + .set('authorization', mockCredentials.user.header()), + ).resolves.toMatchObject({ + status: 200, + body: { credentials: mockCredentials.user() }, + }); + + await expect( + request(server) + .get('/api/test/protected/credentials') + .set('authorization', mockCredentials.service.header()), + ).resolves.toMatchObject({ + status: 200, + body: { credentials: mockCredentials.service() }, + }); + + await expect( + request(server).get('/api/test/protected/service-token'), + ).resolves.toMatchObject({ + status: 200, + body: { token: '' }, + }); + + await expect( + request(server) + .get('/api/test/protected/service-token') + .set('authorization', mockCredentials.user.header()), + ).resolves.toMatchObject({ + status: 200, + body: { + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'test', + }), + }, + }); + + await expect( + request(server) + .get('/api/test/protected/service-token') + .set('authorization', mockCredentials.service.header()), + ).resolves.toMatchObject({ + status: 200, + body: { + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.service(), + targetPluginId: 'test', + }), + }, + }); + }); + }); }); diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts index 6c89834f2b..e72d091b96 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts @@ -40,18 +40,19 @@ export const httpRouterServiceFactory = createServiceFactory( service: coreServices.httpRouter, deps: { plugin: coreServices.pluginMetadata, + config: coreServices.rootConfig, lifecycle: coreServices.lifecycle, rootHttpRouter: coreServices.rootHttpRouter, httpAuth: coreServices.httpAuth, }, - async factory({ httpAuth, plugin, rootHttpRouter, lifecycle }) { + async factory({ httpAuth, config, plugin, rootHttpRouter, lifecycle }) { const getPath = options?.getPath ?? (id => `/api/${id}`); const path = getPath(plugin.getId()); const router = PromiseRouter(); rootHttpRouter.use(path, router); - const credentialsBarrier = createCredentialsBarrier({ httpAuth }); + const credentialsBarrier = createCredentialsBarrier({ httpAuth, config }); router.use(createLifecycleMiddleware({ lifecycle })); router.use(credentialsBarrier.middleware); diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 949caddcfa..a9ebb402c4 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -128,7 +128,10 @@ export interface MockDirectoryOptions { // @public (undocumented) export namespace mockServices { // (undocumented) - export function auth(options?: { pluginId?: string }): AuthService; + export function auth(options?: { + pluginId?: string; + disableDefaultAuthPolicy?: boolean; + }): AuthService; // (undocumented) export namespace auth { const // (undocumented) diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts index 261bc90f77..dfb54b9762 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.test.ts @@ -24,7 +24,10 @@ import { } from './mockCredentials'; describe('MockAuthService', () => { - const auth = new MockAuthService('test'); + const auth = new MockAuthService({ + pluginId: 'test', + disableDefaultAuthPolicy: false, + }); it('should reject invalid tokens', async () => { await expect(auth.authenticate('')).rejects.toThrow('Token is empty'); diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 5c58240b42..5735755f85 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -37,7 +37,16 @@ import { /** @internal */ export class MockAuthService implements AuthService { - constructor(private readonly pluginId: string) {} + readonly pluginId: string; + readonly disableDefaultAuthPolicy: boolean; + + constructor(options: { + pluginId: string; + disableDefaultAuthPolicy: boolean; + }) { + this.pluginId = options.pluginId; + this.disableDefaultAuthPolicy = options.disableDefaultAuthPolicy; + } async authenticate(token: string): Promise { switch (token) { @@ -117,6 +126,10 @@ export class MockAuthService implements AuthService { | BackstageServicePrincipal | BackstageNonePrincipal; + if (principal.type === 'none' && this.disableDefaultAuthPolicy) { + return { token: '' }; + } + if (principal.type !== 'user' && principal.type !== 'service') { throw new AuthenticationError( `Refused to issue service token for credential type '${principal.type}'`, diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts index 2f067e9dcb..9b133f996b 100644 --- a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts @@ -35,7 +35,10 @@ export class MockHttpAuthService implements HttpAuthService { #defaultCredentials: BackstageCredentials; constructor(pluginId: string, defaultCredentials: BackstageCredentials) { - this.#auth = new MockAuthService(pluginId); + this.#auth = new MockAuthService({ + pluginId, + disableDefaultAuthPolicy: false, + }); this.#defaultCredentials = defaultCredentials; } diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index e87319c669..f72f229434 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -169,14 +169,33 @@ export namespace mockServices { })); } - export function auth(options?: { pluginId?: string }): AuthService { - return new MockAuthService(options?.pluginId ?? 'test'); + export function auth(options?: { + pluginId?: string; + disableDefaultAuthPolicy?: boolean; + }): AuthService { + return new MockAuthService({ + pluginId: options?.pluginId ?? 'test', + disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy), + }); } export namespace auth { export const factory = createServiceFactory({ service: coreServices.auth, - deps: { plugin: coreServices.pluginMetadata }, - factory: ({ plugin }) => new MockAuthService(plugin.getId()), + deps: { + plugin: coreServices.pluginMetadata, + config: coreServices.rootConfig, + }, + factory({ plugin, config }) { + const disableDefaultAuthPolicy = Boolean( + config.getOptionalBoolean( + 'backend.auth.dangerouslyDisableDefaultAuthPolicy', + ), + ); + return new MockAuthService({ + pluginId: plugin.getId(), + disableDefaultAuthPolicy, + }); + }, }); export const mock = simpleMock(coreServices.auth, () => ({ authenticate: jest.fn(), From badc55b6c7671e6b142773eef328c084e263ab36 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 19 Feb 2024 19:08:53 +0100 Subject: [PATCH 34/76] kubernetes-backend: workaround for failing integration tests Signed-off-by: Patrik Oldsberg --- .../kubernetes-backend/src/routes/resourceRoutes.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/kubernetes-backend/src/routes/resourceRoutes.test.ts b/plugins/kubernetes-backend/src/routes/resourceRoutes.test.ts index 6d69606316..d3dcc83bb0 100644 --- a/plugins/kubernetes-backend/src/routes/resourceRoutes.test.ts +++ b/plugins/kubernetes-backend/src/routes/resourceRoutes.test.ts @@ -102,6 +102,12 @@ describe('resourcesRoutes', () => { }, ], }, + backend: { + auth: { + // TODO: Remove once migrated to support new auth services + dangerouslyDisableDefaultAuthPolicy: true, + }, + }, }, }), import('@backstage/plugin-kubernetes-backend/alpha'), From 7fe5355575aa992f9a12778c0b1e1920e526029d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 21 Feb 2024 14:52:14 +0100 Subject: [PATCH 35/76] app-config: disable default auth policy for development for now Signed-off-by: Patrik Oldsberg --- app-config.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app-config.yaml b/app-config.yaml index c53a6475f4..9b059da216 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -32,6 +32,12 @@ backend: # auth: # keys: # - secret: ${BACKEND_SECRET} + + auth: + # TODO: once plugins have been migrated we can remove this, but right now it + # is require for the backend-next to work in this repo + dangerouslyDisableDefaultAuthPolicy: true + baseUrl: http://localhost:7007 listen: port: 7007 From 9c4588183d23d2c0c7c510e5eea10edb0aad1ceb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 21 Feb 2024 14:53:52 +0100 Subject: [PATCH 36/76] backend-defaults: add new auth services Signed-off-by: Patrik Oldsberg --- packages/backend-defaults/src/CreateBackend.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index c07d1cc38a..5495665dd8 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -32,13 +32,18 @@ import { tokenManagerServiceFactory, urlReaderServiceFactory, identityServiceFactory, + authServiceFactory, + httpAuthServiceFactory, + userInfoServiceFactory, } from '@backstage/backend-app-api'; export const defaultServiceFactories = [ + authServiceFactory(), cacheServiceFactory(), rootConfigServiceFactory(), databaseServiceFactory(), discoveryServiceFactory(), + httpAuthServiceFactory(), httpRouterServiceFactory(), identityServiceFactory(), lifecycleServiceFactory(), @@ -49,6 +54,7 @@ export const defaultServiceFactories = [ rootLoggerServiceFactory(), schedulerServiceFactory(), tokenManagerServiceFactory(), + userInfoServiceFactory(), urlReaderServiceFactory(), ]; From b68b36b4558c9409e64c977f41530c5afce51a63 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 21 Feb 2024 14:54:37 +0100 Subject: [PATCH 37/76] backend-next: add auth backend with github provider for local development Signed-off-by: Patrik Oldsberg --- packages/backend-next/package.json | 2 + .../src/authModuleGithubProvider.ts | 57 +++++++++++++++++++ packages/backend-next/src/index.ts | 3 + yarn.lock | 4 +- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 packages/backend-next/src/authModuleGithubProvider.ts diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 98ae4c6ac4..c1f09cd0cb 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -30,6 +30,8 @@ "@backstage/backend-tasks": "workspace:^", "@backstage/plugin-adr-backend": "workspace:^", "@backstage/plugin-app-backend": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-backend-module-github-provider": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-azure-devops-backend": "workspace:^", "@backstage/plugin-badges-backend": "workspace:^", diff --git a/packages/backend-next/src/authModuleGithubProvider.ts b/packages/backend-next/src/authModuleGithubProvider.ts new file mode 100644 index 0000000000..5b71f35567 --- /dev/null +++ b/packages/backend-next/src/authModuleGithubProvider.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { githubAuthenticator } from '@backstage/plugin-auth-backend-module-github-provider'; +import { + authProvidersExtensionPoint, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; + +export default createBackendModule({ + pluginId: 'auth', + moduleId: 'githubProvider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + providerId: 'github', + factory: createOAuthProviderFactory({ + authenticator: githubAuthenticator, + async signInResolver({ result: { fullProfile } }, ctx) { + const userId = fullProfile.username; + if (!userId) { + throw new Error( + `GitHub user profile does not contain a username`, + ); + } + + const userEntityRef = `user:default/${userId}`; + + return ctx.issueToken({ + claims: { + sub: userEntityRef, + ent: [userEntityRef], + }, + }); + }, + }), + }); + }, + }); + }, +}); diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 9c61b98ec4..e4dd127208 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -18,6 +18,9 @@ import { createBackend } from '@backstage/backend-defaults'; const backend = createBackend(); +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('./authModuleGithubProvider')); + backend.add(import('@backstage/plugin-adr-backend')); backend.add(import('@backstage/plugin-app-backend/alpha')); backend.add(import('@backstage/plugin-azure-devops-backend')); diff --git a/yarn.lock b/yarn.lock index 218faf39a1..3726b83cf2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27358,6 +27358,8 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/plugin-adr-backend": "workspace:^" "@backstage/plugin-app-backend": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-azure-devops-backend": "workspace:^" "@backstage/plugin-badges-backend": "workspace:^" @@ -32125,7 +32127,7 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.15.4": +"jose@npm:^4.15.4, jose@npm:^4.6.0": version: 4.15.4 resolution: "jose@npm:4.15.4" checksum: dccad91cb3357f36423774a0b89ad830dd84b31090de65cd139b85488439f16a00f8c59c0773825e8a1adb0dd9d13ad725ad66e6ea33880ecb3959bb99e1ea5b From 4a3d434095c4bac92a03f4486f636d95e0fe768a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 21 Feb 2024 14:59:53 +0100 Subject: [PATCH 38/76] add changesets, bump to jose 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/big-yaks-film.md | 7 +++++++ .changeset/eleven-cows-learn.md | 9 +++++++++ .changeset/smart-owls-tease.md | 7 +++++++ .changeset/thirty-shirts-allow.md | 7 +++++++ packages/backend-app-api/package.json | 2 +- yarn.lock | 4 ++-- 6 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 .changeset/big-yaks-film.md create mode 100644 .changeset/eleven-cows-learn.md create mode 100644 .changeset/smart-owls-tease.md create mode 100644 .changeset/thirty-shirts-allow.md diff --git a/.changeset/big-yaks-film.md b/.changeset/big-yaks-film.md new file mode 100644 index 0000000000..432a876e97 --- /dev/null +++ b/.changeset/big-yaks-film.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Added support for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). These services will be present by default in test apps, and you can access mocked versions of their features under `mockServices.auth` and `mockServices.httpAuth` if you want to inspect or replace their behaviors. + +There is also a new `mockCredentials` that you can use for acquiring mocks of the various types of credentials that are used in the new system. diff --git a/.changeset/eleven-cows-learn.md b/.changeset/eleven-cows-learn.md new file mode 100644 index 0000000000..3af2c6dba1 --- /dev/null +++ b/.changeset/eleven-cows-learn.md @@ -0,0 +1,9 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Added the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution) to the `coreServices`. + +At the same time, the [`httpRouter`](https://backstage.io/docs/backend-system/core-services/http-router) service gained a new `addAuthPolicy` method that lets your plugin declare exemptions to the default auth policy - for example if you want to allow unauthenticated or cookie-based access to some subset of your feature routes. + +If you have migrated to the new backend system, please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to move toward using these services. diff --git a/.changeset/smart-owls-tease.md b/.changeset/smart-owls-tease.md new file mode 100644 index 0000000000..8d59586bf8 --- /dev/null +++ b/.changeset/smart-owls-tease.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-app-api': minor +--- + +**BREAKING**: For users that have migrated to the new backend system, incoming requests will now be rejected if they are not properly authenticated (e.g. with a Backstage bearer token or a backend token). Please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to circumvent this behavior in the short term and how to properly leverage it in the longer term. + +Added service factories for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). diff --git a/.changeset/thirty-shirts-allow.md b/.changeset/thirty-shirts-allow.md new file mode 100644 index 0000000000..b84a3a621e --- /dev/null +++ b/.changeset/thirty-shirts-allow.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-common': patch +--- + +Added a `createLegacyAuthAdapters` function that can be used as a compatibility adapter for backend plugins who want to start using the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). + +See the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on the usage of this adapter. diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index d5985d1172..448b4c500a 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -66,7 +66,7 @@ "express-promise-router": "^4.1.0", "fs-extra": "^11.2.0", "helmet": "^6.0.0", - "jose": "^4.6.0", + "jose": "^5.0.0", "lodash": "^4.17.21", "logform": "^2.3.2", "minimatch": "^5.0.0", diff --git a/yarn.lock b/yarn.lock index 3726b83cf2..5948d58b31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3251,7 +3251,7 @@ __metadata: fs-extra: ^11.2.0 helmet: ^6.0.0 http-errors: ^2.0.0 - jose: ^4.6.0 + jose: ^5.0.0 lodash: ^4.17.21 logform: ^2.3.2 minimatch: ^5.0.0 @@ -32127,7 +32127,7 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.15.4, jose@npm:^4.6.0": +"jose@npm:^4.15.4": version: 4.15.4 resolution: "jose@npm:4.15.4" checksum: dccad91cb3357f36423774a0b89ad830dd84b31090de65cd139b85488439f16a00f8c59c0773825e8a1adb0dd9d13ad725ad66e6ea33880ecb3959bb99e1ea5b From 402d99181f1166ffa52acad79ba4c4507067e4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 21 Feb 2024 17:32:04 +0100 Subject: [PATCH 39/76] more esm limitations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/unlucky-lizards-suffer.md | 6 ++++++ .github/renovate.json5 | 8 ++++++++ .../package.json | 2 +- .../github-pull-requests-board/package.json | 2 +- yarn.lock | 20 ++----------------- 5 files changed, 18 insertions(+), 20 deletions(-) create mode 100644 .changeset/unlucky-lizards-suffer.md diff --git a/.changeset/unlucky-lizards-suffer.md b/.changeset/unlucky-lizards-suffer.md new file mode 100644 index 0000000000..15862e1736 --- /dev/null +++ b/.changeset/unlucky-lizards-suffer.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-cicd-statistics-module-gitlab': patch +'@backstage/plugin-github-pull-requests-board': patch +--- + +Align `p-limit` dependency version to v3 diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f0916226cd..22b5735256 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -54,5 +54,13 @@ matchPackageNames: ['inquirer', '@types/inquirer'], allowedVersions: '<9.0.0', }, + { + matchPackageNames: ['ora'], + allowedVersions: '<5.0.0', + }, + { + matchPackageNames: ['p-limit'], + allowedVersions: '<4.0.0', + }, ], } diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 9c6a7c8be6..a08a2cb07c 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -40,7 +40,7 @@ "@gitbeaker/browser": "^35.6.0", "@gitbeaker/core": "^35.6.0", "luxon": "^3.0.0", - "p-limit": "^4.0.0" + "p-limit": "^3.1.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0", diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index acf1ae04e0..e76bbb7505 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -46,7 +46,7 @@ "@octokit/rest": "^19.0.3", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "luxon": "^3.0.0", - "p-limit": "^4.0.0" + "p-limit": "^3.1.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0", diff --git a/yarn.lock b/yarn.lock index 75061be243..4bcad2fb8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5888,7 +5888,7 @@ __metadata: "@gitbeaker/core": ^35.6.0 "@types/react": ^16.13.1 || ^17.0.0 luxon: ^3.0.0 - p-limit: ^4.0.0 + p-limit: ^3.1.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -6839,7 +6839,7 @@ __metadata: "@testing-library/react": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 luxon: ^3.0.0 - p-limit: ^4.0.0 + p-limit: ^3.1.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -36844,15 +36844,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: ^1.0.0 - checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b - languageName: node - linkType: hard - "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0" @@ -46248,13 +46239,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 - languageName: node - linkType: hard - "yup@npm:^0.32.9": version: 0.32.11 resolution: "yup@npm:0.32.11" From d4309ffe6e9cc6f24c3d45fc8e482a8a7a24ed58 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 18:09:15 +0000 Subject: [PATCH 40/76] fix(deps): update dependency isomorphic-git to v1.25.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1a8566ff31..9685b34ef3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31328,8 +31328,8 @@ __metadata: linkType: hard "isomorphic-git@npm:^1.23.0": - version: 1.25.4 - resolution: "isomorphic-git@npm:1.25.4" + version: 1.25.6 + resolution: "isomorphic-git@npm:1.25.6" dependencies: async-lock: ^1.1.0 clean-git-ref: ^2.0.1 @@ -31344,7 +31344,7 @@ __metadata: simple-get: ^4.0.1 bin: isogit: cli.cjs - checksum: 86ed42b7d15db04af5a1918b7cf50153e688a2aabd5d77a6a5f2a1798bb476aef265edd3bb3d80058929d70cd0c23247074760a48720bbba9e76b044881e6d6c + checksum: d1fa30ede586f6bb36a526924dafa92d67a55b331ca1c2e95fe96bbd4b614302a87c1c016a1f7ca76c44cfa80b6c0e83c9df114417a6caabe82a8472d86346c3 languageName: node linkType: hard From ea8f7362a19a3dba682af7ea880cb1b9cac741a4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 21 Feb 2024 20:35:15 +0100 Subject: [PATCH 41/76] scripts/verify-links: allow all absolute URLs from changesets Signed-off-by: Patrik Oldsberg --- scripts/verify-links.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/verify-links.js b/scripts/verify-links.js index f685af191b..94ffc497cd 100755 --- a/scripts/verify-links.js +++ b/scripts/verify-links.js @@ -78,6 +78,9 @@ async function verifyUrl(basePath, absUrl, docPages) { } if (basePath.startsWith('.changeset/')) { + if (absUrl.match(/^https?:\/\//)) { + return undefined; + } return { url, basePath, problem: 'out-of-changeset' }; } From d2600ca208e749e97e799eec368eebd814b45801 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Feb 2024 15:35:03 +0100 Subject: [PATCH 42/76] Update packages/backend-plugin-api/src/services/definitions/coreServices.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .../backend-plugin-api/src/services/definitions/coreServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index a7c9d09445..c760afc7b4 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -23,7 +23,7 @@ import { createServiceRef } from '../system'; */ export namespace coreServices { /** - * The service reference for the plugin scoped {@link IdentityService}. + * The service reference for the plugin scoped {@link AuthService}. * * @public */ From 6fb46ce748e9e66d22f5d331d5bfc313bcc95d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 22 Feb 2024 17:07:07 +0100 Subject: [PATCH 43/76] one more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .github/renovate.json5 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 22b5735256..a9cb54912a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -62,5 +62,9 @@ matchPackageNames: ['p-limit'], allowedVersions: '<4.0.0', }, + { + matchPackageNames: ['p-queue'], + allowedVersions: '<7.0.0', + }, ], } From f86e34c0d9fde6e60fc71cce45e21e25444360f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 22 Feb 2024 17:17:07 +0100 Subject: [PATCH 44/76] remove unused dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/poor-ladybugs-smell.md | 5 +++++ packages/cli/knip-report.md | 1 - packages/cli/package.json | 1 - yarn.lock | 18 ++---------------- 4 files changed, 7 insertions(+), 18 deletions(-) create mode 100644 .changeset/poor-ladybugs-smell.md diff --git a/.changeset/poor-ladybugs-smell.md b/.changeset/poor-ladybugs-smell.md new file mode 100644 index 0000000000..bcd67d2426 --- /dev/null +++ b/.changeset/poor-ladybugs-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Removed unused `replace-in-file` dependency diff --git a/packages/cli/knip-report.md b/packages/cli/knip-report.md index d1989ea4ae..23da9f8411 100644 --- a/packages/cli/knip-report.md +++ b/packages/cli/knip-report.md @@ -18,7 +18,6 @@ | @svgr/plugin-svgo | package.json | error | | @svgr/plugin-jsx | package.json | error | | jest-css-modules | package.json | error | -| replace-in-file | package.json | error | | @swc/helpers | package.json | error | | jest-runtime | package.json | error | | cross-fetch | package.json | error | diff --git a/packages/cli/package.json b/packages/cli/package.json index ca85e2afdb..98f7b3bafb 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -118,7 +118,6 @@ "react-dev-utils": "^12.0.0-next.60", "react-refresh": "^0.14.0", "recursive-readdir": "^2.2.2", - "replace-in-file": "^6.0.0", "rollup": "^2.60.2", "rollup-plugin-dts": "^4.0.1", "rollup-plugin-esbuild": "^4.7.2", diff --git a/yarn.lock b/yarn.lock index 75a9c4b84d..ba8e64663f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3668,7 +3668,6 @@ __metadata: react-dev-utils: ^12.0.0-next.60 react-refresh: ^0.14.0 recursive-readdir: ^2.2.2 - replace-in-file: ^6.0.0 rollup: ^2.60.2 rollup-plugin-dts: ^4.0.1 rollup-plugin-esbuild: ^4.7.2 @@ -28991,7 +28990,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": +"glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -40438,19 +40437,6 @@ __metadata: languageName: node linkType: hard -"replace-in-file@npm:^6.0.0": - version: 6.3.5 - resolution: "replace-in-file@npm:6.3.5" - dependencies: - chalk: ^4.1.2 - glob: ^7.2.0 - yargs: ^17.2.1 - bin: - replace-in-file: bin/cli.js - checksum: e5ac3bfee531dcb70cfbb327e6d4ec86bcf4c8045f292e46fb0e4c8743bd70a274c2402918d2609a25fde829862b6e1fe5f09f6c171aabbdde142a9f33008cf1 - languageName: node - linkType: hard - "request@npm:^2.88.0": version: 2.88.2 resolution: "request@npm:2.88.2" @@ -46145,7 +46131,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.1.1, yargs@npm:^17.2.1, yargs@npm:^17.3.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2": +"yargs@npm:^17.1.1, yargs@npm:^17.3.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: From af7f25dec73059a195722e81b8cc0d0430202fd8 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 22 Feb 2024 11:33:57 -0500 Subject: [PATCH 45/76] Add .ico to assets transformer Allows for import .ico files as assets Signed-off-by: Stephen A. Wilson --- packages/cli/src/lib/bundler/transforms.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index e0308f5c2d..da1eec4e11 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -145,6 +145,7 @@ export const transforms = (options: TransformOptions): Transforms => { /\.vert$/, { and: [/\.svg$/, { not: [/\.icon\.svg$/] }] }, /\.xml$/, + /\.ico$/, ], type: 'asset/resource', generator: { From 472bf729c67123e0077789f8c3b29f6011735191 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 22 Feb 2024 12:11:32 -0500 Subject: [PATCH 46/76] add .ico to asset-types.d.ts Signed-off-by: Stephen A. Wilson --- packages/cli/asset-types/asset-types.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/cli/asset-types/asset-types.d.ts b/packages/cli/asset-types/asset-types.d.ts index 2d288fd0e3..5328a84522 100644 --- a/packages/cli/asset-types/asset-types.d.ts +++ b/packages/cli/asset-types/asset-types.d.ts @@ -55,6 +55,11 @@ declare module '*.webp' { export default src; } +declare module '*.ico' { + const src: string; + export default src; +} + declare module '*.yaml' { const src: string; export default src; From f4404e5ca327473083d4f6ce5f049658866dd4a7 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 22 Feb 2024 12:53:29 -0500 Subject: [PATCH 47/76] add changeset Signed-off-by: Stephen A. Wilson --- .changeset/slimy-trainers-attend.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/slimy-trainers-attend.md diff --git a/.changeset/slimy-trainers-attend.md b/.changeset/slimy-trainers-attend.md new file mode 100644 index 0000000000..43b2b807be --- /dev/null +++ b/.changeset/slimy-trainers-attend.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add .ico import support From db62da78d90a9c5bb37aae53e30ea134f0c73407 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Feb 2024 17:33:33 +0100 Subject: [PATCH 48/76] backend-next: use stringifyEntityRef in github provider module Signed-off-by: Patrik Oldsberg --- packages/backend-next/package.json | 1 + packages/backend-next/src/authModuleGithubProvider.ts | 10 +++++++++- yarn.lock | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index c1f09cd0cb..74016539b0 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -28,6 +28,7 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", + "@backstage/catalog-model": "workspace:^", "@backstage/plugin-adr-backend": "workspace:^", "@backstage/plugin-app-backend": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", diff --git a/packages/backend-next/src/authModuleGithubProvider.ts b/packages/backend-next/src/authModuleGithubProvider.ts index 5b71f35567..9245600d2c 100644 --- a/packages/backend-next/src/authModuleGithubProvider.ts +++ b/packages/backend-next/src/authModuleGithubProvider.ts @@ -15,6 +15,10 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; +import { + DEFAULT_NAMESPACE, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { githubAuthenticator } from '@backstage/plugin-auth-backend-module-github-provider'; import { authProvidersExtensionPoint, @@ -40,7 +44,11 @@ export default createBackendModule({ ); } - const userEntityRef = `user:default/${userId}`; + const userEntityRef = stringifyEntityRef({ + kind: 'User', + name: userId, + namespace: DEFAULT_NAMESPACE, + }); return ctx.issueToken({ claims: { diff --git a/yarn.lock b/yarn.lock index 5948d58b31..faf73dd135 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27355,6 +27355,7 @@ __metadata: "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/plugin-adr-backend": "workspace:^" "@backstage/plugin-app-backend": "workspace:^" From 74062bce288749c0b617d44fb0f88ca022b4f88e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Feb 2024 17:41:42 +0100 Subject: [PATCH 49/76] backend-{app-api,test-utils}: minor cleanup Signed-off-by: Patrik Oldsberg --- .../services/implementations/httpAuth/httpAuthServiceFactory.ts | 2 +- .../backend-test-utils/src/next/services/MockAuthService.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index 44199f4256..1bd9d3cf2a 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -91,7 +91,7 @@ class DefaultHttpAuthService implements HttpAuthService { return credentials; } - async #getCredentials(req: /* */ RequestWithCredentials) { + async #getCredentials(req: RequestWithCredentials) { return (req[credentialsSymbol] ??= this.#extractCredentialsFromRequest(req)); } diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/next/services/MockAuthService.ts index 5735755f85..6a18711798 100644 --- a/packages/backend-test-utils/src/next/services/MockAuthService.ts +++ b/packages/backend-test-utils/src/next/services/MockAuthService.ts @@ -61,6 +61,7 @@ export class MockAuthService implements AuthService { case '': throw new AuthenticationError('Token is empty'); default: + break; } if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) { From 7cbb7606c007cd32ed94d4c0262d3b7c5f3957ba Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Feb 2024 17:43:16 +0100 Subject: [PATCH 50/76] .changesets: added changeset for auth services addition to backend-defaults Signed-off-by: Patrik Oldsberg --- .changeset/perfect-taxis-give.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/perfect-taxis-give.md diff --git a/.changeset/perfect-taxis-give.md b/.changeset/perfect-taxis-give.md new file mode 100644 index 0000000000..540834c5c5 --- /dev/null +++ b/.changeset/perfect-taxis-give.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Added support for the new auth services, which are now installed by default. See the [migration guide](https://backstage.io/docs/tutorials/auth-service-migration) for details. From 0502d826a5f59e4c510a18d81de1bde53c532be8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 17:32:04 +0100 Subject: [PATCH 51/76] permissions: migrate to new auth system and accept credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .changeset/late-turkeys-remember.md | 5 + .changeset/neat-owls-pump.md | 5 + .changeset/polite-tips-begin.md | 5 + .changeset/soft-grapes-cough.md | 5 + .../permissions/permissionsServiceFactory.ts | 4 +- packages/backend-plugin-api/api-report.md | 26 ++++- .../definitions/PermissionsService.ts | 35 ++++++- .../src/services/definitions/index.ts | 5 +- plugins/permission-common/src/types/api.ts | 9 +- plugins/permission-node/api-report.md | 16 ++-- .../src/ServerPermissionClient.ts | 96 +++++++++++++------ 11 files changed, 168 insertions(+), 43 deletions(-) create mode 100644 .changeset/late-turkeys-remember.md create mode 100644 .changeset/neat-owls-pump.md create mode 100644 .changeset/polite-tips-begin.md create mode 100644 .changeset/soft-grapes-cough.md diff --git a/.changeset/late-turkeys-remember.md b/.changeset/late-turkeys-remember.md new file mode 100644 index 0000000000..0640797b9f --- /dev/null +++ b/.changeset/late-turkeys-remember.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-common': patch +--- + +The `token` option of the `PermissionEvaluator` methods is now deprecated. The options that only apply to backend implementations have been moved to `PermissionsService` from `@backstage/backend-plugin-api` instead. diff --git a/.changeset/neat-owls-pump.md b/.changeset/neat-owls-pump.md new file mode 100644 index 0000000000..ca34d12756 --- /dev/null +++ b/.changeset/neat-owls-pump.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Updated the `permissionsServiceFactory` to forward the `AuthService` to the implementation. diff --git a/.changeset/polite-tips-begin.md b/.changeset/polite-tips-begin.md new file mode 100644 index 0000000000..a1211c91a6 --- /dev/null +++ b/.changeset/polite-tips-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Updated the `PermissionsService` methods to accept `BackstageCredentials` through options. diff --git a/.changeset/soft-grapes-cough.md b/.changeset/soft-grapes-cough.md new file mode 100644 index 0000000000..0e43c01a08 --- /dev/null +++ b/.changeset/soft-grapes-cough.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +The `ServerPermissionClient` has been migrated to implement the `PermissionsService` interface, now accepting the new `BackstageCredentials` object in addition to the `token` option, which is now deprecated. It now also optionally depends on the new `AuthService`. diff --git a/packages/backend-app-api/src/services/implementations/permissions/permissionsServiceFactory.ts b/packages/backend-app-api/src/services/implementations/permissions/permissionsServiceFactory.ts index 3e5b7da9dd..9824eb2145 100644 --- a/packages/backend-app-api/src/services/implementations/permissions/permissionsServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/permissions/permissionsServiceFactory.ts @@ -24,12 +24,14 @@ import { ServerPermissionClient } from '@backstage/plugin-permission-node'; export const permissionsServiceFactory = createServiceFactory({ service: coreServices.permissions, deps: { + auth: coreServices.auth, config: coreServices.rootConfig, discovery: coreServices.discovery, tokenManager: coreServices.tokenManager, }, - async factory({ config, discovery, tokenManager }) { + async factory({ auth, config, discovery, tokenManager }) { return ServerPermissionClient.fromConfig(config, { + auth, discovery, tokenManager, }); diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index d676de2fce..cb44ba158d 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -5,6 +5,8 @@ ```ts /// +import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common'; +import { AuthorizePermissionResponse } from '@backstage/plugin-permission-common'; import { Config } from '@backstage/config'; import { Handler } from 'express'; import { IdentityApi } from '@backstage/plugin-auth-node'; @@ -13,6 +15,8 @@ import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { QueryPermissionRequest } from '@backstage/plugin-permission-common'; +import { QueryPermissionResponse } from '@backstage/plugin-permission-common'; import { Readable } from 'stream'; import { Request as Request_2 } from 'express'; import { Response as Response_2 } from 'express'; @@ -364,7 +368,27 @@ export interface LoggerService { } // @public (undocumented) -export interface PermissionsService extends PermissionEvaluator {} +export interface PermissionsService extends PermissionEvaluator { + // (undocumented) + authorize( + requests: AuthorizePermissionRequest[], + options?: PermissionsServiceRequestOptions, + ): Promise; + // (undocumented) + authorizeConditional( + requests: QueryPermissionRequest[], + options?: PermissionsServiceRequestOptions, + ): Promise; +} + +// @public +export type PermissionsServiceRequestOptions = + | { + token?: string; + } + | { + credentials: BackstageCredentials; + }; // @public (undocumented) export interface PluginMetadataService { diff --git a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts index 5847f55ee6..1db15ce5e5 100644 --- a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts +++ b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts @@ -14,7 +14,38 @@ * limitations under the License. */ -import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { + AuthorizePermissionRequest, + AuthorizePermissionResponse, + PermissionEvaluator, + QueryPermissionRequest, + QueryPermissionResponse, +} from '@backstage/plugin-permission-common'; +import { BackstageCredentials } from './AuthService'; + +/** + * Options for {@link @backstage/plugin-permission-common#PermissionEvaluator} requests. + * + * @public + */ +export type PermissionsServiceRequestOptions = + | { + /** @deprecated use the `credentials` option instead. */ + token?: string; + } + | { + credentials: BackstageCredentials; + }; /** @public */ -export interface PermissionsService extends PermissionEvaluator {} +export interface PermissionsService extends PermissionEvaluator { + authorize( + requests: AuthorizePermissionRequest[], + options?: PermissionsServiceRequestOptions, + ): Promise; + + authorizeConditional( + requests: QueryPermissionRequest[], + options?: PermissionsServiceRequestOptions, + ): Promise; +} diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 5955c4cbb1..8a5176379f 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -44,7 +44,10 @@ export type { LifecycleServiceShutdownOptions, } from './LifecycleService'; export type { LoggerService } from './LoggerService'; -export type { PermissionsService } from './PermissionsService'; +export type { + PermissionsService, + PermissionsServiceRequestOptions, +} from './PermissionsService'; export type { PluginMetadataService } from './PluginMetadataService'; export type { RootHttpRouterService } from './RootHttpRouterService'; export type { RootLifecycleService } from './RootLifecycleService'; diff --git a/plugins/permission-common/src/types/api.ts b/plugins/permission-common/src/types/api.ts index 322195a63f..e597384a56 100644 --- a/plugins/permission-common/src/types/api.ts +++ b/plugins/permission-common/src/types/api.ts @@ -263,9 +263,16 @@ export interface PermissionEvaluator { /** * Options for {@link PermissionEvaluator} requests. - * The Backstage identity token should be defined if available. + * * @public */ export type EvaluatorRequestOptions = { + /** + * @deprecated Backend plugins should no longer depend on the + * `PermissionEvaluator`, but instead use the `PermissionService` from + * `@backstage/backend-plugin-api`. Frontend plugins should not need to inject + * this token at all, but instead implicitly rely on underlying fetchApi to do + * it for them. + */ token?: string; }; diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index ea99d22fc5..7d2910d391 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -7,20 +7,21 @@ import { AllOfCriteria } from '@backstage/plugin-permission-common'; import { AnyOfCriteria } from '@backstage/plugin-permission-common'; import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common'; import { AuthorizePermissionResponse } from '@backstage/plugin-permission-common'; +import { AuthService } from '@backstage/backend-plugin-api'; import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; import { Config } from '@backstage/config'; import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; -import { EvaluatorRequestOptions } from '@backstage/plugin-permission-common'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import express from 'express'; import { IdentifiedPermissionMessage } from '@backstage/plugin-permission-common'; import { NotCriteria } from '@backstage/plugin-permission-common'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionCondition } from '@backstage/plugin-permission-common'; import { PermissionCriteria } from '@backstage/plugin-permission-common'; -import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { PermissionsService } from '@backstage/backend-plugin-api'; +import { PermissionsServiceRequestOptions } from '@backstage/backend-plugin-api'; import { PolicyDecision } from '@backstage/plugin-permission-common'; import { QueryPermissionRequest } from '@backstage/plugin-permission-common'; import { ResourcePermission } from '@backstage/plugin-permission-common'; @@ -272,23 +273,24 @@ export type PolicyQuery = { }; // @public -export class ServerPermissionClient implements PermissionEvaluator { +export class ServerPermissionClient implements PermissionsService { // (undocumented) authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionsServiceRequestOptions, ): Promise; // (undocumented) authorizeConditional( queries: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionsServiceRequestOptions, ): Promise; // (undocumented) static fromConfig( config: Config, options: { - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; tokenManager: TokenManager; + auth?: AuthService; }, ): ServerPermissionClient; } diff --git a/plugins/permission-node/src/ServerPermissionClient.ts b/plugins/permission-node/src/ServerPermissionClient.ts index 6275fb835e..87e0eb98d1 100644 --- a/plugins/permission-node/src/ServerPermissionClient.ts +++ b/plugins/permission-node/src/ServerPermissionClient.ts @@ -16,15 +16,20 @@ import { TokenManager, - PluginEndpointDiscovery, + createLegacyAuthAdapters, } from '@backstage/backend-common'; +import { + AuthService, + BackstageCredentials, + DiscoveryService, + PermissionsService, + PermissionsServiceRequestOptions, +} from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { AuthorizeResult, PermissionClient, - PermissionEvaluator, AuthorizePermissionRequest, - EvaluatorRequestOptions, AuthorizePermissionResponse, PolicyDecision, QueryPermissionRequest, @@ -36,16 +41,17 @@ import { * service-to-service requests. * @public */ -export class ServerPermissionClient implements PermissionEvaluator { +export class ServerPermissionClient implements PermissionsService { + private readonly auth: AuthService; private readonly permissionClient: PermissionClient; - private readonly tokenManager: TokenManager; private readonly permissionEnabled: boolean; static fromConfig( config: Config, options: { - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; tokenManager: TokenManager; + auth?: AuthService; }, ) { const { discovery, tokenManager } = options; @@ -62,58 +68,88 @@ export class ServerPermissionClient implements PermissionEvaluator { ); } + const { auth } = createLegacyAuthAdapters(options); + return new ServerPermissionClient({ + auth, permissionClient, - tokenManager, permissionEnabled, }); } private constructor(options: { + auth: AuthService; permissionClient: PermissionClient; - tokenManager: TokenManager; permissionEnabled: boolean; }) { + this.auth = options.auth; this.permissionClient = options.permissionClient; - this.tokenManager = options.tokenManager; this.permissionEnabled = options.permissionEnabled; } async authorizeConditional( queries: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionsServiceRequestOptions, ): Promise { - return (await this.isEnabled(options?.token)) - ? this.permissionClient.authorizeConditional(queries, options) + return (await this.shouldPermissionsBeApplied(options)) + ? this.permissionClient.authorizeConditional( + queries, + await this.getRequestOptions(options), + ) : queries.map(_ => ({ result: AuthorizeResult.ALLOW })); } async authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionsServiceRequestOptions, ): Promise { - return (await this.isEnabled(options?.token)) - ? this.permissionClient.authorize(requests, options) + return (await this.shouldPermissionsBeApplied(options)) + ? this.permissionClient.authorize( + requests, + await this.getRequestOptions(options), + ) : requests.map(_ => ({ result: AuthorizeResult.ALLOW })); } - private async isValidServerToken( - token: string | undefined, - ): Promise { - if (!token) { - return false; + private async getRequestOptions(options?: PermissionsServiceRequestOptions) { + if (options && 'credentials' in options) { + if (this.auth.isPrincipal(options.credentials, 'none')) { + return {}; + } + + return this.auth.getPluginRequestToken({ + onBehalfOf: options.credentials, + targetPluginId: 'permissions', + }); } - return this.tokenManager - .authenticate(token) - .then(() => true) - .catch(() => false); + + return options; } - private async isEnabled(token?: string) { - // Check if permissions are enabled before validating the server token. That - // way when permissions are disabled, the noop token manager can be used - // without fouling up the logic inside the ServerPermissionClient, because - // the code path won't be reached. - return this.permissionEnabled && !(await this.isValidServerToken(token)); + private async shouldPermissionsBeApplied( + options?: PermissionsServiceRequestOptions, + ) { + if (!this.permissionEnabled) { + return false; + } + + let credentials: BackstageCredentials; + if (options && 'credentials' in options) { + credentials = options.credentials; + } else { + if (!options?.token) { + return true; + } + try { + credentials = await this.auth.authenticate(options.token); + } catch { + return true; + } + } + + if (this.auth.isPrincipal(credentials, 'service')) { + return false; + } + return true; } } From 61ff58f1ef39ae90ca948b05d3c2b38cd9b61cd0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 18:43:38 +0100 Subject: [PATCH 52/76] linguist-backend: migrate to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/bright-bulldogs-whisper.md | 5 ++++ plugins/linguist-backend/api-report.md | 6 +++++ .../src/api/LinguistBackendClient.test.ts | 10 ++++---- .../src/api/LinguistBackendClient.ts | 24 +++++++++++++------ plugins/linguist-backend/src/plugin.ts | 6 +++++ .../linguist-backend/src/service/router.ts | 14 +++++++++-- 6 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 .changeset/bright-bulldogs-whisper.md diff --git a/.changeset/bright-bulldogs-whisper.md b/.changeset/bright-bulldogs-whisper.md new file mode 100644 index 0000000000..bedc367856 --- /dev/null +++ b/.changeset/bright-bulldogs-whisper.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': patch +--- + +Migrated to support new auth services. diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md index 95bdc858ee..31892fcdb1 100644 --- a/plugins/linguist-backend/api-report.md +++ b/plugins/linguist-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorCache } from '@backstage/plugin-catalog-node'; @@ -10,6 +11,7 @@ import { Config } from '@backstage/config'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HumanDuration } from '@backstage/types'; import { Languages } from '@backstage/plugin-linguist-common'; import { LanguageType } from '@backstage/plugin-linguist-common'; @@ -94,6 +96,8 @@ export interface PluginOptions { // @public (undocumented) export interface RouterOptions { + // (undocumented) + auth?: AuthService; // (undocumented) config?: Config; // (undocumented) @@ -101,6 +105,8 @@ export interface RouterOptions { // (undocumented) discovery: PluginEndpointDiscovery; // (undocumented) + httpAuth?: HttpAuthService; + // (undocumented) linguistBackendApi?: LinguistBackendApi; // (undocumented) logger: Logger; diff --git a/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts index 55c74df424..be25fa9821 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts @@ -17,7 +17,6 @@ import { getVoidLogger, ReadTreeResponse, - ServerTokenManager, UrlReader, } from '@backstage/backend-common'; import { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client'; @@ -27,6 +26,7 @@ import { LinguistBackendStore } from '../db'; import { kindOrDefault, LinguistBackendClient } from './LinguistBackendClient'; import fs from 'fs-extra'; import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; +import { mockServices } from '@backstage/backend-test-utils'; const linguistResultMock = Promise.resolve({ files: { @@ -97,13 +97,11 @@ describe('Linguist backend API', () => { getEntityByRef: jest.fn(), } as any; - const tokenManager = ServerTokenManager.noop(); - const api = new LinguistBackendClient( logger, store, urlReader, - tokenManager, + mockServices.auth(), catalogApi, ); @@ -230,7 +228,7 @@ describe('Linguist backend API', () => { logger, store, urlReader, - tokenManager, + mockServices.auth(), catalogApi, { days: 5 }, ); @@ -353,7 +351,7 @@ describe('Linguist backend API', () => { logger, store, urlReader, - tokenManager, + mockServices.auth(), catalogApi, undefined, 2, diff --git a/plugins/linguist-backend/src/api/LinguistBackendClient.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.ts index 1be4a7d288..d2c2a9124a 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendClient.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.ts @@ -25,7 +25,7 @@ import { GetEntitiesRequest, CatalogApi, } from '@backstage/catalog-client'; -import { TokenManager, UrlReader } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; import { DateTime } from 'luxon'; import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; @@ -40,6 +40,7 @@ import { import { assertError } from '@backstage/errors'; import { HumanDuration } from '@backstage/types'; import { Results } from 'linguist-js/dist/types'; +import { type AuthService } from '@backstage/backend-plugin-api'; /** @public */ export interface LinguistBackendApi { @@ -52,7 +53,7 @@ export class LinguistBackendClient implements LinguistBackendApi { private readonly logger: Logger; private readonly store: LinguistBackendStore; private readonly urlReader: UrlReader; - private readonly tokenManager: TokenManager; + private readonly auth: AuthService; private readonly catalogApi: CatalogApi; private readonly age?: HumanDuration; @@ -64,7 +65,7 @@ export class LinguistBackendClient implements LinguistBackendApi { logger: Logger, store: LinguistBackendStore, urlReader: UrlReader, - tokenManager: TokenManager, + auth: AuthService, catalogApi: CatalogApi, age?: HumanDuration, batchSize?: number, @@ -75,7 +76,7 @@ export class LinguistBackendClient implements LinguistBackendApi { this.logger = logger; this.store = store; this.urlReader = urlReader; - this.tokenManager = tokenManager; + this.auth = auth; this.catalogApi = catalogApi; this.batchSize = batchSize; this.age = age; @@ -114,7 +115,10 @@ export class LinguistBackendClient implements LinguistBackendApi { fields: ['kind', 'metadata'], }; - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const response = await this.catalogApi.getEntities(request, { token }); const entities = response.items; @@ -130,7 +134,10 @@ export class LinguistBackendClient implements LinguistBackendApi { const allEntities = await this.store.getAllEntities(); for (const entityRef of allEntities) { - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const result = await this.catalogApi.getEntityByRef(entityRef, { token }); if (!result) { @@ -155,7 +162,10 @@ export class LinguistBackendClient implements LinguistBackendApi { ); for (const entityRef of entities) { - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const entity = await this.catalogApi.getEntityByRef(entityRef, { token, }); diff --git a/plugins/linguist-backend/src/plugin.ts b/plugins/linguist-backend/src/plugin.ts index cbf18d9ebe..e569b00233 100644 --- a/plugins/linguist-backend/src/plugin.ts +++ b/plugins/linguist-backend/src/plugin.ts @@ -32,6 +32,8 @@ export const linguistPlugin = createBackendPlugin({ register(env) { env.registerInit({ deps: { + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, logger: coreServices.logger, config: coreServices.rootConfig, reader: coreServices.urlReader, @@ -42,6 +44,8 @@ export const linguistPlugin = createBackendPlugin({ httpRouter: coreServices.httpRouter, }, async init({ + auth, + httpAuth, logger, config, reader, @@ -53,6 +57,8 @@ export const linguistPlugin = createBackendPlugin({ }) { httpRouter.use( await createRouterFromConfig({ + auth, + httpAuth, logger: loggerToWinstonLogger(logger), config, reader, diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index d29943c38b..7d64edc82e 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -15,6 +15,7 @@ */ import { + createLegacyAuthAdapters, errorHandler, PluginDatabaseManager, PluginEndpointDiscovery, @@ -35,6 +36,7 @@ import { HumanDuration } from '@backstage/types'; import { CatalogClient } from '@backstage/catalog-client'; import { LinguistBackendClient } from '../api/LinguistBackendClient'; import { Config } from '@backstage/config'; +import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; /** @public */ export interface PluginOptions { @@ -56,6 +58,8 @@ export interface RouterOptions { discovery: PluginEndpointDiscovery; scheduler?: PluginTaskScheduler; config?: Config; + auth?: AuthService; + httpAuth?: HttpAuthService; } /** @public */ @@ -63,7 +67,7 @@ export async function createRouter( pluginOptions: PluginOptions, routerOptions: RouterOptions, ): Promise { - const { logger, reader, database, discovery, scheduler, tokenManager } = + const { logger, reader, database, discovery, scheduler, tokenManager, auth } = routerOptions; const { @@ -81,13 +85,19 @@ export async function createRouter( const catalogClient = new CatalogClient({ discoveryApi: discovery }); + const { auth: adaptedAuth } = createLegacyAuthAdapters({ + auth, + tokenManager: tokenManager, + discovery: discovery, + }); + const linguistBackendClient = routerOptions.linguistBackendApi || new LinguistBackendClient( logger, linguistBackendStore, reader, - tokenManager, + adaptedAuth, catalogClient, age, batchSize, From 9f9ba708daef7337dc8fd902a1418681e6594a55 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 12:37:54 +0100 Subject: [PATCH 53/76] lighthouse-backend: migrate to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/chilled-goats-matter.md | 5 +++++ packages/backend/src/plugins/lighthouse.ts | 3 ++- plugins/lighthouse-backend/api-report.md | 6 ++++++ plugins/lighthouse-backend/src/plugin.ts | 14 +++++++++++++- .../src/service/EntitiesLoader.ts | 9 ++++++--- .../src/service/createScheduler.ts | 16 +++++++++++++--- 6 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 .changeset/chilled-goats-matter.md diff --git a/.changeset/chilled-goats-matter.md b/.changeset/chilled-goats-matter.md new file mode 100644 index 0000000000..b66381452f --- /dev/null +++ b/.changeset/chilled-goats-matter.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-lighthouse-backend': patch +--- + +**BREAKING**: The `createScheduler` function now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. diff --git a/packages/backend/src/plugins/lighthouse.ts b/packages/backend/src/plugins/lighthouse.ts index 00a67409e3..77204159cb 100644 --- a/packages/backend/src/plugins/lighthouse.ts +++ b/packages/backend/src/plugins/lighthouse.ts @@ -19,7 +19,7 @@ import { PluginEnvironment } from '../types'; import { CatalogClient } from '@backstage/catalog-client'; export default async function createPlugin(env: PluginEnvironment) { - const { logger, scheduler, config, tokenManager } = env; + const { logger, scheduler, config, tokenManager, discovery } = env; const catalogClient = new CatalogClient({ discoveryApi: env.discovery, @@ -31,5 +31,6 @@ export default async function createPlugin(env: PluginEnvironment) { config, catalogClient, tokenManager, + discovery, }); } diff --git a/plugins/lighthouse-backend/api-report.md b/plugins/lighthouse-backend/api-report.md index d382e40def..44379d6569 100644 --- a/plugins/lighthouse-backend/api-report.md +++ b/plugins/lighthouse-backend/api-report.md @@ -3,20 +3,26 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { Logger } from 'winston'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { TokenManager } from '@backstage/backend-common'; // @public (undocumented) export interface CreateLighthouseSchedulerOptions { + // (undocumented) + auth?: AuthService; // (undocumented) catalogClient: CatalogApi; // (undocumented) config: Config; // (undocumented) + discovery: DiscoveryService; + // (undocumented) logger: Logger; // (undocumented) scheduler?: PluginTaskScheduler; diff --git a/plugins/lighthouse-backend/src/plugin.ts b/plugins/lighthouse-backend/src/plugin.ts index 3d5c8dac72..6a36e3f189 100644 --- a/plugins/lighthouse-backend/src/plugin.ts +++ b/plugins/lighthouse-backend/src/plugin.ts @@ -38,8 +38,18 @@ export const lighthousePlugin = createBackendPlugin({ logger: coreServices.logger, scheduler: coreServices.scheduler, tokenManager: coreServices.tokenManager, + discovery: coreServices.discovery, + auth: coreServices.auth, }, - async init({ catalogClient, config, logger, scheduler, tokenManager }) { + async init({ + catalogClient, + config, + logger, + scheduler, + tokenManager, + discovery, + auth, + }) { const winstonLogger = loggerToWinstonLogger(logger); await createScheduler({ @@ -48,6 +58,8 @@ export const lighthousePlugin = createBackendPlugin({ logger: winstonLogger, scheduler, tokenManager, + discovery, + auth, }); }, }); diff --git a/plugins/lighthouse-backend/src/service/EntitiesLoader.ts b/plugins/lighthouse-backend/src/service/EntitiesLoader.ts index c20b95beae..bee00cd4d9 100644 --- a/plugins/lighthouse-backend/src/service/EntitiesLoader.ts +++ b/plugins/lighthouse-backend/src/service/EntitiesLoader.ts @@ -18,11 +18,11 @@ import { CatalogClient, CATALOG_FILTER_EXISTS, } from '@backstage/catalog-client'; -import { TokenManager } from '@backstage/backend-common'; +import { AuthService } from '@backstage/backend-plugin-api'; export async function loadLighthouseEntities( catalogClient: CatalogClient, - tokenManager: TokenManager, + auth: AuthService, ) { const filter: Record = { kind: 'Component', @@ -30,7 +30,10 @@ export async function loadLighthouseEntities( ['lighthouse.com/website-url']: CATALOG_FILTER_EXISTS, }; - const { token } = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); return await catalogClient.getEntities( { diff --git a/plugins/lighthouse-backend/src/service/createScheduler.ts b/plugins/lighthouse-backend/src/service/createScheduler.ts index 45a3e88149..6f0ef497a5 100644 --- a/plugins/lighthouse-backend/src/service/createScheduler.ts +++ b/plugins/lighthouse-backend/src/service/createScheduler.ts @@ -21,22 +21,29 @@ import { Config } from '@backstage/config'; import { LighthouseRestApi } from '@backstage/plugin-lighthouse-common'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { LighthouseAuditScheduleImpl } from '../config'; -import { TokenManager } from '@backstage/backend-common'; +import { + TokenManager, + createLegacyAuthAdapters, +} from '@backstage/backend-common'; +import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; /** @public **/ export interface CreateLighthouseSchedulerOptions { logger: Logger; config: Config; + discovery: DiscoveryService; scheduler?: PluginTaskScheduler; catalogClient: CatalogApi; tokenManager: TokenManager; + auth?: AuthService; } /** @public **/ export async function createScheduler( options: CreateLighthouseSchedulerOptions, ) { - const { logger, scheduler, catalogClient, config, tokenManager } = options; + const { logger, scheduler, catalogClient, config } = options; + const { auth } = createLegacyAuthAdapters(options); const lighthouseApi = LighthouseRestApi.fromConfig(config); const lighthouseAuditConfig = LighthouseAuditScheduleImpl.fromConfig(config, { @@ -78,7 +85,10 @@ export async function createScheduler( logger.info('Running Lighthouse Audit Task'); - const { token } = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const websitesWithUrl = await catalogClient.getEntities( { filter: [filter], From 84af36198715c71c1d7febdbcdf9cd7d82f0f967 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 12:18:01 +0100 Subject: [PATCH 54/76] notifications-backend: migrated to use new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/rude-masks-tan.md | 6 ++ plugins/notifications-backend/src/plugin.ts | 7 ++ .../src/service/router.ts | 39 +++++------ plugins/notifications-node/api-report.md | 12 ++-- plugins/notifications-node/package.json | 1 + plugins/notifications-node/src/lib.ts | 6 +- .../DefaultNotificationService.test.ts | 64 +++++++++++-------- .../src/service/DefaultNotificationService.ts | 27 ++++---- yarn.lock | 1 + 9 files changed, 94 insertions(+), 69 deletions(-) create mode 100644 .changeset/rude-masks-tan.md diff --git a/.changeset/rude-masks-tan.md b/.changeset/rude-masks-tan.md new file mode 100644 index 0000000000..8c8d52da6b --- /dev/null +++ b/.changeset/rude-masks-tan.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-node': minor +'@backstage/plugin-notifications-backend': patch +--- + +Migrated to using the new auth services. diff --git a/plugins/notifications-backend/src/plugin.ts b/plugins/notifications-backend/src/plugin.ts index 1d8806cf49..1d81818e30 100644 --- a/plugins/notifications-backend/src/plugin.ts +++ b/plugins/notifications-backend/src/plugin.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { coreServices, createBackendPlugin, @@ -58,6 +59,8 @@ export const notificationsPlugin = createBackendPlugin({ env.registerInit({ deps: { + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, httpRouter: coreServices.httpRouter, logger: coreServices.logger, identity: coreServices.identity, @@ -67,6 +70,8 @@ export const notificationsPlugin = createBackendPlugin({ signals: signalService, }, async init({ + auth, + httpAuth, httpRouter, logger, identity, @@ -77,6 +82,8 @@ export const notificationsPlugin = createBackendPlugin({ }) { httpRouter.use( await createRouter({ + auth, + httpAuth, logger, identity, database, diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index 6c745e158e..aa03726dfb 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -14,16 +14,14 @@ * limitations under the License. */ import { + createLegacyAuthAdapters, errorHandler, PluginDatabaseManager, TokenManager, } from '@backstage/backend-common'; import express, { Request } from 'express'; import Router from 'express-promise-router'; -import { - getBearerTokenFromAuthorizationHeader, - IdentityApi, -} from '@backstage/plugin-auth-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { DatabaseNotificationsStore, NotificationGetOptions, @@ -39,7 +37,12 @@ import { } from '@backstage/catalog-model'; import { NotificationProcessor } from '@backstage/plugin-notifications-node'; import { AuthenticationError, InputError } from '@backstage/errors'; -import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { SignalService } from '@backstage/plugin-signals-node'; import { NewNotificationSignal, @@ -58,6 +61,8 @@ export interface RouterOptions { signalService?: SignalService; catalog?: CatalogApi; processors?: NotificationProcessor[]; + auth?: AuthService; + httpAuth?: HttpAuthService; } /** @internal */ @@ -70,7 +75,6 @@ export async function createRouter( identity, discovery, catalog, - tokenManager, processors, signalService, } = options; @@ -79,6 +83,8 @@ export async function createRouter( catalog ?? new CatalogClient({ discoveryApi: discovery }); const store = await DatabaseNotificationsStore.create({ database }); + const { auth, httpAuth } = createLegacyAuthAdapters(options); + const getUser = async (req: Request) => { const user = await identity.getIdentity({ request: req }); if (!user) { @@ -87,20 +93,13 @@ export async function createRouter( return user.identity.userEntityRef; }; - const authenticateService = async (req: Request) => { - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); - if (!token) { - throw new AuthenticationError(); - } - await tokenManager.authenticate(token); - }; - const getUsersForEntityRef = async ( entityRef: string | string[] | null, ): Promise => { - const { token } = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); // TODO: Support for broadcast if (entityRef === null) { @@ -276,11 +275,7 @@ export async function createRouter( const notifications = []; let users = []; - try { - await authenticateService(req); - } catch (e) { - throw new AuthenticationError(); - } + await httpAuth.credentials(req, { allow: ['service'] }); const { title, link, scope } = payload; diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/api-report.md index 75a0fb68fd..24ae31904c 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/api-report.md @@ -3,21 +3,19 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { Notification as Notification_2 } from '@backstage/plugin-notifications-common'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; import { ServiceRef } from '@backstage/backend-plugin-api'; -import { TokenManager } from '@backstage/backend-common'; // @public (undocumented) export class DefaultNotificationService implements NotificationService { // (undocumented) - static create({ - tokenManager, - discovery, - pluginId, - }: NotificationServiceOptions): DefaultNotificationService; + static create( + options: NotificationServiceOptions, + ): DefaultNotificationService; // (undocumented) send(notification: NotificationSendOptions): Promise; } @@ -51,8 +49,8 @@ export const notificationService: ServiceRef; // @public (undocumented) export type NotificationServiceOptions = { + auth: AuthService; discovery: DiscoveryService; - tokenManager: TokenManager; pluginId: string; }; diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index ef3bc62ad2..9d2094beaf 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -27,6 +27,7 @@ "postpack": "backstage-cli package postpack" }, "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "msw": "^1.0.0" diff --git a/plugins/notifications-node/src/lib.ts b/plugins/notifications-node/src/lib.ts index c79d871ff8..2ba33608b4 100644 --- a/plugins/notifications-node/src/lib.ts +++ b/plugins/notifications-node/src/lib.ts @@ -29,14 +29,14 @@ export const notificationService = createServiceRef({ createServiceFactory({ service, deps: { + auth: coreServices.auth, discovery: coreServices.discovery, - tokenManager: coreServices.tokenManager, pluginMetadata: coreServices.pluginMetadata, }, - factory({ discovery, tokenManager, pluginMetadata }) { + factory({ auth, discovery, pluginMetadata }) { return DefaultNotificationService.create({ + auth, discovery, - tokenManager, pluginId: pluginMetadata.getId(), }); }, diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts index a9b204ca7f..9d8f5b82d9 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts @@ -22,6 +22,7 @@ import { DefaultNotificationService, NotificationSendOptions, } from './DefaultNotificationService'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; const server = setupServer(); @@ -33,21 +34,14 @@ const testNotification: NotificationPayload = { describe('DefaultNotificationService', () => { setupRequestMockHandlers(server); - const mockBaseUrl = 'http://backstage/api/notifications'; - const discoveryApi = { - getBaseUrl: async () => mockBaseUrl, - getExternalBaseUrl: async () => mockBaseUrl, - }; - const tokenManager = { - getToken: async () => ({ token: '1234' }), - authenticate: jest.fn(), - }; + const discovery = mockServices.discovery(); + const auth = mockServices.auth(); let service: DefaultNotificationService; - beforeEach(() => { + beforeEach(async () => { service = DefaultNotificationService.create({ - discovery: discoveryApi, - tokenManager, + auth, + discovery, pluginId: 'test', }); }); @@ -60,14 +54,22 @@ describe('DefaultNotificationService', () => { }; server.use( - rest.post(`${mockBaseUrl}/`, async (req, res, ctx) => { - const json = await req.json(); - expect(json).toEqual({ ...body, origin: 'plugin-test' }); - expect(req.headers.get('Authorization')).toEqual('Bearer 1234'); - return res(ctx.status(200)); - }), + rest.post( + `${await discovery.getBaseUrl('notifications')}/`, + async (req, res, ctx) => { + const json = await req.json(); + expect(json).toEqual({ ...body, origin: 'plugin-test' }); + expect(req.headers.get('Authorization')).toBe( + mockCredentials.service.header({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }), + ); + return res(ctx.status(200)); + }, + ), ); - await expect(service.send(body)).resolves.not.toThrow(); + await expect(service.send(body)).resolves.toBeUndefined(); }); it('should throw error if failing', async () => { @@ -77,14 +79,24 @@ describe('DefaultNotificationService', () => { }; server.use( - rest.post(`${mockBaseUrl}/`, async (req, res, ctx) => { - const json = await req.json(); - expect(json).toEqual({ ...body, origin: 'plugin-test' }); - expect(req.headers.get('Authorization')).toEqual('Bearer 1234'); - return res(ctx.status(400)); - }), + rest.post( + `${await discovery.getBaseUrl('notifications')}/`, + async (req, res, ctx) => { + const json = await req.json(); + expect(json).toEqual({ ...body, origin: 'plugin-test' }); + expect(req.headers.get('Authorization')).toBe( + mockCredentials.service.header({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }), + ); + return res(ctx.status(400)); + }, + ), + ); + await expect(service.send(body)).rejects.toThrow( + 'Request failed with status 400', ); - await expect(service.send(body)).rejects.toThrow(); }); }); }); diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.ts b/plugins/notifications-node/src/service/DefaultNotificationService.ts index 7e5cf58f53..ef06133d36 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.ts @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { TokenManager } from '@backstage/backend-common'; + import { NotificationService } from './NotificationService'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; /** @public */ export type NotificationServiceOptions = { + auth: AuthService; discovery: DiscoveryService; - tokenManager: TokenManager; pluginId: string; }; @@ -44,22 +44,27 @@ export type NotificationSendOptions = { export class DefaultNotificationService implements NotificationService { private constructor( private readonly discovery: DiscoveryService, - private readonly tokenManager: TokenManager, + private readonly auth: AuthService, private readonly pluginId: string, ) {} - static create({ - tokenManager, - discovery, - pluginId, - }: NotificationServiceOptions): DefaultNotificationService { - return new DefaultNotificationService(discovery, tokenManager, pluginId); + static create( + options: NotificationServiceOptions, + ): DefaultNotificationService { + return new DefaultNotificationService( + options.discovery, + options.auth, + options.pluginId, + ); } async send(notification: NotificationSendOptions): Promise { try { const baseUrl = await this.discovery.getBaseUrl('notifications'); - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }); const response = await fetch(`${baseUrl}/`, { method: 'POST', body: JSON.stringify({ diff --git a/yarn.lock b/yarn.lock index 53c220af6d..19415ada96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7664,6 +7664,7 @@ __metadata: dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" From 4f8ecd65f974500ac43937e03d79868a7af3814d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Feb 2024 13:39:07 +0100 Subject: [PATCH 55/76] entity-feedback-backend: migrated to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/fast-buses-exercise.md | 5 ++ plugins/entity-feedback-backend/api-report.md | 6 ++ .../src/service/router.test.ts | 86 ++++++++++--------- .../src/service/router.ts | 56 ++++++------ 4 files changed, 84 insertions(+), 69 deletions(-) create mode 100644 .changeset/fast-buses-exercise.md diff --git a/.changeset/fast-buses-exercise.md b/.changeset/fast-buses-exercise.md new file mode 100644 index 0000000000..def8ce2ca6 --- /dev/null +++ b/.changeset/fast-buses-exercise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-feedback-backend': patch +--- + +Migrated to support new auth services. diff --git a/plugins/entity-feedback-backend/api-report.md b/plugins/entity-feedback-backend/api-report.md index 1ec466e256..573d56efb5 100644 --- a/plugins/entity-feedback-backend/api-report.md +++ b/plugins/entity-feedback-backend/api-report.md @@ -3,8 +3,10 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import express from 'express'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; @@ -19,11 +21,15 @@ export default entityFeedbackPlugin; // @public (undocumented) export interface RouterOptions { + // (undocumented) + auth?: AuthService; // (undocumented) database: PluginDatabaseManager; // (undocumented) discovery: PluginEndpointDiscovery; // (undocumented) + httpAuth?: HttpAuthService; + // (undocumented) identity: IdentityApi; // (undocumented) logger: Logger; diff --git a/plugins/entity-feedback-backend/src/service/router.test.ts b/plugins/entity-feedback-backend/src/service/router.test.ts index 5df0c5cf9d..73940d96df 100644 --- a/plugins/entity-feedback-backend/src/service/router.test.ts +++ b/plugins/entity-feedback-backend/src/service/router.test.ts @@ -21,11 +21,11 @@ import { } from '@backstage/backend-common'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; -import { IdentityApi } from '@backstage/plugin-auth-node'; import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; const sampleOwnedEntities = [ { @@ -65,7 +65,7 @@ const sampleEntities = [ }, ]; -const mockGetEntties = jest +const mockGetEntities = jest .fn() .mockImplementation(async () => ({ items: sampleOwnedEntities })); @@ -75,15 +75,11 @@ const mockGetEnttiesByRefs = jest jest.mock('@backstage/catalog-client', () => ({ CatalogClient: jest.fn().mockImplementation(() => ({ - getEntities: mockGetEntties, + getEntities: mockGetEntities, getEntitiesByRefs: mockGetEnttiesByRefs, })), })); -jest.mock('@backstage/plugin-auth-node', () => ({ - getBearerTokenFromAuthorizationHeader: () => 'token', -})); - const mockRatings = [ { userRef: 'user:default/foo', rating: 'LIKE' }, { userRef: 'user:default/bar', rating: 'LIKE' }, @@ -149,12 +145,6 @@ describe('createRouter', () => { }), ).forPlugin('entity-feedback'); - const mockIdentityClient = { - getIdentity: jest.fn().mockImplementation(async () => ({ - identity: { userEntityRef: 'user:default/me' }, - })), - } as unknown as IdentityApi; - const discovery: jest.Mocked = { getBaseUrl: jest.fn(), getExternalBaseUrl: jest.fn(), @@ -164,8 +154,10 @@ describe('createRouter', () => { const router = await createRouter({ database: createDatabase(), discovery, - identity: mockIdentityClient, + identity: mockServices.identity(), logger: getVoidLogger(), + auth: mockServices.auth(), + httpAuth: mockServices.httpAuth(), }); app = express().use(router); @@ -174,44 +166,38 @@ describe('createRouter', () => { describe('GET /ratings', () => { it('should get ratings for all entities correctly', async () => { - const response = await request(app).get('/ratings').send(); + const response = await request(app) + .get('/ratings') + .set('authorization', mockCredentials.user.header()) + .send(); + expect(response.status).toEqual(200); + expect(response.body).toEqual([ + { + entityRef: 'component:default/foo', + entityTitle: 'Foo Component', + ratings: { LIKE: 3, DISLIKE: 1 }, + }, + { + entityRef: 'component:default/bar', + entityTitle: 'Bar Component', + ratings: { LIKE: 5 }, + }, + ]); expect(mockDbHandler.getAllRatedEntities).toHaveBeenCalled(); expect(mockDbHandler.getRatingsAggregates).toHaveBeenCalledWith( sampleEntities .filter(Boolean) .map((ent: any) => stringifyEntityRef(ent)), ); - expect(response.status).toEqual(200); - expect(response.body).toEqual([ - { - entityRef: 'component:default/foo', - entityTitle: 'Foo Component', - ratings: { LIKE: 3, DISLIKE: 1 }, - }, - { - entityRef: 'component:default/bar', - entityTitle: 'Bar Component', - ratings: { LIKE: 5 }, - }, - ]); }); it('should get ratings for all owned entities correctly', async () => { const response = await request(app) .get('/ratings?ownerRef=group:default/test-team') + .set('authorization', mockCredentials.user.header()) .send(); - expect(mockGetEntties).toHaveBeenCalledWith( - expect.objectContaining({ - filter: { 'relations.ownedBy': 'group:default/test-team' }, - }), - { token: 'token' }, - ); - expect(mockDbHandler.getAllRatedEntities).not.toHaveBeenCalled(); - expect(mockDbHandler.getRatingsAggregates).toHaveBeenCalledWith( - sampleOwnedEntities.map((ent: any) => stringifyEntityRef(ent)), - ); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -225,6 +211,21 @@ describe('createRouter', () => { ratings: { LIKE: 5 }, }, ]); + expect(mockGetEntities).toHaveBeenCalledWith( + expect.objectContaining({ + filter: { 'relations.ownedBy': 'group:default/test-team' }, + }), + { + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'catalog', + }), + }, + ); + expect(mockDbHandler.getAllRatedEntities).not.toHaveBeenCalled(); + expect(mockDbHandler.getRatingsAggregates).toHaveBeenCalledWith( + sampleOwnedEntities.map((ent: any) => stringifyEntityRef(ent)), + ); }); }); @@ -233,10 +234,11 @@ describe('createRouter', () => { const body = { rating: 'LIKE' }; const response = await request(app) .post('/ratings/component%3Adefault%2Fservice') + .set('authorization', mockCredentials.user.header()) .send(body); expect(mockDbHandler.recordRating).toHaveBeenCalledWith({ entityRef: 'component:default/service', - userRef: 'user:default/me', + userRef: 'user:default/mock', ...body, }); expect(response.status).toEqual(201); @@ -247,6 +249,7 @@ describe('createRouter', () => { it('should get ratings for an entity correctly', async () => { const response = await request(app) .get('/ratings/component%3Adefault%2Fservice') + .set('authorization', mockCredentials.user.header()) .send(); expect(mockDbHandler.getRatings).toHaveBeenCalledWith( 'component:default/service', @@ -262,6 +265,7 @@ describe('createRouter', () => { it('should get aggregated ratings for an entity correctly', async () => { const response = await request(app) .get('/ratings/component%3Adefault%2Fservice/aggregate') + .set('authorization', mockCredentials.user.header()) .send(); expect(mockDbHandler.getRatings).toHaveBeenCalledWith( 'component:default/service', @@ -279,10 +283,11 @@ describe('createRouter', () => { const body = { response: 'blah', comments: 'feedback', consent: true }; const response = await request(app) .post('/responses/component%3Adefault%2Fservice') + .set('authorization', mockCredentials.user.header()) .send(body); expect(mockDbHandler.recordResponse).toHaveBeenCalledWith({ entityRef: 'component:default/service', - userRef: 'user:default/me', + userRef: 'user:default/mock', ...body, }); expect(response.status).toEqual(201); @@ -293,6 +298,7 @@ describe('createRouter', () => { it('should get responses for an entity correctly', async () => { const response = await request(app) .get('/responses/component%3Adefault%2Fservice') + .set('authorization', mockCredentials.user.header()) .send(); expect(mockDbHandler.getResponses).toHaveBeenCalledWith( 'component:default/service', diff --git a/plugins/entity-feedback-backend/src/service/router.ts b/plugins/entity-feedback-backend/src/service/router.ts index 4953c531b8..7cf89bfd5c 100644 --- a/plugins/entity-feedback-backend/src/service/router.ts +++ b/plugins/entity-feedback-backend/src/service/router.ts @@ -15,16 +15,15 @@ */ import { + createLegacyAuthAdapters, errorHandler, PluginDatabaseManager, PluginEndpointDiscovery, } from '@backstage/backend-common'; +import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; import { CatalogClient } from '@backstage/catalog-client'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; -import { - getBearerTokenFromAuthorizationHeader, - IdentityApi, -} from '@backstage/plugin-auth-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { EntityRatingsData, Ratings, @@ -43,6 +42,8 @@ export interface RouterOptions { discovery: PluginEndpointDiscovery; identity: IdentityApi; logger: Logger; + auth?: AuthService; + httpAuth?: HttpAuthService; } /** @@ -51,9 +52,10 @@ export interface RouterOptions { export async function createRouter( options: RouterOptions, ): Promise { - const { database, discovery, identity, logger } = options; + const { database, discovery, logger } = options; logger.info('Initializing Entity Feedback backend'); + const { auth, httpAuth } = createLegacyAuthAdapters(options); const catalogClient = new CatalogClient({ discoveryApi: discovery }); const db = await database.getClient(); @@ -63,9 +65,10 @@ export async function createRouter( router.use(express.json()); router.get('/ratings', async (req, res) => { - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await httpAuth.credentials(req), + targetPluginId: 'catalog', + }); const requestedEntities: { [ref: string]: Entity } = {}; if (req.query.ownerRef) { @@ -131,11 +134,12 @@ export async function createRouter( }); router.post('/ratings/:entityRef', async (req, res) => { - const user = await identity.getIdentity({ request: req }); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); + const rating = req.body.rating; - if (!user || !rating) { + if (!rating) { logger.warn( - `Can't save rating because there is not enough info: user=${user}, rating=${rating}`, + `Can't save rating because there is not enough info: user=${credentials.principal.userEntityRef}, rating=${rating}`, ); res.status(400).end(); return; @@ -144,7 +148,7 @@ export async function createRouter( await dbHandler.recordRating({ entityRef: req.params.entityRef, rating, - userRef: user.identity.userEntityRef, + userRef: credentials.principal.userEntityRef, }); res.status(201).end(); @@ -153,9 +157,10 @@ export async function createRouter( router.get('/ratings/:entityRef', async (req, res) => { const ratings = await dbHandler.getRatings(req.params.entityRef); - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await httpAuth.credentials(req), + targetPluginId: 'catalog', + }); // Filter ratings via user refs to only expose entity refs accessible by current user const accessibleEntityRefs = ( @@ -177,9 +182,7 @@ export async function createRouter( const entityRatings = ( await dbHandler.getRatings(req.params.entityRef) ).reduce((ratings: Ratings, { rating }) => { - ratings[rating] = ratings[rating] ?? 0; - ratings[rating]++; - + ratings[rating] = (ratings[rating] ?? 0) + 1; return ratings; }, {}); @@ -187,21 +190,15 @@ export async function createRouter( }); router.post('/responses/:entityRef', async (req, res) => { - const user = await identity.getIdentity({ request: req }); const { response, comments, consent } = req.body; - - if (!user) { - logger.warn(`Could not identify user to save responses, user=${user}`); - res.status(400).end(); - return; - } + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); await dbHandler.recordResponse({ entityRef: req.params.entityRef, response, comments, consent, - userRef: user.identity.userEntityRef, + userRef: credentials.principal.userEntityRef, }); res.status(201).end(); @@ -210,9 +207,10 @@ export async function createRouter( router.get('/responses/:entityRef', async (req, res) => { const responses = await dbHandler.getResponses(req.params.entityRef); - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await httpAuth.credentials(req), + targetPluginId: 'catalog', + }); // Filter responses via user refs to only expose entity refs accessible by current user const accessibleEntityRefs = ( From 29a1f91c95d5cbf97a6e4ec2027ae60381beb2c3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 14 Feb 2024 12:36:11 +0100 Subject: [PATCH 56/76] badges-backend: migrate to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/two-snails-fry.md | 5 ++ plugins/badges-backend/api-report.md | 6 ++ plugins/badges-backend/src/plugin.ts | 6 ++ .../src/service/router-obfuscated.test.ts | 18 +++- plugins/badges-backend/src/service/router.ts | 83 +++++++++++-------- 5 files changed, 79 insertions(+), 39 deletions(-) create mode 100644 .changeset/two-snails-fry.md diff --git a/.changeset/two-snails-fry.md b/.changeset/two-snails-fry.md new file mode 100644 index 0000000000..979134f98e --- /dev/null +++ b/.changeset/two-snails-fry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-badges-backend': patch +--- + +Migrated to support new auth services. diff --git a/plugins/badges-backend/api-report.md b/plugins/badges-backend/api-report.md index ab5dbd9720..fb0c71dd75 100644 --- a/plugins/badges-backend/api-report.md +++ b/plugins/badges-backend/api-report.md @@ -3,11 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { Logger } from 'winston'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -131,6 +133,8 @@ export class DefaultBadgeBuilder implements BadgeBuilder { // @public (undocumented) export interface RouterOptions { + // (undocumented) + auth?: AuthService; // (undocumented) badgeBuilder?: BadgeBuilder; // (undocumented) @@ -144,6 +148,8 @@ export interface RouterOptions { // (undocumented) discovery: PluginEndpointDiscovery; // (undocumented) + httpAuth?: HttpAuthService; + // (undocumented) identity: IdentityApi; // (undocumented) logger: Logger; diff --git a/plugins/badges-backend/src/plugin.ts b/plugins/badges-backend/src/plugin.ts index e5a51d763f..be965ae4a6 100644 --- a/plugins/badges-backend/src/plugin.ts +++ b/plugins/badges-backend/src/plugin.ts @@ -38,6 +38,8 @@ export const badgesPlugin = createBackendPlugin({ tokenManager: coreServices.tokenManager, identity: coreServices.identity, httpRouter: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, + auth: coreServices.auth, }, async init({ config, @@ -46,6 +48,8 @@ export const badgesPlugin = createBackendPlugin({ tokenManager, identity, httpRouter, + httpAuth, + auth, }) { httpRouter.use( await createRouter({ @@ -55,6 +59,8 @@ export const badgesPlugin = createBackendPlugin({ discovery, tokenManager, identity, + httpAuth, + auth, }), ); }, diff --git a/plugins/badges-backend/src/service/router-obfuscated.test.ts b/plugins/badges-backend/src/service/router-obfuscated.test.ts index fd4a525234..10029dddd9 100644 --- a/plugins/badges-backend/src/service/router-obfuscated.test.ts +++ b/plugins/badges-backend/src/service/router-obfuscated.test.ts @@ -32,6 +32,7 @@ import { IdentityApiGetIdentityRequest, } from '@backstage/plugin-auth-node'; import { BadgesStore } from '../database/badgesStore'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('createRouter', () => { let app: express.Express; @@ -148,6 +149,8 @@ describe('createRouter', () => { tokenManager, logger: getVoidLogger(), identity: { getIdentity }, + auth: mockServices.auth(), + httpAuth: mockServices.httpAuth(), }); app = express().use(router); }); @@ -167,6 +170,8 @@ describe('createRouter', () => { logger: getVoidLogger(), identity: { getIdentity }, badgeStore: badgeStore, + auth: mockServices.auth(), + httpAuth: mockServices.httpAuth(), }); expect(router).toBeDefined(); }); @@ -232,9 +237,9 @@ describe('createRouter', () => { it('returns obfuscated entity and badges', async () => { catalog.getEntityByRef = jest.fn().mockResolvedValue(entity); - const obfuscatedEntity = await request(app) - .get('/entity/default/component/test/obfuscated') - .set('Authorization', 'Bearer fakeToken'); + const obfuscatedEntity = await request(app).get( + '/entity/default/component/test/obfuscated', + ); expect(obfuscatedEntity.status).toEqual(200); expect(obfuscatedEntity.body.uuid).toMatch( @@ -245,7 +250,12 @@ describe('createRouter', () => { expect(catalog.getEntityByRef).toHaveBeenCalledWith( { namespace: 'default', kind: 'component', name: 'test' }, - { token: 'fakeToken' }, + { + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'catalog', + }), + }, ); const uuid = obfuscatedEntity.body.uuid; diff --git a/plugins/badges-backend/src/service/router.ts b/plugins/badges-backend/src/service/router.ts index 5a8fbb538a..d508a02b2a 100644 --- a/plugins/badges-backend/src/service/router.ts +++ b/plugins/badges-backend/src/service/router.ts @@ -17,6 +17,7 @@ import express from 'express'; import Router from 'express-promise-router'; import { + createLegacyAuthAdapters, DatabaseManager, errorHandler, PluginEndpointDiscovery, @@ -30,9 +31,9 @@ import { BadgeContext, BadgeFactories } from '../types'; import { isNil } from 'lodash'; import { Logger } from 'winston'; import { IdentityApi } from '@backstage/plugin-auth-node'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { BadgesStore, DatabaseBadgesStore } from '../database/badgesStore'; import { createDefaultBadgeFactories } from '../badges'; +import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; /** @public */ export interface RouterOptions { @@ -42,6 +43,8 @@ export interface RouterOptions { config: Config; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; logger: Logger; identity: IdentityApi; badgeStore?: BadgesStore; @@ -60,28 +63,31 @@ export async function createRouter( ); const router = Router(); - const { config, logger, tokenManager, discovery } = options; + const { config, logger, discovery } = options; const baseUrl = await discovery.getExternalBaseUrl('badges'); + const { auth, httpAuth } = createLegacyAuthAdapters(options); + if (config.getOptionalBoolean('app.badges.obfuscate')) { return obfuscatedRoute( router, catalog, badgeBuilder, - tokenManager, logger, options, config, baseUrl, + auth, + httpAuth, ); } return nonObfuscatedRoute( router, catalog, badgeBuilder, - tokenManager, config, baseUrl, + auth, ); } @@ -89,18 +95,19 @@ async function obfuscatedRoute( router: express.Router, catalog: CatalogApi, badgeBuilder: BadgeBuilder, - tokenManager: TokenManager, logger: Logger, options: RouterOptions, config: Config, baseUrl: string, + auth: AuthService, + httpAuth: HttpAuthService, ) { logger.info('Badges obfuscation is enabled'); const store = options.badgeStore ? options.badgeStore : await DatabaseBadgesStore.create({ - database: await DatabaseManager.fromConfig(config).forPlugin('badges'), + database: DatabaseManager.fromConfig(config).forPlugin('badges'), }); router.get('/entity/:entityUuid/badge-specs', async (req, res) => { @@ -117,16 +124,15 @@ async function obfuscatedRoute( const name = badgeInfos.name; const namespace = badgeInfos.namespace; const kind = badgeInfos.kind; - const token = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); - // Query the catalog with the name, namespace, kind to get the entity informations + // Query the catalog with the name, namespace, kind to get the entity information const entity = await catalog.getEntityByRef( - { - namespace, - kind, - name, - }, - token, + { namespace, kind, name }, + { token }, ); if (isNil(entity)) { @@ -168,14 +174,15 @@ async function obfuscatedRoute( const name = badgeInfo.name; const namespace = badgeInfo.namespace; const kind = badgeInfo.kind; - const token = await tokenManager.getToken(); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entity = await catalog.getEntityByRef( - { - namespace, - kind, - name, - }, - token, + { namespace, kind, name }, + { token }, ); if (isNil(entity)) { throw new NotFoundError( @@ -217,20 +224,17 @@ async function obfuscatedRoute( router.get( '/entity/:namespace/:kind/:name/obfuscated', async function authenticate(req, _res, next) { - const token = getBearerTokenFromAuthorizationHeader( - req.headers.authorization, - ); - const { kind, namespace, name } = req.params; + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await httpAuth.credentials(req), + targetPluginId: 'catalog', + }); + // check that the user has the correct permissions // to view the catalog entity by forwarding the token const entity = await catalog.getEntityByRef( - { - kind, - namespace, - name, - }, + { kind, namespace, name }, { token }, ); @@ -266,16 +270,20 @@ async function nonObfuscatedRoute( router: express.Router, catalog: CatalogApi, badgeBuilder: BadgeBuilder, - tokenManager: TokenManager, config: Config, baseUrl: string, + auth: AuthService, ) { router.get('/entity/:namespace/:kind/:name/badge-specs', async (req, res) => { - const token = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const { namespace, kind, name } = req.params; const entity = await catalog.getEntityByRef( { namespace, kind, name }, - token, + { token }, ); if (!entity) { throw new NotFoundError( @@ -306,11 +314,16 @@ async function nonObfuscatedRoute( '/entity/:namespace/:kind/:name/badge/:badgeId', async (req, res) => { const { namespace, kind, name, badgeId } = req.params; - const token = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entity = await catalog.getEntityByRef( { namespace, kind, name }, - token, + { token }, ); + if (!entity) { throw new NotFoundError( `No ${kind} entity in ${namespace} named "${name}"`, From 43a9ae1a252d825c64d04584b6ce7d5e6c532e7a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 19:05:08 +0100 Subject: [PATCH 57/76] catalog-backend-module-backstage-openapi: migrate to use new auth service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/thin-spiders-do.md | 5 ++++ .../InternalOpenApiDocumentationProvider.ts | 26 ++++++++++++------- .../src/index.ts | 14 +++------- 3 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 .changeset/thin-spiders-do.md diff --git a/.changeset/thin-spiders-do.md b/.changeset/thin-spiders-do.md new file mode 100644 index 0000000000..df8672fd6c --- /dev/null +++ b/.changeset/thin-spiders-do.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-backstage-openapi': patch +--- + +Migrated to use new auth service. diff --git a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts index a8782e5eea..17e5a331f0 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION, @@ -25,7 +26,6 @@ import { EntityProviderConnection, } from '@backstage/plugin-catalog-node'; import { merge, isErrorResult } from 'openapi-merge'; -import { TokenManager } from '@backstage/backend-common'; import { getOpenApiSpecRoute } from '@backstage/backend-openapi-utils'; import type { OpenAPIObject, @@ -33,7 +33,11 @@ import type { PathItemObject, } from 'openapi3-ts'; import fetch from 'cross-fetch'; -import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + LoggerService, +} from '@backstage/backend-plugin-api'; import * as uuid from 'uuid'; import { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks'; @@ -108,19 +112,22 @@ const loadSpecs = async ({ discovery, plugins, logger, - tokenManager, + auth, }: { baseUrl: string; plugins: string[]; discovery: DiscoveryService; logger: LoggerService; - tokenManager: TokenManager; + auth: AuthService; }) => { const specs: OpenAPIObject[] = []; for (const pluginId of plugins) { const url = await discovery.getExternalBaseUrl(pluginId); const openApiUrl = getOpenApiSpecRoute(url); - const { token } = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: pluginId, + }); const response = await fetch(openApiUrl, { method: 'GET', headers: { @@ -149,11 +156,12 @@ const loadSpecs = async ({ export class InternalOpenApiDocumentationProvider implements EntityProvider { private connection?: EntityProviderConnection; private readonly scheduleFn: () => Promise; + constructor( public readonly config: Config, public readonly discovery: DiscoveryService, public readonly logger: LoggerService, - public readonly tokenManager: TokenManager, + public readonly auth: AuthService, taskRunner: TaskRunner, ) { this.scheduleFn = this.createScheduleFn(taskRunner); @@ -165,7 +173,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { discovery: DiscoveryService; logger: LoggerService; schedule: PluginTaskScheduler; - tokenManager: TokenManager; + auth: AuthService; }, ) { const taskRunner = options.schedule.createScheduledTaskRunner({ @@ -180,7 +188,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { config, options.discovery, options.logger, - options.tokenManager, + options.auth, taskRunner, ); } @@ -243,7 +251,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { await loadSpecs({ baseUrl: this.config.getString('backend.baseUrl'), discovery: this.discovery, - tokenManager: this.tokenManager, + auth: this.auth, plugins: pluginsToMerge, logger, }), diff --git a/plugins/catalog-backend-module-backstage-openapi/src/index.ts b/plugins/catalog-backend-module-backstage-openapi/src/index.ts index ac425afaf2..16810a9cfa 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/index.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/index.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { coreServices, createBackendModule, @@ -44,22 +45,15 @@ export const catalogModuleInternalOpenApiSpec = createBackendModule({ discovery: coreServices.discovery, scheduler: coreServices.scheduler, logger: coreServices.logger, - tokenManager: coreServices.tokenManager, + auth: coreServices.auth, }, - async init({ - catalog, - config, - discovery, - scheduler, - logger, - tokenManager, - }) { + async init({ catalog, config, discovery, scheduler, logger, auth }) { catalog.addEntityProvider( InternalOpenApiDocumentationProvider.fromConfig(config, { discovery, schedule: scheduler, logger, - tokenManager, + auth, }), ); }, From a936a8f8c8e2ccdd40ba6ed0f4a6d18358a2a2de Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 19:01:13 +0100 Subject: [PATCH 58/76] catalog-backend-module-github: migrated to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/cold-dolphins-raise.md | 5 +++++ .../api-report.md | 4 +++- .../analyzers/GithubLocationAnalyzer.test.ts | 22 +++++++++---------- .../src/analyzers/GithubLocationAnalyzer.ts | 19 ++++++++++++---- 4 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 .changeset/cold-dolphins-raise.md diff --git a/.changeset/cold-dolphins-raise.md b/.changeset/cold-dolphins-raise.md new file mode 100644 index 0000000000..1581edcc14 --- /dev/null +++ b/.changeset/cold-dolphins-raise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +Migrated the `GithubLocationAnalyzer` to support new auth services. diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index eb43748aa1..abae10035f 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -4,6 +4,7 @@ ```ts import { AnalyzeOptions } from '@backstage/plugin-catalog-node'; +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; @@ -124,7 +125,8 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { export type GithubLocationAnalyzerOptions = { config: Config; discovery: PluginEndpointDiscovery; - tokenManager: TokenManager; + tokenManager?: TokenManager; + auth?: AuthService; githubCredentialsProvider?: GithubCredentialsProvider; }; diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts index 549ca385e8..b745dd37ba 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts @@ -32,12 +32,12 @@ jest.mock('@octokit/rest', () => { return { Octokit }; }); -import { - PluginEndpointDiscovery, - TokenManager, -} from '@backstage/backend-common'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { GithubLocationAnalyzer } from './GithubLocationAnalyzer'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { + setupRequestMockHandlers, + mockServices, +} from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -49,10 +49,9 @@ describe('GithubLocationAnalyzer', () => { getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007'), getExternalBaseUrl: jest.fn(), }; - const mockTokenManager: jest.Mocked = { - authenticate: jest.fn(), - getToken: jest.fn().mockResolvedValue('abc123'), - }; + const mockAuthService = mockServices.auth.mock({ + getPluginRequestToken: async () => ({ token: 'abc123' }), + }); const config = new ConfigReader({ integrations: { github: [ @@ -123,8 +122,8 @@ describe('GithubLocationAnalyzer', () => { const analyzer = new GithubLocationAnalyzer({ discovery: mockDiscoveryApi, + auth: mockAuthService, config, - tokenManager: mockTokenManager, }); const result = await analyzer.analyze({ url: 'https://github.com/foo/bar', @@ -137,6 +136,7 @@ describe('GithubLocationAnalyzer', () => { 'https://github.com/foo/bar/blob/my_default_branch/catalog-info.yaml', }); }); + it('should use the provided entity filename for search', async () => { octokit.search.code.mockImplementation((opts: { q: string }) => { if (opts.q === 'filename:anvil.yaml repo:foo/bar') { @@ -149,8 +149,8 @@ describe('GithubLocationAnalyzer', () => { const analyzer = new GithubLocationAnalyzer({ discovery: mockDiscoveryApi, + auth: mockAuthService, config, - tokenManager: mockTokenManager, }); const result = await analyzer.analyze({ url: 'https://github.com/foo/bar', diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts index 3353254400..2648b1bcdc 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts @@ -31,14 +31,17 @@ import { import { PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { Config } from '@backstage/config'; +import { AuthService } from '@backstage/backend-plugin-api'; /** @public */ export type GithubLocationAnalyzerOptions = { config: Config; discovery: PluginEndpointDiscovery; - tokenManager: TokenManager; + tokenManager?: TokenManager; + auth?: AuthService; githubCredentialsProvider?: GithubCredentialsProvider; }; @@ -47,7 +50,7 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { private readonly catalogClient: CatalogApi; private readonly githubCredentialsProvider: GithubCredentialsProvider; private readonly integrations: ScmIntegrationRegistry; - private readonly tokenManager: TokenManager; + private readonly auth: AuthService; constructor(options: GithubLocationAnalyzerOptions) { this.catalogClient = new CatalogClient({ discoveryApi: options.discovery }); @@ -55,7 +58,12 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { this.githubCredentialsProvider = options.githubCredentialsProvider || DefaultGithubCredentialsProvider.fromIntegrations(this.integrations); - this.tokenManager = options.tokenManager; + + this.auth = createLegacyAuthAdapters({ + auth: options.auth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }).auth; } supports(url: string) { @@ -101,7 +109,10 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { }); const defaultBranch = repoInformation.data.default_branch; - const { token: serviceToken } = await this.tokenManager.getToken(); + const { token: serviceToken } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const result = await Promise.all( searchResult.data.items From 492fe83977f2da6c873a5193d5ba145356ad1a8e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 18:59:33 +0100 Subject: [PATCH 59/76] auth-backend: migrate to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/tasty-beans-confess.md | 5 +++ plugins/auth-backend/api-report.md | 15 ++++++- plugins/auth-backend/src/authPlugin.ts | 4 ++ .../lib/catalog/CatalogIdentityClient.test.ts | 2 + .../src/lib/catalog/CatalogIdentityClient.ts | 45 ++++++++++++++++--- .../resolvers/CatalogAuthResolverContext.ts | 23 ++++++++-- plugins/auth-backend/src/providers/router.ts | 17 +++++-- plugins/auth-backend/src/service/router.ts | 14 +++++- 8 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 .changeset/tasty-beans-confess.md diff --git a/.changeset/tasty-beans-confess.md b/.changeset/tasty-beans-confess.md new file mode 100644 index 0000000000..4498272dbf --- /dev/null +++ b/.changeset/tasty-beans-confess.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': minor +--- + +**BREAKING**: The `CatalogIdentityClient` constructor now also requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support the new auth services, which has also been done for the `createRouter` function. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 8d81751b39..1beddb6419 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -8,6 +8,7 @@ import { AuthProviderFactory as AuthProviderFactory_2 } from '@backstage/plugin- import { AuthProviderRouteHandlers as AuthProviderRouteHandlers_2 } from '@backstage/plugin-auth-node'; import { AuthResolverCatalogUserQuery as AuthResolverCatalogUserQuery_2 } from '@backstage/plugin-auth-node'; import { AuthResolverContext as AuthResolverContext_2 } from '@backstage/plugin-auth-node'; +import { AuthService } from '@backstage/backend-plugin-api'; import { AwsAlbResult as AwsAlbResult_2 } from '@backstage/plugin-auth-backend-module-aws-alb-provider'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { BackstageSignInResult } from '@backstage/plugin-auth-node'; @@ -17,11 +18,13 @@ import { ClientAuthResponse } from '@backstage/plugin-auth-node'; import { Config } from '@backstage/config'; import { CookieConfigurer as CookieConfigurer_2 } from '@backstage/plugin-auth-node'; import { decodeOAuthState } from '@backstage/plugin-auth-node'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { encodeOAuthState } from '@backstage/plugin-auth-node'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { GcpIapResult as GcpIapResult_2 } from '@backstage/plugin-auth-backend-module-gcp-iap-provider'; import { GcpIapTokenInfo as GcpIapTokenInfo_2 } from '@backstage/plugin-auth-backend-module-gcp-iap-provider'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { OAuth2ProxyResult as OAuth2ProxyResult_2 } from '@backstage/plugin-auth-backend-module-oauth2-proxy-provider'; import { OAuthEnvironmentHandler as OAuthEnvironmentHandler_2 } from '@backstage/plugin-auth-node'; @@ -117,7 +120,13 @@ export type BitbucketServerOAuthResult = { // @public export class CatalogIdentityClient { - constructor(options: { catalogApi: CatalogApi; tokenManager: TokenManager }); + constructor(options: { + catalogApi: CatalogApi; + tokenManager: TokenManager; + discovery: DiscoveryService; + auth?: AuthService; + httpAuth?: HttpAuthService; + }); findUser(query: { annotations: Record }): Promise; resolveCatalogMembership(query: { entityRefs: string[]; @@ -642,6 +651,8 @@ export const readState: typeof decodeOAuthState; // @public (undocumented) export interface RouterOptions { + // (undocumented) + auth?: AuthService; // (undocumented) catalogApi?: CatalogApi; // (undocumented) @@ -653,6 +664,8 @@ export interface RouterOptions { // (undocumented) discovery: PluginEndpointDiscovery; // (undocumented) + httpAuth?: HttpAuthService; + // (undocumented) logger: LoggerService; // (undocumented) providerFactories?: ProviderFactories; diff --git a/plugins/auth-backend/src/authPlugin.ts b/plugins/auth-backend/src/authPlugin.ts index 0522424a99..756d8b80a1 100644 --- a/plugins/auth-backend/src/authPlugin.ts +++ b/plugins/auth-backend/src/authPlugin.ts @@ -75,6 +75,10 @@ export const authPlugin = createBackendPlugin({ providerFactories: Object.fromEntries(providers), disableDefaultProviderFactories: true, }); + httpRouter.addAuthPolicy({ + path: '/', + allow: 'unauthenticated', + }); httpRouter.use(router); }, }); diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts index 96cd8d32cb..3439578d5e 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts @@ -48,6 +48,7 @@ describe('CatalogIdentityClient', () => { catalogApi.getEntities.mockResolvedValueOnce({ items: [{} as UserEntity] }); tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ + discovery: {} as any, catalogApi: catalogApi as Partial as CatalogApi, tokenManager, }); @@ -106,6 +107,7 @@ describe('CatalogIdentityClient', () => { tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ + discovery: {} as any, catalogApi: catalogApi as Partial as CatalogApi, tokenManager, }); diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts index ff983e27a5..51c72eeb63 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { ConflictError, NotFoundError } from '@backstage/errors'; import { CatalogApi } from '@backstage/catalog-client'; import { @@ -24,7 +29,10 @@ import { stringifyEntityRef, UserEntity, } from '@backstage/catalog-model'; -import { TokenManager } from '@backstage/backend-common'; +import { + TokenManager, + createLegacyAuthAdapters, +} from '@backstage/backend-common'; /** * A catalog client tailored for reading out identity data from the catalog. @@ -33,11 +41,25 @@ import { TokenManager } from '@backstage/backend-common'; */ export class CatalogIdentityClient { private readonly catalogApi: CatalogApi; - private readonly tokenManager: TokenManager; + private readonly auth: AuthService; - constructor(options: { catalogApi: CatalogApi; tokenManager: TokenManager }) { + constructor(options: { + catalogApi: CatalogApi; + tokenManager: TokenManager; + discovery: DiscoveryService; + auth?: AuthService; + httpAuth?: HttpAuthService; + }) { this.catalogApi = options.catalogApi; - this.tokenManager = options.tokenManager; + + const { auth } = createLegacyAuthAdapters({ + auth: options.auth, + httpAuth: options.httpAuth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }); + + this.auth = auth; } /** @@ -55,7 +77,11 @@ export class CatalogIdentityClient { filter[`metadata.annotations.${key}`] = value; } - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const { items } = await this.catalogApi.getEntities({ filter }, { token }); if (items.length !== 1) { @@ -101,7 +127,12 @@ export class CatalogIdentityClient { 'metadata.namespace': ref.namespace, 'metadata.name': ref.name, })); - const { token } = await this.tokenManager.getToken(); + + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entities = await this.catalogApi .getEntities({ filter }, { token }) .then(r => r.items); diff --git a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts index a7e02c1c31..a4bd2203ae 100644 --- a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts +++ b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts @@ -24,7 +24,12 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { ConflictError, InputError, NotFoundError } from '@backstage/errors'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { TokenIssuer } from '../../identity/types'; import { CatalogIdentityClient } from '../catalog'; import { @@ -61,17 +66,24 @@ export class CatalogAuthResolverContext implements AuthResolverContext { catalogApi: CatalogApi; tokenIssuer: TokenIssuer; tokenManager: TokenManager; + discovery: DiscoveryService; + auth: AuthService; + httpAuth: HttpAuthService; }): CatalogAuthResolverContext { const catalogIdentityClient = new CatalogIdentityClient({ catalogApi: options.catalogApi, tokenManager: options.tokenManager, + discovery: options.discovery, + auth: options.auth, + httpAuth: options.httpAuth, }); + return new CatalogAuthResolverContext( options.logger, options.tokenIssuer, catalogIdentityClient, options.catalogApi, - options.tokenManager, + options.auth, ); } @@ -80,7 +92,7 @@ export class CatalogAuthResolverContext implements AuthResolverContext { public readonly tokenIssuer: TokenIssuer, public readonly catalogIdentityClient: CatalogIdentityClient, private readonly catalogApi: CatalogApi, - private readonly tokenManager: TokenManager, + private readonly auth: AuthService, ) {} async issueToken(params: TokenParams) { @@ -90,7 +102,10 @@ export class CatalogAuthResolverContext implements AuthResolverContext { async findCatalogUser(query: AuthResolverCatalogUserQuery) { let result: Entity[] | Entity | undefined = undefined; - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); if ('entityRef' in query) { const entityRef = parseEntityRef(query.entityRef, { diff --git a/plugins/auth-backend/src/providers/router.ts b/plugins/auth-backend/src/providers/router.ts index 9971466ad4..8c927f52c6 100644 --- a/plugins/auth-backend/src/providers/router.ts +++ b/plugins/auth-backend/src/providers/router.ts @@ -18,7 +18,11 @@ import { PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { NotFoundError, assertError } from '@backstage/errors'; @@ -41,6 +45,8 @@ export function bindProviderRouters( config: Config; logger: LoggerService; discovery: PluginEndpointDiscovery; + auth: AuthService; + httpAuth: HttpAuthService; tokenManager: TokenManager; tokenIssuer: TokenIssuer; catalogApi?: CatalogApi; @@ -53,6 +59,8 @@ export function bindProviderRouters( config, logger, discovery, + auth, + httpAuth, tokenManager, tokenIssuer, catalogApi, @@ -69,10 +77,10 @@ export function bindProviderRouters( const provider = providerFactory({ providerId, appUrl, - baseUrl: baseUrl, + baseUrl, isOriginAllowed, globalConfig: { - baseUrl: baseUrl, + baseUrl, appUrl, isOriginAllowed, }, @@ -84,6 +92,9 @@ export function bindProviderRouters( catalogApi ?? new CatalogClient({ discoveryApi: discovery }), tokenIssuer, tokenManager, + discovery, + auth, + httpAuth, }), }); diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index 459c347835..5628e7be55 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -17,12 +17,17 @@ import express from 'express'; import Router from 'express-promise-router'; import cookieParser from 'cookie-parser'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { defaultAuthProviderFactories } from '../providers'; import { PluginDatabaseManager, PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { NotFoundError } from '@backstage/errors'; import { CatalogApi } from '@backstage/catalog-client'; @@ -45,6 +50,8 @@ export interface RouterOptions { config: Config; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; tokenFactoryAlgorithm?: string; providerFactories?: ProviderFactories; disableDefaultProviderFactories?: boolean; @@ -63,6 +70,9 @@ export async function createRouter( tokenFactoryAlgorithm, providerFactories = {}, } = options; + + const { auth, httpAuth } = createLegacyAuthAdapters(options); + const router = Router(); const appUrl = config.getString('app.baseUrl'); @@ -136,6 +146,8 @@ export async function createRouter( baseUrl: authUrl, tokenIssuer, ...options, + auth, + httpAuth, }); bindOidcRouter(router, { From b4fc6e316429ee549a998d8feb7e8f2b24609f7b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 18:57:04 +0100 Subject: [PATCH 60/76] auth-node: deprecate getBearerTokenFromAuthorizationHeader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/chilled-dolls-accept.md | 5 +++++ plugins/auth-node/api-report.md | 2 +- .../src/identity/getBearerTokenFromAuthorizationHeader.ts | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/chilled-dolls-accept.md diff --git a/.changeset/chilled-dolls-accept.md b/.changeset/chilled-dolls-accept.md new file mode 100644 index 0000000000..1df2b0dc98 --- /dev/null +++ b/.changeset/chilled-dolls-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-node': patch +--- + +Deprecated the `getBearerTokenFromAuthorizationHeader` function, which is being replaced by the new `HttpAuthService`. diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index 5c8c547442..26e11236d2 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -223,7 +223,7 @@ export class DefaultIdentityClient implements IdentityApi { // @public (undocumented) export function encodeOAuthState(state: OAuthState): string; -// @public +// @public @deprecated export function getBearerTokenFromAuthorizationHeader( authorizationHeader: unknown, ): string | undefined; diff --git a/plugins/auth-node/src/identity/getBearerTokenFromAuthorizationHeader.ts b/plugins/auth-node/src/identity/getBearerTokenFromAuthorizationHeader.ts index 8451cd6ab1..f9ed969144 100644 --- a/plugins/auth-node/src/identity/getBearerTokenFromAuthorizationHeader.ts +++ b/plugins/auth-node/src/identity/getBearerTokenFromAuthorizationHeader.ts @@ -24,6 +24,7 @@ * call it directly with e.g. the output of `req.header('authorization')` * without first checking that it exists. * + * @deprecated Use the `credentials` method of `HttpAuthService` from `@backstage/backend-plugin-api` instead * @public */ export function getBearerTokenFromAuthorizationHeader( From c8fdd8381083c9fda385b271251852ca03bee028 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 18:50:43 +0100 Subject: [PATCH 61/76] adr-backend: migrated to support new auth services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .changeset/tiny-bugs-enjoy.md | 5 +++++ plugins/adr-backend/api-report.md | 2 ++ .../src/search/DefaultAdrCollatorFactory.ts | 17 ++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 .changeset/tiny-bugs-enjoy.md diff --git a/.changeset/tiny-bugs-enjoy.md b/.changeset/tiny-bugs-enjoy.md new file mode 100644 index 0000000000..963ccc2a1f --- /dev/null +++ b/.changeset/tiny-bugs-enjoy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-adr-backend': patch +--- + +Migrated `DefaultAdrCollatorFactory` to support new auth services. diff --git a/plugins/adr-backend/api-report.md b/plugins/adr-backend/api-report.md index 1247a7aa8f..9b00888435 100644 --- a/plugins/adr-backend/api-report.md +++ b/plugins/adr-backend/api-report.md @@ -7,6 +7,7 @@ import { AdrDocument } from '@backstage/plugin-adr-common'; import { AdrFilePathFilterFn } from '@backstage/plugin-adr-common'; +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CacheClient } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; @@ -32,6 +33,7 @@ export type AdrCollatorFactoryOptions = { parser?: AdrParser; reader: UrlReader; tokenManager: TokenManager; + auth?: AuthService; }; // @public diff --git a/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts b/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts index 78f6e0226e..21aa7f32a4 100644 --- a/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts +++ b/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts @@ -22,6 +22,7 @@ import { PluginEndpointDiscovery, TokenManager, UrlReader, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { CatalogApi, @@ -46,6 +47,7 @@ import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { createMadrParser } from './createMadrParser'; import { AdrParser } from './types'; +import { AuthService } from '@backstage/backend-plugin-api'; /** * Options to configure the AdrCollatorFactory @@ -89,6 +91,10 @@ export type AdrCollatorFactoryOptions = { * Token Manager */ tokenManager: TokenManager; + /** + * Auth Service + */ + auth?: AuthService; }; /** @@ -103,8 +109,8 @@ export class DefaultAdrCollatorFactory implements DocumentCollatorFactory { private readonly logger: Logger; private readonly parser: AdrParser; private readonly reader: UrlReader; + private readonly auth: AuthService; private readonly scmIntegrations: ScmIntegrationRegistry; - private readonly tokenManager: TokenManager; private constructor(options: AdrCollatorFactoryOptions) { this.adrFilePathFilterFn = @@ -117,7 +123,8 @@ export class DefaultAdrCollatorFactory implements DocumentCollatorFactory { this.parser = options.parser ?? createMadrParser(); this.reader = options.reader; this.scmIntegrations = ScmIntegrations.fromConfig(options.config); - this.tokenManager = options.tokenManager; + + this.auth = createLegacyAuthAdapters(options).auth; } static fromConfig(options: AdrCollatorFactoryOptions) { @@ -129,7 +136,11 @@ export class DefaultAdrCollatorFactory implements DocumentCollatorFactory { } async *execute(): AsyncGenerator { - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entities = ( await this.catalogClient.getEntities( { From e77d7a90c645c435210ed950d293df8a42bf2a3d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 18:45:41 +0100 Subject: [PATCH 62/76] auth-backend-module-oauth2-proxy-provider: internal refactor to avoid deprecated method Signed-off-by: Patrik Oldsberg --- .changeset/spicy-dragons-sin.md | 5 +++++ .../src/authenticator.ts | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 .changeset/spicy-dragons-sin.md diff --git a/.changeset/spicy-dragons-sin.md b/.changeset/spicy-dragons-sin.md new file mode 100644 index 0000000000..06d3316dd5 --- /dev/null +++ b/.changeset/spicy-dragons-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-oauth2-proxy-provider': patch +--- + +Internal refactor to avoid deprecated method. diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts index fb124fef30..21fe52e824 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts @@ -15,10 +15,7 @@ */ import { AuthenticationError } from '@backstage/errors'; -import { - createProxyAuthenticator, - getBearerTokenFromAuthorizationHeader, -} from '@backstage/plugin-auth-node'; +import { createProxyAuthenticator } from '@backstage/plugin-auth-node'; import { decodeJwt } from 'jose'; import { OAuth2ProxyResult } from './types'; @@ -46,7 +43,7 @@ export const oauth2ProxyAuthenticator = createProxyAuthenticator({ async authenticate({ req }) { try { const authHeader = req.header(OAUTH2_PROXY_JWT_HEADER); - const jwt = getBearerTokenFromAuthorizationHeader(authHeader); + const jwt = authHeader?.match(/^Bearer[ ]+(\S+)$/i)?.[1]; const decodedJWT = jwt && decodeJwt(jwt); const result = { From aff4feb7767541d65469c189bdc6c8b6a99d87ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 23 Feb 2024 11:22:44 +0100 Subject: [PATCH 63/76] sort the root package.json, and make sure that all package.json files get sorted going forward MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- package.json | 154 ++++++++++++++++++++++++++------------------------- yarn.lock | 61 ++++++++++++++++++-- 2 files changed, 136 insertions(+), 79 deletions(-) diff --git a/package.json b/package.json index ad3b7feed4..c48c97f54b 100644 --- a/package.json +++ b/package.json @@ -1,50 +1,7 @@ { "name": "root", + "version": "1.23.0", "private": true, - "engines": { - "node": "18 || 20" - }, - "scripts": { - "dev": "concurrently 'yarn start' 'yarn start-backend'", - "dev:next": "concurrently 'yarn start:next' 'yarn start-backend:next'", - "start": "yarn workspace example-app start", - "start-backend": "yarn workspace example-backend start", - "start:next": "yarn workspace example-app-next start", - "start-backend:next": "yarn workspace example-backend-next start", - "start:microsite": "cd microsite/ && yarn start", - "build:backend": "yarn workspace example-backend build", - "build:all": "backstage-cli repo build --all", - "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", - "build:knip-reports": "backstage-repo-tools knip-reports", - "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", - "build:plugins-report": "node ./scripts/build-plugins-report", - "tsc": "tsc", - "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false", - "clean": "backstage-cli repo clean", - "test": "backstage-cli repo test", - "test:all": "backstage-cli repo test --coverage", - "test:e2e": "playwright test", - "fix": "backstage-cli repo fix", - "lint": "backstage-cli repo lint --since origin/master", - "lint:docs": "node ./scripts/check-docs-quality", - "lint:all": "backstage-cli repo lint", - "lint:type-deps": "backstage-repo-tools type-deps", - "docker-build": "yarn tsc && yarn workspace example-backend build && yarn workspace example-backend build-image", - "new": "backstage-cli new --scope backstage --baseVersion 0.0.0 --no-private", - "create-plugin": "echo \"use 'yarn new' instead\"", - "release": "node scripts/prepare-release.js && changeset version && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install --no-immutable", - "prettier:check": "prettier --check .", - "prettier:fix": "prettier --write .", - "storybook": "yarn ./storybook run start", - "snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false", - "snyk:test:package": "yarn snyk:test --include", - "build-storybook": "yarn ./storybook run build-storybook", - "techdocs-cli": "node scripts/techdocs-cli.js", - "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", - "prepare": "husky", - "postinstall": "husky || true" - }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage" @@ -55,14 +12,83 @@ "plugins/*" ] }, + "scripts": { + "build-storybook": "yarn ./storybook run build-storybook", + "build:all": "backstage-cli repo build --all", + "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", + "build:api-reports": "yarn build:api-reports:only --tsc", + "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", + "build:backend": "yarn workspace example-backend build", + "build:knip-reports": "backstage-repo-tools knip-reports", + "build:plugins-report": "node ./scripts/build-plugins-report", + "clean": "backstage-cli repo clean", + "create-plugin": "echo \"use 'yarn new' instead\"", + "dev": "concurrently 'yarn start' 'yarn start-backend'", + "dev:next": "concurrently 'yarn start:next' 'yarn start-backend:next'", + "docker-build": "yarn tsc && yarn workspace example-backend build && yarn workspace example-backend build-image", + "fix": "backstage-cli repo fix", + "postinstall": "husky || true", + "lint": "backstage-cli repo lint --since origin/master", + "lint:all": "backstage-cli repo lint", + "lint:docs": "node ./scripts/check-docs-quality", + "lint:type-deps": "backstage-repo-tools type-deps", + "new": "backstage-cli new --scope backstage --baseVersion 0.0.0 --no-private", + "prepare": "husky", + "prettier:check": "prettier --check .", + "prettier:fix": "prettier --write .", + "release": "node scripts/prepare-release.js && changeset version && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install --no-immutable", + "snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false", + "snyk:test:package": "yarn snyk:test --include", + "start": "yarn workspace example-app start", + "start-backend": "yarn workspace example-backend start", + "start-backend:next": "yarn workspace example-backend-next start", + "start:microsite": "cd microsite/ && yarn start", + "start:next": "yarn workspace example-app-next start", + "storybook": "yarn ./storybook run start", + "techdocs-cli": "node scripts/techdocs-cli.js", + "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", + "test": "backstage-cli repo test", + "test:all": "backstage-cli repo test --coverage", + "test:e2e": "playwright test", + "tsc": "tsc", + "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx,mjs,cjs}": [ + "eslint --fix", + "prettier --write" + ], + "*.json": [ + "prettier --write" + ], + "*.md": [ + "prettier --write", + "node ./scripts/check-docs-quality" + ], + "{plugins,packages}/*/catalog-info.yaml": [ + "yarn backstage-repo-tools generate-catalog-info --ci" + ], + ".github/CODEOWNERS": [ + "yarn backstage-repo-tools generate-catalog-info", + "git add */catalog-info.yaml" + ], + "package.json": [ + "yarn backstage-repo-tools generate-catalog-info", + "git add */catalog-info.yaml", + "yarn sort-package-json" + ], + "yarn.lock": [ + "node ./scripts/verify-lockfile-duplicates --fix" + ] + }, + "prettier": "@spotify/prettier-config", "resolutions": { + "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", + "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", "@types/react": "^18", "@types/react-dom": "^18", - "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch", - "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", - "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch" + "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch" }, - "version": "1.23.0", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", @@ -100,34 +126,12 @@ "semver": "^7.5.3", "shx": "^0.3.2", "sloc": "^0.3.1", + "sort-package-json": "^2.8.0", "ts-node": "^10.4.0", "typescript": "~5.1.0" }, - "prettier": "@spotify/prettier-config", - "lint-staged": { - "*.{js,jsx,ts,tsx,mjs,cjs}": [ - "eslint --fix", - "prettier --write" - ], - "*.{json,md}": [ - "prettier --write" - ], - "*.md": [ - "node ./scripts/check-docs-quality" - ], - "{plugins,packages}/*/catalog-info.yaml": [ - "yarn backstage-repo-tools generate-catalog-info --ci" - ], - "{.github/CODEOWNERS,package.json}": [ - "yarn backstage-repo-tools generate-catalog-info", - "git add */catalog-info.yaml" - ], - "./yarn.lock": [ - "node ./scripts/verify-lockfile-duplicates --fix" - ], - "*/yarn.lock": [ - "node ./scripts/verify-lockfile-duplicates --fix" - ] - }, - "packageManager": "yarn@3.2.3" + "packageManager": "yarn@3.2.3", + "engines": { + "node": "18 || 20" + } } diff --git a/yarn.lock b/yarn.lock index 922409280e..1f0414cb59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25340,6 +25340,13 @@ __metadata: languageName: node linkType: hard +"detect-indent@npm:^7.0.1": + version: 7.0.1 + resolution: "detect-indent@npm:7.0.1" + checksum: cbf3f0b1c3c881934ca94428e1179b26ab2a587e0d719031d37a67fb506d49d067de54ff057cb1e772e75975fed5155c01cd4518306fee60988b1486e3fc7768 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0": version: 2.0.1 resolution: "detect-libc@npm:2.0.1" @@ -25354,6 +25361,13 @@ __metadata: languageName: node linkType: hard +"detect-newline@npm:^4.0.0": + version: 4.0.1 + resolution: "detect-newline@npm:4.0.1" + checksum: 0409ecdfb93419591ccff24fccfe2ddddad29b66637d1ed898872125b25af05014fdeedc9306339577060f69f59fe6e9830cdd80948597f136dfbffefa60599c + languageName: node + linkType: hard + "detect-node-es@npm:^1.1.0": version: 1.1.0 resolution: "detect-node-es@npm:1.1.0" @@ -28859,6 +28873,13 @@ __metadata: languageName: node linkType: hard +"get-stdin@npm:^9.0.0": + version: 9.0.0 + resolution: "get-stdin@npm:9.0.0" + checksum: 5972bc34d05932b45512c8e2d67b040f1c1ca8afb95c56cbc480985f2d761b7e37fe90dc8abd22527f062cc5639a6930ff346e9952ae4c11a2d4275869459594 + languageName: node + linkType: hard + "get-stream@npm:^4.0.0, get-stream@npm:^4.1.0": version: 4.1.0 resolution: "get-stream@npm:4.1.0" @@ -28938,6 +28959,13 @@ __metadata: languageName: node linkType: hard +"git-hooks-list@npm:^3.0.0": + version: 3.1.0 + resolution: "git-hooks-list@npm:3.1.0" + checksum: 05cbdb29e1e14f3b6fde78c876a34383e4476b1be32e8486ad03293f01add884c1a8df8c2dce2ca5d99119c94951b2ff9fa9cbd51d834ae6477b6813cefb998f + languageName: node + linkType: hard + "git-up@npm:^7.0.0": version: 7.0.0 resolution: "git-up@npm:7.0.0" @@ -30979,10 +31007,10 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^4.0.0": - version: 4.0.0 - resolution: "is-plain-obj@npm:4.0.0" - checksum: a6bb55a90636345a64c6153b74d85a9b6440f9975f4dcc57eed596c280b7ba228c71c406355a3147ed0488330d2743d5756e052c9492b1aa4f7dcd281f08c4b6 +"is-plain-obj@npm:^4.0.0, is-plain-obj@npm:^4.1.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce languageName: node linkType: hard @@ -40987,6 +41015,7 @@ __metadata: semver: ^7.5.3 shx: ^0.3.2 sloc: ^0.3.1 + sort-package-json: ^2.8.0 ts-node: ^10.4.0 typescript: ~5.1.0 languageName: unknown @@ -41921,6 +41950,30 @@ __metadata: languageName: node linkType: hard +"sort-object-keys@npm:^1.1.3": + version: 1.1.3 + resolution: "sort-object-keys@npm:1.1.3" + checksum: abea944d6722a1710a1aa6e4f9509da085d93d5fc0db23947cb411eedc7731f80022ce8fa68ed83a53dd2ac7441fcf72a3f38c09b3d9bbc4ff80546aa2e151ad + languageName: node + linkType: hard + +"sort-package-json@npm:^2.8.0": + version: 2.8.0 + resolution: "sort-package-json@npm:2.8.0" + dependencies: + detect-indent: ^7.0.1 + detect-newline: ^4.0.0 + get-stdin: ^9.0.0 + git-hooks-list: ^3.0.0 + globby: ^13.1.2 + is-plain-obj: ^4.1.0 + sort-object-keys: ^1.1.3 + bin: + sort-package-json: cli.js + checksum: 8739392ae4f5f6aa07948e317e43c62e2165fa815175c4678b1eef815f27d93846262113a16f17c10f12856f72222c312a8a5ed2dcae60265bfbacee64967312 + languageName: node + linkType: hard + "source-list-map@npm:^2.0.0": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" From 9c27f594a8a07d28687417ad43e6fd6188019bf4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:34:54 +0000 Subject: [PATCH 64/76] chore(deps): update github/codeql-action action to v3.24.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 2 +- .github/workflows/verify_codeql.yml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 621776d69b..d94373e9d1 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 7ee4e72d38..c5374951d7 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 with: sarif_file: snyk.sarif diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index 7c7ef286db..dabbff24db 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/init@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/autobuild@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/analyze@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 From ab01673c01bd3056625a534f266171eebf37cc18 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 23 Feb 2024 13:18:41 +0100 Subject: [PATCH 65/76] backend-app-api: add tests for createCretentialsBarrier + fix Signed-off-by: Patrik Oldsberg --- .../createCredentialsBarrier.test.ts | 122 ++++++++++++++++++ .../httpRouter/createCredentialsBarrier.ts | 17 ++- 2 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts new file mode 100644 index 0000000000..b8430d398e --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts @@ -0,0 +1,122 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint-disable jest/expect-expect */ + +import express from 'express'; +import request from 'supertest'; +import { createCredentialsBarrier } from './createCredentialsBarrier'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { MiddlewareFactory } from '../../../http'; + +const errorMiddleware = MiddlewareFactory.create({ + config: mockServices.rootConfig(), + logger: mockServices.rootLogger(), +}).error(); + +function setup() { + const barrier = createCredentialsBarrier({ + httpAuth: mockServices.httpAuth({ + defaultCredentials: mockCredentials.none(), + }), + config: mockServices.rootConfig(), + }); + + const app = express(); + app.use(barrier.middleware); + app.use(errorMiddleware); + app.get('*', (_req, res) => res.status(200).end()); + + return { app, barrier }; +} + +describe('createCredentialsBarrier', () => { + it('should enforce default auth policy', async () => { + const { app } = setup(); + + await request(app) + .get('/') + .send() + .expect(401) + .expect(res => + expect(res.body).toMatchObject({ + error: { name: 'AuthenticationError', message: '' }, + }), + ); + + await request(app) + .get('/') + .set('authorization', mockCredentials.user.invalidHeader()) + .send() + .expect(401) + .expect(res => + expect(res.body).toMatchObject({ + error: { + name: 'AuthenticationError', + message: 'User token is invalid', + }, + }), + ); + + await request(app) + .get('/') + .set('authorization', mockCredentials.service.invalidHeader()) + .send() + .expect(401) + .expect(res => + expect(res.body).toMatchObject({ + error: { + name: 'AuthenticationError', + message: 'Service token is invalid', + }, + }), + ); + + await request(app) + .get('/') + .set('authorization', mockCredentials.user.header()) + .send() + .expect(200); + + await request(app) + .get('/') + .set('authorization', mockCredentials.service.header()) + .send() + .expect(200); + }); + + it('should allow exceptions to the default auth policy to be made', async () => { + const { app, barrier } = setup(); + + await request(app).get('/').send().expect(401); + await request(app).get('/public').send().expect(401); + await request(app).get('/other').send().expect(401); + + barrier.addAuthPolicy({ allow: 'unauthenticated', path: '/public' }); + + await request(app).get('/').send().expect(401); + await request(app).get('/public').send().expect(200); + await request(app).get('/other').send().expect(401); + + barrier.addAuthPolicy({ allow: 'unauthenticated', path: '/' }); + + await request(app).get('/').send().expect(200); + await request(app).get('/public').send().expect(200); + await request(app).get('/other').send().expect(200); + }); + + // TODO: cookie auth +}); diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts index 801c87d430..a512c5ac9e 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts @@ -59,7 +59,7 @@ export function createCredentialsBarrier(options: { const unauthenticatedPredicates = new Array<(path: string) => boolean>(); const cookiePredicates = new Array<(path: string) => boolean>(); - const middleware: RequestHandler = async (req, _, next) => { + const middleware: RequestHandler = (req, _, next) => { const allowsUnauthenticated = unauthenticatedPredicates.some(predicate => predicate(req.path), ); @@ -73,12 +73,15 @@ export function createCredentialsBarrier(options: { predicate(req.path), ); - await httpAuth.credentials(req, { - allow: ['user', 'service'], - allowedAuthMethods: allowsCookie ? ['token', 'cookie'] : ['token'], - }); - - next(); + httpAuth + .credentials(req, { + allow: ['user', 'service'], + allowedAuthMethods: allowsCookie ? ['token', 'cookie'] : ['token'], + }) + .then( + () => next(), + err => next(err), + ); }; const addAuthPolicy = (policy: HttpRouterServiceAuthPolicy) => { From c66a99c27220fccef8571fdee1a0f5905581eb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 23 Feb 2024 12:32:02 +0100 Subject: [PATCH 66/76] sort package.json files that have no PRs active toward them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- package.json | 2 +- packages/app-defaults/package.json | 38 ++++++------ packages/app-next-example-plugin/package.json | 38 ++++++------ packages/backend-dev-utils/package.json | 28 ++++----- packages/catalog-client/package.json | 32 +++++----- packages/catalog-model/package.json | 44 +++++++------- packages/cli-common/package.json | 32 +++++----- packages/cli-node/package.json | 28 ++++----- packages/codemods/package.json | 54 ++++++++--------- packages/config-loader/package.json | 28 ++++----- packages/config/package.json | 28 ++++----- packages/dev-utils/package.json | 38 ++++++------ packages/e2e-test-utils/package.json | 40 ++++++------- packages/errors/package.json | 32 +++++----- packages/frontend-app-api/package.json | 46 +++++++-------- packages/frontend-plugin-api/package.json | 34 +++++------ packages/frontend-test-utils/package.json | 40 ++++++------- packages/integration-aws-node/package.json | 30 +++++----- packages/integration-react/package.json | 36 ++++++------ packages/integration/package.json | 32 +++++----- packages/release-manifests/package.json | 30 +++++----- packages/theme/package.json | 36 ++++++------ packages/version-bridge/package.json | 38 ++++++------ plugins/adr-common/package.json | 28 ++++----- plugins/adr/package.json | 54 ++++++++--------- plugins/airbrake/package.json | 34 +++++------ plugins/allure/package.json | 36 ++++++------ plugins/analytics-module-ga/package.json | 36 ++++++------ plugins/analytics-module-ga4/package.json | 36 ++++++------ .../package.json | 34 +++++------ plugins/apache-airflow/package.json | 36 ++++++------ .../package.json | 42 +++++++------- plugins/api-docs/package.json | 54 ++++++++--------- plugins/apollo-explorer/package.json | 36 ++++++------ plugins/app-visualizer/package.json | 32 +++++----- .../package.json | 30 +++++----- plugins/auth-backend/package.json | 34 +++++------ plugins/auth-node/package.json | 26 ++++----- plugins/azure-sites-common/package.json | 34 +++++------ plugins/azure-sites/package.json | 44 +++++++------- plugins/badges-backend/package.json | 36 ++++++------ plugins/badges/package.json | 36 ++++++------ plugins/bazaar-backend/package.json | 42 +++++++------- plugins/bazaar/package.json | 34 +++++------ plugins/bitbucket-cloud-common/package.json | 30 +++++----- plugins/bitrise/package.json | 36 ++++++------ .../catalog-backend-module-aws/package.json | 44 +++++++------- .../catalog-backend-module-azure/package.json | 44 +++++++------- .../package.json | 30 +++++----- .../catalog-backend-module-gcp/package.json | 44 +++++++------- .../package.json | 38 ++++++------ .../package.json | 30 +++++----- .../package.json | 44 +++++++------- .../package.json | 48 +++++++-------- .../package.json | 44 +++++++------- .../package.json | 32 +++++----- .../package.json | 50 ++++++++-------- .../package.json | 40 ++++++------- plugins/catalog-common/package.json | 44 +++++++------- plugins/catalog-graph/package.json | 48 +++++++-------- plugins/catalog-import/package.json | 56 +++++++++--------- plugins/catalog-node/package.json | 42 +++++++------- .../catalog-unprocessed-entities/package.json | 36 ++++++------ plugins/catalog/package.json | 56 +++++++++--------- plugins/cicd-statistics/package.json | 44 +++++++------- plugins/circleci/package.json | 46 +++++++-------- plugins/cloudbuild/package.json | 44 +++++++------- plugins/code-climate/package.json | 34 +++++------ plugins/config-schema/package.json | 36 ++++++------ plugins/cost-insights-common/package.json | 32 +++++----- plugins/cost-insights/package.json | 44 +++++++------- plugins/devtools-common/package.json | 28 ++++----- plugins/dynatrace/package.json | 40 ++++++------- plugins/entity-feedback-common/package.json | 28 ++++----- plugins/entity-feedback/package.json | 36 ++++++------ plugins/entity-validation/package.json | 36 ++++++------ .../events-backend-test-utils/package.json | 30 +++++----- plugins/events-backend/package.json | 40 ++++++------- .../example-todo-list-backend/package.json | 36 ++++++------ plugins/example-todo-list-common/package.json | 30 +++++----- plugins/example-todo-list/package.json | 42 +++++++------- plugins/explore-backend/package.json | 28 ++++----- plugins/explore-common/package.json | 34 +++++------ plugins/explore-react/package.json | 42 +++++++------- plugins/explore/package.json | 54 ++++++++--------- plugins/firehydrant/package.json | 36 ++++++------ plugins/fossa/package.json | 46 +++++++-------- plugins/gcp-projects/package.json | 44 +++++++------- plugins/github-actions/package.json | 48 +++++++-------- plugins/github-deployments/package.json | 36 ++++++------ plugins/github-issues/package.json | 36 ++++++------ plugins/gitops-profiles/package.json | 44 +++++++------- plugins/gocd/package.json | 38 ++++++------ plugins/graphiql/package.json | 44 +++++++------- plugins/home-react/package.json | 44 +++++++------- plugins/home/package.json | 50 ++++++++-------- plugins/ilert/package.json | 38 ++++++------ plugins/jenkins-common/package.json | 24 ++++---- plugins/jenkins/package.json | 44 +++++++------- plugins/kafka-backend/package.json | 50 ++++++++-------- plugins/kafka/package.json | 40 ++++++------- plugins/kubernetes-cluster/package.json | 44 +++++++------- plugins/kubernetes-common/package.json | 40 ++++++------- plugins/kubernetes-node/package.json | 44 +++++++------- plugins/lighthouse-backend/package.json | 34 +++++------ plugins/lighthouse-common/package.json | 32 +++++----- plugins/lighthouse/package.json | 44 +++++++------- plugins/linguist-backend/package.json | 30 +++++----- plugins/linguist-common/package.json | 28 ++++----- plugins/linguist/package.json | 50 ++++++++-------- plugins/newrelic-dashboard/package.json | 34 +++++------ plugins/newrelic/package.json | 44 +++++++------- plugins/nomad-backend/package.json | 28 ++++----- plugins/nomad/package.json | 36 ++++++------ plugins/notifications-backend/package.json | 28 ++++----- plugins/notifications-common/package.json | 36 ++++++------ plugins/octopus-deploy/package.json | 38 ++++++------ plugins/opencost/package.json | 36 ++++++------ plugins/org-react/package.json | 42 +++++++------- plugins/org/package.json | 56 +++++++++--------- plugins/pagerduty/package.json | 46 +++++++-------- plugins/periskop-backend/package.json | 30 +++++----- plugins/periskop/package.json | 42 +++++++------- .../package.json | 30 +++++----- plugins/permission-backend/package.json | 38 ++++++------ plugins/permission-common/package.json | 36 ++++++------ plugins/permission-react/package.json | 40 ++++++------- plugins/playlist-backend/package.json | 30 +++++----- plugins/playlist-common/package.json | 28 ++++----- plugins/playlist/package.json | 38 ++++++------ plugins/proxy-backend/package.json | 46 +++++++-------- plugins/puppetdb/package.json | 50 ++++++++-------- plugins/rollbar-backend/package.json | 34 +++++------ plugins/rollbar/package.json | 46 +++++++-------- plugins/scaffolder-common/package.json | 44 +++++++------- plugins/scaffolder-node/package.json | 44 +++++++------- .../package.json | 40 ++++++------- .../package.json | 40 ++++++------- .../package.json | 40 ++++++------- plugins/search-backend-module-pg/package.json | 42 +++++++------- .../package.json | 28 ++++----- .../package.json | 40 ++++++------- plugins/search-backend-node/package.json | 40 ++++++------- plugins/search-common/package.json | 40 ++++++------- plugins/search-react/package.json | 52 ++++++++--------- plugins/search/package.json | 56 +++++++++--------- plugins/sentry/package.json | 46 +++++++-------- plugins/shortcuts/package.json | 36 ++++++------ plugins/signals-react/package.json | 34 +++++------ plugins/signals/package.json | 32 +++++----- plugins/sonarqube-backend/package.json | 28 ++++----- plugins/sonarqube-react/package.json | 54 ++++++++--------- plugins/sonarqube/package.json | 52 ++++++++--------- plugins/splunk-on-call/package.json | 48 +++++++-------- plugins/stack-overflow-backend/package.json | 34 +++++------ plugins/stack-overflow/package.json | 50 ++++++++-------- plugins/stackstorm/package.json | 52 ++++++++--------- .../package.json | 38 ++++++------ plugins/tech-insights-backend/package.json | 40 ++++++------- plugins/tech-insights-common/package.json | 34 +++++------ plugins/tech-insights-node/package.json | 32 +++++----- plugins/tech-insights/package.json | 34 +++++------ plugins/tech-radar/package.json | 44 +++++++------- .../techdocs-addons-test-utils/package.json | 46 +++++++-------- plugins/techdocs-backend/package.json | 46 +++++++-------- .../package.json | 46 +++++++-------- plugins/techdocs-node/package.json | 32 +++++----- plugins/techdocs-react/package.json | 42 +++++++------- plugins/techdocs/package.json | 58 +++++++++---------- plugins/todo/package.json | 38 ++++++------ plugins/user-settings-backend/package.json | 38 ++++++------ plugins/user-settings/package.json | 58 +++++++++---------- plugins/vault-node/package.json | 28 ++++----- plugins/vault/package.json | 46 +++++++-------- plugins/xcmetrics/package.json | 36 ++++++------ scripts/sort-package-json.mjs | 40 +++++++++++++ 176 files changed, 3443 insertions(+), 3403 deletions(-) create mode 100644 scripts/sort-package-json.mjs diff --git a/package.json b/package.json index c48c97f54b..937ea4e19d 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "package.json": [ "yarn backstage-repo-tools generate-catalog-info", "git add */catalog-info.yaml", - "yarn sort-package-json" + "node ./scripts/sort-package-json.mjs" ], "yarn.lock": [ "node ./scripts/verify-lockfile-duplicates --fix" diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 6913fcbfa3..3b695129e1 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/app-defaults", - "description": "Provides the default wiring of a Backstage App", "version": "1.5.0", + "description": "Provides the default wiring of a Backstage App", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/app-defaults" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -41,11 +44,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -53,7 +51,9 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index e0db94e6d7..08a08f9603 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,54 +1,54 @@ { "name": "app-next-example-plugin", - "description": "Backstage internal example plugin", "version": "0.0.6", + "description": "Backstage internal example plugin", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, "private": true, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/app-next-example-plugin" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@material-ui/icons": "^4.9.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "cross-fetch": "^4.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/backend-dev-utils/package.json b/packages/backend-dev-utils/package.json index 5829092b43..b24c9102b2 100644 --- a/packages/backend-dev-utils/package.json +++ b/packages/backend-dev-utils/package.json @@ -1,36 +1,36 @@ { "name": "@backstage/backend-dev-utils", "version": "0.1.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/backend-dev-utils" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 3c42864533..f2be0fecb1 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/catalog-client", - "description": "An isomorphic client for the catalog backend", "version": "1.6.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "An isomorphic client for the catalog backend", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/catalog-client" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -41,8 +44,5 @@ "devDependencies": { "@backstage/cli": "workspace:^", "msw": "^1.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 3c99c80291..ac076ba8d2 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/catalog-model", - "description": "Types and validators that help describe the model of a Backstage Catalog", "version": "1.4.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Types and validators that help describe the model of a Backstage Catalog", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/catalog-model" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +36,16 @@ ] } }, - "backstage": { - "role": "common-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/catalog-model" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/errors": "workspace:^", @@ -55,8 +58,5 @@ "@types/json-schema": "^7.0.5", "@types/lodash": "^4.14.151", "yaml": "^2.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index b8bd27cef9..be91af578c 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,41 +1,41 @@ { "name": "@backstage/cli-common", - "description": "Common functionality used by cli, backend, and create-app", "version": "0.1.13", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Common functionality used by cli, backend, and create-app", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/cli-common" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/node": "^18.17.8" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 9fa25ac707..ee0e94215f 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,31 +1,34 @@ { "name": "@backstage/cli-node", - "description": "Node.js library for Backstage CLIs", "version": "0.2.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Node.js library for Backstage CLIs", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/cli-node" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/cli-common": "workspace:^", @@ -40,8 +43,5 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/codemods/package.json b/packages/codemods/package.json index f5980ba117..3fc1d63eae 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,37 +1,47 @@ { "name": "@backstage/codemods", - "description": "A collection of codemods for Backstage projects", "version": "0.1.47", + "description": "A collection of codemods for Backstage projects", + "backstage": { + "role": "cli" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js" }, - "backstage": { - "role": "cli" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/codemods" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", "main": "src/index.ts", - "scripts": { - "start": "nodemon --", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, "bin": { "backstage-codemods": "bin/backstage-codemods" }, + "files": [ + "bin", + "dist", + "transforms" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "nodemon --", + "test": "backstage-cli package test" + }, + "nodemonConfig": { + "exec": "bin/backstage-codemods", + "ext": "ts", + "watch": "./src" + }, "dependencies": { "@backstage/cli-common": "workspace:^", "chalk": "^4.0.0", @@ -44,15 +54,5 @@ "@types/jscodeshift": "^0.11.0", "@types/node": "^18.17.8", "ts-node": "^10.0.0" - }, - "nodemonConfig": { - "watch": "./src", - "exec": "bin/backstage-codemods", - "ext": "ts" - }, - "files": [ - "bin", - "dist", - "transforms" - ] + } } diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 6b8b3b5df7..fa549e039b 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/config-loader", - "description": "Config loading functionality used by Backstage backend, and CLI", "version": "1.6.2", + "description": "Config loading functionality used by Backstage backend, and CLI", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/config-loader" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", "main": "src/index.ts", "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/cli-common": "workspace:^", @@ -56,8 +59,5 @@ "@types/json-schema-merge-allof": "^0.6.0", "msw": "^1.0.0", "zen-observable": "^0.10.0" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/config/package.json b/packages/config/package.json index d7127b8c05..97ca8c0af6 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/config", - "description": "Config API used by Backstage core, backend, and CLI", "version": "1.1.1", + "description": "Config API used by Backstage core, backend, and CLI", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/config" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/errors": "workspace:^", @@ -40,8 +43,5 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index fc8d72631b..533ddc469a 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/dev-utils", - "description": "Utilities for developing Backstage plugins.", "version": "1.0.27", + "description": "Utilities for developing Backstage plugins.", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/dev-utils" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/app-defaults": "workspace:^", @@ -46,11 +49,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -60,7 +58,9 @@ "@testing-library/user-event": "^14.0.0", "zen-observable": "^0.10.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 6bfd524f8f..b3044facf6 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,17 +1,25 @@ { "name": "@backstage/e2e-test-utils", - "description": "Shared end-to-end test utilities Backstage", "version": "0.1.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Shared end-to-end test utilities Backstage", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/e2e-test-utils" + }, + "license": "Apache-2.0", "exports": { "./playwright": "./src/playwright/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "playwright": [ @@ -22,22 +30,17 @@ ] } }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/e2e-test-utils" - }, - "backstage": { - "role": "node-library" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@manypkg/get-packages": "^1.1.3", @@ -55,8 +58,5 @@ "@playwright/test": { "optional": true } - }, - "files": [ - "dist" - ] + } } diff --git a/packages/errors/package.json b/packages/errors/package.json index 7dc17a10a2..d62c5ea215 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/errors", - "description": "Common utilities for error handling within Backstage", "version": "1.2.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common utilities for error handling within Backstage", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/errors" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/types": "workspace:^", @@ -38,8 +41,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 66437a8402..40f6ce351f 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/frontend-app-api", "version": "0.6.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,30 +14,23 @@ "url": "https://github.com/backstage/backstage", "directory": "packages/frontend-app-api" }, - "backstage": { - "role": "web-library" - }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "configSchema": "config.d.ts", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "config.d.ts", "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/config": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -53,8 +46,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "lodash": "^4.17.21" }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0" + }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - } + }, + "configSchema": "config.d.ts" } diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index f5baddfda8..493d6fd553 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,31 +1,34 @@ { "name": "@backstage/frontend-plugin-api", "version": "0.6.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/frontend-plugin-api" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -38,10 +41,6 @@ "zod": "^3.22.4", "zod-to-json-schema": "^3.21.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/frontend-app-api": "workspace:^", @@ -51,7 +50,8 @@ "@testing-library/react": "^14.0.0", "history": "^5.3.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 7141c1da3b..6c5ceb4d7c 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/frontend-test-utils", "version": "0.1.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,33 +14,33 @@ "url": "https://github.com/backstage/backstage", "directory": "packages/frontend-test-utils" }, - "backstage": { - "role": "web-library" - }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@testing-library/jest-dom": "^6.0.0", - "@types/react": "*" - }, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/test-utils": "workspace:^", "@backstage/types": "workspace:^" }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@types/react": "*" + }, "peerDependencies": { "@testing-library/react": "^12.1.3 || ^13.0.0 || ^14.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", diff --git a/packages/integration-aws-node/package.json b/packages/integration-aws-node/package.json index eb90422e45..a515a01d31 100644 --- a/packages/integration-aws-node/package.json +++ b/packages/integration-aws-node/package.json @@ -1,35 +1,39 @@ { "name": "@backstage/integration-aws-node", - "description": "Helpers for fetching AWS account credentials", "version": "0.1.9", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Helpers for fetching AWS account credentials", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/integration-aws-node" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@aws-sdk/client-sts": "^3.350.0", @@ -47,9 +51,5 @@ "aws-sdk-client-mock": "^3.0.0", "aws-sdk-client-mock-jest": "^3.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 080ef464a2..6fad954df9 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/integration-react", - "description": "Frontend package for managing integrations towards external systems", "version": "1.1.24", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Frontend package for managing integrations towards external systems", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/integration-react" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -37,11 +40,6 @@ "@material-ui/icons": "^4.9.1", "@types/react": "^16.13.1 || ^17.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-components": "workspace:^", @@ -51,7 +49,9 @@ "@testing-library/jest-dom": "^6.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/integration/package.json b/packages/integration/package.json index b5e49dd217..3b156ee323 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/integration", - "description": "Helpers for managing integrations towards external systems", "version": "1.9.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Helpers for managing integrations towards external systems", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/integration" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@azure/identity": "^4.0.0", @@ -49,9 +53,5 @@ "@types/luxon": "^3.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index f9de4d6d2d..0b0e7e1591 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/release-manifests", - "description": "Helper library for receiving release manifests", "version": "0.0.11", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Helper library for receiving release manifests", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/release-manifests" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "cross-fetch": "^4.0.0" @@ -39,8 +42,5 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "msw": "^1.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/theme/package.json b/packages/theme/package.json index 703d97c568..ef3f56071f 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,34 +1,37 @@ { "name": "@backstage/theme", - "description": "material-ui theme for use with Backstage.", "version": "0.5.1", + "description": "material-ui theme for use with Backstage.", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/theme" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", "start": "backstage-cli package start", "test": "backstage-cli package test" }, @@ -37,12 +40,6 @@ "@emotion/styled": "^11.10.5", "@mui/material": "^5.12.2" }, - "peerDependencies": { - "@material-ui/core": "^4.12.2", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@mui/styles": "^5.14.18", @@ -50,7 +47,10 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "@material-ui/core": "^4.12.2", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0" + } } diff --git a/packages/version-bridge/package.json b/packages/version-bridge/package.json index f40ef91d0c..402e60465c 100644 --- a/packages/version-bridge/package.json +++ b/packages/version-bridge/package.json @@ -1,51 +1,51 @@ { "name": "@backstage/version-bridge", - "description": "Utilities used by @backstage packages to support multiple concurrent versions", "version": "1.0.7", + "description": "Utilities used by @backstage packages to support multiple concurrent versions", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/version-bridge" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@types/react": "^16.13.1 || ^17.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 91e3b5e096..d0cc173bbf 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-adr-common", - "description": "Common functionalities for the adr plugin", "version": "0.2.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the adr plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/adr-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -38,8 +41,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 896745d768..1e6f6ece0e 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,14 +1,27 @@ { "name": "@backstage/plugin-adr", "version": "0.6.13", - "main": "src/index.ts", - "types": "src/index.ts", + "backstage": { + "role": "frontend-plugin" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/adr" + }, "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -19,27 +32,17 @@ ] } }, - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/adr" - }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -59,18 +62,15 @@ "react-use": "^17.2.4", "remark-gfm": "^3.0.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index bd519a2b63..8138bdc19f 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-airbrake", "version": "0.3.30", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/airbrake" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -40,11 +43,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/app-defaults": "workspace:^", "@backstage/cli": "workspace:^", @@ -55,7 +53,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 15498f5c23..130daa540c 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-allure", - "description": "A Backstage plugin that integrates with Allure", "version": "0.1.46", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates with Allure", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/allure" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -37,11 +40,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -51,9 +49,11 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/allure", diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 7093f08873..5dec21a816 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-analytics-module-ga", "version": "0.2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin-module" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/analytics-module-ga" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -35,11 +39,6 @@ "@backstage/frontend-plugin-api": "workspace:^", "react-ga": "^3.3.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -48,9 +47,10 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/analytics-module-ga4/package.json b/plugins/analytics-module-ga4/package.json index e70ca1bff6..396ba80195 100644 --- a/plugins/analytics-module-ga4/package.json +++ b/plugins/analytics-module-ga4/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-analytics-module-ga4", "version": "0.2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin-module" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/analytics-module-ga4" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -35,11 +39,6 @@ "@backstage/frontend-plugin-api": "workspace:^", "react-ga4": "^2.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -49,9 +48,10 @@ "@types/jest": "^29.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json index 42c5386e0f..e443c5a56d 100644 --- a/plugins/analytics-module-newrelic-browser/package.json +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-analytics-module-newrelic-browser", "version": "0.1.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,18 +14,22 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/analytics-module-newrelic-browser" }, - "backstage": { - "role": "frontend-plugin-module" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -34,18 +38,14 @@ "@backstage/frontend-plugin-api": "workspace:^", "@newrelic/browser-agent": "^1.236.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 09c9bf199e..11317ce08f 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-apache-airflow", "version": "0.2.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/apache-airflow" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -39,11 +43,6 @@ "qs": "^6.10.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -54,9 +53,10 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/api-docs-module-protoc-gen-doc/package.json b/plugins/api-docs-module-protoc-gen-doc/package.json index d2067ac050..e90fa57137 100644 --- a/plugins/api-docs-module-protoc-gen-doc/package.json +++ b/plugins/api-docs-module-protoc-gen-doc/package.json @@ -1,50 +1,50 @@ { "name": "@backstage/plugin-api-docs-module-protoc-gen-doc", - "description": "Additional functionalities for the api-docs plugin that renders the output of the protoc-gen-doc", "version": "0.1.6", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Additional functionalities for the api-docs plugin that renders the output of the protoc-gen-doc", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin-module" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/api-docs-module-protoc-gen-doc" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "grpc-docs": "^1.1.2" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 3bfd94dd6b..fb42a30a27 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-api-docs", - "description": "A Backstage plugin that helps represent API entities in the frontend", "version": "0.11.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that helps represent API entities in the frontend", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/api-docs" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,17 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/api-docs" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@asyncapi/react-component": "1.2.13", @@ -68,11 +71,6 @@ "isomorphic-form-data": "^2.0.0", "swagger-ui-react": "^5.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -84,7 +82,9 @@ "@testing-library/user-event": "^14.0.0", "@types/swagger-ui-react": "^4.18.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 0118c84a36..2aac8cec9a 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-apollo-explorer", "version": "0.1.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/apollo-explorer" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@apollo/explorer": "^3.0.0", @@ -36,11 +39,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "use-deep-compare-effect": "^1.8.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -48,7 +46,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 2a4d0896d6..c49386e291 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,7 +1,10 @@ { "name": "@backstage/plugin-app-visualizer", - "description": "Visualizes the Backstage app structure", "version": "0.1.1", + "description": "Visualizes the Backstage app structure", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, @@ -10,21 +13,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/app-visualizer" }, - "backstage": { - "role": "frontend-plugin" - }, "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -33,16 +36,13 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index c534f461e4..841709b7ed 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "description": "The vmware-cloud-provider backend module for the auth plugin.", "version": "0.1.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The vmware-cloud-provider backend module for the auth plugin.", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,17 +15,20 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/auth-backend-module-vmware-cloud-provider" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -44,8 +47,5 @@ "@backstage/plugin-auth-backend": "workspace:^", "msw": "^2.0.8", "supertest": "^6.3.3" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 79ecaba8b2..967233e586 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,35 +1,40 @@ { "name": "@backstage/plugin-auth-backend", - "description": "A Backstage backend plugin that handles authentication", "version": "0.21.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage backend plugin that handles authentication", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/auth-backend" }, - "keywords": [ - "backstage" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "migrations", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -103,10 +108,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "migrations", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 42905a7af5..add7087ace 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,31 +1,34 @@ { "name": "@backstage/plugin-auth-node", "version": "0.4.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/auth-node" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -55,8 +58,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3", "uuid": "^8.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/azure-sites-common/package.json b/plugins/azure-sites-common/package.json index 7e49bf2c4b..6b3ec694a1 100644 --- a/plugins/azure-sites-common/package.json +++ b/plugins/azure-sites-common/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-azure-sites-common", - "description": "Common functionalities for the azure plugin", "version": "0.1.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the azure plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/azure-sites-common" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,8 +42,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 72a2e496b7..f1a4e81e9b 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-azure-sites", "version": "0.1.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "azure" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/azure-sites" }, - "keywords": [ - "backstage", - "azure" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -48,11 +51,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -62,7 +60,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 7ca752054d..9c87360a2a 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/plugin-badges-backend", - "description": "A Backstage backend plugin that generates README badges for your entities", "version": "0.3.7", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage backend plugin that generates README badges for your entities", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, + "keywords": [ + "backstage", + "badges" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/badges-backend" }, - "keywords": [ - "backstage", - "badges" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -56,9 +60,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist", - "migrations/**/*.{js,d.ts}" - ] + } } diff --git a/plugins/badges/package.json b/plugins/badges/package.json index cd326192ca..0dc5fb81a5 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-badges", - "description": "A Backstage plugin that generates README badges for your entities", "version": "0.2.54", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that generates README badges for your entities", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/badges" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,18 +42,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 67c45bca66..0b286cfa5c 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,17 +1,26 @@ { "name": "@backstage/plugin-bazaar-backend", "version": "0.3.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/bazaar-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,23 +31,19 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/bazaar-backend" - }, + "files": [ + "dist", + "migrations/**/*.{js,d.ts}", + "alpha" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -55,10 +60,5 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist", - "migrations/**/*.{js,d.ts}", - "alpha" - ] + } } diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index ef89972045..2593e6f5f2 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-bazaar", "version": "0.2.22", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/bazaar" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -47,17 +50,14 @@ "react-hook-form": "^7.13.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index f35f66b616..107da5b82e 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", - "description": "Common functionalities for bitbucket-cloud plugins", "version": "0.2.16", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for bitbucket-cloud plugins", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/bitbucket-cloud-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "generate-models": "scripts/generate-models.sh", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "refresh-schema": "scripts/prepare-schema.js && yarn run -T prettier --check bitbucket-cloud.oas.json -w", - "generate-models": "scripts/generate-models.sh", "reduce-models": "scripts/reduce-models.js", + "refresh-schema": "scripts/prepare-schema.js && yarn run -T prettier --check bitbucket-cloud.oas.json -w", + "test": "backstage-cli package test", "update-models": "yarn refresh-schema && yarn generate-models && yarn reduce-models" }, "dependencies": { @@ -42,8 +45,5 @@ "@openapitools/openapi-generator-cli": "^2.4.26", "msw": "^1.0.0", "ts-morph": "^21.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 1994ab5990..d25cdfbb8b 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-bitrise", - "description": "A Backstage plugin that integrates towards Bitrise", "version": "0.1.57", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Bitrise", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/bitrise" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -44,11 +47,6 @@ "react-use": "^17.2.4", "recharts": "^2.5.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -61,7 +59,9 @@ "@types/recharts": "^1.8.15", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index c34dcf40be..346daa2d09 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "description": "A Backstage catalog backend module that helps integrate towards AWS", "version": "0.3.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards AWS", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-aws" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-aws" - }, - "keywords": [ - "backstage" + "files": [ + "config.d.ts", + "dist" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@aws-sdk/client-eks": "^3.350.0", @@ -75,9 +79,5 @@ "luxon": "^3.0.0", "yaml": "^2.0.0" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 329e582542..08b1dceeb5 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "description": "A Backstage catalog backend module that helps integrate towards Azure", "version": "0.1.29", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards Azure", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-azure" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-azure" - }, - "keywords": [ - "backstage" + "files": [ + "config.d.ts", + "dist" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -62,9 +66,5 @@ "luxon": "^3.0.0", "msw": "^1.0.0" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index 583c88f194..3ce3ebd404 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-catalog-backend-module-backstage-openapi", "version": "0.1.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -14,17 +14,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/catalog-backend-module-backstage-openapi" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -47,9 +51,5 @@ "@types/supertest": "^2.0.8", "openapi3-ts": "^3.1.2" }, - "configSchema": "config.d.ts", - "files": [ - "dist", - "config.d.ts" - ] + "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 8c0e8868f6..64404eff32 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "description": "A Backstage catalog backend module that helps integrate towards GCP", "version": "0.1.10", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards GCP", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-gcp" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-gcp" - }, - "keywords": [ - "backstage" + "files": [ + "config.d.ts", + "dist" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -59,9 +63,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 29680e9dde..3337176653 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,17 +1,26 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", "version": "0.1.26", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-gerrit" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,23 +31,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-gerrit" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -60,9 +64,5 @@ "luxon": "^3.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index 4c44b122ea..8f2b683e61 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "description": "The github-org backend module for the catalog plugin.", "version": "0.1.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The github-org backend module for the catalog plugin.", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,17 +15,20 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/catalog-backend-module-github-org" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -39,8 +42,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "luxon": "^3.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index c1f9aba9a4..b6a8f3acfe 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "description": "A Backstage catalog backend module that helps integrate towards GitHub", "version": "0.5.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards GitHub", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-github" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-github" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -72,9 +76,5 @@ "luxon": "^3.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 7c2157d7e5..e4d7b7efcf 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "description": "An entity provider for streaming large asset sources into the catalog", "version": "0.4.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "An entity provider for streaming large asset sources into the catalog", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-incremental-ingestion" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-incremental-ingestion" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -68,9 +72,5 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist", - "migrations/**/*.{js,d.ts}" - ] + } } diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index f477ae5b6a..95070e6d78 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "version": "0.5.17", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-msgraph" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-msgraph" - }, - "keywords": [ - "backstage" + "files": [ + "config.d.ts", + "dist" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@azure/identity": "^4.0.0", @@ -70,9 +74,5 @@ "luxon": "^3.0.0", "msw": "^1.0.0" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 2382efb297..dd7cdd487b 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,35 +1,38 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "version": "0.1.27", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps with OpenAPI specifications", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin-module" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/catalog-backend-module-openapi" }, - "keywords": [ - "backstage" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@apidevtools/json-schema-ref-parser": "^9.0.6", @@ -49,8 +52,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "openapi-types": "^12.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 1cc55b5950..4e127953bc 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,18 +1,32 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "version": "0.1.15", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "puppetdb", + "puppet" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-puppetdb" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,28 +37,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-puppetdb" - }, - "keywords": [ - "backstage", - "puppetdb", - "puppet" + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -67,9 +71,5 @@ "@types/lodash": "^4.14.151", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index f3a32b7526..d3df44cea7 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,17 +1,25 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "version": "0.1.7", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-scaffolder-entity-model" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -19,22 +27,17 @@ ] } }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-backend-module-scaffolder-entity-model" - }, - "backstage": { - "role": "backend-plugin-module" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -46,8 +49,5 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 6fe678bcff..35858ee400 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-catalog-common", - "description": "Common functionalities for the catalog plugin", "version": "1.0.21", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the catalog plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-common" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +36,16 @@ ] } }, - "backstage": { - "role": "common-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-common" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -51,8 +54,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index e7010b4fed..0aa451d86a 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,17 +1,27 @@ { "name": "@backstage/plugin-catalog-graph", "version": "0.4.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-graph" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,24 +32,17 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-graph" - }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -60,11 +63,6 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -76,7 +74,9 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index a6c519ca33..030a1ea036 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-catalog-import", - "description": "A Backstage plugin the helps you import entities into your catalog", "version": "0.10.6", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin the helps you import entities into your catalog", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-import" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-import" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -70,11 +74,6 @@ "react-use": "^17.2.4", "yaml": "^2.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -86,9 +85,10 @@ "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index fc084a7c61..14d805b4d1 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-catalog-node", - "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "version": "1.7.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-node" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,17 @@ ] } }, - "backstage": { - "role": "node-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog-node" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -54,8 +57,5 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 13beb281d4..4279cf4dcc 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", "version": "0.1.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/catalog-unprocessed-entities" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,18 +42,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index eb453acdc2..e87b325991 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-catalog", - "description": "The Backstage plugin for browsing the Backstage catalog", "version": "1.17.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The Backstage plugin for browsing the Backstage catalog", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/catalog" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -74,11 +78,6 @@ "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -90,9 +89,10 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 8832e958d4..d0a90efcc9 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,41 +1,39 @@ { "name": "@backstage/plugin-cicd-statistics", - "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", "version": "0.1.32", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/cicd-statistics" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/luxon": "^3.0.0", - "@types/react": "^16.13.1 || ^17.0.0" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -53,12 +51,14 @@ "react-use": "^17.3.1", "recharts": "^2.5.0" }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/luxon": "^3.0.0", + "@types/react": "^16.13.1 || ^17.0.0" + }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index e63e94fe03..f60a3bb2bc 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-circleci", - "description": "A Backstage plugin that integrates towards Circle CI", "version": "0.3.30", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Circle CI", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "circleci" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/circleci" }, - "keywords": [ - "backstage", - "circleci" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", - "start": "backstage-cli package start", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -47,17 +50,14 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@types/humanize-duration": "^3.25.1" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index c0765e681b..0aed36d3cc 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-cloudbuild", - "description": "A Backstage plugin that integrates towards Google Cloud Build", "version": "0.4.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Google Cloud Build", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "google cloud" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/cloudbuild" }, - "keywords": [ - "backstage", - "google cloud" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +48,6 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -58,7 +56,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index c8e6747b8c..137c8729a4 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-code-climate", "version": "0.1.30", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/code-climate" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,11 +42,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -54,7 +52,9 @@ "@types/humanize-duration": "^3.27.1", "@types/luxon": "^3.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 2b97c4409e..ba1c16af37 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-config-schema", - "description": "A Backstage plugin that lets you browse the configuration schema of your app", "version": "0.1.50", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that lets you browse the configuration schema of your app", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/config-schema" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,11 +45,6 @@ "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -54,7 +52,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/cost-insights-common/package.json b/plugins/cost-insights-common/package.json index 629d743ee9..6735674d00 100644 --- a/plugins/cost-insights-common/package.json +++ b/plugins/cost-insights-common/package.json @@ -1,41 +1,41 @@ { "name": "@backstage/plugin-cost-insights-common", - "description": "Common functionalities for the cost-insights plugin", "version": "0.1.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the cost-insights plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/cost-insights-common" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index e55d116dc5..4bc0454ab0 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/plugin-cost-insights", - "description": "A Backstage plugin that helps you keep track of your cloud spend", "version": "0.12.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that helps you keep track of your cloud spend", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/cost-insights" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -56,11 +60,6 @@ "regression": "^2.0.1", "yup": "^0.32.9" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -76,9 +75,10 @@ "@types/yup": "^0.29.13", "canvas": "^2.10.2" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/devtools-common/package.json b/plugins/devtools-common/package.json index a488e997a1..8f127fa063 100644 --- a/plugins/devtools-common/package.json +++ b/plugins/devtools-common/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-devtools-common", - "description": "Common functionalities for the devtools plugin", "version": "0.1.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the devtools plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/devtools-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^", @@ -35,8 +38,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 684b8878d2..cc318ece25 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-dynatrace", "version": "9.0.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/dynatrace" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -36,12 +40,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "@backstage/plugin-catalog-react": "workspace:^", - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -51,9 +49,11 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "@backstage/plugin-catalog-react": "workspace:^", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/entity-feedback-common/package.json b/plugins/entity-feedback-common/package.json index 7688ded0d7..bc5d29ce7d 100644 --- a/plugins/entity-feedback-common/package.json +++ b/plugins/entity-feedback-common/package.json @@ -1,38 +1,38 @@ { "name": "@backstage/plugin-entity-feedback-common", - "description": "Common functionalities for the entity-feedback plugin", "version": "0.1.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the entity-feedback plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/entity-feedback-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index db96316530..3f888ad1b2 100644 --- a/plugins/entity-feedback/package.json +++ b/plugins/entity-feedback/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-entity-feedback", "version": "0.2.13", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/entity-feedback" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -40,11 +43,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -54,7 +52,9 @@ "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index 5cb35ce073..7ae8a6404e 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-entity-validation", "version": "0.1.15", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/entity-validation" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -49,11 +52,6 @@ "react-use": "^17.2.4", "yaml": "^2.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -62,7 +60,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 43a090a2fc..6479a3e86d 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,40 +1,40 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "version": "0.1.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/events-backend-test-utils" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-events-node": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 6ab70a3f0a..9365d8c7dc 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,17 +1,26 @@ { "name": "@backstage/plugin-events-backend", "version": "0.2.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/events-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,23 +31,18 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/events-backend" - }, + "files": [ + "config.d.ts", + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -57,9 +61,5 @@ "@backstage/plugin-events-backend-test-utils": "workspace:^", "supertest": "^6.1.3" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index dfc3809b87..d938d9816f 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,32 +1,36 @@ { "name": "@internal/plugin-todo-list-backend", "version": "1.0.22", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "private": true, "backstage": { "role": "backend-plugin" }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/example-todo-list-backend" - }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, + "private": true, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/example-todo-list-backend" + }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "alpha" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -45,9 +49,5 @@ "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", "supertest": "^6.1.6" - }, - "files": [ - "dist", - "alpha" - ] + } } diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index df2cd403c4..ccc97efe20 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,41 +1,41 @@ { "name": "@internal/plugin-todo-list-common", "version": "1.0.17", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "private": true, + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "private": true, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/example-todo-list-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index 26074acaa2..6faf4195a8 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,33 +1,36 @@ { "name": "@internal/plugin-todo-list", "version": "1.0.22", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "private": true, "backstage": { "role": "frontend-plugin" }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/example-todo-list" - }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, + "private": true, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/example-todo-list" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -36,11 +39,6 @@ "@material-ui/lab": "4.0.0-alpha.61", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/dom": "^9.0.0", @@ -48,7 +46,9 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index edfb05eb73..285af827a5 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -1,31 +1,35 @@ { "name": "@backstage/plugin-explore-backend", "version": "0.0.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/explore-backend" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "config.d.ts", + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -48,9 +52,5 @@ "@types/supertest": "^2.0.8", "supertest": "^6.2.4" }, - "files": [ - "config.d.ts", - "dist" - ], "configSchema": "config.d.ts" } diff --git a/plugins/explore-common/package.json b/plugins/explore-common/package.json index c71f888ad9..d9520a378e 100644 --- a/plugins/explore-common/package.json +++ b/plugins/explore-common/package.json @@ -1,40 +1,40 @@ { "name": "@backstage/plugin-explore-common", - "description": "Common functionalities for the explore plugin", "version": "0.0.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the explore plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/explore-common" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 363abb57ea..6cae83ed87 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,46 +1,44 @@ { "name": "@backstage/plugin-explore-react", - "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", "version": "0.0.36", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/explore-react" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-plugin-api": "workspace:^", "@backstage/plugin-explore-common": "workspace:^" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/dom": "^9.0.0", @@ -48,7 +46,9 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 2965eb69fb..177464db55 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-explore", - "description": "A Backstage plugin for building an exploration page of your software ecosystem", "version": "0.4.16", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin for building an exploration page of your software ecosystem", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/explore" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,17 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/explore" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -63,11 +66,6 @@ "pluralize": "^8.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -79,7 +77,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index ac99584fc2..f7eb4ae52e 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-firehydrant", - "description": "A Backstage plugin that integrates towards FireHydrant", "version": "0.2.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards FireHydrant", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/firehydrant" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -40,11 +43,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -54,9 +52,11 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/plugin-firehydrant", diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index eacb5cc955..e3e45688b4 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-fossa", - "description": "A Backstage plugin that integrates towards FOSSA", "version": "0.2.62", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards FOSSA", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "fossa" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/fossa" }, - "keywords": [ - "backstage", - "fossa" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -47,11 +51,6 @@ "p-limit": "^3.0.2", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -62,9 +61,10 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 3c3d6d5520..0d4d30dd4a 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-gcp-projects", - "description": "A Backstage plugin that helps you manage projects in GCP", "version": "0.3.46", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that helps you manage projects in GCP", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "google cloud" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/gcp-projects" }, - "keywords": [ - "backstage", - "google cloud" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -40,11 +43,6 @@ "@react-hookz/web": "^24.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -52,7 +50,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index ed76c135e0..c805baa08a 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,38 +1,41 @@ { "name": "@backstage/plugin-github-actions", - "description": "A Backstage plugin that integrates towards GitHub Actions", "version": "0.6.11", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards GitHub Actions", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/github-actions" - }, "keywords": [ "backstage", "github", "github actions" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/github-actions" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -50,11 +53,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -64,7 +62,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 55bbf96739..35adeb3328 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-github-deployments", - "description": "A Backstage plugin that integrates towards GitHub Deployments", "version": "0.1.61", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards GitHub Deployments", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/github-deployments" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -44,11 +47,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -59,7 +57,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 822eb17182..5f00caa0d6 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-github-issues", "version": "0.2.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/github-issues" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -43,11 +46,6 @@ "octokit": "^3.0.0", "react-use": "^17.4.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -56,7 +54,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 79f242f0f9..d75a81be96 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-gitops-profiles", - "description": "A Backstage plugin that helps you manage GitOps profiles", "version": "0.3.45", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that helps you manage GitOps profiles", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "gitops" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/gitops-profiles" }, - "keywords": [ - "backstage", - "gitops" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,11 +45,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -56,7 +54,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index ead4427566..42cb7bd1ee 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,33 +1,37 @@ { "name": "@backstage/plugin-gocd", - "description": "A Backstage plugin that integrates towards GoCD", "version": "0.1.36", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards GoCD", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/gocd" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -43,11 +47,6 @@ "qs": "^6.10.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -61,9 +60,10 @@ "@types/luxon": "^3.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 9a7bc2d353..c5bc76ce2a 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,27 +1,31 @@ { "name": "@backstage/plugin-graphiql", - "description": "Backstage plugin for browsing GraphQL APIs", "version": "0.3.3", - "publishConfig": { - "access": "public" - }, + "description": "Backstage plugin for browsing GraphQL APIs", "backstage": { "role": "frontend-plugin" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], "homepage": "https://github.com/backstage/backstage/tree/master/plugins/graphiql#readme", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/graphiql" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -32,18 +36,17 @@ ] } }, - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-compat-api": "workspace:^", @@ -57,11 +60,6 @@ "graphql-ws": "^5.4.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -71,9 +69,11 @@ "@testing-library/react": "^14.0.0", "@types/codemirror": "^5.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "experimentalInstallationRecipe": { "type": "frontend-plugin", "steps": [ diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 9965e0d221..c2ef4d5c22 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-home-react", - "description": "A Backstage plugin that contains react components helps you build a home page", "version": "0.1.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that contains react components helps you build a home page", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage", + "homepage" + ], "homepage": "https://github.com/backstage/backstage/tree/master/plugins/home-react#readme", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/home-react" }, - "keywords": [ - "backstage", - "homepage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -41,16 +44,13 @@ "@rjsf/utils": "5.17.1", "@types/react": "^16.13.1 || ^17.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/react-grid-layout": "^1.3.2" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/home/package.json b/plugins/home/package.json index d3b90e56bf..86c8efe80a 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,31 +1,32 @@ { "name": "@backstage/plugin-home", - "description": "A Backstage plugin that helps you build a home page", "version": "0.6.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, + "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage", + "homepage" + ], "homepage": "https://github.com/backstage/backstage/tree/master/plugins/home#readme", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/home" }, - "keywords": [ - "backstage", - "homepage" - ], + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -36,16 +37,18 @@ ] } }, - "configSchema": "config.d.ts", - "sideEffects": false, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -74,11 +77,6 @@ "react-use": "^17.2.4", "zod": "^3.22.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -89,8 +87,10 @@ "@testing-library/user-event": "^14.0.0", "@types/react-grid-layout": "^1.3.2" }, - "files": [ - "dist", - "config.d.ts" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "configSchema": "config.d.ts" } diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 6c2a056306..09ee791a4c 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,33 +1,37 @@ { "name": "@backstage/plugin-ilert", - "description": "A Backstage plugin that integrates towards iLert", "version": "0.2.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards iLert", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/ilert" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +49,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -57,9 +56,10 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/jenkins-common/package.json b/plugins/jenkins-common/package.json index 0d4ab4587a..e9f4295645 100644 --- a/plugins/jenkins-common/package.json +++ b/plugins/jenkins-common/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-jenkins-common", "version": "0.1.24", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/jenkins-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-catalog-common": "workspace:^", @@ -34,8 +37,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 5c75728e5c..570c49734c 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-jenkins", - "description": "A Backstage plugin that integrates towards Jenkins", "version": "0.9.5", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Jenkins", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "jenkins" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/jenkins" }, - "keywords": [ - "backstage", - "jenkins" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -46,11 +49,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -60,7 +58,9 @@ "@testing-library/react": "^14.0.0", "@types/testing-library__jest-dom": "^5.9.1" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 26bcf92573..29d538b354 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-kafka-backend", - "description": "A Backstage backend plugin that integrates towards Kafka", "version": "0.3.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage backend plugin that integrates towards Kafka", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "kafka" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/kafka-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,28 +36,19 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/kafka-backend" - }, - "keywords": [ - "backstage", - "kafka" + "files": [ + "dist", + "config.d.ts", + "alpha" ], - "configSchema": "config.d.ts", "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -65,9 +69,5 @@ "jest-when": "^3.1.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts", - "alpha" - ] + "configSchema": "config.d.ts" } diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index aa54ccccd0..9df3023ab9 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,34 +1,37 @@ { "name": "@backstage/plugin-kafka", - "description": "A Backstage plugin that integrates towards Kafka", "version": "0.3.30", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Kafka", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/kafka" }, - "configSchema": "config.d.ts", + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -40,11 +43,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -54,8 +52,10 @@ "@testing-library/react": "^14.0.0", "jest-when": "^3.1.0" }, - "files": [ - "dist", - "config.d.ts" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "configSchema": "config.d.ts" } diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 31a62b1ed4..aa30d6b340 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "description": "A Backstage plugin that shows details of Kubernetes clusters", "version": "0.0.6", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that shows details of Kubernetes clusters", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "kubernetes" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/kubernetes-cluster" }, - "keywords": [ - "backstage", - "kubernetes" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -52,11 +55,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -65,7 +63,9 @@ "@testing-library/react": "^14.0.0", "@types/node": "^16.11.26" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 87532eedb4..1c9a314a3c 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,42 +1,47 @@ { "name": "@backstage/plugin-kubernetes-common", - "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", "version": "0.7.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "kubernetes" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/kubernetes-common" }, - "keywords": [ - "kubernetes" - ], + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "jest": { + "roots": [ + ".." + ] }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -49,10 +54,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "jest": { - "roots": [ - ".." - ] } } diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 4473f82d2f..76d2692767 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-kubernetes-node", - "description": "Node.js library for the kubernetes plugin", "version": "0.1.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Node.js library for the kubernetes plugin", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,16 +15,28 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/kubernetes-node" }, - "backstage": { - "role": "node-library" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/catalog-model": "workspace:^", + "@backstage/plugin-kubernetes-common": "workspace:^", + "@backstage/types": "workspace:^", + "@kubernetes/client-node": "^0.20.0", + "node-fetch": "^2.6.7", + "winston": "^3.2.1" }, "devDependencies": { "@backstage/backend-app-api": "workspace:^", @@ -34,17 +46,5 @@ "@backstage/plugin-kubernetes-backend": "workspace:^", "msw": "^1.3.1", "supertest": "^6.1.3" - }, - "files": [ - "dist" - ], - "dependencies": { - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/catalog-model": "workspace:^", - "@backstage/plugin-kubernetes-common": "workspace:^", - "@backstage/types": "workspace:^", - "@kubernetes/client-node": "^0.20.0", - "node-fetch": "^2.6.7", - "winston": "^3.2.1" } } diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index f8b03715ed..1f68cb3972 100644 --- a/plugins/lighthouse-backend/package.json +++ b/plugins/lighthouse-backend/package.json @@ -1,43 +1,42 @@ { "name": "@backstage/plugin-lighthouse-backend", - "description": "Backend functionalities for lighthouse", "version": "0.4.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Backend functionalities for lighthouse", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, + "keywords": [ + "lighthouse" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/lighthouse-backend" }, - "keywords": [ - "lighthouse" - ], + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist", "config.d.ts" ], - "configSchema": "config.d.ts", "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,5 +52,6 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - } + }, + "configSchema": "config.d.ts" } diff --git a/plugins/lighthouse-common/package.json b/plugins/lighthouse-common/package.json index e03436fd88..d47b7c7edf 100644 --- a/plugins/lighthouse-common/package.json +++ b/plugins/lighthouse-common/package.json @@ -1,42 +1,42 @@ { "name": "@backstage/plugin-lighthouse-common", - "description": "Common functionalities for lighthouse, to be shared between lighthouse and lighthouse-backend plugin", "version": "0.1.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for lighthouse, to be shared between lighthouse and lighthouse-backend plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "lighthouse" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/lighthouse-common" }, - "keywords": [ - "lighthouse" - ], + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^" diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 052db3f2cd..f10f9ab650 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-lighthouse", - "description": "A Backstage plugin that integrates towards Lighthouse", "version": "0.4.15", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Lighthouse", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "lighthouse" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/lighthouse" }, - "keywords": [ - "backstage", - "lighthouse" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +48,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -60,9 +58,11 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/lighthouse", diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json index c355b67f1c..0983b72f47 100644 --- a/plugins/linguist-backend/package.json +++ b/plugins/linguist-backend/package.json @@ -1,31 +1,36 @@ { "name": "@backstage/plugin-linguist-backend", "version": "0.5.7", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/linguist-backend" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts", + "migrations/**/*.{js,d.ts}" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -58,10 +63,5 @@ "js-yaml": "^4.1.0", "supertest": "^6.2.4" }, - "files": [ - "dist", - "config.d.ts", - "migrations/**/*.{js,d.ts}" - ], "configSchema": "config.d.ts" } diff --git a/plugins/linguist-common/package.json b/plugins/linguist-common/package.json index ff2e78affd..87d641ca39 100644 --- a/plugins/linguist-common/package.json +++ b/plugins/linguist-common/package.json @@ -1,38 +1,38 @@ { "name": "@backstage/plugin-linguist-common", - "description": "Common functionalities for the linguist plugin", "version": "0.1.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the linguist plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/linguist-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json index 1466eaae11..9d59cea976 100644 --- a/plugins/linguist/package.json +++ b/plugins/linguist/package.json @@ -1,17 +1,27 @@ { "name": "@backstage/plugin-linguist", "version": "0.1.15", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/linguist" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,24 +32,17 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/linguist" - }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -57,11 +60,6 @@ "react-use": "^17.2.4", "slugify": "^1.6.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -69,7 +67,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index d5e1a6fb47..fc6bc9c671 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-newrelic-dashboard", "version": "0.3.5", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/newrelic-dashboard" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,18 +42,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index c411514be0..ba348f7cde 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-newrelic", - "description": "A Backstage plugin that integrates towards New Relic", "version": "0.3.45", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards New Relic", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "newrelic" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/newrelic" }, - "keywords": [ - "backstage", - "newrelic" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,11 +45,6 @@ "parse-link-header": "^2.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -57,7 +55,9 @@ "@types/parse-link-header": "^2.0.1", "msw": "^1.2.3" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/nomad-backend/package.json b/plugins/nomad-backend/package.json index e701caba53..dca0c09f66 100644 --- a/plugins/nomad-backend/package.json +++ b/plugins/nomad-backend/package.json @@ -1,31 +1,34 @@ { "name": "@backstage/plugin-nomad-backend", "version": "0.1.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/nomad-backend" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -43,8 +46,5 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.2.4" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/nomad/package.json b/plugins/nomad/package.json index 562bd6d314..cb490032da 100644 --- a/plugins/nomad/package.json +++ b/plugins/nomad/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-nomad", "version": "0.1.11", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/nomad" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -39,11 +42,6 @@ "luxon": "^3.3.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -51,9 +49,11 @@ "@testing-library/react": "^14.0.0", "cross-fetch": "^4.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/plugin-nomad", diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index 62b6856001..809cab9973 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-notifications-backend", "version": "0.0.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -14,17 +14,20 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications-backend" }, - "backstage": { - "role": "backend-plugin" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,8 +56,5 @@ "@types/supertest": "^2.0.8", "msw": "^1.0.0", "supertest": "^6.2.4" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/notifications-common/package.json b/plugins/notifications-common/package.json index 2a014605b8..b3b15798ee 100644 --- a/plugins/notifications-common/package.json +++ b/plugins/notifications-common/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-notifications-common", - "description": "Common functionalities for the notifications plugin", "version": "0.0.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the notifications plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -16,25 +16,25 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications-common" }, - "backstage": { - "role": "common-library" - }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, "dependencies": { "@material-ui/icons": "^4.9.1" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" } } diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json index 339deda9e9..c297f370eb 100644 --- a/plugins/octopus-deploy/package.json +++ b/plugins/octopus-deploy/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-octopus-deploy", "version": "0.2.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/octopus-deploy" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -37,11 +41,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -49,9 +48,10 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/opencost/package.json b/plugins/opencost/package.json index ff81427cda..37ab923ff9 100644 --- a/plugins/opencost/package.json +++ b/plugins/opencost/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-opencost", "version": "0.2.5", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,18 +14,22 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/opencost" }, - "backstage": { - "role": "frontend-plugin" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -41,18 +45,14 @@ "lodash": "^4.17.21", "recharts": "^2.5.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "*" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "*" + }, "configSchema": "config.d.ts" } diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index b2d019ff9e..96f77a29b4 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,35 +1,38 @@ { "name": "@backstage/plugin-org-react", "version": "0.1.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/org-react" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -43,11 +46,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -57,7 +55,9 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/org/package.json b/plugins/org/package.json index 984907905f..8981f564d4 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,14 +1,28 @@ { "name": "@backstage/plugin-org", - "description": "A Backstage plugin that helps you create entity pages for your organization", "version": "0.6.20", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "A Backstage plugin that helps you create entity pages for your organization", + "backstage": { + "role": "frontend-plugin" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/org" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -19,28 +33,17 @@ ] } }, - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/org" - }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -60,11 +63,6 @@ "qs": "^6.10.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/catalog-client": "workspace:^", "@backstage/cli": "workspace:^", @@ -80,7 +78,9 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 6b08903e26..128394adfb 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-pagerduty", - "description": "This plugin has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead.", "version": "0.7.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "This plugin has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead.", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "pagerduty" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/pagerduty" }, - "keywords": [ - "backstage", - "pagerduty" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -47,11 +51,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -61,9 +60,10 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 443faf2fc6..161ab1956c 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,26 +1,26 @@ { "name": "@backstage/plugin-periskop-backend", "version": "0.2.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "homepage": "https://periskop.io", "backstage": { "role": "backend-plugin" }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://periskop.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/periskop-backend" }, - "publishConfig": { - "access": "public" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -31,14 +31,18 @@ ] } }, + "files": [ + "dist", + "alpha" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -55,9 +59,5 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.1.6" - }, - "files": [ - "dist", - "alpha" - ] + } } diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 9af13ce15a..52d30cb07a 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-periskop", "version": "0.1.28", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "homepage": "https://periskop.io", "backstage": { "role": "frontend-plugin" }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/periskop" - }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, + "homepage": "https://periskop.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/periskop" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -38,11 +42,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -51,9 +50,10 @@ "@testing-library/react": "^14.0.0", "@types/luxon": "^3.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/permission-backend-module-policy-allow-all/package.json b/plugins/permission-backend-module-policy-allow-all/package.json index 4fcc0a1368..291b267bcf 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "description": "Allow all policy backend module for the permission plugin.", "version": "0.1.7", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Allow all policy backend module for the permission plugin.", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,17 +15,20 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/permission-backend-module-policy-allow-all" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -36,8 +39,5 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 51f356f7d0..cc986c4cc8 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,17 +1,26 @@ { "name": "@backstage/plugin-permission-backend", "version": "0.5.33", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/permission-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,23 +31,17 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/permission-backend" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -64,8 +67,5 @@ "@types/supertest": "^2.0.8", "msw": "^1.0.0", "supertest": "^6.1.6" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index b0ca7d74bf..7dd86b3b0d 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,45 +1,44 @@ { "name": "@backstage/plugin-permission-common", - "description": "Isomorphic types and client for Backstage permissions and authorization", "version": "0.7.12", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Isomorphic types and client for Backstage permissions and authorization", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage", + "permissions" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/permission-common" }, - "keywords": [ - "backstage", - "permissions" - ], "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist", "config.d.ts" ], - "configSchema": "config.d.ts", - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -52,5 +51,6 @@ "devDependencies": { "@backstage/cli": "workspace:^", "msw": "^1.0.0" - } + }, + "configSchema": "config.d.ts" } diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 060b7d10bc..ba8eafe830 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,35 +1,38 @@ { "name": "@backstage/plugin-permission-react", "version": "0.4.20", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/permission-react" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -38,18 +41,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "swr": "^2.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index b55b9c3442..af26e90102 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,31 +1,35 @@ { "name": "@backstage/plugin-playlist-backend", "version": "0.3.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/playlist-backend" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,9 +57,5 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" - }, - "files": [ - "dist", - "migrations/**/*.{js,d.ts}" - ] + } } diff --git a/plugins/playlist-common/package.json b/plugins/playlist-common/package.json index 9ab95c4c8a..2fae0ecdf0 100644 --- a/plugins/playlist-common/package.json +++ b/plugins/playlist-common/package.json @@ -1,41 +1,41 @@ { "name": "@backstage/plugin-playlist-common", - "description": "Common functionalities for the playlist plugin", "version": "0.1.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the playlist plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/playlist-common" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index cf68e55618..512cbc74ab 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-playlist", "version": "0.2.4", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/playlist" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -49,11 +53,6 @@ "react-hook-form": "^7.13.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -66,9 +65,10 @@ "msw": "^1.0.0", "swr": "^2.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index e368f672eb..30ce530b9b 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-proxy-backend", - "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "version": "0.4.8", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/proxy-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,19 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/proxy-backend" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts", + "alpha" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -70,10 +75,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts", - "alpha" - ], "configSchema": "config.d.ts" } diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json index ec1da5c1c4..e3017182b4 100644 --- a/plugins/puppetdb/package.json +++ b/plugins/puppetdb/package.json @@ -1,38 +1,41 @@ { "name": "@backstage/plugin-puppetdb", - "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", "version": "0.1.13", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/puppetdb" - }, "keywords": [ "backstage", "puppetdb", "puppet" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/puppetdb" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -44,11 +47,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -58,7 +56,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.1" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 3199db653b..aea99d495a 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/plugin-rollbar-backend", - "description": "A Backstage backend plugin that integrates towards Rollbar", "version": "0.1.55", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage backend plugin that integrates towards Rollbar", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, + "keywords": [ + "backstage", + "rollbar" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/rollbar-backend" }, - "keywords": [ - "backstage", - "rollbar" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -54,9 +58,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 566a15ee5b..6990f08141 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-rollbar", - "description": "A Backstage plugin that integrates towards Rollbar", "version": "0.4.30", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Rollbar", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "rollbar" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/rollbar" }, - "keywords": [ - "backstage", - "rollbar" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +49,6 @@ "react-sparklines": "^1.7.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -58,9 +57,10 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 54d96fb1aa..a72ccfbb82 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,18 +1,34 @@ { "name": "@backstage/plugin-scaffolder-common", - "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", "version": "1.5.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "scaffolder" + ], + "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-common" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,32 +39,16 @@ ] } }, - "backstage": { - "role": "common-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-common" - }, - "keywords": [ - "scaffolder" - ], "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 89924f51fc..6de7c48782 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-scaffolder-node", - "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "version": "0.3.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-node" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "node-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-node" - }, + "files": [ + "alpha", + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -61,9 +65,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^" - }, - "files": [ - "alpha", - "dist" - ] + } } diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 57dd98ed19..ee14c15b1a 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "description": "A module for the search backend that exports catalog modules", "version": "0.1.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that exports catalog modules", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-catalog" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-catalog" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -61,9 +65,5 @@ "@backstage/cli": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index e7c828377b..88b6d9542a 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "description": "A module for the search backend that implements search using ElasticSearch", "version": "1.3.13", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that implements search using ElasticSearch", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-elasticsearch" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-elasticsearch" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -62,9 +66,5 @@ "@elastic/elasticsearch-mock": "^1.0.0", "@short.io/opensearch-mock": "^0.3.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index c0b2f632d1..9a69c90259 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "description": "A module for the search backend that exports explore modules", "version": "0.1.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that exports explore modules", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-explore" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-explore" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -57,9 +61,5 @@ "@backstage/cli": "workspace:^", "msw": "^1.2.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 7a09d50a55..2ba5331a4d 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "description": "A module for the search backend that implements search using PostgreSQL", "version": "0.5.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that implements search using PostgreSQL", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-pg" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,19 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-pg" - }, + "files": [ + "dist", + "migrations", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -56,10 +61,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" }, - "files": [ - "dist", - "migrations", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 786c0d51b6..4632ea13b8 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "description": "A module for the search backend that exports stack overflow modules", "version": "0.1.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that exports stack overflow modules", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin-module" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/search-backend-module-stack-overflow-collator" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -44,9 +48,5 @@ "@backstage/cli": "workspace:^", "msw": "^1.2.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 96a5f700d8..f4a17db6b1 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "description": "A module for the search backend that exports techdocs modules", "version": "0.1.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A module for the search backend that exports techdocs modules", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-techdocs" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-techdocs" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -64,9 +68,5 @@ "@backstage/cli": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 96f18f927f..b87bd15f7d 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-node", - "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "version": "1.2.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-node" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,17 @@ ] } }, - "backstage": { - "role": "node-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-node" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -60,8 +63,5 @@ "@backstage/backend-common": "workspace:^", "@backstage/cli": "workspace:^", "@types/ndjson": "^2.0.1" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index e753ea764c..cdec0b98f4 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,42 +1,47 @@ { "name": "@backstage/plugin-search-common", - "description": "Common functionalities for Search, to be shared between various search-enabled plugins", "version": "1.2.10", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Common functionalities for Search, to be shared between various search-enabled plugins", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage", + "search" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/search-common" }, - "keywords": [ - "backstage", - "search" - ], "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "jest": { + "roots": [ + ".." + ] }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^", @@ -44,10 +49,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "jest": { - "roots": [ - ".." - ] } } diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 2a66d99f34..79223e13b1 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,17 +1,30 @@ { "name": "@backstage/plugin-search-react", "version": "1.7.6", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-react" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,27 +35,17 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-react" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -60,11 +63,6 @@ "qs": "^6.9.4", "react-use": "^17.3.2" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -76,7 +74,9 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/search/package.json b/plugins/search/package.json index ab25d6a10f..6b67fd95bf 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-search", - "description": "The Backstage plugin that provides your backstage app with search", "version": "1.4.6", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The Backstage plugin that provides your backstage app with search", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-compat-api": "workspace:^", @@ -62,11 +66,6 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -78,9 +77,10 @@ "@testing-library/user-event": "^14.0.0", "history": "^5.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 47255dff7f..c28be2cb47 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-sentry", - "description": "A Backstage plugin that integrates towards Sentry", "version": "0.5.15", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Sentry", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "sentry" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/sentry" }, - "keywords": [ - "backstage", - "sentry" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -46,11 +50,6 @@ "react-sparklines": "^1.7.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -60,9 +59,10 @@ "@testing-library/react": "^14.0.0", "@types/luxon": "^3.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 9b617b0e83..5e3e6f9bb3 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-shortcuts", - "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", "version": "0.3.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/shortcuts" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,11 +45,6 @@ "uuid": "^8.3.2", "zen-observable": "^0.10.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -56,7 +54,9 @@ "@testing-library/react": "^14.0.0", "@types/zen-observable": "^0.8.2" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index 1543217039..ebaecbf337 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-signals-react", - "description": "Web library for the signals plugin", "version": "0.0.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Web library for the signals plugin", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -15,34 +15,34 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/signals-react" }, - "backstage": { - "role": "web-library" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-plugin-api": "workspace:^", "@backstage/types": "workspace:^", "@material-ui/core": "^4.12.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + } } diff --git a/plugins/signals/package.json b/plugins/signals/package.json index eb75eb65dc..22cc82ef54 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-signals", "version": "0.0.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,18 +14,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/signals" }, - "backstage": { - "role": "frontend-plugin" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -39,9 +42,6 @@ "react-use": "^17.2.4", "uuid": "^8.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -53,7 +53,7 @@ "jest-websocket-mock": "^2.5.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + } } diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 02fa8b8f21..0b4c7fe86c 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,31 +1,35 @@ { "name": "@backstage/plugin-sonarqube-backend", "version": "0.2.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/sonarqube-backend" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -46,9 +50,5 @@ "msw": "^1.0.0", "supertest": "^6.2.4" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/sonarqube-react/package.json b/plugins/sonarqube-react/package.json index 0ac143884d..83b1291edf 100644 --- a/plugins/sonarqube-react/package.json +++ b/plugins/sonarqube-react/package.json @@ -1,16 +1,29 @@ { "name": "@backstage/plugin-sonarqube-react", "version": "0.1.13", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/sonarqube-react" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -18,43 +31,30 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sonarqube-react" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "alpha" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", "@backstage/core-plugin-api": "workspace:^" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist", - "alpha" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 65bff2e348..352254b0e5 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,38 +1,43 @@ { "name": "@backstage/plugin-sonarqube", - "description": "", "version": "0.7.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sonarqube" - }, "keywords": [ "backstage", "sonarqube", "sonarcloud" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/sonarqube" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "alpha", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -49,11 +54,6 @@ "rc-progress": "3.5.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -64,10 +64,10 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "alpha", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index b0d2dc8c0a..d14316e21f 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-splunk-on-call", - "description": "A Backstage plugin that integrates towards Splunk On-Call", "version": "0.4.19", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Splunk On-Call", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "splunk-on-call" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/splunk-on-call" }, - "keywords": [ - "backstage", - "splunk-on-call" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +49,6 @@ "luxon": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -60,9 +59,10 @@ "@testing-library/react": "^14.0.0", "@types/luxon": "^3.0.0" }, - "configSchema": "config.d.ts", - "files": [ - "dist", - "config.d.ts" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "configSchema": "config.d.ts" } diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 255fccbb02..b47ef94c7e 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "description": "Deprecated, consider using @backstage/plugin-search-backend-module-stack-overflow-collator instead", "version": "0.2.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Deprecated, consider using @backstage/plugin-search-backend-module-stack-overflow-collator instead", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, + "keywords": [ + "backstage", + "stack-overflow" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/stack-overflow-backend" }, - "keywords": [ - "backstage", - "stack-overflow" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/plugin-search-backend-module-stack-overflow-collator": "workspace:^", @@ -42,9 +46,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 260db40e76..4a25eec41a 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,17 +1,27 @@ { "name": "@backstage/plugin-stack-overflow", "version": "0.1.25", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/stack-overflow" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,24 +32,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/stack-overflow" - }, - "sideEffects": false, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -58,11 +62,6 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -71,9 +70,10 @@ "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index d7d3e5d436..ffec91508f 100644 --- a/plugins/stackstorm/package.json +++ b/plugins/stackstorm/package.json @@ -1,38 +1,42 @@ { "name": "@backstage/plugin-stackstorm", - "description": "A Backstage plugin that integrates towards StackStorm", "version": "0.1.11", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards StackStorm", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/stackstorm" - }, "keywords": [ "backstage", "stackstorm", "st2" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/stackstorm" + }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -43,11 +47,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -58,9 +57,10 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index e377a4b8e2..d4dcb23f4b 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,36 +1,40 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", "version": "0.1.42", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-insights-backend-module-jsonfc" - }, "keywords": [ "backstage", "tech-insights", "scorecard" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/tech-insights-backend-module-jsonfc" + }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "config.json", + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -50,9 +54,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" }, - "files": [ - "config.json", - "dist" - ], "configSchema": "config.json" } diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index c65d3c25c8..d39f8a3d6d 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,36 +1,41 @@ { "name": "@backstage/plugin-tech-insights-backend", "version": "0.5.24", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-insights-backend" - }, "keywords": [ "backstage", "tech-insights", "reporting" ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/tech-insights-backend" + }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "config.d.ts", + "dist", + "migrations/**/*.{js,d.ts}" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -63,10 +68,5 @@ "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" }, - "files": [ - "config.d.ts", - "dist", - "migrations/**/*.{js,d.ts}" - ], "configSchema": "config.d.ts" } diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json index cef4b5c627..bcaaca84e5 100644 --- a/plugins/tech-insights-common/package.json +++ b/plugins/tech-insights-common/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-tech-insights-common", "version": "0.2.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage", + "tech-insights" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/tech-insights-common" }, - "keywords": [ - "backstage", - "tech-insights" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli backend:dev", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli backend:dev", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/types": "workspace:^", @@ -39,8 +42,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index ec3da1b9f7..b94be91a80 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,35 +1,38 @@ { "name": "@backstage/plugin-tech-insights-node", "version": "0.4.16", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "backstage", + "tech-insights" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/tech-insights-node" }, - "keywords": [ - "backstage", - "tech-insights" + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -43,8 +46,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index d476532e32..e2cf61f6b3 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,32 +1,35 @@ { "name": "@backstage/plugin-tech-insights", "version": "0.3.22", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/tech-insights" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -43,11 +46,6 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -55,7 +53,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 51a7e8279b..dc329bf37e 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,30 +1,31 @@ { "name": "@backstage/plugin-tech-radar", - "description": "A Backstage plugin that lets you display a Tech Radar for your organization", "version": "0.6.13", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, + "description": "A Backstage plugin that lets you display a Tech Radar for your organization", "backstage": { "role": "frontend-plugin" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/tech-radar" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -35,15 +36,17 @@ ] } }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-compat-api": "workspace:^", @@ -57,11 +60,6 @@ "d3-force": "^3.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -74,7 +72,9 @@ "@types/color": "^3.0.1", "@types/d3-force": "^3.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 99afbacc6a..27d58a93ed 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", "version": "1.0.27", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-addons-test-utils" }, - "keywords": [ - "backstage", - "techdocs" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -45,18 +48,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "testing-library__dom": "^7.29.4-beta.1" }, - "peerDependencies": { - "@testing-library/react": "^12.1.3 || ^13.0.0 || ^14.0.0", - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^6.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "@testing-library/react": "^12.1.3 || ^13.0.0 || ^14.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 543eb8b178..3543dcf5cb 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-techdocs-backend", - "description": "The Backstage backend plugin that renders technical documentation for your components", "version": "1.9.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The Backstage backend plugin that renders technical documentation for your components", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "techdocs" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/techdocs-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/techdocs-backend" - }, - "keywords": [ - "backstage", - "techdocs" + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -75,9 +79,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 9361595175..85e47fea06 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "description": "Plugin module for contributed TechDocs Addons", "version": "1.1.5", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Plugin module for contributed TechDocs Addons", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin-module" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-module-addons-contrib" }, - "keywords": [ - "backstage", - "techdocs" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -45,11 +48,6 @@ "git-url-parse": "^14.0.0", "photoswipe": "^5.3.7" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/plugin-techdocs-addons-test-utils": "workspace:^", @@ -59,7 +57,9 @@ "@testing-library/react": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 5c64b78e2e..083e595ec9 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,42 +1,42 @@ { "name": "@backstage/plugin-techdocs-node", - "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "version": "1.11.2", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "techdocs", + "backstage" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-node" }, - "keywords": [ - "techdocs", - "backstage" - ], "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@aws-sdk/client-s3": "^3.350.0", diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index aa4aa50162..e1f50f629d 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,37 +1,41 @@ { "name": "@backstage/plugin-techdocs-react", - "description": "Shared frontend utilities for TechDocs and Addons", "version": "1.1.16", + "description": "Shared frontend utilities for TechDocs and Addons", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-react" }, - "keywords": [ - "backstage", - "techdocs" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "alpha", + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -47,11 +51,6 @@ "react-helmet": "6.1.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", @@ -59,8 +58,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "alpha", - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a1f5abaa14..47ff100ab0 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,18 +1,32 @@ { "name": "@backstage/plugin-techdocs", - "description": "The Backstage plugin that renders technical documentation for your components", "version": "1.10.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The Backstage plugin that renders technical documentation for your components", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "techdocs" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/techdocs" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,28 +37,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/techdocs" - }, - "keywords": [ - "backstage", - "techdocs" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -74,11 +78,6 @@ "react-helmet": "6.1.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -93,9 +92,10 @@ "@types/event-source-polyfill": "^1.0.0", "canvas": "^2.10.2" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/todo/package.json b/plugins/todo/package.json index d64a1d1520..0ec887afa1 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,33 +1,37 @@ { "name": "@backstage/plugin-todo", - "description": "A Backstage plugin that lets you browse TODO comments in your source code", "version": "0.2.34", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that lets you browse TODO comments in your source code", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/todo" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "alpha" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -38,11 +42,6 @@ "@material-ui/icons": "^4.9.1", "@types/react": "^16.13.1 || ^17.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -51,8 +50,9 @@ "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" }, - "files": [ - "dist", - "alpha" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 2c3c3498d5..05da152f7f 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,21 +1,27 @@ { "name": "@backstage/plugin-user-settings-backend", - "description": "The Backstage backend plugin to manage user settings", "version": "0.2.9", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin" }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/user-settings-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -26,20 +32,19 @@ ] } }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/user-settings-backend" - }, + "files": [ + "dist", + "migrations", + "alpha" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -60,10 +65,5 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" - }, - "files": [ - "dist", - "migrations", - "alpha" - ] + } } diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 7f79dfe663..2d5a8b118e 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,15 +1,31 @@ { "name": "@backstage/plugin-user-settings", - "description": "A Backstage plugin that provides a settings page", "version": "0.8.1", - "main": "src/index.ts", - "types": "src/index.ts", + "description": "A Backstage plugin that provides a settings page", + "backstage": { + "role": "frontend-plugin" + }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/user-settings" + }, "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -20,30 +36,17 @@ ] } }, - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/user-settings" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -62,11 +65,6 @@ "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -78,9 +76,11 @@ "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/user-settings", diff --git a/plugins/vault-node/package.json b/plugins/vault-node/package.json index dc091ac9cc..c4043d44d1 100644 --- a/plugins/vault-node/package.json +++ b/plugins/vault-node/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-vault-node", - "description": "Node.js library for the vault plugin", "version": "0.1.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Node.js library for the vault plugin", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,24 +15,24 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/vault-node" }, - "backstage": { - "role": "node-library" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 82e8c4ebae..d49330fe97 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-vault", - "description": "A Backstage plugin that integrates towards Vault", "version": "0.1.25", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that integrates towards Vault", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage", + "vault" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/vault" }, - "keywords": [ - "backstage", - "vault" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -45,11 +48,6 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", @@ -60,7 +58,9 @@ "@testing-library/react": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index e1cb8763e7..e0063b8d05 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,33 +1,36 @@ { "name": "@backstage/plugin-xcmetrics", - "description": "A Backstage plugin that shows XCode build metrics for your components", "version": "0.2.48", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "A Backstage plugin that shows XCode build metrics for your components", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin" - }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/xcmetrics" }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,11 +45,6 @@ "react-use": "^17.2.4", "recharts": "^2.5.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", @@ -57,7 +55,9 @@ "@testing-library/user-event": "^14.0.0", "@types/luxon": "^3.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/scripts/sort-package-json.mjs b/scripts/sort-package-json.mjs new file mode 100644 index 0000000000..e1e0745326 --- /dev/null +++ b/scripts/sort-package-json.mjs @@ -0,0 +1,40 @@ +#!/usr/bin/env node +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import sortPackage from 'sort-package-json'; +import fs from 'fs-extra'; + +const sortOrder = [ + 'name', + 'version', + 'description', + 'backstage', + 'publishConfig', + // ...and whatever is not in here, goes in the library's default order +]; + +const files = process.argv.slice(2).filter(arg => !arg.startsWith('--')); + +for (const file of files) { + const originalPackage = JSON.parse(fs.readFileSync(file).toString()); + const sortedPackage = JSON.stringify( + sortPackage(originalPackage, { sortOrder }), + null, + 2, + ); + fs.writeFileSync(file, `${sortedPackage}\n`); +} From 04c74a96a1d96f93a0735ae5003edbc89739c689 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 23 Feb 2024 14:48:46 +0100 Subject: [PATCH 67/76] entity-feedback-backend: add missing auth services for new backend system Signed-off-by: Patrik Oldsberg --- plugins/entity-feedback-backend/src/plugin.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/entity-feedback-backend/src/plugin.ts b/plugins/entity-feedback-backend/src/plugin.ts index 6a4ff442ce..a3111a2308 100644 --- a/plugins/entity-feedback-backend/src/plugin.ts +++ b/plugins/entity-feedback-backend/src/plugin.ts @@ -36,14 +36,26 @@ export const entityFeedbackPlugin = createBackendPlugin({ identity: coreServices.identity, logger: coreServices.logger, httpRouter: coreServices.httpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, }, - async init({ database, discovery, identity, logger, httpRouter }) { + async init({ + database, + discovery, + identity, + logger, + httpRouter, + auth, + httpAuth, + }) { httpRouter.use( await createRouter({ database, discovery, identity, logger: loggerToWinstonLogger(logger), + auth, + httpAuth, }), ); }, From 6c06f99ba65fbe3e596203216b6f295a57306d5d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 23 Feb 2024 15:11:26 +0100 Subject: [PATCH 68/76] permission-node: refactor to true private fields for ServerPermissionClient Signed-off-by: Patrik Oldsberg --- .../src/ServerPermissionClient.ts | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/plugins/permission-node/src/ServerPermissionClient.ts b/plugins/permission-node/src/ServerPermissionClient.ts index 87e0eb98d1..05202caf70 100644 --- a/plugins/permission-node/src/ServerPermissionClient.ts +++ b/plugins/permission-node/src/ServerPermissionClient.ts @@ -42,9 +42,9 @@ import { * @public */ export class ServerPermissionClient implements PermissionsService { - private readonly auth: AuthService; - private readonly permissionClient: PermissionClient; - private readonly permissionEnabled: boolean; + readonly #auth: AuthService; + readonly #permissionClient: PermissionClient; + readonly #permissionEnabled: boolean; static fromConfig( config: Config, @@ -82,42 +82,46 @@ export class ServerPermissionClient implements PermissionsService { permissionClient: PermissionClient; permissionEnabled: boolean; }) { - this.auth = options.auth; - this.permissionClient = options.permissionClient; - this.permissionEnabled = options.permissionEnabled; + this.#auth = options.auth; + this.#permissionClient = options.permissionClient; + this.#permissionEnabled = options.permissionEnabled; } async authorizeConditional( queries: QueryPermissionRequest[], options?: PermissionsServiceRequestOptions, ): Promise { - return (await this.shouldPermissionsBeApplied(options)) - ? this.permissionClient.authorizeConditional( - queries, - await this.getRequestOptions(options), - ) - : queries.map(_ => ({ result: AuthorizeResult.ALLOW })); + if (await this.#shouldPermissionsBeApplied(options)) { + return this.#permissionClient.authorizeConditional( + queries, + await this.#getRequestOptions(options), + ); + } + + return queries.map(_ => ({ result: AuthorizeResult.ALLOW })); } async authorize( requests: AuthorizePermissionRequest[], options?: PermissionsServiceRequestOptions, ): Promise { - return (await this.shouldPermissionsBeApplied(options)) - ? this.permissionClient.authorize( - requests, - await this.getRequestOptions(options), - ) - : requests.map(_ => ({ result: AuthorizeResult.ALLOW })); + if (await this.#shouldPermissionsBeApplied(options)) { + return this.#permissionClient.authorize( + requests, + await this.#getRequestOptions(options), + ); + } + + return requests.map(_ => ({ result: AuthorizeResult.ALLOW })); } - private async getRequestOptions(options?: PermissionsServiceRequestOptions) { + async #getRequestOptions(options?: PermissionsServiceRequestOptions) { if (options && 'credentials' in options) { - if (this.auth.isPrincipal(options.credentials, 'none')) { + if (this.#auth.isPrincipal(options.credentials, 'none')) { return {}; } - return this.auth.getPluginRequestToken({ + return this.#auth.getPluginRequestToken({ onBehalfOf: options.credentials, targetPluginId: 'permissions', }); @@ -126,10 +130,10 @@ export class ServerPermissionClient implements PermissionsService { return options; } - private async shouldPermissionsBeApplied( + async #shouldPermissionsBeApplied( options?: PermissionsServiceRequestOptions, ) { - if (!this.permissionEnabled) { + if (!this.#permissionEnabled) { return false; } @@ -141,13 +145,13 @@ export class ServerPermissionClient implements PermissionsService { return true; } try { - credentials = await this.auth.authenticate(options.token); + credentials = await this.#auth.authenticate(options.token); } catch { return true; } } - if (this.auth.isPrincipal(credentials, 'service')) { + if (this.#auth.isPrincipal(credentials, 'service')) { return false; } return true; From 16b23eddd312497299e9c40b028042378eac41a4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 23 Feb 2024 15:12:18 +0100 Subject: [PATCH 69/76] permission-node: added tests for ServerPermissionClient with credentials Signed-off-by: Patrik Oldsberg --- .../src/ServerPermissionClient.test.ts | 148 +++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/plugins/permission-node/src/ServerPermissionClient.test.ts b/plugins/permission-node/src/ServerPermissionClient.test.ts index eb8abefc95..9cff45a5aa 100644 --- a/plugins/permission-node/src/ServerPermissionClient.test.ts +++ b/plugins/permission-node/src/ServerPermissionClient.test.ts @@ -22,7 +22,11 @@ import { DefinitivePolicyDecision, ConditionalPolicyDecision, } from '@backstage/plugin-permission-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { + mockCredentials, + mockServices, + setupRequestMockHandlers, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger, @@ -201,4 +205,146 @@ describe('ServerPermissionClient', () => { expect(mockAuthorizeHandler).toHaveBeenCalled(); }); }); + + describe('with credentials', () => { + describe('authorize', () => { + let mockAuthorizeHandler: jest.Mock; + + beforeEach(() => { + mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => { + const responses = req.body.items.map( + (r: IdentifiedPermissionMessage) => ({ + id: r.id, + result: AuthorizeResult.ALLOW, + }), + ); + + return res(json({ items: responses })); + }); + + server.use(rest.post(`${mockBaseUrl}/authorize`, mockAuthorizeHandler)); + }); + + it('should bypass the permission backend if permissions are disabled', async () => { + const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { + discovery, + tokenManager: ServerTokenManager.noop(), + auth: mockServices.auth(), + }); + + await client.authorize( + [ + { + permission: testBasicPermission, + }, + ], + { credentials: mockCredentials.none() }, + ); + + expect(mockAuthorizeHandler).not.toHaveBeenCalled(); + }); + + it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { + const tokenManager = ServerTokenManager.fromConfig(config, { logger }); + const client = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + auth: mockServices.auth(), + }); + + await client.authorize([{ permission: testBasicPermission }], { + credentials: mockCredentials.service(), + }); + + expect(mockAuthorizeHandler).not.toHaveBeenCalled(); + }); + + it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { + const tokenManager = ServerTokenManager.fromConfig(config, { logger }); + const client = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + auth: mockServices.auth(), + }); + + await client.authorize([{ permission: testBasicPermission }], { + credentials: mockCredentials.user(), + }); + + expect(mockAuthorizeHandler).toHaveBeenCalled(); + }); + }); + + describe('authorizeConditional', () => { + let mockAuthorizeHandler: jest.Mock; + + beforeEach(() => { + mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => { + const responses = req.body.items.map( + (r: IdentifiedPermissionMessage) => ({ + id: r.id, + result: AuthorizeResult.ALLOW, + }), + ); + + return res(json({ items: responses })); + }); + + server.use(rest.post(`${mockBaseUrl}/authorize`, mockAuthorizeHandler)); + }); + + it('should bypass the permission backend if permissions are disabled', async () => { + const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { + discovery, + tokenManager: ServerTokenManager.noop(), + auth: mockServices.auth(), + }); + + await client.authorizeConditional( + [{ permission: testResourcePermission }], + { + credentials: mockCredentials.none(), + }, + ); + + expect(mockAuthorizeHandler).not.toHaveBeenCalled(); + }); + + it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { + const tokenManager = ServerTokenManager.fromConfig(config, { logger }); + const client = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + auth: mockServices.auth(), + }); + + await client.authorizeConditional( + [{ permission: testResourcePermission }], + { + credentials: mockCredentials.service(), + }, + ); + + expect(mockAuthorizeHandler).not.toHaveBeenCalled(); + }); + + it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { + const tokenManager = ServerTokenManager.fromConfig(config, { logger }); + const client = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + auth: mockServices.auth(), + }); + + await client.authorizeConditional( + [{ permission: testResourcePermission }], + { + credentials: mockCredentials.user(), + }, + ); + + expect(mockAuthorizeHandler).toHaveBeenCalled(); + }); + }); + }); }); From ef4557486b349eb89f5992e63addc42cdf2d2007 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:13:54 +0000 Subject: [PATCH 70/76] chore(deps): update dependency knip to v5.0.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index ef671a6c59..963449dae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33087,8 +33087,8 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.0.1 - resolution: "knip@npm:5.0.1" + version: 5.0.2 + resolution: "knip@npm:5.0.2" dependencies: "@ericcornelissen/bash-parser": 0.5.2 "@nodelib/fs.walk": 2.0.0 @@ -33112,13 +33112,13 @@ __metadata: strip-json-comments: 5.0.1 summary: 2.1.0 zod: 3.22.4 - zod-validation-error: 3.0.0 + zod-validation-error: 3.0.2 peerDependencies: "@types/node": ">=18" typescript: ">=5.0.4" bin: knip: bin/knip.js - checksum: d4d97e44c45d0c7b2b0c86495e6337d89cd94e005a4d29190498f29dc61945d51be2e6d2373b53104a98949c6b1eb9ca71f24f58526459d6118ea72713536ad4 + checksum: af0e395ab1f8a9974fa0e83711d13b252017cc7aacd92293d13b8a0219c9f4d98a04f0ea074202c9adf5af3aa3fd22a1b5bbbbe3f00effc143656961b92c6512 languageName: node linkType: hard @@ -46386,12 +46386,12 @@ __metadata: languageName: node linkType: hard -"zod-validation-error@npm:3.0.0": - version: 3.0.0 - resolution: "zod-validation-error@npm:3.0.0" +"zod-validation-error@npm:3.0.2": + version: 3.0.2 + resolution: "zod-validation-error@npm:3.0.2" peerDependencies: zod: ^3.18.0 - checksum: a1492268847aa69a160a50ad04dcce3d65454520c56a63680c1e6382f07a66a98463f5fbc0d58ee536651ec189fd0464d6ce657dddbdc37700cc8f7fc6e9c292 + checksum: 5127ff75f50db2f195d739142d4e56b1d8f7294b82c08d1b308978bc546afc7c3b2958f677d00eca1e3254342704d48a34ba93f8e88ae5799feefda6b6dc911e languageName: node linkType: hard From 7f071a16024c6ebd9fd948245da0da0ce2f1ca79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:14:17 +0000 Subject: [PATCH 71/76] fix(deps): update dependency swagger-ui-react to v5.11.8 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 54 +++++++++++++++--------------------------------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/yarn.lock b/yarn.lock index ef671a6c59..b787e7a004 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11226,13 +11226,6 @@ __metadata: languageName: node linkType: hard -"@fastify/busboy@npm:^2.0.0": - version: 2.0.0 - resolution: "@fastify/busboy@npm:2.0.0" - checksum: 41879937ce1dee6421ef9cd4da53239830617e1f0bb7a0e843940772cd72827205d05e518af6adabe6e1ea19301285fff432b9d11bad01a531e698bea95c781b - languageName: node - linkType: hard - "@floating-ui/core@npm:^1.5.3": version: 1.5.3 resolution: "@floating-ui/core@npm:1.5.3" @@ -25677,10 +25670,10 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:=3.0.8": - version: 3.0.8 - resolution: "dompurify@npm:3.0.8" - checksum: cac660ccae15a9603f06a85344da868a4c3732d8b57f7998de0f421eb4b9e67d916be52e9bb2a57b2f95b49e994cc50bcd06bb87f2cb2849cf058bdf15266237 +"dompurify@npm:=3.0.9, dompurify@npm:^3.0.0": + version: 3.0.9 + resolution: "dompurify@npm:3.0.9" + checksum: 09794f2e40a0003d36e3cd70be1036f83de39d9d4a0f199c45e0b9962ce8ae5f9fe424d7edc4c8ff9ec615be9744a140d66788f0925913ac482d4628b283cae5 languageName: node linkType: hard @@ -25691,13 +25684,6 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:^3.0.0": - version: 3.0.9 - resolution: "dompurify@npm:3.0.9" - checksum: 09794f2e40a0003d36e3cd70be1036f83de39d9d4a0f199c45e0b9962ce8ae5f9fe424d7edc4c8ff9ec615be9744a140d66788f0925913ac482d4628b283cae5 - languageName: node - linkType: hard - "domutils@npm:^2.5.2, domutils@npm:^2.8.0": version: 2.8.0 resolution: "domutils@npm:2.8.0" @@ -35831,7 +35817,7 @@ __metadata: languageName: node linkType: hard -"node-fetch-commonjs@npm:^3.3.1": +"node-fetch-commonjs@npm:^3.3.2": version: 3.3.2 resolution: "node-fetch-commonjs@npm:3.3.2" dependencies: @@ -43015,9 +43001,9 @@ __metadata: languageName: node linkType: hard -"swagger-client@npm:^3.25.0": - version: 3.25.0 - resolution: "swagger-client@npm:3.25.0" +"swagger-client@npm:^3.25.3": + version: 3.25.3 + resolution: "swagger-client@npm:3.25.3" dependencies: "@babel/runtime-corejs3": ^7.22.15 "@swagger-api/apidom-core": ">=0.90.0 <1.0.0" @@ -43031,17 +43017,16 @@ __metadata: is-plain-object: ^5.0.0 js-yaml: ^4.1.0 node-abort-controller: ^3.1.1 - node-fetch-commonjs: ^3.3.1 + node-fetch-commonjs: ^3.3.2 qs: ^6.10.2 traverse: ~0.6.6 - undici: ^5.24.0 - checksum: 2e989059b4edeab26b148993cea8a68c4ad34927d4058479f2722c01d8bd0f67bfb1f69dc93ce24a5adb5a8e0f45e4438ad38f8bfb70f8d0b1a8d66650abe060 + checksum: 01ef0298c6b078db42d3eb191d418cd82645cff35887c6e7f533940153c01f44265a2a03140b0d309b010843ea5bc3bf71edaf09e7090c59fcf25fda644c4c24 languageName: node linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.11.7 - resolution: "swagger-ui-react@npm:5.11.7" + version: 5.11.8 + resolution: "swagger-ui-react@npm:5.11.8" dependencies: "@babel/runtime-corejs3": ^7.23.9 "@braintree/sanitize-url": =7.0.0 @@ -43049,7 +43034,7 @@ __metadata: classnames: ^2.5.1 css.escape: 1.5.1 deep-extend: 0.6.0 - dompurify: =3.0.8 + dompurify: =3.0.9 ieee754: ^1.2.1 immutable: ^3.x.x js-file-download: ^0.4.12 @@ -43072,7 +43057,7 @@ __metadata: reselect: ^5.1.0 serialize-error: ^8.1.0 sha.js: ^2.4.11 - swagger-client: ^3.25.0 + swagger-client: ^3.25.3 url-parse: ^1.5.10 xml: =1.0.1 xml-but-prettier: ^1.0.1 @@ -43080,7 +43065,7 @@ __metadata: peerDependencies: react: ">=16.8.0 <19" react-dom: ">=16.8.0 <19" - checksum: b4589abe7d4cdc97fd05f8f8f8b40daee33bb4604faa1f9c513b3ef4765fc407fef37c704dbc56c5493fa5430472e8cb30921a4d4ba544372266d06ef4d1b1e6 + checksum: 131a3421e182225368822e49944e72e51cae10d8263263fbd4bcc4c5eed9782314bb6b42ca471d9542393961c1305190c149cc19c7163b3ec1540f1e288509ce languageName: node linkType: hard @@ -44292,15 +44277,6 @@ __metadata: languageName: node linkType: hard -"undici@npm:^5.24.0": - version: 5.28.3 - resolution: "undici@npm:5.28.3" - dependencies: - "@fastify/busboy": ^2.0.0 - checksum: fa1e65aff896c5e2ee23637b632e306f9e3a2b32a3dc0b23ea71e5555ad350bcc25713aea894b3dccc0b7dc2c5e92a5a58435ebc2033b731a5524506f573dfd2 - languageName: node - linkType: hard - "unescape-js@npm:^1.0.5": version: 1.1.4 resolution: "unescape-js@npm:1.1.4" From 5c3720a228b2777796381cfe8395c1c0943cf23c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 23 Feb 2024 15:22:46 +0100 Subject: [PATCH 72/76] permission-node: assert user credentials forwarding in ServerPermissionClient Signed-off-by: Patrik Oldsberg --- .../src/ServerPermissionClient.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plugins/permission-node/src/ServerPermissionClient.test.ts b/plugins/permission-node/src/ServerPermissionClient.test.ts index 9cff45a5aa..29a5648c70 100644 --- a/plugins/permission-node/src/ServerPermissionClient.test.ts +++ b/plugins/permission-node/src/ServerPermissionClient.test.ts @@ -272,6 +272,14 @@ describe('ServerPermissionClient', () => { }); expect(mockAuthorizeHandler).toHaveBeenCalled(); + expect( + mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), + ).toBe( + mockCredentials.service.header({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'permissions', + }), + ); }); }); @@ -344,6 +352,14 @@ describe('ServerPermissionClient', () => { ); expect(mockAuthorizeHandler).toHaveBeenCalled(); + expect( + mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), + ).toBe( + mockCredentials.service.header({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'permissions', + }), + ); }); }); }); From 58e37d2cafaf096b609b1ac462bb0e60caad0620 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:12:05 +0000 Subject: [PATCH 73/76] chore(deps): update dependency nodemon to v3.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index d20b92a690..497e01bbf0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36049,8 +36049,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.0.3 - resolution: "nodemon@npm:3.0.3" + version: 3.1.0 + resolution: "nodemon@npm:3.1.0" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -36064,7 +36064,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: 121ebb6349167d87cefd5767ec453ceb49ec5a8d50146134a54b0e25502c29ad01caaa41460e303b35728439012564782d278b3fef3c615f3c278979c2b7d586 + checksum: 0b721f66ee60d9bf092f6101965bc65769698fa2921d0283d90bbf3f0906aa4f3ac77316682375bd7f09c91679fddb131aa39f9fc839fea57061bbc8e81b60e3 languageName: node linkType: hard From 8e514e4dec30ab502c9ff447f5228d076cf8ac8b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:13:19 +0000 Subject: [PATCH 74/76] fix(deps): update dependency @google-cloud/container to v5.8.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index d20b92a690..f2177914e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11355,11 +11355,11 @@ __metadata: linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.7.0 - resolution: "@google-cloud/container@npm:5.7.0" + version: 5.8.0 + resolution: "@google-cloud/container@npm:5.8.0" dependencies: google-gax: ^4.0.3 - checksum: 8d6d1e80b1bd33e24e4d0ed667fc16543b7ad2962c3918b74ff42efc0ed3c915a3682e83d8f53aaa06eb5fbe6fb661e46640f954f59b79f991598b03c68f3e13 + checksum: 6d82c417d7819fee322397f482785f3dfec28a82f0f1cf1a3f5059a7822f2b438b893eb068bb7ac9909011a63b22e6f1115e7c1386adf3fbfa93980b2657cfc1 languageName: node linkType: hard From d5d83094283d1ce41f2593187f5f50e5c9de50f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 17:07:09 +0000 Subject: [PATCH 75/76] fix(deps): update dependency @smithy/node-http-handler to v2.4.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/yarn.lock b/yarn.lock index b525d739c4..1d2fe96275 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15937,13 +15937,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/abort-controller@npm:2.1.1" +"@smithy/abort-controller@npm:^2.1.1, @smithy/abort-controller@npm:^2.1.2": + version: 2.1.2 + resolution: "@smithy/abort-controller@npm:2.1.2" dependencies: - "@smithy/types": ^2.9.1 + "@smithy/types": ^2.10.0 tslib: ^2.5.0 - checksum: 4bfad0d6b3a75bd1e6f997aa41cc9d8ba8bfdf548cfe703553ad7b42f0bf3e06b595d584be7b9ab90d2e3b22aacad94c02c32e21bea96e46933443f09c59523a + checksum: 0646908e0afce70bc15484bdddff2b862ebdc9566f96e6ff4e0dd7bc430b3c71a503f822786d2fc0f67b109e5c14d58cf29468d43dc2356662f03069c6d41508 languageName: node linkType: hard @@ -16217,15 +16217,15 @@ __metadata: linkType: hard "@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/node-http-handler@npm:2.3.1" + version: 2.4.0 + resolution: "@smithy/node-http-handler@npm:2.4.0" dependencies: - "@smithy/abort-controller": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/querystring-builder": ^2.1.1 - "@smithy/types": ^2.9.1 + "@smithy/abort-controller": ^2.1.2 + "@smithy/protocol-http": ^3.2.0 + "@smithy/querystring-builder": ^2.1.2 + "@smithy/types": ^2.10.0 tslib: ^2.5.0 - checksum: e6a514098f44cfc962318b15df79bb5e9de7fffe883fe073965879b2cf2436726709b5be14262871794104272e8506f793f8e77b8bf5b36398714a3a51512516 + checksum: f4f4171b9b527d142752e2bcf2fc2cc86924bf4f807c435dd8decfdeef88667fd2bba5bb2ed8459f94f0373793aeecfa57960527ffc2ac1a4c71d424f7e7a64b languageName: node linkType: hard @@ -16239,24 +16239,24 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.1.1": - version: 3.1.1 - resolution: "@smithy/protocol-http@npm:3.1.1" +"@smithy/protocol-http@npm:^3.1.1, @smithy/protocol-http@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/protocol-http@npm:3.2.0" dependencies: - "@smithy/types": ^2.9.1 + "@smithy/types": ^2.10.0 tslib: ^2.5.0 - checksum: a5be1c5b5bff18c5a35c23870e1ffa38da33e56f93bdd8f26c615f4c0d2d3e1effffe441e756c0b0ba3aad2dd0845332f634702bf8455ed865a04eebfef1329b + checksum: a2082228ea933734795db27b3d5c893f31fa6c80154ddb3b8cce46494fb429088f636db202a482fb67686908fd829d20adc04c1786f09e8c67b9835c6eb1a918 languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/querystring-builder@npm:2.1.1" +"@smithy/querystring-builder@npm:^2.1.1, @smithy/querystring-builder@npm:^2.1.2": + version: 2.1.2 + resolution: "@smithy/querystring-builder@npm:2.1.2" dependencies: - "@smithy/types": ^2.9.1 + "@smithy/types": ^2.10.0 "@smithy/util-uri-escape": ^2.1.1 tslib: ^2.5.0 - checksum: b8623c7ef6d19fb21c41bfda29cce9c673ac501914085b39642ff5a72cf5742b19cd9de1a1851d13f2e1bbfc2e9522070b5ca32ed906aacf93f732a56e76098a + checksum: 480bfc64d5beb6da9c0ecdcd6cb0961cf5afa30c5188b32e3a70608e8f5205d6dc56b13e854b5f541dfdb78b9d9e88a349ec6fc5db8f8d00f11ad137e0b81085 languageName: node linkType: hard @@ -16328,12 +16328,12 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.9.1": - version: 2.9.1 - resolution: "@smithy/types@npm:2.9.1" +"@smithy/types@npm:^2.10.0, @smithy/types@npm:^2.9.1": + version: 2.10.0 + resolution: "@smithy/types@npm:2.10.0" dependencies: tslib: ^2.5.0 - checksum: 8570affb4abb5d0ead57293977fc915d44be481120defcabb87a3fb1c7b5d2501b117835eca357b5d54ea4bbee08032f9dc3d909ecbf0abb0cec2ca9678ae7bd + checksum: f353ff0d8f91454288585c7e03485c698af70d46490856abe21d1e2f2154f704a68599328297a1151c1585cd5b0f80a83c759f6d8e02ab168ce616e33cba18c4 languageName: node linkType: hard From f4c08bb6712e18338159fa7e7337f87c996db823 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Fri, 23 Feb 2024 12:33:03 -0500 Subject: [PATCH 76/76] Add ico extension to jest Signed-off-by: Stephen A. Wilson --- packages/cli/config/jest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js index 584a31c672..6d7b2bf038 100644 --- a/packages/cli/config/jest.js +++ b/packages/cli/config/jest.js @@ -185,7 +185,7 @@ async function getProjectConfig(targetPath, extraConfig) { }, }, ], - '\\.(bmp|gif|jpg|jpeg|png|frag|xml|svg|eot|woff|woff2|ttf)$': + '\\.(bmp|gif|jpg|jpeg|png|ico|frag|xml|svg|eot|woff|woff2|ttf)$': require.resolve('./jestFileTransform.js'), '\\.(yaml)$': require.resolve('./jestYamlTransform'), },