From 8e8a25dba58de9582a3dd3379e46791f628affab Mon Sep 17 00:00:00 2001 From: Andy Muldoon Date: Fri, 22 Dec 2023 13:58:07 +0000 Subject: [PATCH 01/52] Ability for Users to configure auth token expiration [19341] Signed-off-by: Andy Muldoon --- .changeset/spotty-kids-pay.md | 5 +++ plugins/auth-backend/README.md | 9 ++++++ plugins/auth-backend/config.d.ts | 6 ++++ plugins/auth-backend/package.json | 1 + .../auth-backend/src/service/router.test.ts | 31 ++++++++++++++++++- plugins/auth-backend/src/service/router.ts | 29 ++++++++++++++--- yarn.lock | 1 + 7 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 .changeset/spotty-kids-pay.md diff --git a/.changeset/spotty-kids-pay.md b/.changeset/spotty-kids-pay.md new file mode 100644 index 0000000000..199d0fdff0 --- /dev/null +++ b/.changeset/spotty-kids-pay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': minor +--- + +Ability for user to configure backstage token expiration diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index ce7525fb6b..e9dca26a5b 100644 --- a/plugins/auth-backend/README.md +++ b/plugins/auth-backend/README.md @@ -165,3 +165,12 @@ To try out SAML, you can use the mock identity provider: ## Links - [The Backstage homepage](https://backstage.io) + +## Configuring Token Expiration in App Config + +The expiration feature is not enabled unless you set this in your config file: + +``` +auth: + backstageTokenExpiration: { minutes: } +``` diff --git a/plugins/auth-backend/config.d.ts b/plugins/auth-backend/config.d.ts index 34139593d3..d24b2c64b7 100644 --- a/plugins/auth-backend/config.d.ts +++ b/plugins/auth-backend/config.d.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { HumanDuration } from '@backstage/types'; + export interface Config { /** Configuration options for the auth plugin */ auth?: { @@ -212,6 +214,10 @@ export interface Config { cfaccess?: { teamName: string; }; + /** + * The backstage token expiration. + */ + backstageTokenExpiration?: HumanDuration; }; }; } diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index f05551736a..07d80ddabe 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -48,6 +48,7 @@ "@backstage/plugin-auth-backend-module-okta-provider": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", + "@backstage/types": "workspace:^", "@google-cloud/firestore": "^7.0.0", "@types/express": "^4.17.6", "@types/passport": "^1.0.3", diff --git a/plugins/auth-backend/src/service/router.test.ts b/plugins/auth-backend/src/service/router.test.ts index 3a1fde881e..fd339e349e 100644 --- a/plugins/auth-backend/src/service/router.test.ts +++ b/plugins/auth-backend/src/service/router.test.ts @@ -15,7 +15,11 @@ */ import { ConfigReader } from '@backstage/config'; -import { createOriginFilter } from './router'; +import { + createOriginFilter, + getDefaultBackstageTokenExpiryTime, +} from './router'; +import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session'; describe('Auth origin filtering', () => { const config = new ConfigReader({ @@ -52,3 +56,28 @@ describe('Auth origin filtering', () => { expect(createOriginFilter(config)(origin)).toBeTruthy(); }); }); + +describe('Test for default backstage token expiry time', () => { + it('Will return default backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + }); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe( + BACKSTAGE_SESSION_EXPIRATION, + ); + }); + + it('Will return user defined backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 120 }, + }, + }); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe(7200); + }); +}); diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index 320870b3ee..eea858dd9c 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -29,7 +29,6 @@ import { } from '@backstage/backend-common'; import { assertError, NotFoundError } from '@backstage/errors'; import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; -import { Config } from '@backstage/config'; import { createOidcRouter, TokenFactory, KeyStores } from '../identity'; import session from 'express-session'; import connectSessionKnex from 'connect-session-knex'; @@ -41,6 +40,8 @@ import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session'; import { TokenIssuer } from '../identity/types'; import { StaticTokenIssuer } from '../identity/StaticTokenIssuer'; import { StaticKeyStore } from '../identity/StaticKeyStore'; +import { Config, readDurationFromConfig } from '@backstage/config'; +import { durationToMilliseconds } from '@backstage/types'; /** @public */ export type ProviderFactories = { [s: string]: AuthProviderFactory }; @@ -76,9 +77,8 @@ export async function createRouter( const appUrl = config.getString('app.baseUrl'); const authUrl = await discovery.getExternalBaseUrl('auth'); - + const backstageTokenExpiration = getDefaultBackstageTokenExpiryTime(config); const authDb = AuthDatabase.create(database); - const sessionExpirationSeconds = BACKSTAGE_SESSION_EXPIRATION; const keyStore = await KeyStores.fromConfig(config, { logger, @@ -91,7 +91,7 @@ export async function createRouter( { logger: logger.child({ component: 'token-factory' }), issuer: authUrl, - sessionExpirationSeconds: sessionExpirationSeconds, + sessionExpirationSeconds: backstageTokenExpiration, }, keyStore as StaticKeyStore, ); @@ -99,7 +99,7 @@ export async function createRouter( tokenIssuer = new TokenFactory({ issuer: authUrl, keyStore, - keyDurationSeconds: sessionExpirationSeconds, + keyDurationSeconds: backstageTokenExpiration, logger: logger.child({ component: 'token-factory' }), algorithm: tokenFactoryAlgorithm ?? @@ -249,3 +249,22 @@ export function createOriginFilter( return allowedOriginPatterns.some(pattern => pattern.match(origin)); }; } + +/** @internal */ +export function getDefaultBackstageTokenExpiryTime(config: Config) { + const processingIntervalKey = 'auth.backstageTokenExpiration'; + + if (!config.has(processingIntervalKey)) { + return BACKSTAGE_SESSION_EXPIRATION; + } + + const duration = readDurationFromConfig(config, { + key: processingIntervalKey, + }); + const seconds = Math.max( + 600, + Math.round(durationToMilliseconds(duration) / 1000), + ); + + return seconds; +} diff --git a/yarn.lock b/yarn.lock index edb50887c1..c0bb552222 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4859,6 +4859,7 @@ __metadata: "@backstage/plugin-auth-backend-module-okta-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/types": "workspace:^" "@google-cloud/firestore": ^7.0.0 "@types/body-parser": ^1.19.0 "@types/cookie-parser": ^1.4.2 From 3bd2cc33c3be9da7d390f1db939f32ce8658c60a Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:15:49 +0000 Subject: [PATCH 02/52] Update plugins/auth-backend/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- plugins/auth-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index e9dca26a5b..3133266614 100644 --- a/plugins/auth-backend/README.md +++ b/plugins/auth-backend/README.md @@ -168,7 +168,7 @@ To try out SAML, you can use the mock identity provider: ## Configuring Token Expiration in App Config -The expiration feature is not enabled unless you set this in your config file: +If you need to change Backstage token expiration from the default value of one hour, set the following in your config file: ``` auth: From ab9c9eb77e6638b03176cb90f53da6ccaa59e8da Mon Sep 17 00:00:00 2001 From: Danyelle Amarante <90638175+Danyelleac@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:04:03 -0300 Subject: [PATCH 03/52] fix/textSize-fix value label text color Signed-off-by: Danyelle Amarante <90638175+Danyelleac@users.noreply.github.com> --- .changeset/fresh-gifts-smile.md | 5 +++++ .../techdocs-module-addons-contrib/src/TextSize/TextSize.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/fresh-gifts-smile.md diff --git a/.changeset/fresh-gifts-smile.md b/.changeset/fresh-gifts-smile.md new file mode 100644 index 0000000000..bde5edc4b1 --- /dev/null +++ b/.changeset/fresh-gifts-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': major +--- + +textsize-fix value label text color diff --git a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.tsx b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.tsx index 50cc59b814..167f9c7c7c 100644 --- a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.tsx +++ b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.tsx @@ -70,7 +70,7 @@ const StyledSlider = withStyles(theme => ({ left: '50%', transform: 'scale(1) translate(-50%, -5px) !important', '& *': { - color: theme.palette.common.black, + color: theme.palette.textSubtle, fontSize: theme.typography.caption.fontSize, background: 'transparent', }, From d00c36df6d0b712a1dd0de5bb173908745eb105b Mon Sep 17 00:00:00 2001 From: Danyelle AC <90638175+Danyelleac@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:40:50 -0300 Subject: [PATCH 04/52] Update .changeset/fresh-gifts-smile.md Co-authored-by: Patrik Oldsberg Signed-off-by: Danyelle AC <90638175+Danyelleac@users.noreply.github.com> --- .changeset/fresh-gifts-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fresh-gifts-smile.md b/.changeset/fresh-gifts-smile.md index bde5edc4b1..ffa680bb8e 100644 --- a/.changeset/fresh-gifts-smile.md +++ b/.changeset/fresh-gifts-smile.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-techdocs-module-addons-contrib': major +'@backstage/plugin-techdocs-module-addons-contrib': patch --- textsize-fix value label text color From 9a43c63662a2082c188c4677d0c533f21c44f729 Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:49:27 +0000 Subject: [PATCH 05/52] Update .changeset/spotty-kids-pay.md Co-authored-by: Patrik Oldsberg Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- .changeset/spotty-kids-pay.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spotty-kids-pay.md b/.changeset/spotty-kids-pay.md index 199d0fdff0..157515201d 100644 --- a/.changeset/spotty-kids-pay.md +++ b/.changeset/spotty-kids-pay.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-auth-backend': minor +'@backstage/plugin-auth-backend': patch --- Ability for user to configure backstage token expiration From 442206eaae5cb2ba0880121a0e38cbb82c56a4a6 Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:50:22 +0000 Subject: [PATCH 06/52] Update plugins/auth-backend/README.md Co-authored-by: Patrik Oldsberg Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- plugins/auth-backend/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index 3133266614..290745454e 100644 --- a/plugins/auth-backend/README.md +++ b/plugins/auth-backend/README.md @@ -168,7 +168,9 @@ To try out SAML, you can use the mock identity provider: ## Configuring Token Expiration in App Config -If you need to change Backstage token expiration from the default value of one hour, set the following in your config file: +If you need to change Backstage token expiration from the default value of one hour you can do so through configuration. Note that this is **not** the session duration, but rather the duration that the short-term cryptographic tokens are valid for. The expiration can not be set lower than 10 minutes or above 24 hours. + +This is what the configuration looks like: ``` auth: From 0abf05967d1a0304e769c8adff71de0e38d0fcc6 Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:51:39 +0000 Subject: [PATCH 07/52] Update router.ts with suggested change Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- plugins/auth-backend/src/service/router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index eea858dd9c..e04053c478 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -262,7 +262,7 @@ export function getDefaultBackstageTokenExpiryTime(config: Config) { key: processingIntervalKey, }); const seconds = Math.max( - 600, + 86400, Math.round(durationToMilliseconds(duration) / 1000), ); From cf9b58c3405b942b3b8e692f58b57db4c6e740ef Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:52:42 +0000 Subject: [PATCH 08/52] Update router.test.ts as per the changes in router.ts Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- plugins/auth-backend/src/service/router.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/src/service/router.test.ts b/plugins/auth-backend/src/service/router.test.ts index fd339e349e..6c0b060fdb 100644 --- a/plugins/auth-backend/src/service/router.test.ts +++ b/plugins/auth-backend/src/service/router.test.ts @@ -78,6 +78,6 @@ describe('Test for default backstage token expiry time', () => { backstageTokenExpiration: { minutes: 120 }, }, }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe(7200); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe(86400); }); }); From 233045d964c0dfb4aa4088bf2b6a9a924fdc30f8 Mon Sep 17 00:00:00 2001 From: secustor Date: Tue, 23 Jan 2024 22:12:55 +0100 Subject: [PATCH 09/52] chore(Renovate): add schema for intellisense in editors Signed-off-by: secustor --- .github/renovate.json5 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index b58c0beb05..69059b70c8 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,4 +1,6 @@ { + $schema: "https://docs.renovatebot.com/renovate-schema.json", + labels: ['dependencies'], extends: ['config:base', ':disableDependencyDashboard', ':gitSignOff'], postUpdateOptions: ['yarnDedupeHighest'], From c2dcfe4b261d944c06f8bd91a40ac9eb510016d4 Mon Sep 17 00:00:00 2001 From: secustor Date: Tue, 23 Jan 2024 22:15:20 +0100 Subject: [PATCH 10/52] chore(Renovate): use config:recommended to get community groupings and workarounds, as well dependency dashboard Signed-off-by: secustor --- .github/renovate.json5 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 69059b70c8..8071169950 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -2,7 +2,8 @@ $schema: "https://docs.renovatebot.com/renovate-schema.json", labels: ['dependencies'], - extends: ['config:base', ':disableDependencyDashboard', ':gitSignOff'], + extends: ['config:recommended', ':gitSignOff'], + postUpdateOptions: ['yarnDedupeHighest'], rangeStrategy: 'update-lockfile', // @elastic/elasticsearch is ignored due to licensing issues. See #10992 From ac08102c8f17afce2b1f838773f7c0f6a87e7f82 Mon Sep 17 00:00:00 2001 From: secustor Date: Tue, 23 Jan 2024 22:22:37 +0100 Subject: [PATCH 11/52] chore(Renovate): double concurrent PR limit to 20 Signed-off-by: secustor --- .github/renovate.json5 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 8071169950..a217e7a98d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -4,6 +4,9 @@ labels: ['dependencies'], extends: ['config:recommended', ':gitSignOff'], + // the default limit are 10 PRs + prConcurrentLimit: 20, + postUpdateOptions: ['yarnDedupeHighest'], rangeStrategy: 'update-lockfile', // @elastic/elasticsearch is ignored due to licensing issues. See #10992 From 0c120f4cd20e3f1e4d7b07503fcd815fc1352a9e Mon Sep 17 00:00:00 2001 From: secustor Date: Tue, 23 Jan 2024 22:30:56 +0100 Subject: [PATCH 12/52] chore(Renovate): use-bestpractices like pinning docker images Signed-off-by: secustor --- .github/renovate.json5 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a217e7a98d..32e46ead4a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -2,7 +2,10 @@ $schema: "https://docs.renovatebot.com/renovate-schema.json", labels: ['dependencies'], - extends: ['config:recommended', ':gitSignOff'], + + extends: ['config:best-practices', ':gitSignOff'], + // do not pin dev dependencies, which are part of the best-practices preset + ignorePresets: [':pinDevDependencies'], // the default limit are 10 PRs prConcurrentLimit: 20, From d7665705019f4a00356f8fe46fca8ec08656aa9e Mon Sep 17 00:00:00 2001 From: secustor Date: Wed, 24 Jan 2024 09:54:24 +0100 Subject: [PATCH 13/52] prettier Signed-off-by: secustor --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 32e46ead4a..828e5f5481 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,5 +1,5 @@ { - $schema: "https://docs.renovatebot.com/renovate-schema.json", + $schema: 'https://docs.renovatebot.com/renovate-schema.json', labels: ['dependencies'], From 5c05f8ac0f3263fbd8537739f7faa7032f9fb4dd Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Wed, 24 Jan 2024 12:27:11 +0200 Subject: [PATCH 14/52] feat: harmonize the package naming with cli Custom scopes should be named as `backstage-plugin-` while backstage scoped ones shoul be named just `plugin-`. Also allow custom prefix after the scope for example `custom/myapp.` to be used as scope. Signed-off-by: Heikki Hellgren --- .changeset/spotty-jokes-unite.md | 5 ++ .../src/lib/new/factories/backendModule.ts | 11 ++- .../src/lib/new/factories/backendPlugin.ts | 11 ++- .../src/lib/new/factories/common/util.test.ts | 78 +++++++++++++++++++ .../cli/src/lib/new/factories/common/util.ts | 38 +++++++++ .../lib/new/factories/frontendPlugin.test.ts | 4 +- .../src/lib/new/factories/frontendPlugin.ts | 11 ++- .../lib/new/factories/nodeLibraryPackage.ts | 9 ++- .../cli/src/lib/new/factories/pluginCommon.ts | 11 ++- .../cli/src/lib/new/factories/pluginNode.ts | 11 ++- .../cli/src/lib/new/factories/pluginWeb.ts | 11 ++- .../src/lib/new/factories/scaffolderModule.ts | 16 ++-- .../lib/new/factories/webLibraryPackage.ts | 9 ++- 13 files changed, 186 insertions(+), 39 deletions(-) create mode 100644 .changeset/spotty-jokes-unite.md create mode 100644 packages/cli/src/lib/new/factories/common/util.test.ts create mode 100644 packages/cli/src/lib/new/factories/common/util.ts diff --git a/.changeset/spotty-jokes-unite.md b/.changeset/spotty-jokes-unite.md new file mode 100644 index 0000000000..15097e42d0 --- /dev/null +++ b/.changeset/spotty-jokes-unite.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Harmonize the package naming and allow custom prefix diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index 221adcb1f3..1450e7b6ce 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -19,7 +19,7 @@ import chalk from 'chalk'; import camelCase from 'lodash/camelCase'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { addPackageDependency, Task } from '../../tasks'; import { moduleIdIdPrompt, @@ -27,6 +27,7 @@ import { pluginIdPrompt, } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -45,9 +46,11 @@ export const backendModule = createFactory({ async create(options: Options, ctx: CreateContext) { const { id: pluginId, moduleId } = options; const dirName = `${pluginId}-backend-module-${moduleId}`; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${dirName}` - : `backstage-plugin-${dirName}`; + const name = resolvePackageName({ + baseName: dirName, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating backend module ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index c5c9b5bd0e..09ea98fbe7 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -19,10 +19,11 @@ import chalk from 'chalk'; import camelCase from 'lodash/camelCase'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { addPackageDependency, Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -40,9 +41,11 @@ export const backendPlugin = createFactory({ async create(options: Options, ctx: CreateContext) { const { id } = options; const pluginId = `${id}-backend`; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${pluginId}` - : `backstage-plugin-${pluginId}`; + const name = resolvePackageName({ + baseName: pluginId, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating backend plugin ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/common/util.test.ts b/packages/cli/src/lib/new/factories/common/util.test.ts new file mode 100644 index 0000000000..6f168d8035 --- /dev/null +++ b/packages/cli/src/lib/new/factories/common/util.test.ts @@ -0,0 +1,78 @@ +/* + * 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 { resolvePackageName } from './util'; + +describe('resolvePackageName', () => { + it('should generate correct name without scope', () => { + expect(resolvePackageName({ baseName: 'test', plugin: true })).toEqual( + 'backstage-plugin-test', + ); + expect(resolvePackageName({ baseName: 'test', plugin: false })).toEqual( + 'test', + ); + }); + + it('should generate correct name for backstage scope', () => { + expect( + resolvePackageName({ + baseName: 'test', + scope: 'backstage', + plugin: true, + }), + ).toEqual('@backstage/plugin-test'); + expect( + resolvePackageName({ + baseName: 'test', + scope: 'backstage', + plugin: false, + }), + ).toEqual('@backstage/test'); + }); + + it('should generate correct name for custom scope', () => { + expect( + resolvePackageName({ + baseName: 'test', + scope: 'custom', + plugin: true, + }), + ).toEqual('@custom/backstage-plugin-test'); + expect( + resolvePackageName({ + baseName: 'test', + scope: 'custom', + plugin: false, + }), + ).toEqual('@custom/test'); + }); + + it('should generate correct name for custom scope and custom prefix', () => { + expect( + resolvePackageName({ + baseName: 'test', + scope: 'custom/myapp.', + plugin: true, + }), + ).toEqual('@custom/myapp.backstage-plugin-test'); + expect( + resolvePackageName({ + baseName: 'test', + scope: 'custom/myapp.', + plugin: false, + }), + ).toEqual('@custom/myapp.test'); + }); +}); diff --git a/packages/cli/src/lib/new/factories/common/util.ts b/packages/cli/src/lib/new/factories/common/util.ts new file mode 100644 index 0000000000..d9c6970afd --- /dev/null +++ b/packages/cli/src/lib/new/factories/common/util.ts @@ -0,0 +1,38 @@ +/* + * 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 const resolvePackageName = (options: { + baseName: string; + scope?: string; + plugin: boolean; +}) => { + const { baseName, scope, plugin } = options; + if (scope) { + if (plugin) { + const pluginName = scope.startsWith('backstage') + ? 'plugin' + : 'backstage-plugin'; + return scope.includes('/') + ? `@${scope}${pluginName}-${baseName}` + : `@${scope}/${pluginName}-${baseName}`; + } + return scope.includes('/') + ? `@${scope}${baseName}` + : `@${scope}/${baseName}`; + } + + return plugin ? `backstage-plugin-${baseName}` : baseName; +}; diff --git a/packages/cli/src/lib/new/factories/frontendPlugin.test.ts b/packages/cli/src/lib/new/factories/frontendPlugin.test.ts index 94d4a7eb4c..cca79dea2a 100644 --- a/packages/cli/src/lib/new/factories/frontendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/frontendPlugin.test.ts @@ -180,7 +180,7 @@ const router = ( fs.readJson(mockDir.resolve('packages/app/package.json')), ).resolves.toEqual({ dependencies: { - '@internal/plugin-test': '^1.0.0', + '@internal/backstage-plugin-test': '^1.0.0', }, }); @@ -188,7 +188,7 @@ const router = ( fs.readFile(mockDir.resolve('packages/app/src/App.tsx'), 'utf8'), ).resolves.toBe(` import { createApp } from '@backstage/app-defaults'; -import { TestPage } from '@internal/plugin-test'; +import { TestPage } from '@internal/backstage-plugin-test'; const router = ( diff --git a/packages/cli/src/lib/new/factories/frontendPlugin.ts b/packages/cli/src/lib/new/factories/frontendPlugin.ts index d0e81207ca..1058c879c1 100644 --- a/packages/cli/src/lib/new/factories/frontendPlugin.ts +++ b/packages/cli/src/lib/new/factories/frontendPlugin.ts @@ -20,10 +20,11 @@ import camelCase from 'lodash/camelCase'; import upperFirst from 'lodash/upperFirst'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { addPackageDependency, Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -41,9 +42,11 @@ export const frontendPlugin = createFactory({ async create(options: Options, ctx: CreateContext) { const { id } = options; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${id}` - : `backstage-plugin-${id}`; + const name = resolvePackageName({ + baseName: id, + scope: ctx.scope, + plugin: true, + }); const extensionName = `${upperFirst(camelCase(id))}Page`; Task.log(); diff --git a/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts b/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts index 4b1fda4abc..3fae1242a2 100644 --- a/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts +++ b/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -37,7 +38,11 @@ export const nodeLibraryPackage = createFactory({ optionsPrompts: [pluginIdPrompt(), ownerPrompt()], async create(options: Options, ctx: CreateContext) { const { id } = options; - const name = ctx.scope ? `@${ctx.scope}/${id}` : `${id}`; + const name = resolvePackageName({ + baseName: id, + scope: ctx.scope, + plugin: false, + }); Task.log(); Task.log(`Creating node-library package ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/pluginCommon.ts b/packages/cli/src/lib/new/factories/pluginCommon.ts index 1bcca2fb6a..560386c618 100644 --- a/packages/cli/src/lib/new/factories/pluginCommon.ts +++ b/packages/cli/src/lib/new/factories/pluginCommon.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -38,9 +39,11 @@ export const pluginCommon = createFactory({ async create(options: Options, ctx: CreateContext) { const { id } = options; const suffix = `${id}-common`; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${suffix}` - : `backstage-plugin-${suffix}`; + const name = resolvePackageName({ + baseName: suffix, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating backend plugin ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/pluginNode.ts b/packages/cli/src/lib/new/factories/pluginNode.ts index 44dbea9fce..c7f9ba6f6a 100644 --- a/packages/cli/src/lib/new/factories/pluginNode.ts +++ b/packages/cli/src/lib/new/factories/pluginNode.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -38,9 +39,11 @@ export const pluginNode = createFactory({ async create(options: Options, ctx: CreateContext) { const { id } = options; const suffix = `${id}-node`; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${suffix}` - : `backstage-plugin-${suffix}`; + const name = resolvePackageName({ + baseName: suffix, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating Node.js plugin library ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/pluginWeb.ts b/packages/cli/src/lib/new/factories/pluginWeb.ts index 8189654eb2..dc8cb73dce 100644 --- a/packages/cli/src/lib/new/factories/pluginWeb.ts +++ b/packages/cli/src/lib/new/factories/pluginWeb.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -38,9 +39,11 @@ export const pluginWeb = createFactory({ async create(options: Options, ctx: CreateContext) { const { id } = options; const suffix = `${id}-react`; - const name = ctx.scope - ? `@${ctx.scope}/plugin-${suffix}` - : `backstage-plugin-${suffix}`; + const name = resolvePackageName({ + baseName: suffix, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating web plugin library ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.ts b/packages/cli/src/lib/new/factories/scaffolderModule.ts index b89f0fc691..07f67ce78c 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -55,14 +56,11 @@ export const scaffolderModule = createFactory({ const { id } = options; const slug = `scaffolder-backend-module-${id}`; - let name = `backstage-plugin-${slug}`; - if (ctx.scope) { - if (ctx.scope === 'backstage') { - name = `@backstage/plugin-${slug}`; - } else { - name = `@${ctx.scope}/backstage-plugin-${slug}`; - } - } + const name = resolvePackageName({ + baseName: slug, + scope: ctx.scope, + plugin: true, + }); Task.log(); Task.log(`Creating module ${chalk.cyan(name)}`); diff --git a/packages/cli/src/lib/new/factories/webLibraryPackage.ts b/packages/cli/src/lib/new/factories/webLibraryPackage.ts index a160220cab..8f4488926d 100644 --- a/packages/cli/src/lib/new/factories/webLibraryPackage.ts +++ b/packages/cli/src/lib/new/factories/webLibraryPackage.ts @@ -17,10 +17,11 @@ import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; -import { createFactory, CreateContext } from '../types'; +import { CreateContext, createFactory } from '../types'; import { Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; +import { resolvePackageName } from './common/util'; type Options = { id: string; @@ -37,7 +38,11 @@ export const webLibraryPackage = createFactory({ optionsPrompts: [pluginIdPrompt(), ownerPrompt()], async create(options: Options, ctx: CreateContext) { const { id } = options; - const name = ctx.scope ? `@${ctx.scope}/${id}` : `${id}`; + const name = resolvePackageName({ + baseName: id, + scope: ctx.scope, + plugin: false, + }); Task.log(); Task.log(`Creating web-library package ${chalk.cyan(name)}`); From 2e440d4723dd2f6a5553c12eb53512fa2aa00656 Mon Sep 17 00:00:00 2001 From: Aramis Date: Thu, 25 Jan 2024 23:42:14 -0500 Subject: [PATCH 15/52] docs: add a central glossary Signed-off-by: Aramis --- docs/auth/glossary.md | 30 -- docs/local-dev/cli-build-system.md | 13 +- docs/local-dev/cli-overview.md | 20 +- docs/overview/glossary.md | 26 -- docs/permissions/concepts.md | 14 +- docs/permissions/custom-rules.md | 2 +- .../02-adding-a-basic-permission-check.md | 4 +- .../03-adding-a-resource-permission-check.md | 2 +- docs/references/glossary.md | 310 ++++++++++++++++++ microsite/docusaurus.config.js | 8 + microsite/sidebars.json | 9 +- 11 files changed, 341 insertions(+), 97 deletions(-) delete mode 100644 docs/auth/glossary.md delete mode 100644 docs/overview/glossary.md create mode 100644 docs/references/glossary.md diff --git a/docs/auth/glossary.md b/docs/auth/glossary.md deleted file mode 100644 index ad7ae78d19..0000000000 --- a/docs/auth/glossary.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: glossary -title: Glossary -description: All Glossaries related to auth ---- - -- **Popup** - A separate browser window opened on top of the previous one. -- **OAuth** - More specifically OAuth 2.0, a standard protocol for - authorization. See [oauth.net/2/](https://oauth.net/2/). -- **OpenID Connect** - A layer on top of OAuth which standardises - authentication. See - [en.wikipedia.org/wiki/OpenID_Connect](https://en.wikipedia.org/wiki/OpenID_Connect). -- **JWT** - JSON Web Token, a popular JSON based token format that is commonly - encrypted and/or signed, see - [en.wikipedia.org/wiki/JSON_Web_Token](https://en.wikipedia.org/wiki/JSON_Web_Token) -- **Scope** - A string that describes a certain type of access that can be - granted to a user using OAuth. -- **Access token** - A token that gives access to perform actions on behalf of a - user. It will commonly have a short expiry time, and be limited to a set of - scopes. Part of the OAuth protocol. -- **ID token** - A JWT used to prove a user's identity, containing for example - the user's email. Part of OpenID Connect. -- **Offline access** - OAuth flow that results in both a refresh and access - token, where the refresh token has a long expiration or never expires, and can - be used to request more access tokens in the future. This lets the user go - "offline" with respect to the token issuer, but still be able to request more - tokens at a later time without further direct interaction for the user. -- **Code grant** - OAuth flow where the client receives an authorization code - that is passed to the backend to be exchanged for an access token and possibly - refresh token. diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index 51c328c871..a95db95f85 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -258,7 +258,7 @@ When building CommonJS or ESM output, the build commands will always use `src/index.ts` as the entrypoint. All non-relative modules imports are considered external, meaning the Rollup build will only compile the source code of the package itself. All import statements of external dependencies, even within the same -monorepo, will stay intact. +[monorepo](../references/glossary.md#monorepo), will stay intact. The build of the type definitions works quite differently. The entrypoint of the type definition build is the relative location of the package within the @@ -307,11 +307,12 @@ support for them instead. ### Frontend Production -The frontend production bundling creates your typical web content bundle, all -contained within a single folder, ready for static serving. It is used when building -packages with the `'frontend'` role, and unlike the development bundling there is no way to -build a production bundle of an individual plugin. The output of the bundling -process is written to the `dist` folder in the package. +The frontend production bundling creates your typical web content +[bundle](../references/glossary.md#bundle), all contained within a single +folder, ready for static serving. It is used when building packages with the +`'frontend'` role, and unlike the development bundling there is no way to +build a production [bundle](../references/glossary.md#bundle) of an individual plugin. +The output of the bundling process is written to the `dist` folder in the package. Just like the development bundling, the production bundling is based on [Webpack](https://webpack.js.org/). It uses the diff --git a/docs/local-dev/cli-overview.md b/docs/local-dev/cli-overview.md index 74c09d2865..4ab8bb21ac 100644 --- a/docs/local-dev/cli-overview.md +++ b/docs/local-dev/cli-overview.md @@ -7,11 +7,12 @@ description: Overview of the Backstage CLI ## Introduction A goal of Backstage is to provide a delightful developer experience in and -around the project. Creating new apps and plugins should be simple, iteration +around the project. Creating new [apps](../references/glossary.md#app) and +[plugins](../references/glossary.md#plugin) should be simple, iteration speed should be fast, and the overhead of maintaining custom tooling should be minimal. As a part of accomplishing this goal, Backstage provides its own build system and tooling, delivered primarily through the -[`@backstage/cli`](https://www.npmjs.com/package/@backstage/cli) package. When +[`@backstage/cli`](https://www.npmjs.com/package/@backstage/cli) [package](../references/glossary.md#package). When creating an app using [`@backstage/create-app`](https://www.npmjs.com/package/@backstage/create-app), you receive a project that's already prepared with a typical setup and package @@ -36,18 +37,3 @@ The Backstage CLI intentionally does not provide many hooks for overriding or customizing the build process. This is to allow for evolution of the CLI without having to take a wide API surface into account. This allows us to iterate and improve the tooling, as well as to more easily keep the system up to date. - -## Glossary - -- **Package** - A package in the Node.js ecosystem, often published to a package - registry such as [NPM](https://www.npmjs.com/). -- **Monorepo** - A project layout that consists of multiple packages within a - single project, where packages are able to have local dependencies on each - other. Often enabled through tooling such as [lerna](https://lerna.js.org/) - and [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) -- **Local Package** - One of the packages within a monorepo. These package may - or may not also be published to a package registry. -- **Bundle** - A collection of the deployment artifacts. The output of the - bundling process, which brings a collection of packages into a single - collection of deployment artifacts. -- **Package Role** - The declared role of a package, see [package roles](./cli-build-system.md#package-roles). diff --git a/docs/overview/glossary.md b/docs/overview/glossary.md deleted file mode 100644 index ab7d224f4d..0000000000 --- a/docs/overview/glossary.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -id: glossary -title: Backstage Glossary -# prettier-ignore -description: List of terms, abbreviations, and phrases used in Backstage, together with their explanations. ---- - -The Backstage Glossary lists terms, abbreviations, and phrases used in -Backstage, together with their explanations. We encourage you to use the -terminology below for clarity and consistency when discussing Backstage. - -See also [Authentication Glossary](../auth/glossary.md), a separate glossary of terms and phrases -specifically related to the authentication and identity section of Backstage. - -### Backstage User Profiles - -There are three main user profiles for Backstage: the integrator, the -contributor, and the end user (typically a software engineer). - -| Term | Explanation | -| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Integrator | The **integrator** hosts the Backstage app and configures which plugins are available to use in the app. | -| Contributor | The **contributor** adds functionality to the app by writing plugins. | -| End user | The **end user** uses the app's functionality and interacts with its plugins. This profile covers the various roles that help deliver software. The typical end user is a **software engineer**, but users might also consider themselves _designers_, _data scientists_, _product owners_, _engineering managers_, _technical writers_, and so on. | -| Software engineer | The **software engineer** is an **end user** who uses the app's functionality and interacts with its plugins in the course of writing and documenting code. This user is more likely to embed documentation in the code files they produce, and create rough drafts of conceptual pages in collaboration with a **technical writer** or _technical editor_. | -| Technical writer | The **technical writer** is an **end user** who uses the app's functionality and interacts with its plugins in the course of writing and editing documentation. This user is more likely to produce and customize templates and produce conceptual pages to supplement documentation embedded in code files. | diff --git a/docs/permissions/concepts.md b/docs/permissions/concepts.md index e7d65b3583..c3c32601df 100644 --- a/docs/permissions/concepts.md +++ b/docs/permissions/concepts.md @@ -4,22 +4,16 @@ title: Concepts description: A list of important permission framework concepts --- -### Permission - -Any action that a user performs within Backstage may be represented as a permission. More complex actions, like executing a software template, may require authorization for multiple permissions throughout the flow. Permissions are identified by a unique name and optionally include a set of attributes that describe the corresponding action. Plugins are responsible for defining and exposing the permissions they enforce. - -### Policy - -User permissions are authorized by a central, user-defined permission policy. At a high level, a policy is a function that receives a Backstage user and permission, and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular authorization model, like role-based access control (RBAC) or attribute-based access control (ABAC). - ### Policy decision versus enforcement Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, policies are responsible for decisions and plugins (typically backends) are responsible for enforcing them. ### Resources and rules -In many cases, a permission represents a user's interaction with another object. This object likely has information that policy authors can use to define more granular access. The permission framework introduces two abstractions to account for this: resources and rules. Resources represent the objects that users interact with. Rules are predicate-based controls that tap into a resource's data. For example, the catalog plugin defines a resource for catalog entities and a rule to check if an entity has a given annotation. +In many cases, a permission represents a user's interaction with another object. This object likely has information that policy authors can use to define more granular access. The permission framework introduces two abstractions to account for this: [resources](../references/glossary.md#permission-resource) and [rules](../references/glossary.md#permission-rule). For example, the catalog plugin defines a resource for catalog entities and a rule to check if an entity has a given annotation. ### Conditional decisions -Rules need additional data before they can be used in a decision. For example, the catalog plugin's "has annotation" rule needs to know what annotation to look for on a given entity. Once a rule is bound to relevant information it forms a condition. Conditions are then used to return a conditional decision from a policy. Conditional decisions tell the permission framework to delegate evaluation to the plugin that owns the corresponding resource. Permission requests that result in a conditional decision are allowed if all of the provided conditions evaluate to be true. This conditional behavior avoids coupling between policies and resource schemas, and allows plugins to evaluate complex rules in an efficient way. For example, a plugin may convert a conditional decision to a database query instead of loading and filtering objects in memory. +See [Conditional decisions](../references/glossary.md#conditional-decisions). + +A good example would be the catalog plugin's "has annotation" rule needs to know what annotation to look for on a given entity. The permission framework would respond to a request by the catalog plugin in this case with a condition decision. The catalog plugin would then need to correctly filter for entities matching the "has annotations" condition. This conditional behavior avoids coupling between policies and resource schemas, and allows plugins to evaluate complex rules in an efficient way. For example, a plugin may convert a conditional decision to a database query instead of loading and filtering objects in memory. diff --git a/docs/permissions/custom-rules.md b/docs/permissions/custom-rules.md index c0f4e3e156..4b38c8986d 100644 --- a/docs/permissions/custom-rules.md +++ b/docs/permissions/custom-rules.md @@ -4,7 +4,7 @@ title: Defining custom permission rules description: How to define custom permission rules for existing resources --- -For some use cases, you may want to define custom [rules](./concepts.md#resources-and-rules) in addition to the ones provided by a plugin. In the [previous section](./writing-a-policy.md) we used the `isEntityOwner` rule to control access for catalog entities. Let's extend this policy with a custom rule that checks what [system](https://backstage.io/docs/features/software-catalog/system-model#system) an entity is part of. +For some use cases, you may want to define custom [rules](../references/glossary.md#permission-rules) in addition to the ones provided by a plugin. In the [previous section](./writing-a-policy.md) we used the `isEntityOwner` rule to control access for catalog entities. Let's extend this policy with a custom rule that checks what [system](https://backstage.io/docs/features/software-catalog/system-model#system) an entity is part of. ## Define a custom rule diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md index 23bc4e84f1..223d55d3d8 100644 --- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md @@ -4,9 +4,9 @@ title: 2. Adding a basic permission check description: Explains how to add a basic permission check to a Backstage plugin --- -If the outcome of a permission check doesn't need to change for different [resources](../concepts.md#resources-and-rules), you can use a _basic permission check_. For this kind of check, we simply need to define a [permission](../concepts.md#resources-and-rules), and call `authorize` with it. +If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary#permission-resource), you can use a _basic permission check_. For this kind of check, we simply need to define a [permission](../../references/glossary.md#permission), and call `authorize` with it. -For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../concepts.md#policy). +For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy). We'll start by creating a new permission, and then we'll use the permission api to call `authorize` with it during todo creation. diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md index a4d51b64d0..3feecc7342 100644 --- a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md +++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md @@ -4,7 +4,7 @@ title: 3. Adding a resource permission check description: Explains how to add a resource permission check to a Backstage plugin --- -When performing updates (or other operations) on specific [resources](../concepts.md#resources-and-rules), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. +When performing updates (or other operations) on specific [resources](../../references/glossary.md#permission-resource), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. ## Creating the update permission diff --git a/docs/references/glossary.md b/docs/references/glossary.md new file mode 100644 index 0000000000..b82b2da064 --- /dev/null +++ b/docs/references/glossary.md @@ -0,0 +1,310 @@ +--- +id: glossary +title: Glossary +# prettier-ignore +description: List of terms, abbreviations, and phrases used in Backstage, together with their explanations. +--- + +## Access token + +A [token](#token) that gives access to perform actions on behalf of a user. It will commonly have a short expiry time, and be limited to a set of [scopes](#scope). Part of the [OAuth](#oauth) protocol. + +https://oauth.net/2/access-tokens/ + +## Administrator + +Someone responsible for installing and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). + +## API + +In the Backstage [Catalog](#catalog), an API is an [entity](#entity) representing a boundary between two [components](#component). + +https://backstage.io/docs/features/software-catalog/system-model + +## App + +An installed instance of Backstage. An app can be local, intended for a single development group or individual developer, or organizational, for use by an entire enterprise. + +## Authorization Code + +A type of [OAuth flow](#oauth) used by confidential and public clients to get an [access token](#access-token). + +https://oauth.net/2/grant-types/authorization-code/ + +## Backstage + +A platform for creating and deploying [developer portals](#developer-portal), originally created at Spotify. + +Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). + +## Bundle + +A collection of [deployment artifacts](#deployment-artifacts). + +Can also be: The output of the bundling process, which brings a collection of [packages](#package) into a single collection of [deployment artifacts](#deployment-artifacts). + +## Catalog + +An organization's portfolio of software products managed in Backstage. + +## Cloud Native Computing + +A set of technologies that "empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach." ([CNCF Cloud Native Definition v1.0](https://github.com/cncf/toc/blob/main/DEFINITION.md)). + +## Cloud Native Computing Foundation + +A foundation dedicated to the promotion and advancement of [Cloud Native Computing](#Cloud-Native-Computing). The mission of the Cloud Native Computing Foundation (CNCF) is "to make cloud native computing ubiquitous" ([CNCF Charter](https://github.com/cncf/foundation/blob/main/charter.md)). + +CNCF is part of the [Linux Foundation](https://www.linuxfoundation.org/). + +## CNCF + +Cloud Native Computing Foundation. + +## Code Grant + +[OAuth](#oauth) flow where the client receives an [authorization code](#code) that is passed to the backend to be exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token). + +## Collators + +Collators transform streams of [documents](#documents) into searchable texts. They're usually responsible for the data transformation and definition and collection process for specific [documents](#documents). Part of [Backstage Search](#search). + +## Component + +A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. + +https://backstage.io/docs/features/software-catalog/system-model + +## Condition + +Conditions are used to return a conditional decision from a policy. They contain information about a given entity and restrictions on what types of users can view that entity. + +## Conditional decisions + +[Rules](#permission-rules) need additional data before they can be used in a decision. Once a [rule](#permission-rule) is bound to relevant information it forms a [condition](#condition). Conditional decisions tell the [permission framework](#permission) to delegate evaluation to the [plugin](#plugin) that owns the corresponding [resource](#permission-resource). Permission requests that result in a conditional decision are allowed if all of the provided conditions evaluate to be true. + +## Contributor + +A volunteer who helps to improve an OSS product such as Backstage. This volunteer effort includes coding, testing, technical writing, user support, and other work. A [user role](#user-role). + +## Decorators + +A transform stream. Decorators allow you to add additional information to documents outside of the [collator](#collators). They sit between the [collators](#collators) and the [indexers](#indexer) and can add extra fields to documents as they're being collated and indexed. + +Possible use cases for a decorator could be to bias search results or otherwise improve the search experience in your Backstage instance. Decorators can also be used to remove [metadata](#metadata), filter out, or even add extra documents at index-time. Part of [Backstage Search](#search). + +## Deployment Artifacts + +An executable or package file with all of the necessary information required to deploy the application at runtime. Deployment artifacts can be hosted on [package registries](#package-registry). + +## Developer + +Someone who writes code and develops software. + +A [user role](#user-role) defined as someone who uses a Backstage [app](#app). Might or might not actually be a software developer. + +## Developer Portal + +A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a platform for creating developer portals. + +## Documents + +An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). Part of [Backstage Search](#search). + +## Domain + +In the Backstage Catalog, a domain is an area that relates systems or entities to a business unit. + +https://backstage.io/docs/features/software-catalog/system-model + +## Entity + +What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. + +## Evaluator + +Someone who assesses whether Backstage is a suitable solution for their organization. The only [user role](#user-role) with a pre-deployment [use case](#use-case). + +## ID Token + +A [JWT](#jwt) used to prove a user's identity, containing for example the user's email. Part of [OpenID Connect](#openid-connect). + +## Index + +An index is a collection of [documents](#documents) of a given type. Part of [Backstage Search](#search). + +## Indexer + +A write stream of [documents](#documents). Part of [Backstage Search](#search). + +## Integrator + +Someone who develops one or more plugins that enable Backstage to interoperate with another software system. A [user role](#user-role). + +## JWT + +JSON Web Token. + +A popular JSON based token format that is commonly encrypted and/or signed, see [en.wikipedia.org/wiki/JSON_Web_Token](https://en.wikipedia.org/wiki/JSON_Web_Token) + +## Kind + +Classification of an [entity](#Entity) in the Backstage Software Catalog, for example _service_, _database_, and _team_. + +## Kubernetes Plugin + +A plugin enabling configuration of Backstage on a Kubernetes cluster. Kubernetes plugin has been promoted to a Backstage core feature. + +## Local Package + +One of the [packages](#package) within a [monorepo](#monorepo). These package may or may not also be published to a [package registry](#package-registry). + +## Monorepo + +A single repository for a collection of related software projects, such as all projects belonging to an organization. + +Can also mean: A project layout that consists of multiple [packages](#package) within a single project, where packages are able to have local dependencies on each other. Often enabled through tooling such as [lerna](https://lerna.js.org/) and [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) + +## Namespace + +In the Backstage Software Catalog, an optional attribute that can be used to organize [entities](#entity). + +## Objective + +A high level goal of a [user role](#User-Role) interacting with Backstage. Some goals of the _administrator_ user role, for example, are to maintain an instance ("app") of Backstage; to add and update functionality via plugins; and to troubleshoot issues. + +## OAuth + +Refers to: OAuth 2.0, a standard protocol for authorization. See [oauth.net/2/](https://oauth.net/2/). + +## Offline Access + +[OAuth](#oauth) flow that results in both a refresh token and [access token](#access-token), where the refresh token has a long expiration or never expires, and can be used to request more access tokens in the future. This lets the user go "offline" with respect to the token issuer, but still be able to request more tokens at a later time without further direct interaction for the user. + +## OpenID Connect + +A layer on top of [OAuth](#oauth) which standardises authentication. See [en.wikipedia.org/wiki/OpenID_Connect](https://en.wikipedia.org/wiki/OpenID_Connect). + +## OSS + +Open source software. + +## Package + +A package in the Node.js ecosystem, often published to a [package registry](#package-registry). + +## Package Registry + +A service that hosts packages. The most prominent example is [NPM](https://www.npmjs.com/). + +## Package Role + +The declared role of a package, see [package roles](../local-dev/cli-build-system.md#package-roles). + +## Permission + +A core Backstage plugin and framework that allows restriction of actions to specific users. + +Any action that a user performs within Backstage may be represented as a permission. More complex actions, like executing a [software template](#software-templates), may require [authorization](#authorization) for multiple permissions throughout the flow. Permissions are identified by a unique name and optionally include a set of attributes that describe the corresponding action. [Plugins](#plugin) are responsible for defining and exposing the permissions they enforce as well as enforcing restrictions from the permission framework. + +https://backstage.io/docs/permissions/overview + +## Permission Resource + +Not to be confused with [Software Catalog resources](#resource). Permission resources represent the objects that users interact with and that can be permissioned. + +## Permission Rule + +Rules are predicate-based controls that tap into a [resource](#permission-resource)'s data. + +## Persona + +Alternative term for a [User Role](#user-role). + +## Plugin + +A module in Backstage that adds a feature. All functionality in Backstage, even the core features, are implemented as plugins. + +## Policy + +User [permissions](#permission) are authorized by a central, user-defined [permission](#permission) policy. At a high level, a policy is a function that receives a Backstage user and [permission](#permission), and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular [authorization](#authorization) model, like role-based access control (RBAC) or attribute-based access control (ABAC). + +## Policy decision + +Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, policies are responsible for decisions and plugins (typically backends) are responsible for enforcing them. + +## Popup + +A separate browser window opened on top of the previous one. + +## Procedure + +A set of actions that accomplish a goal, usually as part of a [use case](#Use-Case). A procedure can be high-level, containing other procedures, or can be as simple as a single [task](#Task). + +## Query Translators + +An abstraction layer between a search engine and the [Backstage Search](#search) backend. Allows for translation into queries against your search engine. Part of [Backstage Search](#search). + +## Refresh Token + +A string that an [OAuth](#oauth) client can use to get a new access token. + +https://oauth.net/2/refresh-tokens/ + +## Resource + +In the Backstage Catalog, an [entity](#entity) that represents a piece of physical or virtual infrastructure, for example a database, required by a component. + +https://backstage.io/docs/features/software-catalog/system-model + +## Role + +See [User Role](#User-Role). + +## Scope + +A string that describes a certain type of access that can be granted to a user using OAuth. + +## Search + +A Backstage plugin that provides a framework for searching a Backstage [app](#app), including the [Software Catalog](#Software-Catalog) and [TechDocs](#TechDocs). A core feature of Backstage. + +## Search Engines + +Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in [Backstage Search](#search). Part of [Backstage Search](#search). + +## Software Catalog + +A Backstage plugin that provides a framework to keep track of ownership and metadata for any number and type of software [components](#component). A core feature of Backstage. + +## Software Templates + +A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. + +Can also refer to: A "skeleton" software project created and managed in the Backstage Software Templates tool. + +## System + +In the Backspace Catalog, a system is a collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources and private APIs. + +https://backstage.io/docs/features/software-catalog/system-model + +## Task + +A low-level step-by-step [Procedure](#Procedure). + +## TechDocs + +A documentation solution that manages and generates a technical documentation from Markdown files stored with software component code. A core feature of Backstage. + +## Token + +A string containing information. + +## Use Case + +A purpose for which a [user role](#User-Role) interacts with Backstage. Related to [Objective](#objective): An objective is _what_ the user wants to do; a use case is _how_ the user does it. + +## User Role + +A class of Backspace user for purposes of analyzing [use cases](#use-case). One of: evaluator; administrator; developer; integrator; and contributor. diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index df2833b3e2..88fed74ac2 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -144,6 +144,14 @@ module.exports = { from: '/docs/features/software-templates/testing-scaffolder-alpha', to: '/docs/features/software-templates/migrating-to-rjsf-v5', }, + { + from: '/docs/auth/glossary', + to: '/docs/references/glossary' + }, + { + from: '/docs/overview/glossary', + to: '/docs/references/glossary' + } ], }, ], diff --git a/microsite/sidebars.json b/microsite/sidebars.json index e32e027807..1c151159db 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -37,7 +37,6 @@ "overview/versioning-policy", "overview/threat-model", "overview/support", - "overview/glossary", "overview/logos" ], "Getting Started": [ @@ -318,8 +317,7 @@ "auth/add-auth-provider", "auth/service-to-service-auth", "auth/autologout", - "auth/troubleshooting", - "auth/glossary" + "auth/troubleshooting" ], "Permissions": [ "permissions/overview", @@ -479,6 +477,9 @@ "architecture-decisions/adrs-adr013" ], "FAQ": ["faq/index", "faq/product", "faq/technical"], - "Accessibility": ["accessibility/index"] + "Accessibility": ["accessibility/index"], + "References": [ + "references/glossary" + ] } } From a560bfd7a3f7900c9f6534aa33a7b68c0f76f5ca Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 26 Jan 2024 10:39:36 -0500 Subject: [PATCH 16/52] fix missing extension Signed-off-by: Aramis --- .../plugin-authors/02-adding-a-basic-permission-check.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md index 223d55d3d8..0ef50670ef 100644 --- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md @@ -4,7 +4,7 @@ title: 2. Adding a basic permission check description: Explains how to add a basic permission check to a Backstage plugin --- -If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary#permission-resource), you can use a _basic permission check_. For this kind of check, we simply need to define a [permission](../../references/glossary.md#permission), and call `authorize` with it. +If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary.md#permission-resource), you can use a _basic permission check_. For this kind of check, we simply need to define a [permission](../../references/glossary.md#permission), and call `authorize` with it. For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy). From ecab5c032c5f0d2b3e4223065cca19bf4796e71a Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 26 Jan 2024 10:40:45 -0500 Subject: [PATCH 17/52] update mkdocs file Signed-off-by: Aramis --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 8c9f84ba81..2a17613672 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -18,7 +18,6 @@ nav: - Release & Versioning Policy: 'overview/versioning-policy.md' - Backstage Threat Model: 'overview/threat-model.md' - Support and community: 'overview/support.md' - - Glossary: 'overview/glossary.md' - Logo assets: 'overview/logos.md' - Getting Started: - Getting Started: 'getting-started/index.md' @@ -171,7 +170,6 @@ nav: - Contributing New Providers: 'auth/add-auth-provider.md' - Service to Service Auth: 'auth/service-to-service-auth.md' - Troubleshooting Auth: 'auth/troubleshooting.md' - - Glossary: 'auth/glossary.md' - Deployment: - Deploying Backstage: 'deployment/index.md' - Scaling: 'deployment/scaling.md' @@ -218,3 +216,5 @@ nav: - Overview: 'faq/index.md' - Product FAQ: 'faq/product.md' - Technical FAQ: 'faq/technical.md' + - References: + - Glossary: 'references/glossary.md' From 23f073ff1459b77c859ab5e745b70ac359a228d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:21:03 +0000 Subject: [PATCH 18/52] chore(deps): update dependency @types/express-serve-static-core to v4.17.42 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 5a15adff92..ada693c4a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17995,14 +17995,14 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.17.41 - resolution: "@types/express-serve-static-core@npm:4.17.41" + version: 4.17.42 + resolution: "@types/express-serve-static-core@npm:4.17.42" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 12750f6511dd870bbaccfb8208ad1e79361cf197b147f62a3bedc19ec642f3a0f9926ace96705f4bc88ec2ae56f61f7ca8c2438e6b22f5540842b5569c28a121 + checksum: 58273f80fcc94de42691f48e22542e69f0b17863378e3216ce8b782ace012f32241bfeb02a2be837f0e2b4ef96e916979adc30bbfea13f6545bd3ab81b7d2773 languageName: node linkType: hard From 8316e3407ff78b29ebb41480d9e851118633a646 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:44:52 +0000 Subject: [PATCH 19/52] chore(deps): update dependency @types/tar to v6.1.11 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 5a15adff92..105be68e30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19151,12 +19151,12 @@ __metadata: linkType: hard "@types/tar@npm:^6.1.1": - version: 6.1.10 - resolution: "@types/tar@npm:6.1.10" + version: 6.1.11 + resolution: "@types/tar@npm:6.1.11" dependencies: "@types/node": "*" minipass: ^4.0.0 - checksum: 82d46f1246e830b98833ed94fbdfbcb3ffb8a5d7173609622d56c9326124523a3cc541607876c63a6ab9117eb59fb37ef8a6284b194164ab1d1d8c03a8ba59c6 + checksum: 9b79f61f9179db65ecd3f5e9c0d2152839ad13381d39c38c3a9408aa1f3a2b061ba195e7d758be1863294a0ce69df6659f0e3e09f440c9f5309bded58bc87c89 languageName: node linkType: hard From fe069efbe693cdc092d5d5b1729f7fe3b5c83796 Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 26 Jan 2024 11:49:19 -0500 Subject: [PATCH 20/52] fix prettier Signed-off-by: Aramis --- microsite/docusaurus.config.js | 6 +++--- microsite/sidebars.json | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index 88fed74ac2..a49fca85c7 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -146,12 +146,12 @@ module.exports = { }, { from: '/docs/auth/glossary', - to: '/docs/references/glossary' + to: '/docs/references/glossary', }, { from: '/docs/overview/glossary', - to: '/docs/references/glossary' - } + to: '/docs/references/glossary', + }, ], }, ], diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 1c151159db..9bbc42dbfc 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -478,8 +478,6 @@ ], "FAQ": ["faq/index", "faq/product", "faq/technical"], "Accessibility": ["accessibility/index"], - "References": [ - "references/glossary" - ] + "References": ["references/glossary"] } } From c1b29586737b82f53931360632c0168b62253558 Mon Sep 17 00:00:00 2001 From: Mahendra <42772952+mahendra1290@users.noreply.github.com> Date: Sun, 28 Jan 2024 15:12:56 +0530 Subject: [PATCH 21/52] Update migrate-to-mui5.md update key from `provider` to `Provider` Signed-off-by: Mahendra <42772952+mahendra1290@users.noreply.github.com> --- docs/tutorials/migrate-to-mui5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/migrate-to-mui5.md b/docs/tutorials/migrate-to-mui5.md index aaf8cff7f5..c65abbc680 100644 --- a/docs/tutorials/migrate-to-mui5.md +++ b/docs/tutorials/migrate-to-mui5.md @@ -19,7 +19,7 @@ By default, the `UnifiedThemeProvider` is already used. If you add a custom them themes: [ { // ... - provider: ({ children }) => ( + Provider: ({ children }) => ( - . - {children}. - Date: Mon, 29 Jan 2024 14:34:41 -0500 Subject: [PATCH 22/52] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Aramis Sennyey <34432188+sennyeya@users.noreply.github.com> --- docs/permissions/concepts.md | 2 +- docs/references/glossary.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/permissions/concepts.md b/docs/permissions/concepts.md index c3c32601df..556d752c52 100644 --- a/docs/permissions/concepts.md +++ b/docs/permissions/concepts.md @@ -16,4 +16,4 @@ In many cases, a permission represents a user's interaction with another object. See [Conditional decisions](../references/glossary.md#conditional-decisions). -A good example would be the catalog plugin's "has annotation" rule needs to know what annotation to look for on a given entity. The permission framework would respond to a request by the catalog plugin in this case with a condition decision. The catalog plugin would then need to correctly filter for entities matching the "has annotations" condition. This conditional behavior avoids coupling between policies and resource schemas, and allows plugins to evaluate complex rules in an efficient way. For example, a plugin may convert a conditional decision to a database query instead of loading and filtering objects in memory. +A good example would be the catalog plugin's "has annotation" rule which needs to know what annotation to look for on a given entity. The permission framework would respond to a request by the catalog plugin in this case with a condition decision. The catalog plugin would then need to correctly filter for entities matching the "has annotations" condition. This conditional behavior avoids coupling between policies and resource schemas, and allows plugins to evaluate complex rules in an efficient way. For example, a plugin may convert a conditional decision to a database query instead of loading and filtering objects in memory. diff --git a/docs/references/glossary.md b/docs/references/glossary.md index b82b2da064..abbb8ce5ef 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -183,7 +183,7 @@ Refers to: OAuth 2.0, a standard protocol for authorization. See [oauth.net/2/]( ## OpenID Connect -A layer on top of [OAuth](#oauth) which standardises authentication. See [en.wikipedia.org/wiki/OpenID_Connect](https://en.wikipedia.org/wiki/OpenID_Connect). +A layer on top of [OAuth](#oauth) which standardises authentication. See [the Wikipedia article](https://en.wikipedia.org/wiki/OpenID_Connect) for more details. ## OSS @@ -195,7 +195,7 @@ A package in the Node.js ecosystem, often published to a [package registry](#pac ## Package Registry -A service that hosts packages. The most prominent example is [NPM](https://www.npmjs.com/). +A service that hosts [packages](#package). The most prominent example is [NPM](https://www.npmjs.com/). ## Package Role @@ -247,7 +247,7 @@ An abstraction layer between a search engine and the [Backstage Search](#search) ## Refresh Token -A string that an [OAuth](#oauth) client can use to get a new access token. +A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. https://oauth.net/2/refresh-tokens/ @@ -263,7 +263,7 @@ See [User Role](#User-Role). ## Scope -A string that describes a certain type of access that can be granted to a user using OAuth. +A string that describes a certain type of access that can be granted to a user using OAuth, usually in conjunction with [access tokens](#access-token). ## Search @@ -307,4 +307,4 @@ A purpose for which a [user role](#User-Role) interacts with Backstage. Related ## User Role -A class of Backspace user for purposes of analyzing [use cases](#use-case). One of: evaluator; administrator; developer; integrator; and contributor. +A class of Backstage user for purposes of analyzing [use cases](#use-case). One of: evaluator; administrator; developer; integrator; and contributor. From 312257e1a1bfa85298878db72b98dd25cfb9cc4e Mon Sep 17 00:00:00 2001 From: Aramis Date: Mon, 29 Jan 2024 14:49:31 -0500 Subject: [PATCH 23/52] add better headers for differentiating similar terms and add more definitions Signed-off-by: Aramis --- docs/local-dev/cli-build-system.md | 2 +- docs/references/glossary.md | 62 +++++++++++++++++++----------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index a95db95f85..ddcfa44cf5 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -311,7 +311,7 @@ The frontend production bundling creates your typical web content [bundle](../references/glossary.md#bundle), all contained within a single folder, ready for static serving. It is used when building packages with the `'frontend'` role, and unlike the development bundling there is no way to -build a production [bundle](../references/glossary.md#bundle) of an individual plugin. +build a production bundle of an individual plugin. The output of the bundling process is written to the `dist` folder in the package. Just like the development bundling, the production bundling is based on diff --git a/docs/references/glossary.md b/docs/references/glossary.md index abbb8ce5ef..751b56608d 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -15,7 +15,7 @@ https://oauth.net/2/access-tokens/ Someone responsible for installing and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). -## API +## API (catalog plugin) In the Backstage [Catalog](#catalog), an API is an [entity](#entity) representing a boundary between two [components](#component). @@ -37,6 +37,12 @@ A platform for creating and deploying [developer portals](#developer-portal), or Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). +Can also refer to: [Backstage framework](#backstage-framework). + +## Backstage framework + +The actual framework that Backstage [plugins](#plugin) sit on. This spans both the frontend and the backend, and includes core functionality such as declarative integration, config reading, database management, and many more. + ## Bundle A collection of [deployment artifacts](#deployment-artifacts). @@ -47,6 +53,8 @@ Can also be: The output of the bundling process, which brings a collection of [p An organization's portfolio of software products managed in Backstage. +Can also be: The core Backstage plugin that handle ingestion and display of your organizations software products. + ## Cloud Native Computing A set of technologies that "empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach." ([CNCF Cloud Native Definition v1.0](https://github.com/cncf/toc/blob/main/DEFINITION.md)). @@ -65,17 +73,17 @@ Cloud Native Computing Foundation. [OAuth](#oauth) flow where the client receives an [authorization code](#code) that is passed to the backend to be exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token). -## Collators +## Collators (search plugin) Collators transform streams of [documents](#documents) into searchable texts. They're usually responsible for the data transformation and definition and collection process for specific [documents](#documents). Part of [Backstage Search](#search). -## Component +## Component (catalog plugin) A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. https://backstage.io/docs/features/software-catalog/system-model -## Condition +## Condition (permission plugin) Conditions are used to return a conditional decision from a policy. They contain information about a given entity and restrictions on what types of users can view that entity. @@ -87,7 +95,13 @@ Conditions are used to return a conditional decision from a policy. They contain A volunteer who helps to improve an OSS product such as Backstage. This volunteer effort includes coding, testing, technical writing, user support, and other work. A [user role](#user-role). -## Decorators +## Declarative integration + +A new paradigm for Backstage frontend plugins, allowing definition in config files instead of hosting complete React pages. + +https://backstage.io/docs/frontend-system + +## Decorators (search plugin) A transform stream. Decorators allow you to add additional information to documents outside of the [collator](#collators). They sit between the [collators](#collators) and the [indexers](#indexer) and can add extra fields to documents as they're being collated and indexed. @@ -107,7 +121,7 @@ A [user role](#user-role) defined as someone who uses a Backstage [app](#app). M A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a platform for creating developer portals. -## Documents +## Documents (search plugin) An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). Part of [Backstage Search](#search). @@ -129,11 +143,11 @@ Someone who assesses whether Backstage is a suitable solution for their organiza A [JWT](#jwt) used to prove a user's identity, containing for example the user's email. Part of [OpenID Connect](#openid-connect). -## Index +## Index (search plugin) An index is a collection of [documents](#documents) of a given type. Part of [Backstage Search](#search). -## Indexer +## Indexer (search plugin) A write stream of [documents](#documents). Part of [Backstage Search](#search). @@ -209,21 +223,13 @@ Any action that a user performs within Backstage may be represented as a permiss https://backstage.io/docs/permissions/overview -## Permission Resource - -Not to be confused with [Software Catalog resources](#resource). Permission resources represent the objects that users interact with and that can be permissioned. - -## Permission Rule - -Rules are predicate-based controls that tap into a [resource](#permission-resource)'s data. - ## Persona Alternative term for a [User Role](#user-role). ## Plugin -A module in Backstage that adds a feature. All functionality in Backstage, even the core features, are implemented as plugins. +A module in Backstage that adds a feature. All functionality outside of [the Backstage framework](#backstage-framework), even the core features, are implemented as plugins. ## Policy @@ -231,7 +237,7 @@ User [permissions](#permission) are authorized by a central, user-defined [permi ## Policy decision -Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, policies are responsible for decisions and plugins (typically backends) are responsible for enforcing them. +Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, [policies](#policy) are responsible for decisions and [plugins](#plugin) (typically backends) are responsible for enforcing them. ## Popup @@ -251,16 +257,28 @@ A special token that an [OAuth](#oauth) client can use to get a new [access toke https://oauth.net/2/refresh-tokens/ -## Resource +## Resource (catalog plugin) In the Backstage Catalog, an [entity](#entity) that represents a piece of physical or virtual infrastructure, for example a database, required by a component. https://backstage.io/docs/features/software-catalog/system-model +## Resource (permission plugin) + +Not to be confused with [Software Catalog resources](#resource-catalog-plugin). Permission resources represent the objects that users interact with and that can be permissioned. + +## Rule + +Rules are predicate-based controls that tap into a [resource](#resource-permission-plugin)'s data. + ## Role See [User Role](#User-Role). +## Scaffolder + +Known as [Software Templates](#software-templates). + ## Scope A string that describes a certain type of access that can be granted to a user using OAuth, usually in conjunction with [access tokens](#access-token). @@ -269,7 +287,7 @@ A string that describes a certain type of access that can be granted to a user u A Backstage plugin that provides a framework for searching a Backstage [app](#app), including the [Software Catalog](#Software-Catalog) and [TechDocs](#TechDocs). A core feature of Backstage. -## Search Engines +## Search Engine Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in [Backstage Search](#search). Part of [Backstage Search](#search). @@ -279,7 +297,7 @@ A Backstage plugin that provides a framework to keep track of ownership and meta ## Software Templates -A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. +A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. Can also refer to: A "skeleton" software project created and managed in the Backstage Software Templates tool. @@ -289,7 +307,7 @@ In the Backspace Catalog, a system is a collection of [entities](#entity) that c https://backstage.io/docs/features/software-catalog/system-model -## Task +## Task (use cases) A low-level step-by-step [Procedure](#Procedure). From e221a0b285500e5c1ce269aefdf7376f7a3ddb63 Mon Sep 17 00:00:00 2001 From: Aramis Date: Mon, 29 Jan 2024 14:51:56 -0500 Subject: [PATCH 24/52] add more header clarifications Signed-off-by: Aramis --- docs/references/glossary.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 751b56608d..c5d991292a 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -223,7 +223,7 @@ Any action that a user performs within Backstage may be represented as a permiss https://backstage.io/docs/permissions/overview -## Persona +## Persona (use cases) Alternative term for a [User Role](#user-role). @@ -231,11 +231,11 @@ Alternative term for a [User Role](#user-role). A module in Backstage that adds a feature. All functionality outside of [the Backstage framework](#backstage-framework), even the core features, are implemented as plugins. -## Policy +## Policy (permission plugin) User [permissions](#permission) are authorized by a central, user-defined [permission](#permission) policy. At a high level, a policy is a function that receives a Backstage user and [permission](#permission), and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular [authorization](#authorization) model, like role-based access control (RBAC) or attribute-based access control (ABAC). -## Policy decision +## Policy decision (permission plugin) Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, [policies](#policy) are responsible for decisions and [plugins](#plugin) (typically backends) are responsible for enforcing them. @@ -243,11 +243,11 @@ Two important responsibilities of any authorization system are to decide if a us A separate browser window opened on top of the previous one. -## Procedure +## Procedure (use cases) A set of actions that accomplish a goal, usually as part of a [use case](#Use-Case). A procedure can be high-level, containing other procedures, or can be as simple as a single [task](#Task). -## Query Translators +## Query Translators (search plugin) An abstraction layer between a search engine and the [Backstage Search](#search) backend. Allows for translation into queries against your search engine. Part of [Backstage Search](#search). @@ -267,7 +267,7 @@ https://backstage.io/docs/features/software-catalog/system-model Not to be confused with [Software Catalog resources](#resource-catalog-plugin). Permission resources represent the objects that users interact with and that can be permissioned. -## Rule +## Rule (permission plugin) Rules are predicate-based controls that tap into a [resource](#resource-permission-plugin)'s data. From 571f6bceffcd6c773476382633b8ac74b0e6a3e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:22:49 +0000 Subject: [PATCH 25/52] fix(deps): update dependency express-openapi-validator to v5.1.3 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 79d27b5501..c7c275d5d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26880,8 +26880,8 @@ __metadata: linkType: hard "express-openapi-validator@npm:^5.0.4": - version: 5.1.2 - resolution: "express-openapi-validator@npm:5.1.2" + version: 5.1.3 + resolution: "express-openapi-validator@npm:5.1.3" dependencies: "@apidevtools/json-schema-ref-parser": ^9.1.2 "@types/multer": ^1.4.7 @@ -26898,7 +26898,7 @@ __metadata: multer: ^1.4.5-lts.1 ono: ^7.1.3 path-to-regexp: ^6.2.0 - checksum: e02eaad8549893f874916cfc52a9d81f1ef15c553e726876e6b73cc93469a21e28e42d1d25449aa04c764f8d024b1ea664b7ce6083abdd8513168ece7929ee20 + checksum: c99785e6bf3072086a671e854369e338bce2a20fea65d2a4445dac6c40ac632e67dc91d9e0edeb4cce5e739124b5d5742bcf2447c09b3085dc76e1ba89a71ca0 languageName: node linkType: hard From 4944f29f2cc61dbd29019cd5693c051301f8497f Mon Sep 17 00:00:00 2001 From: Aramis Date: Tue, 30 Jan 2024 22:28:02 -0500 Subject: [PATCH 26/52] update documentation and add a simple guide. Signed-off-by: Aramis --- docs/permissions/concepts.md | 4 +- docs/permissions/custom-rules.md | 2 +- .../02-adding-a-basic-permission-check.md | 4 +- .../03-adding-a-resource-permission-check.md | 2 +- docs/references/glossary.md | 118 ++++++++---------- docs/references/writing-a-glossary-entry.md | 83 ++++++++++++ 6 files changed, 141 insertions(+), 72 deletions(-) create mode 100644 docs/references/writing-a-glossary-entry.md diff --git a/docs/permissions/concepts.md b/docs/permissions/concepts.md index 556d752c52..8e348373cf 100644 --- a/docs/permissions/concepts.md +++ b/docs/permissions/concepts.md @@ -10,10 +10,10 @@ Two important responsibilities of any authorization system are to decide if a us ### Resources and rules -In many cases, a permission represents a user's interaction with another object. This object likely has information that policy authors can use to define more granular access. The permission framework introduces two abstractions to account for this: [resources](../references/glossary.md#permission-resource) and [rules](../references/glossary.md#permission-rule). For example, the catalog plugin defines a resource for catalog entities and a rule to check if an entity has a given annotation. +In many cases, a permission represents a user's interaction with another object. This object likely has information that policy authors can use to define more granular access. The permission framework introduces two abstractions to account for this: [resources](../references/glossary.md#resource-permission-plugin) and [rules](../references/glossary.md#rule-permission-plugin). For example, the catalog plugin defines a resource for catalog entities and a rule to check if an entity has a given annotation. ### Conditional decisions -See [Conditional decisions](../references/glossary.md#conditional-decisions). +[Rules](../references/glossary.md#rule-permission-plugin) need additional data before they can be used in a decision. Once a [rule](../references/glossary.md#rule-permission-plugin) is bound to relevant information it forms a [condition](../references/glossary.md#condition-permission-plugin). Conditional decisions tell the [permission framework](#permission) to delegate evaluation to the [plugin](#plugin) that owns the corresponding [resource](#resource-permission-plugin). Permission requests that result in a conditional decision are allowed if all of the provided conditions evaluate to be true. A good example would be the catalog plugin's "has annotation" rule which needs to know what annotation to look for on a given entity. The permission framework would respond to a request by the catalog plugin in this case with a condition decision. The catalog plugin would then need to correctly filter for entities matching the "has annotations" condition. This conditional behavior avoids coupling between policies and resource schemas, and allows plugins to evaluate complex rules in an efficient way. For example, a plugin may convert a conditional decision to a database query instead of loading and filtering objects in memory. diff --git a/docs/permissions/custom-rules.md b/docs/permissions/custom-rules.md index 4b38c8986d..9063ed7257 100644 --- a/docs/permissions/custom-rules.md +++ b/docs/permissions/custom-rules.md @@ -4,7 +4,7 @@ title: Defining custom permission rules description: How to define custom permission rules for existing resources --- -For some use cases, you may want to define custom [rules](../references/glossary.md#permission-rules) in addition to the ones provided by a plugin. In the [previous section](./writing-a-policy.md) we used the `isEntityOwner` rule to control access for catalog entities. Let's extend this policy with a custom rule that checks what [system](https://backstage.io/docs/features/software-catalog/system-model#system) an entity is part of. +For some use cases, you may want to define custom [rules](../references/glossary.md#rule-permission-plugin) in addition to the ones provided by a plugin. In the [previous section](./writing-a-policy.md) we used the `isEntityOwner` rule to control access for catalog entities. Let's extend this policy with a custom rule that checks what [system](https://backstage.io/docs/features/software-catalog/system-model#system) an entity is part of. ## Define a custom rule diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md index 0ef50670ef..f3380bdb6f 100644 --- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md @@ -4,9 +4,9 @@ title: 2. Adding a basic permission check description: Explains how to add a basic permission check to a Backstage plugin --- -If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary.md#permission-resource), you can use a _basic permission check_. For this kind of check, we simply need to define a [permission](../../references/glossary.md#permission), and call `authorize` with it. +If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary.md#resource-permission-plugin), you can use a _basic permission check_. For this kind of check, we simply need to define a permission, and call `authorize` with it. -For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy). +For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy-permission-plugin). We'll start by creating a new permission, and then we'll use the permission api to call `authorize` with it during todo creation. diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md index 3feecc7342..76c1a85e24 100644 --- a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md +++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md @@ -4,7 +4,7 @@ title: 3. Adding a resource permission check description: Explains how to add a resource permission check to a Backstage plugin --- -When performing updates (or other operations) on specific [resources](../../references/glossary.md#permission-resource), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. +When performing updates (or other operations) on specific [resources](../../references/glossary.md#resource-permission-plugin), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. ## Creating the update permission diff --git a/docs/references/glossary.md b/docs/references/glossary.md index c5d991292a..165c000fc8 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -5,11 +5,9 @@ title: Glossary description: List of terms, abbreviations, and phrases used in Backstage, together with their explanations. --- -## Access token +## Access Token -A [token](#token) that gives access to perform actions on behalf of a user. It will commonly have a short expiry time, and be limited to a set of [scopes](#scope). Part of the [OAuth](#oauth) protocol. - -https://oauth.net/2/access-tokens/ +A [token](#token) that gives access to perform actions on behalf of a user. It will commonly have a short expiry time, and be limited to a set of [scopes](#scope). Part of the [OAuth](#oauth) protocol, see [their docs](https://oauth.net/2/access-tokens/) for more information. ## Administrator @@ -17,9 +15,7 @@ Someone responsible for installing and maintaining a Backstage [app](#app) for a ## API (catalog plugin) -In the Backstage [Catalog](#catalog), an API is an [entity](#entity) representing a boundary between two [components](#component). - -https://backstage.io/docs/features/software-catalog/system-model +An [entity](#entity) representing a schema that two [components](#component) use to communicate. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## App @@ -27,33 +23,29 @@ An installed instance of Backstage. An app can be local, intended for a single d ## Authorization Code -A type of [OAuth flow](#oauth) used by confidential and public clients to get an [access token](#access-token). - -https://oauth.net/2/grant-types/authorization-code/ +A type of [OAuth flow](#oauth) used by confidential and public clients to get an [access token](#access-token). See [the OAuth docs](https://oauth.net/2/grant-types/authorization-code/) for more details. ## Backstage -A platform for creating and deploying [developer portals](#developer-portal), originally created at Spotify. +1. A platform for creating and deploying [developer portals](#developer-portal), originally created at Spotify. Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). -Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). +2. [The Backstage Framework](#backstage-framework). -Can also refer to: [Backstage framework](#backstage-framework). - -## Backstage framework +## Backstage Framework The actual framework that Backstage [plugins](#plugin) sit on. This spans both the frontend and the backend, and includes core functionality such as declarative integration, config reading, database management, and many more. ## Bundle -A collection of [deployment artifacts](#deployment-artifacts). +1. A collection of [deployment artifacts](#deployment-artifacts). -Can also be: The output of the bundling process, which brings a collection of [packages](#package) into a single collection of [deployment artifacts](#deployment-artifacts). +2. The output of the bundling process, which brings a collection of [packages](#package) into a single collection of [deployment artifacts](#deployment-artifacts). ## Catalog -An organization's portfolio of software products managed in Backstage. +1. The core Backstage plugin that handle ingestion and display of your organizations software products. -Can also be: The core Backstage plugin that handle ingestion and display of your organizations software products. +2. An organization's portfolio of software products managed in Backstage. ## Cloud Native Computing @@ -73,39 +65,37 @@ Cloud Native Computing Foundation. [OAuth](#oauth) flow where the client receives an [authorization code](#code) that is passed to the backend to be exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token). -## Collators (search plugin) +## Collator (search plugin) -Collators transform streams of [documents](#documents) into searchable texts. They're usually responsible for the data transformation and definition and collection process for specific [documents](#documents). Part of [Backstage Search](#search). +A transformer that takes streams of [documents](#documents) and outputs searchable texts. They're usually responsible for the data transformation and definition and collection process for specific [documents](#documents). ## Component (catalog plugin) -A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. - -https://backstage.io/docs/features/software-catalog/system-model +A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Condition (permission plugin) Conditions are used to return a conditional decision from a policy. They contain information about a given entity and restrictions on what types of users can view that entity. -## Conditional decisions +A mapping from a given entity to criteria a user must fulfill to perform an action on that entity. Examples include `isOwner`, `hasRole`, etc. -[Rules](#permission-rules) need additional data before they can be used in a decision. Once a [rule](#permission-rule) is bound to relevant information it forms a [condition](#condition). Conditional decisions tell the [permission framework](#permission) to delegate evaluation to the [plugin](#plugin) that owns the corresponding [resource](#permission-resource). Permission requests that result in a conditional decision are allowed if all of the provided conditions evaluate to be true. +## Conditional Decision (permission plugin) + +A type of [decision](#policy-decision-permission-plugin) that allows for per-user evaluation of [conditions](#condition-permission-plugin) against a [resource](#resource-permission-plugin). See [Conditional Decisions](../permissions/concepts.md#conditional-decisions) ## Contributor A volunteer who helps to improve an OSS product such as Backstage. This volunteer effort includes coding, testing, technical writing, user support, and other work. A [user role](#user-role). -## Declarative integration +## Declarative Integration -A new paradigm for Backstage frontend plugins, allowing definition in config files instead of hosting complete React pages. +A new paradigm for Backstage frontend plugins, allowing definition in config files instead of hosting complete React pages. See [the Frontend System](https://backstage.io/docs/frontend-system). -https://backstage.io/docs/frontend-system +## Decorator (search plugin) -## Decorators (search plugin) +A transform stream. Decorators allow you to add additional information to documents outside of the [collator](#collator-search-plugin). They sit between the collators and the [indexers](#indexer-search-plugin) and can add extra fields to documents as they're being collated and indexed. -A transform stream. Decorators allow you to add additional information to documents outside of the [collator](#collators). They sit between the [collators](#collators) and the [indexers](#indexer) and can add extra fields to documents as they're being collated and indexed. - -Possible use cases for a decorator could be to bias search results or otherwise improve the search experience in your Backstage instance. Decorators can also be used to remove [metadata](#metadata), filter out, or even add extra documents at index-time. Part of [Backstage Search](#search). +Possible use cases for a decorator could be to bias search results or otherwise improve the search experience in your Backstage instance. Decorators can also be used to remove [metadata](#metadata), filter out, or even add extra documents at index-time. ## Deployment Artifacts @@ -121,19 +111,17 @@ A [user role](#user-role) defined as someone who uses a Backstage [app](#app). M A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a platform for creating developer portals. -## Documents (search plugin) +## Document (search plugin) -An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). Part of [Backstage Search](#search). +An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). ## Domain -In the Backstage Catalog, a domain is an area that relates systems or entities to a business unit. - -https://backstage.io/docs/features/software-catalog/system-model +An area that relates systems or entities to a business unit. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Entity -What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. +What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Evaluator @@ -145,11 +133,11 @@ A [JWT](#jwt) used to prove a user's identity, containing for example the user's ## Index (search plugin) -An index is a collection of [documents](#documents) of a given type. Part of [Backstage Search](#search). +An index is a collection of [documents](#documents) of a given type. ## Indexer (search plugin) -A write stream of [documents](#documents). Part of [Backstage Search](#search). +A write stream of [documents](#documents). ## Integrator @@ -159,15 +147,19 @@ Someone who develops one or more plugins that enable Backstage to interoperate w JSON Web Token. -A popular JSON based token format that is commonly encrypted and/or signed, see [en.wikipedia.org/wiki/JSON_Web_Token](https://en.wikipedia.org/wiki/JSON_Web_Token) +A popular JSON based token format that is commonly encrypted and/or signed, see [the Wikipedia article](https://en.wikipedia.org/wiki/JSON_Web_Token) for more details. ## Kind Classification of an [entity](#Entity) in the Backstage Software Catalog, for example _service_, _database_, and _team_. -## Kubernetes Plugin +## Kubernetes (CNCF Project) -A plugin enabling configuration of Backstage on a Kubernetes cluster. Kubernetes plugin has been promoted to a Backstage core feature. +An open-source system for automating deployment, scaling, and management of containerized applications. + +## Kubernetes (Backstage plugin) + +A core Backstage plugin enabling a service owner-focused view of Kubernetes resources. ## Local Package @@ -175,13 +167,13 @@ One of the [packages](#package) within a [monorepo](#monorepo). These package ma ## Monorepo -A single repository for a collection of related software projects, such as all projects belonging to an organization. +1. A single repository for a collection of related software projects, such as all projects belonging to an organization. -Can also mean: A project layout that consists of multiple [packages](#package) within a single project, where packages are able to have local dependencies on each other. Often enabled through tooling such as [lerna](https://lerna.js.org/) and [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) +2. A project layout that consists of multiple [packages](#package) within a single project, where packages are able to have local dependencies on each other. Often enabled through tooling such as [lerna](https://lerna.js.org/) and [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) -## Namespace +## Namespace (catalog plugin) -In the Backstage Software Catalog, an optional attribute that can be used to organize [entities](#entity). +An optional attribute that can be used to organize [entities](#entity). ## Objective @@ -217,12 +209,10 @@ The declared role of a package, see [package roles](../local-dev/cli-build-syste ## Permission -A core Backstage plugin and framework that allows restriction of actions to specific users. +A core Backstage plugin and framework that allows restriction of actions to specific users. See [their docs](https://backstage.io/docs/permissions/overview) for more information. Any action that a user performs within Backstage may be represented as a permission. More complex actions, like executing a [software template](#software-templates), may require [authorization](#authorization) for multiple permissions throughout the flow. Permissions are identified by a unique name and optionally include a set of attributes that describe the corresponding action. [Plugins](#plugin) are responsible for defining and exposing the permissions they enforce as well as enforcing restrictions from the permission framework. -https://backstage.io/docs/permissions/overview - ## Persona (use cases) Alternative term for a [User Role](#user-role). @@ -235,9 +225,9 @@ A module in Backstage that adds a feature. All functionality outside of [the Bac User [permissions](#permission) are authorized by a central, user-defined [permission](#permission) policy. At a high level, a policy is a function that receives a Backstage user and [permission](#permission), and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular [authorization](#authorization) model, like role-based access control (RBAC) or attribute-based access control (ABAC). -## Policy decision (permission plugin) +## Policy Decision (permission plugin) -Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, [policies](#policy) are responsible for decisions and [plugins](#plugin) (typically backends) are responsible for enforcing them. +A specific response to a user's request to perform an action on a list of [resources](#resource-permission-plugin). Can be either `Approve`, `Deny` or [`Conditional`](#conditional-decision-permission-plugin). ## Popup @@ -249,9 +239,9 @@ A set of actions that accomplish a goal, usually as part of a [use case](#Use-Ca ## Query Translators (search plugin) -An abstraction layer between a search engine and the [Backstage Search](#search) backend. Allows for translation into queries against your search engine. Part of [Backstage Search](#search). +An abstraction layer between a search engine and the [Backstage Search](#search) backend. Allows for translation into queries against your search engine. -## Refresh Token +## Refresh token A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. @@ -259,9 +249,7 @@ https://oauth.net/2/refresh-tokens/ ## Resource (catalog plugin) -In the Backstage Catalog, an [entity](#entity) that represents a piece of physical or virtual infrastructure, for example a database, required by a component. - -https://backstage.io/docs/features/software-catalog/system-model +An [entity](#entity) that represents a piece of physical or virtual infrastructure, for example a database, required by a component. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Resource (permission plugin) @@ -287,9 +275,9 @@ A string that describes a certain type of access that can be granted to a user u A Backstage plugin that provides a framework for searching a Backstage [app](#app), including the [Software Catalog](#Software-Catalog) and [TechDocs](#TechDocs). A core feature of Backstage. -## Search Engine +## Search Engine (Backstage search) -Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in [Backstage Search](#search). Part of [Backstage Search](#search). +Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in Backstage Search. ## Software Catalog @@ -297,15 +285,13 @@ A Backstage plugin that provides a framework to keep track of ownership and meta ## Software Templates -A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. +1. A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. -Can also refer to: A "skeleton" software project created and managed in the Backstage Software Templates tool. +2. A "skeleton" software project created and managed in the Backstage Software Templates tool. -## System +## System (catalog plugin) -In the Backspace Catalog, a system is a collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources and private APIs. - -https://backstage.io/docs/features/software-catalog/system-model +A system is a collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources and private APIs. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Task (use cases) diff --git a/docs/references/writing-a-glossary-entry.md b/docs/references/writing-a-glossary-entry.md new file mode 100644 index 0000000000..ecc9f22bd1 --- /dev/null +++ b/docs/references/writing-a-glossary-entry.md @@ -0,0 +1,83 @@ + + +## Entry format + +A glossary entry should consist of two required things and two optional things, + +1. a header, +2. a sentence defining what the thing is, and +3. an optional additional sentence or two giving more context into what the thing is and possible pointers on where to find more information, and possibly +4. links out to additional information. + +### The header + +The header (and first sentence) are the way users will discover your entry. The header has two parts, + +1. The actual term, this should be as minimal as possible. You can fit more information into the body of the entry. +2. A disambiguator, this allows users to understand when certain entries are context specific or may have different meanings in different contexts. + +### The term + +Think of this as a dictionary. Single words are the base units and most definitions refer to a single word. Acronyms are acceptable. An adjective and a noun are also useful, `conditional decision`, `backstage framework`, etc. After 3 or _maybe_ 4 words, you should be trying to simplify and place more content in your entry instead. + +In the title, your term should be in Title Case. It should also be in the singular. + +### The disambiguator + +The goal of a disambiguator is to differentiate terms that may have context specific meanings. This can have two interpretations, either + +1. There are multiple terms and we need to create clear boundaries between their contexts, or +2. There are single terms that have meanings that are specific to a single context. + +A good example for the first would be resources. Both the catalog plugin and permission plugin have the idea of resources, but they do not refer to the same thing. + +A good example for the second would be `Query translators`. In our case, this refers to _search_ query translators, but it may refer to database query translators or the latter. By disambiguating early, we avoid confusion. + +Beyond the above advice, there are no strong rules for when or when not to use a disambiguator. It is up to the entry writer and the reviewer. + +Your disambiguator should be short, but need not be a single word -- examples include "use cases", "search plugin", "catalog plugin". When used the disambiguator should have the following form, `({disambiguator})` (a parenthesis enclosed term) and will sit to the right of the title. Your disambiguator should use lower case. + +### Putting it together + +Your title should look like `{word} ({disambiguator})`. Entries are not nested besides the disambiguator and should sit at `##`. + +## The first sentence + +Your first sentence should include the what for your word. Your goal should be to answer the question, "What is x?". Do _not_ use the word in your first sentence. If you are using other words in the glossary in your definition, you should reference them following [the Referencing section](#referencing). + +If you have a term that could mean multiple things in the same context or the context is difficult to add boundaries for, you should separate each meaning into a separate section of the entry using an ordered list. For example, + +```md +## Bundle + +1. A deployment artifact. +2. A collection of packages. +``` + +## Additional sentences + +You may not be able to fully define what you want in a single sentence. Use more sentences to flush out the meaning; however, if you start to get into the weeds, you should reconsider rehousing that information into a plugin specific "concepts" section. It's okay for words to be duplicated across both if the concepts section adds meaningful technical or architectural discussion. + +## Linking out to additional resources + +If the term you're defining has a better or more in depth source for that information, link to it. This can include plugin specific concept documents, external documentation, or core framework documentation. + +You should format these links as `See [link1 title](link1.url) for more details`. Additional links beyond the first one should be appended with `and` or `or` as necessary. + +## Putting it all together + +```md +## Component (catalog plugin) + +A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +``` + +## Referencing + +### In the glossary + +You should reference often. Words are defined recursively, especially in tech and un-nesting some terms requires additional glossary items. It's okay if your terms require multiple other terms to build on. Your goal with referencing is to provide small reusable words that you can trust users know the definition of. + +### In the text + +You should reference (and create a new entry if it doesn't exist) whenever you see a new word that a reasonable reader may not know. If you've already added a reference in your current passage -- in the glossary this will be your entry -- don't add a new reference. References should point initially to the glossary and if there is additional information (like a concepts page), the glossary should have a link to that page. From f0192acb7092ab85f57264a795de2df18ea17ff9 Mon Sep 17 00:00:00 2001 From: Aramis Date: Tue, 30 Jan 2024 22:29:46 -0500 Subject: [PATCH 27/52] fix: condition definition Signed-off-by: Aramis --- docs/references/glossary.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 165c000fc8..773e7bfb50 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -75,8 +75,6 @@ A software product that is managed in the Backstage [Software Catalog](#software ## Condition (permission plugin) -Conditions are used to return a conditional decision from a policy. They contain information about a given entity and restrictions on what types of users can view that entity. - A mapping from a given entity to criteria a user must fulfill to perform an action on that entity. Examples include `isOwner`, `hasRole`, etc. ## Conditional Decision (permission plugin) From ddfeada98095ee2fd1de4f4fa844f31c85f036bd Mon Sep 17 00:00:00 2001 From: Aramis Date: Tue, 30 Jan 2024 22:43:23 -0500 Subject: [PATCH 28/52] remove lengthy definitions Signed-off-by: Aramis --- docs/permissions/concepts.md | 8 ++++++++ docs/references/glossary.md | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/permissions/concepts.md b/docs/permissions/concepts.md index 8e348373cf..7c8b9e9f69 100644 --- a/docs/permissions/concepts.md +++ b/docs/permissions/concepts.md @@ -4,6 +4,14 @@ title: Concepts description: A list of important permission framework concepts --- +### Permission + +Any action that a user performs within Backstage may be represented as a permission. More complex actions, like executing a [software template](../references/glossary.md#software-templates), may require [authorization](../references/glossary.md#authorization) for multiple permissions throughout the flow. Permissions are identified by a unique name and optionally include a set of attributes that describe the corresponding action. [Plugins](../references/glossary.md#plugin) are responsible for defining and exposing the permissions they enforce as well as enforcing restrictions from the permission framework. + +### Policy + +User [permissions](../references/glossary.md#permission-permission-plugin) are authorized by a central, user-defined permission policy. At a high level, a policy is a function that receives a Backstage user and permission, and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular [authorization](../references/glossary.md#authorization) model, like role-based access control (RBAC) or attribute-based access control (ABAC). + ### Policy decision versus enforcement Two important responsibilities of any authorization system are to decide if a user can do something, and to enforce that decision. In the Backstage permission framework, policies are responsible for decisions and plugins (typically backends) are responsible for enforcing them. diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 773e7bfb50..45c2bbcd35 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -91,9 +91,7 @@ A new paradigm for Backstage frontend plugins, allowing definition in config fil ## Decorator (search plugin) -A transform stream. Decorators allow you to add additional information to documents outside of the [collator](#collator-search-plugin). They sit between the collators and the [indexers](#indexer-search-plugin) and can add extra fields to documents as they're being collated and indexed. - -Possible use cases for a decorator could be to bias search results or otherwise improve the search experience in your Backstage instance. Decorators can also be used to remove [metadata](#metadata), filter out, or even add extra documents at index-time. +A transform stream that allows you to add additional information to [documents](#document-search-plugin). ## Deployment Artifacts @@ -205,11 +203,13 @@ A service that hosts [packages](#package). The most prominent example is [NPM](h The declared role of a package, see [package roles](../local-dev/cli-build-system.md#package-roles). -## Permission +## Permission (core Backstage plugin) A core Backstage plugin and framework that allows restriction of actions to specific users. See [their docs](https://backstage.io/docs/permissions/overview) for more information. -Any action that a user performs within Backstage may be represented as a permission. More complex actions, like executing a [software template](#software-templates), may require [authorization](#authorization) for multiple permissions throughout the flow. Permissions are identified by a unique name and optionally include a set of attributes that describe the corresponding action. [Plugins](#plugin) are responsible for defining and exposing the permissions they enforce as well as enforcing restrictions from the permission framework. +## Permission (permission plugin) + +A restriction on any action that a user can perform against a specific [resource](#resource-permission-plugin) or set of resources. See [the permission framework docs](../permissions/concepts.md#permission) for more details. ## Persona (use cases) @@ -221,7 +221,7 @@ A module in Backstage that adds a feature. All functionality outside of [the Bac ## Policy (permission plugin) -User [permissions](#permission) are authorized by a central, user-defined [permission](#permission) policy. At a high level, a policy is a function that receives a Backstage user and [permission](#permission), and returns a decision to allow or deny. Policies are expressed as code, which decouples the framework from any particular [authorization](#authorization) model, like role-based access control (RBAC) or attribute-based access control (ABAC). +A construct that takes in a Backstage user and a [permission](#permission-permission-plugin) and returns a [policy decision](#policy-decision-permission-plugin). ## Policy Decision (permission plugin) From a5f3d839ecff924a764bfeaa579973dec3329465 Mon Sep 17 00:00:00 2001 From: Aramis Date: Tue, 30 Jan 2024 22:43:30 -0500 Subject: [PATCH 29/52] fix links issue Signed-off-by: Aramis --- docs/references/writing-a-glossary-entry.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/references/writing-a-glossary-entry.md b/docs/references/writing-a-glossary-entry.md index ecc9f22bd1..90a13e9675 100644 --- a/docs/references/writing-a-glossary-entry.md +++ b/docs/references/writing-a-glossary-entry.md @@ -62,7 +62,13 @@ You may not be able to fully define what you want in a single sentence. Use more If the term you're defining has a better or more in depth source for that information, link to it. This can include plugin specific concept documents, external documentation, or core framework documentation. -You should format these links as `See [link1 title](link1.url) for more details`. Additional links beyond the first one should be appended with `and` or `or` as necessary. +You should format these links as + +```md +See [the glossary](./glossary.md) for more details. +``` + +. Additional links beyond the first one should be appended with `and` or `or` as necessary. ## Putting it all together From 830e724a2104463edbc0db127280df2d79dd19fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:39:48 +0000 Subject: [PATCH 30/52] chore(deps): update dependency lint-staged to v15.2.1 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 19e38d0aaf..d6dd1c14ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32713,22 +32713,22 @@ __metadata: linkType: hard "lint-staged@npm:^15.0.0": - version: 15.2.0 - resolution: "lint-staged@npm:15.2.0" + version: 15.2.1 + resolution: "lint-staged@npm:15.2.1" dependencies: chalk: 5.3.0 commander: 11.1.0 debug: 4.3.4 execa: 8.0.1 lilconfig: 3.0.0 - listr2: 8.0.0 + listr2: 8.0.1 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 yaml: 2.3.4 bin: lint-staged: bin/lint-staged.js - checksum: 4fb178b8d3ff454f7874697dfbd41017630f61a06296d12ac9dfd578d078c70aff7108b67fab38af94896ef2740a1e7541c1512d0d3c688ed90e6c3af3530f0d + checksum: d2b0361b311cb3384e58a5d4bfd5d34e6ff6ad41e5ea5dcc87c65379ea6e280c84f0a037df147355963dcf4d3dc1487795e3132c38e1bc5511b25889f405e189 languageName: node linkType: hard @@ -32739,9 +32739,9 @@ __metadata: languageName: node linkType: hard -"listr2@npm:8.0.0": - version: 8.0.0 - resolution: "listr2@npm:8.0.0" +"listr2@npm:8.0.1": + version: 8.0.1 + resolution: "listr2@npm:8.0.1" dependencies: cli-truncate: ^4.0.0 colorette: ^2.0.20 @@ -32749,7 +32749,7 @@ __metadata: log-update: ^6.0.0 rfdc: ^1.3.0 wrap-ansi: ^9.0.0 - checksum: 5cb110a710d14488c71d2207fc5141256abb1f21cbe5ebc12177ae640f94e040a1ef8c031b70ff9f24c4a8fa57c0825a54b534e52bdfaffc122a81082faae8ed + checksum: 4dfeabfa037b3981d0edbf30789971ba727ba4cfcc13051ceaff7a1b3d26509ef2d946015c65c600b0775ec9d1ef58a81937d94c9c03de464b654f429cc7c3ed languageName: node linkType: hard From a21497d33dfaed45a22929d0355221f63a1eb6a3 Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:53:16 +0000 Subject: [PATCH 31/52] Update router.ts Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- plugins/auth-backend/src/service/router.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index e04053c478..dddac82c2d 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -261,10 +261,15 @@ export function getDefaultBackstageTokenExpiryTime(config: Config) { const duration = readDurationFromConfig(config, { key: processingIntervalKey, }); - const seconds = Math.max( - 86400, - Math.round(durationToMilliseconds(duration) / 1000), - ); - return seconds; + const roundedDuration = Math.round(durationToMilliseconds(duration) / 1000); + + const minSeconds = Math.max(600, roundedDuration); + + const maxSeconds = Math.min(86400, roundedDuration); + + if (roundedDuration < minSeconds) { + return minSeconds + } + return maxSeconds; } From de1aa5179cefd6cbdab082b2f11c757c5281167d Mon Sep 17 00:00:00 2001 From: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:57:03 +0000 Subject: [PATCH 32/52] Update router.test.ts Signed-off-by: Lavanya Sainik <137502642+lavanya-sainik-ericsson@users.noreply.github.com> --- .../auth-backend/src/service/router.test.ts | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/plugins/auth-backend/src/service/router.test.ts b/plugins/auth-backend/src/service/router.test.ts index 6c0b060fdb..8805a60e56 100644 --- a/plugins/auth-backend/src/service/router.test.ts +++ b/plugins/auth-backend/src/service/router.test.ts @@ -69,7 +69,7 @@ describe('Test for default backstage token expiry time', () => { ); }); - it('Will return user defined backstage session expiration', () => { + it('Will return user defined 120 minutes as backstage session expiration', () => { const config = new ConfigReader({ app: { baseUrl: 'http://example.com/extra-path', @@ -78,6 +78,42 @@ describe('Test for default backstage token expiry time', () => { backstageTokenExpiration: { minutes: 120 }, }, }); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe(7200); + }); + + it('Will return minimum duration of 10 minutes as backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 2 }, + }, + }); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe(600); + }); + + it('Will return user configured value as backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 20 }, + }, + }); + expect(getDefaultBackstageTokenExpiryTime(config)).toBe(1200); + }); + + it('Will return maximum of 24 hour as backstage session expiration if user configured value is more than a day', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 1500 }, + }, + }); expect(getDefaultBackstageTokenExpiryTime(config)).toBe(86400); }); }); From 449556a528ccec603850bc87325ac3d0069a7997 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Wed, 31 Jan 2024 18:09:37 +0100 Subject: [PATCH 33/52] Remove old unmaintained 'on-demand' page Signed-off-by: Philipp Hugenroth --- docs/overview/support.md | 40 +---- microsite/data/on-demand/20211117-1.yaml | 7 - microsite/data/on-demand/20211118-1.yaml | 7 - microsite/data/on-demand/20211215-1.yaml | 7 - microsite/data/on-demand/20211216-1.yaml | 7 - microsite/data/on-demand/20220216-1.yaml | 7 - microsite/data/on-demand/20220223-1.yaml | 7 - microsite/data/on-demand/20220316-1.yaml | 9 -- microsite/data/on-demand/20220323-1.yaml | 9 -- microsite/data/on-demand/20220420-1.yaml | 9 -- microsite/data/on-demand/20220427-1.yaml | 9 -- microsite/data/on-demand/20220518-1.yaml | 9 -- microsite/data/on-demand/20220525-1.yaml | 9 -- microsite/data/on-demand/20220615-1.yaml | 9 -- microsite/data/on-demand/20220622-1.yaml | 9 -- microsite/data/on-demand/20220720-1.yaml | 9 -- microsite/data/on-demand/20220727-1.yaml | 9 -- microsite/data/on-demand/20220817-1.yaml | 7 - microsite/data/on-demand/20220824-1.yaml | 7 - microsite/data/on-demand/20220921-1.yaml | 7 - microsite/data/on-demand/20220928-1.yaml | 7 - microsite/src/pages/community/index.tsx | 4 +- .../src/pages/on-demand/_onDemandCard.tsx | 66 -------- microsite/src/pages/on-demand/index.tsx | 78 ---------- .../src/pages/on-demand/onDemand.module.scss | 44 ------ microsite/static/css/on-demand.css | 143 ------------------ 26 files changed, 3 insertions(+), 532 deletions(-) delete mode 100644 microsite/data/on-demand/20211117-1.yaml delete mode 100644 microsite/data/on-demand/20211118-1.yaml delete mode 100644 microsite/data/on-demand/20211215-1.yaml delete mode 100644 microsite/data/on-demand/20211216-1.yaml delete mode 100644 microsite/data/on-demand/20220216-1.yaml delete mode 100644 microsite/data/on-demand/20220223-1.yaml delete mode 100644 microsite/data/on-demand/20220316-1.yaml delete mode 100644 microsite/data/on-demand/20220323-1.yaml delete mode 100644 microsite/data/on-demand/20220420-1.yaml delete mode 100644 microsite/data/on-demand/20220427-1.yaml delete mode 100644 microsite/data/on-demand/20220518-1.yaml delete mode 100644 microsite/data/on-demand/20220525-1.yaml delete mode 100644 microsite/data/on-demand/20220615-1.yaml delete mode 100644 microsite/data/on-demand/20220622-1.yaml delete mode 100644 microsite/data/on-demand/20220720-1.yaml delete mode 100644 microsite/data/on-demand/20220727-1.yaml delete mode 100644 microsite/data/on-demand/20220817-1.yaml delete mode 100644 microsite/data/on-demand/20220824-1.yaml delete mode 100644 microsite/data/on-demand/20220921-1.yaml delete mode 100644 microsite/data/on-demand/20220928-1.yaml delete mode 100644 microsite/src/pages/on-demand/_onDemandCard.tsx delete mode 100644 microsite/src/pages/on-demand/index.tsx delete mode 100644 microsite/src/pages/on-demand/onDemand.module.scss delete mode 100644 microsite/static/css/on-demand.css diff --git a/docs/overview/support.md b/docs/overview/support.md index 38bb60784f..0433683406 100644 --- a/docs/overview/support.md +++ b/docs/overview/support.md @@ -6,11 +6,11 @@ description: Support and Community Details and Links - [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Get support or discuss the project. -- [Stack Overflow](https://stackoverflow.com/questions/tagged/backstage) - Browse or ask questions on Stack Overflow. - [Good First Issues](https://github.com/backstage/backstage/contribute) - Start here if you want to contribute. - [RFCs](https://github.com/backstage/backstage/labels/rfc) - Help shape the technical direction by reviewing _Request for Comments_ issues. +- [BEPs](https://github.com/backstage/backstage/tree/master/beps#backstage-enhancement-proposals-beps) - A Backstage Enhancement Proposal (BEP) is a way to propose, communicate and coordinate on new efforts for the Backstage project. - [FAQ](../faq/index.md) - Frequently Asked Questions. - [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md) - This is how we roll. @@ -23,41 +23,3 @@ description: Support and Community Details and Links ## Community Hub Check out the Backstage.io [Backstage Community Hub](https://backstage.io/community) for the Community Sessions, recordings, and community resources. - -### Adding a recording to the meetup page - -To add a new recording to the [meetup page](https://backstage.io/on-demand) -create a file in -[`microsite/data/on-demand`](https://github.com/backstage/backstage/tree/master/microsite/data/on-demand) -with your recording's information. Filenames should be in the format `yyyymmdd-xx.yaml`. The page will sort using the filename. Example file content: - -```yaml ---- -title: # name of the meetup -date: February 23, 2022 # date, format: Month day, year. -category: Meetup # Can be Event, Meetup, Webinar -description: # description, summary -youtubeUrl: # Url to youtube video -youtubeImgUrl: # Url to the preview image, for Youtube this is the format: https://i1.ytimg.com/vi//mqdefault.jpg -``` - -### Adding an upcoming meetup to the meetup page - -To add an upcoming meetup to the [meetup page](https://backstage.io/on-demand) -create a file in -[`microsite/data/on-demand`](https://github.com/backstage/backstage/tree/master/microsite/data/on-demand) -with your meetup's information. Filenames should be in the format `yyyymmdd-xx.yaml`, the page will sort using the filename. Example file content: - -```yaml ---- -title: # name of the meetup -date: February 23, 2022 # date, format: Month day, year. -category: Upcoming # Should be "Upcoming" -description: # description, summary -youtubeUrl: # Url to youtube video -youtubeImgUrl: # Url to the preview image, for Youtube this is the format: https://i1.ytimg.com/vi//mqdefault.jpg -rsvpUrl: # Link to registration, calendar item, etc -eventUrl: # Link to event landing page -``` - -After the meetup is done, and the recording is ready you can change it to a meetup recording. diff --git a/microsite/data/on-demand/20211117-1.yaml b/microsite/data/on-demand/20211117-1.yaml deleted file mode 100644 index 21410fc85f..0000000000 --- a/microsite/data/on-demand/20211117-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: November 17, 2021 -category: Meetup -description: At this month’s adopters session, get the scoop on Spotify’s plan for paid plugins, a first look at Box’s DevPortal, and answers to big questions, like “How will I know if Backstage will work at a large company like mine?” -youtubeUrl: https://youtu.be/apCDT3_DmFk -youtubeImgUrl: https://i1.ytimg.com/vi/apCDT3_DmFk/mqdefault.jpg diff --git a/microsite/data/on-demand/20211118-1.yaml b/microsite/data/on-demand/20211118-1.yaml deleted file mode 100644 index 754344a62e..0000000000 --- a/microsite/data/on-demand/20211118-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: November 18, 2021 -category: Meetup -description: In the contributors track for this month’s community session, hear about upcoming deprecations, the fruits of Hacktoberfest, the future of both the Kubernetes plugin and the Tech Insights plugin, tips on contributing, and more. -youtubeUrl: https://youtu.be/n1OWGwYAOiI -youtubeImgUrl: https://i1.ytimg.com/vi/n1OWGwYAOiI/mqdefault.jpg diff --git a/microsite/data/on-demand/20211215-1.yaml b/microsite/data/on-demand/20211215-1.yaml deleted file mode 100644 index ce51fe3a9c..0000000000 --- a/microsite/data/on-demand/20211215-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: December 15, 2021 -category: Meetup -description: At our final adopters session of 2021, the community received a grab bag of end-of-year treats, including eye-catching infographics, a presentation from finance startup Brex about their path to adopting Backstage, and tips on branding your Backstage portal. Plus, get your official Backstage Zoom background. But first up, a quick look back at the year that was. -youtubeUrl: https://youtu.be/0QMQYSTKAx0 -youtubeImgUrl: https://i1.ytimg.com/vi/0QMQYSTKAx0/mqdefault.jpg diff --git a/microsite/data/on-demand/20211216-1.yaml b/microsite/data/on-demand/20211216-1.yaml deleted file mode 100644 index 9600a5f13b..0000000000 --- a/microsite/data/on-demand/20211216-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: December 16, 2021 -category: Meetup -description: At our final contributors session of 2021, see how the new Backstage Upgrade Helper works and enjoy smoother upgrades, hear updates from the maintainers, and meet our contributor of the month. As in the adopters session, first we celebrate the year’s milestones and share a few resources you can use to spread the word about Backstage. -youtubeUrl: https://youtu.be/nYjI2j-lWEM -youtubeImgUrl: https://i1.ytimg.com/vi/nYjI2j-lWEM/mqdefault.jpg diff --git a/microsite/data/on-demand/20220216-1.yaml b/microsite/data/on-demand/20220216-1.yaml deleted file mode 100644 index 1fc7371345..0000000000 --- a/microsite/data/on-demand/20220216-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: February 16, 2022 -category: Meetup -description: This community session marks one year of Backstage community sessions! In this session, we celebrate one year of the Backstage community, hear from Patrik on stabilizing core APIs, learn more about Homepage Templates, find hidden info about your catalog entities, and Q&A. -youtubeUrl: https://youtu.be/evf_LV0KzIk -youtubeImgUrl: https://i1.ytimg.com/vi/evf_LV0KzIk/mqdefault.jpg diff --git a/microsite/data/on-demand/20220223-1.yaml b/microsite/data/on-demand/20220223-1.yaml deleted file mode 100644 index 6efc9fe22c..0000000000 --- a/microsite/data/on-demand/20220223-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Community Sessions -date: February 23, 2022 -category: Meetup -description: Community Sessions Anniversary , SWAG opportunity❗, TechDocs add-on framework, URL Reader demo 👨‍💻, Q&A -youtubeUrl: https://youtu.be/Buu_KWdIFwU -youtubeImgUrl: https://i1.ytimg.com/vi/Buu_KWdIFwU/mqdefault.jpg diff --git a/microsite/data/on-demand/20220316-1.yaml b/microsite/data/on-demand/20220316-1.yaml deleted file mode 100644 index b4ecc1f696..0000000000 --- a/microsite/data/on-demand/20220316-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Adopter Community Sessions -date: March 16, 2022 -category: Meetup -description: In this community session, we celebrate Backstage’s 2nd birthday and a few other milestones that Backstage reached in March! The amazing Suzanne Daniels also put together a panel from some of our community members to discuss all things developer experience! -youtubeUrl: https://youtu.be/2s98-sxJT1c -youtubeImgUrl: https://i1.ytimg.com/vi/2s98-sxJT1c/mqdefault.jpg -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues diff --git a/microsite/data/on-demand/20220323-1.yaml b/microsite/data/on-demand/20220323-1.yaml deleted file mode 100644 index 2f198775e8..0000000000 --- a/microsite/data/on-demand/20220323-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contributor Community Sessions -date: March 23, 2022 -category: Meetup -description: In this Community Session, we review the recent milestones our Backstage community hit, chat with Djamaile Rahamat, our contributor spotlight, and watch three demos ranging from new plugins to test environments. -youtubeUrl: https://youtu.be/BAzxljI765U -youtubeImgUrl: https://i1.ytimg.com/vi/BAzxljI765U/mqdefault.jpg -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues diff --git a/microsite/data/on-demand/20220420-1.yaml b/microsite/data/on-demand/20220420-1.yaml deleted file mode 100644 index 96560ec436..0000000000 --- a/microsite/data/on-demand/20220420-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Adopters Community Sessions -date: April 20, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/mFi_X58igzk -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/44 diff --git a/microsite/data/on-demand/20220427-1.yaml b/microsite/data/on-demand/20220427-1.yaml deleted file mode 100644 index 80ec8eae00..0000000000 --- a/microsite/data/on-demand/20220427-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contributor Community Sessions -date: April 27, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/evf_LV0KzIk -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/44 diff --git a/microsite/data/on-demand/20220518-1.yaml b/microsite/data/on-demand/20220518-1.yaml deleted file mode 100644 index e8d70df2d9..0000000000 --- a/microsite/data/on-demand/20220518-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Adopters Community Sessions -date: May 18, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/dEd1fl3wRvo -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/46 diff --git a/microsite/data/on-demand/20220525-1.yaml b/microsite/data/on-demand/20220525-1.yaml deleted file mode 100644 index f9a3f87a8a..0000000000 --- a/microsite/data/on-demand/20220525-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contributor Community Sessions -date: May 25, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/neNipVE5ffY -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/46 diff --git a/microsite/data/on-demand/20220615-1.yaml b/microsite/data/on-demand/20220615-1.yaml deleted file mode 100644 index fb296dd6ce..0000000000 --- a/microsite/data/on-demand/20220615-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Adopters Community Sessions -date: June 15, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/aKZnjnE5Wy8 -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/49 diff --git a/microsite/data/on-demand/20220622-1.yaml b/microsite/data/on-demand/20220622-1.yaml deleted file mode 100644 index 27634609cb..0000000000 --- a/microsite/data/on-demand/20220622-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contributor Community Sessions -date: June 22, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/E-jWqWXBxUY -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/49 diff --git a/microsite/data/on-demand/20220720-1.yaml b/microsite/data/on-demand/20220720-1.yaml deleted file mode 100644 index a7c0386a56..0000000000 --- a/microsite/data/on-demand/20220720-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Adopters Community Sessions -date: July 20, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/4VFNlPxWcx8 -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/52 diff --git a/microsite/data/on-demand/20220727-1.yaml b/microsite/data/on-demand/20220727-1.yaml deleted file mode 100644 index b25b2e0789..0000000000 --- a/microsite/data/on-demand/20220727-1.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contributor Community Sessions -date: July 27, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/pNLLrNN_hkE -youtubeImgUrl: https://backstage.io/img/b-sessions.png -rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com -eventUrl: https://github.com/backstage/community/issues/52 diff --git a/microsite/data/on-demand/20220817-1.yaml b/microsite/data/on-demand/20220817-1.yaml deleted file mode 100644 index f67c8cf4cd..0000000000 --- a/microsite/data/on-demand/20220817-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Adopters Community Sessions -date: August 17, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/qYnvc8ge1kg -youtubeImgUrl: https://backstage.io/img/b-sessions.png diff --git a/microsite/data/on-demand/20220824-1.yaml b/microsite/data/on-demand/20220824-1.yaml deleted file mode 100644 index a2387a8aad..0000000000 --- a/microsite/data/on-demand/20220824-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Contributor Community Sessions -date: August 24, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/8ydEFFiuHAc -youtubeImgUrl: https://backstage.io/img/b-sessions.png diff --git a/microsite/data/on-demand/20220921-1.yaml b/microsite/data/on-demand/20220921-1.yaml deleted file mode 100644 index fe3dda08c0..0000000000 --- a/microsite/data/on-demand/20220921-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Adopters Community Sessions -date: September 21, 2022 -category: Meetup -description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. -youtubeUrl: https://youtu.be/K44RQAVWWnY -youtubeImgUrl: https://backstage.io/img/b-sessions.png diff --git a/microsite/data/on-demand/20220928-1.yaml b/microsite/data/on-demand/20220928-1.yaml deleted file mode 100644 index 31ae752e3a..0000000000 --- a/microsite/data/on-demand/20220928-1.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Contributor Community Sessions -date: September 28, 2022 -category: Meetup -description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/jmNT5x3mKaQ -youtubeImgUrl: https://backstage.io/img/b-sessions.png diff --git a/microsite/src/pages/community/index.tsx b/microsite/src/pages/community/index.tsx index dbc2c4b5e1..fdb97b39ec 100644 --- a/microsite/src/pages/community/index.tsx +++ b/microsite/src/pages/community/index.tsx @@ -42,8 +42,8 @@ const Community = () => { { title: 'Community sessions', content: - 'Maintainers and adopters meet monthly to share updates, demos, and ideas. Yep, all sessions are recorded!', - link: '/on-demand', + 'Maintainers and adopters meet monthly to share updates, demos, and ideas. You can find recorded session on our YouTube channel!', + link: 'https://github.com/backstage/community/tree/main/backstage-community-sessions#backstage-community-sessions', label: 'Join a session', }, { diff --git a/microsite/src/pages/on-demand/_onDemandCard.tsx b/microsite/src/pages/on-demand/_onDemandCard.tsx deleted file mode 100644 index e203c80f9a..0000000000 --- a/microsite/src/pages/on-demand/_onDemandCard.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import Link from '@docusaurus/Link'; -import { SimpleCard } from '@site/src/components/simpleCard/simpleCard'; -import React from 'react'; - -export interface IOnDemandData { - title: string; - category: string; - description: string; - date: string; - youtubeUrl: string; - youtubeImgUrl: string; - rsvpUrl: string; - eventUrl: string; -} - -export const OnDemandCard = ({ - title, - category, - description, - date, - youtubeUrl, - youtubeImgUrl, - rsvpUrl, - eventUrl, -}: IOnDemandData) => ( - -

{title}

- -

on {date}

- - {category} - - {title} - - } - body={

{description}

} - footer={ - category.toLowerCase() === 'upcoming' ? ( - <> - - Event page - - - - Remind me - - - ) : ( - - Watch on YouTube - - ) - } - /> -); diff --git a/microsite/src/pages/on-demand/index.tsx b/microsite/src/pages/on-demand/index.tsx deleted file mode 100644 index 8d78c393ce..0000000000 --- a/microsite/src/pages/on-demand/index.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import Layout from '@theme/Layout'; -import clsx from 'clsx'; -import React from 'react'; - -import { IOnDemandData, OnDemandCard } from './_onDemandCard'; -import pluginsStyles from './onDemand.module.scss'; -import { truncateDescription } from '@site/src/util/truncateDescription'; -import Link from '@docusaurus/Link'; - -//#region Plugin data import -const onDemandContext = require.context( - '../../../data/on-demand', - false, - /\.ya?ml/, -); - -const onDemandData = onDemandContext.keys().reduce( - (acum, id) => { - const pluginData: IOnDemandData = onDemandContext(id).default; - - acum[ - pluginData.category === 'Upcoming' ? 'upcomingEvents' : 'onDemandEvents' - ].push(truncateDescription(pluginData)); - - return acum; - }, - { - upcomingEvents: [] as IOnDemandData[], - onDemandEvents: [] as IOnDemandData[], - }, -); -//#endregion - -const Plugins = () => ( - -
-
-
-

Community sessions

- -

- Upcoming events and recorded sessions about updates, demos and - discussions. -

-
- - - Add an event or recording - -
- -
- -

Upcoming live events

- -
- {onDemandData.upcomingEvents.map(eventData => ( - - ))} -
- -

Community on demand

- -
- {onDemandData.onDemandEvents.map(eventData => ( - - ))} -
-
-
-); - -export default Plugins; diff --git a/microsite/src/pages/on-demand/onDemand.module.scss b/microsite/src/pages/on-demand/onDemand.module.scss deleted file mode 100644 index ff5797b687..0000000000 --- a/microsite/src/pages/on-demand/onDemand.module.scss +++ /dev/null @@ -1,44 +0,0 @@ -.onDemandPage { - :global(.communityBanner) { - display: flex; - align-items: center; - } - - :global(.communityContent) { - flex: 1; - } - - :global(.card) { - max-width: 100%; - } - - :global(.card .card__header) { - display: grid; - row-gap: 0.25rem; - column-gap: 1rem; - justify-items: start; - - > * { - margin: 0; - } - - :global(img) { - width: 250px; - max-width: 100%; - justify-self: center; - } - } - - :global(.card .card__footer) { - gap: 1rem; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); - } - - :global(.cardsContainer) { - gap: 1rem; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - justify-items: start; - } -} diff --git a/microsite/static/css/on-demand.css b/microsite/static/css/on-demand.css deleted file mode 100644 index 909459796c..0000000000 --- a/microsite/static/css/on-demand.css +++ /dev/null @@ -1,143 +0,0 @@ -.VideoCard { - background-color: #282828; - height: 100%; - padding: 16px; - display: flex; - flex-direction: column; -} - -.VideoGrid { - display: grid; - grid-gap: 1rem; - grid-template-columns: repeat(4, 1fr); - grid-auto-rows: 1fr; -} - -@media (max-width: 1200px) { - .VideoGrid { - grid-template-columns: repeat(3, 1fr); - } -} - -@media only screen and (max-width: 815px) { - .VideoGrid { - grid-template-columns: repeat(2, 1fr); - } -} - -@media only screen and (max-width: 485px) { - .VideoGrid { - grid-template-columns: 1fr; - } -} - -.VideoCard img { - float: left; - margin: 0px 16px 8px 0px; - height: 160px; - width: 300px; -} - -.VideoCardHeader { - display: flex; - flex-direction: row; - align-items: center; - max-height: fit-content; - min-height: fit-content; -} - -.VideoCardImage { - width: 200px; - height: 80px; - margin-right: 16px; -} - -.VideoCardImage img { - width: 100%; - max-width: 100%; -} - -.VideoCardTitle { - color: white; - vertical-align: top; - margin: 8px 0 0; -} - -.VideoCardInfo { - flex: 1; -} - -.VideoAddNewButton { - position: absolute; - bottom: 16px; - right: 0px; -} - -@media only screen and (max-width: 485px) { - .VideoAddNewButton { - bottom: -4px; - } -} - -.VideoButtonFilled { - padding: 4px 8px; - border-radius: 4px; - color: #69ddc7; -} - -.VideoButtonFilled:hover { - border: 1px solid #69ddc7; - background-color: transparent; -} - -.VideoCardChipOutlined { - font-size: small; - border-radius: 16px; - padding: 2px 8px; - border: 1px solid #69ddc7; - color: #69ddc7; -} - -.VideoCardFooter { - display: flex; - justify-content: flex-end; - align-items: flex-end; - margin-top: auto; - min-height: 2em; -} - -.VideoCardFooter a { - padding: 2px 8px; -} - -.VideoPageLayout { - margin: auto; - max-width: 1430px; - padding: 20px; -} - -.VideoPageHeader { - position: relative; -} - -.VideoPageHeader h2 { - display: inline-block; -} - -.VideoCardBody { - padding-top: 8px; -} - -.VideoCardDate, -.VideoCardDate a { - margin-bottom: 0.25em; - color: rgba(255, 255, 255, 0.6); -} - -.VideoCardDate a:hover { - color: white; -} - -#add-video-card { - border: 1px solid #69ddc7; -} From cd548c7c76ac7f9b3ae7f13a13cc20ae9962ad81 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey <34432188+sennyeya@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:31:50 -0500 Subject: [PATCH 34/52] Apply suggestions from code review Co-authored-by: Dave Welsch <116022979+dwelsch-esi@users.noreply.github.com> Signed-off-by: Aramis Sennyey <34432188+sennyeya@users.noreply.github.com> --- docs/references/glossary.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 45c2bbcd35..9d525d2430 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -99,9 +99,9 @@ An executable or package file with all of the necessary information required to ## Developer -Someone who writes code and develops software. +1. Someone who writes code and develops software. -A [user role](#user-role) defined as someone who uses a Backstage [app](#app). Might or might not actually be a software developer. +2. A [user role](#user-role) defined as someone who uses a Backstage [app](#app). Might or might not actually be a software developer. ## Developer Portal @@ -251,11 +251,11 @@ An [entity](#entity) that represents a piece of physical or virtual infrastructu ## Resource (permission plugin) -Not to be confused with [Software Catalog resources](#resource-catalog-plugin). Permission resources represent the objects that users interact with and that can be permissioned. +A representation of an object that a user interacts with and that can be permissioned. Not to be confused with [Software Catalog resources](#resource-catalog-plugin). ## Rule (permission plugin) -Rules are predicate-based controls that tap into a [resource](#resource-permission-plugin)'s data. +A predicate-based control that taps into a [resource](#resource-permission-plugin)'s data. ## Role From b408b6e28dbee90afe6a0b76d078dff0f3b39747 Mon Sep 17 00:00:00 2001 From: Aramis Date: Wed, 31 Jan 2024 12:32:24 -0500 Subject: [PATCH 35/52] differentiate software templates and software template Signed-off-by: Aramis --- docs/references/glossary.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 9d525d2430..8266dd02f7 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -251,7 +251,7 @@ An [entity](#entity) that represents a piece of physical or virtual infrastructu ## Resource (permission plugin) -A representation of an object that a user interacts with and that can be permissioned. Not to be confused with [Software Catalog resources](#resource-catalog-plugin). +A representation of an object that a user interacts with and that can be permissioned. Not to be confused with [Software Catalog resources](#resource-catalog-plugin). ## Rule (permission plugin) @@ -283,9 +283,11 @@ A Backstage plugin that provides a framework to keep track of ownership and meta ## Software Templates -1. A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. +A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. -2. A "skeleton" software project created and managed in the Backstage Software Templates tool. +## Software Template + +A "skeleton" software project created and managed in the Backstage Software Templates tool. ## System (catalog plugin) From cf860203c58b7adb1e6c161d9da39d8c50fdacca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:24:02 +0000 Subject: [PATCH 36/52] chore(deps): update dependency @playwright/test to v1.41.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 19e38d0aaf..60fe30ffb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14355,13 +14355,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.41.1 - resolution: "@playwright/test@npm:1.41.1" + version: 1.41.2 + resolution: "@playwright/test@npm:1.41.2" dependencies: - playwright: 1.41.1 + playwright: 1.41.2 bin: playwright: cli.js - checksum: d9877e777a1a7f60f097df57b6abc2478e2ae342930a409c8546c8aa40d6e206cbc16bf1c71b23414ac3fbad36dcae1ad79635d7f4eb705ab54d3c705e82ea04 + checksum: 87d9e725106111b2af1b2dec32454cd2a2d9665ff735669dc751caa30240e6db595ecfb9422719fa65dcff6ca19dea93ac2ae70d587efddde31def0754549d4c languageName: node linkType: hard @@ -37099,27 +37099,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.41.1": - version: 1.41.1 - resolution: "playwright-core@npm:1.41.1" +"playwright-core@npm:1.41.2": + version: 1.41.2 + resolution: "playwright-core@npm:1.41.2" bin: playwright-core: cli.js - checksum: c83446a560c6bd85f6f0cd586ff8c643b77e2005567386e12f85890936cc370673114b94cd883246018797cc1580e93b0296ade7d07275bb611b8962f5bb9693 + checksum: b41ede0db3fd3e3f7e0b0efbdfb2dbc4db345e113cf9c4451af21d1d5b5d9ab5e969f5662852925e37b2198ae5daab92aa48108fe3d4eb81c849ba8752aaf8cc languageName: node linkType: hard -"playwright@npm:1.41.1": - version: 1.41.1 - resolution: "playwright@npm:1.41.1" +"playwright@npm:1.41.2": + version: 1.41.2 + resolution: "playwright@npm:1.41.2" dependencies: fsevents: 2.3.2 - playwright-core: 1.41.1 + playwright-core: 1.41.2 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 3da7fb929abdec6adbdd8829f840580f5f210713214a8d230b130127f2270403eb2113c6c1418012221149707250fff896794c7c22c260dd09a92bf800227f31 + checksum: acf166003ec42cd795f5fca096c5135880d78e84ec2d0a1911b2cab984cf75dc06e50d3aa24b56cbcbc5369ca8c61831e76c5f8674531a272fbd0f6e624fa387 languageName: node linkType: hard From c4aaad016da9386eddd4fadd20091edfe5015d01 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 26 Jan 2024 14:02:55 -0500 Subject: [PATCH 37/52] backfill tests for makeProfileInfo Signed-off-by: Jamie Klassen --- .../passport/PassportStrategyHelper.test.ts | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.test.ts b/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.test.ts index dd0c1579a9..4d94634473 100644 --- a/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.test.ts +++ b/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.test.ts @@ -15,17 +15,118 @@ */ import express from 'express'; +import { UnsecuredJWT } from 'jose'; import passport from 'passport'; import { InternalOAuthError } from 'passport-oauth2'; import { executeRedirectStrategy, executeFrameHandlerStrategy, executeRefreshTokenStrategy, + makeProfileInfo, } from './PassportStrategyHelper'; +import { PassportProfile } from './types'; const mockRequest = {} as unknown as express.Request; describe('PassportStrategyHelper', () => { + describe('makeProfileInfo', () => { + it('retrieves email from passport profile', () => { + const profile: PassportProfile = { + emails: [{ value: 'email' }], + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo(profile); + + expect(profileInfo.email).toEqual('email'); + }); + + it('retrieves picture from passport profile avatarUrl', () => { + const profile: PassportProfile = { + avatarUrl: 'avatarUrl', + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo(profile); + + expect(profileInfo.picture).toEqual('avatarUrl'); + }); + + it('falls back to picture from passport profile photos field', () => { + const profile: PassportProfile = { + photos: [{ value: 'picture' }], + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo(profile); + + expect(profileInfo.picture).toEqual('picture'); + }); + + it('falls back to email from ID token', async () => { + const profile: PassportProfile = { + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo( + profile, + await new UnsecuredJWT({ email: 'email' }).encode(), + ); + + expect(profileInfo.email).toEqual('email'); + }); + + it('falls back to picture from ID token', async () => { + const profile: PassportProfile = { + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo( + profile, + await new UnsecuredJWT({ picture: 'picture' }).encode(), + ); + + expect(profileInfo.picture).toEqual('picture'); + }); + + it('falls back to name from ID token', async () => { + const profile: PassportProfile = { + provider: '', + id: '', + displayName: '', + }; + + const profileInfo = makeProfileInfo( + profile, + await new UnsecuredJWT({ name: 'name' }).encode(), + ); + + expect(profileInfo.displayName).toEqual('name'); + }); + + it('fails when attempting to fall back to invalid JWT', () => { + const profile: PassportProfile = { + provider: '', + id: '', + displayName: '', + }; + + expect(() => makeProfileInfo(profile, 'invalid JWT')).toThrow( + 'Failed to parse id token and get profile info', + ); + }); + }); + class MyCustomRedirectStrategy extends passport.Strategy { authenticate() { this.redirect('a', 302); From d4cc552ab1c1057fa1c7c6dee864c88e79dba54a Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 26 Jan 2024 14:05:24 -0500 Subject: [PATCH 38/52] refactor auth plugins to use jose Signed-off-by: Jamie Klassen --- .changeset/red-bottles-swim.md | 7 +++++ plugins/auth-backend/package.json | 1 - .../lib/passport/PassportStrategyHelper.ts | 8 +++-- .../auth-node/src/passport/PassportHelpers.ts | 31 ++++--------------- yarn.lock | 1 - 5 files changed, 19 insertions(+), 29 deletions(-) create mode 100644 .changeset/red-bottles-swim.md diff --git a/.changeset/red-bottles-swim.md b/.changeset/red-bottles-swim.md new file mode 100644 index 0000000000..eebdc85298 --- /dev/null +++ b/.changeset/red-bottles-swim.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-auth-node': patch +--- + +The helper function `makeProfileInfo` and `PassportHelpers.transformProfile` +were refactored to use the `jose` library. diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index eb0d30a9ba..25e0651361 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -64,7 +64,6 @@ "fs-extra": "10.1.0", "google-auth-library": "^8.0.0", "jose": "^4.6.0", - "jwt-decode": "^3.1.0", "knex": "^3.0.0", "lodash": "^4.17.21", "luxon": "^3.0.0", diff --git a/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.ts b/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.ts index 7589254862..44feb916c5 100644 --- a/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.ts +++ b/plugins/auth-backend/src/lib/passport/PassportStrategyHelper.ts @@ -16,7 +16,7 @@ import express from 'express'; import passport from 'passport'; -import jwtDecoder from 'jwt-decode'; +import { decodeJwt } from 'jose'; import { InternalOAuthError } from 'passport-oauth2'; import { PassportProfile } from './types'; @@ -51,7 +51,11 @@ export const makeProfileInfo = ( if ((!email || !picture || !displayName) && idToken) { try { - const decoded: Record = jwtDecoder(idToken); + const decoded = decodeJwt(idToken) as { + email?: string; + name?: string; + picture?: string; + }; if (!email && decoded.email) { email = decoded.email; } diff --git a/plugins/auth-node/src/passport/PassportHelpers.ts b/plugins/auth-node/src/passport/PassportHelpers.ts index 6c13523811..d7b554d56a 100644 --- a/plugins/auth-node/src/passport/PassportHelpers.ts +++ b/plugins/auth-node/src/passport/PassportHelpers.ts @@ -15,6 +15,7 @@ */ import { Request } from 'express'; +import { decodeJwt } from 'jose'; import { Strategy } from 'passport'; import { PassportProfile } from './types'; import { ProfileInfo } from '../types'; @@ -27,30 +28,6 @@ interface InternalOAuthError extends Error { }; } -/** @internal */ -function decodeJwtPayload(token: string): Record { - const payloadStr = token.split('.')[1]; - if (!payloadStr) { - throw new Error('Invalid JWT token'); - } - - let payload: unknown; - try { - payload = JSON.parse( - Buffer.from( - payloadStr.replace(/-/g, '+').replace(/_/g, '/'), - 'base64', - ).toString('utf8'), - ); - } catch (e) { - throw new Error('Invalid JWT token'); - } - if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { - throw new Error('Invalid JWT token'); - } - return payload as Record; -} - /** @public */ export class PassportHelpers { private constructor() {} @@ -78,7 +55,11 @@ export class PassportHelpers { if ((!email || !picture || !displayName) && idToken) { try { - const decoded: Record = decodeJwtPayload(idToken); + const decoded = decodeJwt(idToken) as { + email?: string; + name?: string; + picture?: string; + }; if (!email && decoded.email) { email = decoded.email; } diff --git a/yarn.lock b/yarn.lock index 8c0ddcabc2..de0169115f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4932,7 +4932,6 @@ __metadata: fs-extra: 10.1.0 google-auth-library: ^8.0.0 jose: ^4.6.0 - jwt-decode: ^3.1.0 knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 From d309cadf47de530e4dcca9592bd6ed95a491b600 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Tue, 30 Jan 2024 11:25:04 -0500 Subject: [PATCH 39/52] remove jwt-decode from aws-alb provider Signed-off-by: Jamie Klassen --- .changeset/nasty-days-jog.md | 5 + .../package.json | 7 +- .../src/authenticator.test.ts | 113 ++++++++++++------ .../src/helpers.test.ts | 69 ++++++----- .../src/helpers.ts | 15 ++- plugins/auth-backend/package.json | 1 - yarn.lock | 20 +--- 7 files changed, 130 insertions(+), 100 deletions(-) create mode 100644 .changeset/nasty-days-jog.md diff --git a/.changeset/nasty-days-jog.md b/.changeset/nasty-days-jog.md new file mode 100644 index 0000000000..09454609b2 --- /dev/null +++ b/.changeset/nasty-days-jog.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +--- + +Refactored to use the `jose` library for JWT handling. diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index f6238cca5d..d4658dd7ea 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -38,14 +38,15 @@ "@backstage/plugin-auth-backend": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "jose": "^4.6.0", - "jwt-decode": "^3.1.0", - "node-cache": "^5.1.2" + "node-cache": "^5.1.2", + "node-fetch": "^2.6.7" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^", - "express": "^4.18.2" + "express": "^4.18.2", + "msw": "^2.0.8" }, "files": [ "dist" diff --git a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts index bfcbfce622..5f19d800a0 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts @@ -14,36 +14,30 @@ * limitations under the License. */ +import express from 'express'; +import { SignJWT } from 'jose'; import { ALB_ACCESS_TOKEN_HEADER, ALB_JWT_HEADER, awsAlbAuthenticator, } from './authenticator'; -import { jwtVerify } from 'jose'; -import express from 'express'; -import { AuthenticationError } from '@backstage/errors'; import { Config } from '@backstage/config'; +import { AuthenticationError } from '@backstage/errors'; -const jwtMock = jwtVerify as jest.Mocked; -const mockJwt = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktFWV9JRCIsImlzcyI6IklTU1VFUl9VUkwifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlVzZXIgTmFtZSIsImlhdCI6MTUxNjIzOTAyMn0.uMCSBGhij1xn5pnot8XgD-huQuTIBOFGs6kkW_p_X94'; -const mockAccessToken = 'ACCESS_TOKEN'; -const mockClaims = { - sub: '1234567890', - name: 'User Name', - family_name: 'Name', - given_name: 'User', - picture: 'PICTURE_URL', - email: 'user.name@email.test', - exp: 1632833763, - iss: 'ISSUER_URL', -}; -jest.mock('jose'); - -beforeEach(() => { - jest.clearAllMocks(); -}); describe('AwsAlbProvider', () => { + const mockAccessToken = 'ACCESS_TOKEN'; + const mockClaims = { + sub: '1234567890', + name: 'User Name', + family_name: 'Name', + given_name: 'User', + picture: 'PICTURE_URL', + email: 'user.name@email.test', + exp: Date.now() + 10000, + iss: 'ISSUER_URL', + }; + const signingKey = new TextEncoder().encode('signingKey'); + let mockJwt: string; const mockRequest = { header: jest.fn(name => { if (name === ALB_JWT_HEADER) { @@ -54,6 +48,16 @@ describe('AwsAlbProvider', () => { return undefined; }), } as unknown as express.Request; + const mockRequestWithInvalidJwt = { + header: jest.fn(name => { + if (name === ALB_JWT_HEADER) { + return 'invalid.jwt'; + } else if (name === ALB_ACCESS_TOKEN_HEADER) { + return mockAccessToken; + } + return undefined; + }), + } as unknown as express.Request; const mockRequestWithoutJwt = { header: jest.fn(name => { if (name === ALB_ACCESS_TOKEN_HEADER) { @@ -71,13 +75,20 @@ describe('AwsAlbProvider', () => { }), } as unknown as express.Request; + beforeEach(async () => { + mockJwt = await new SignJWT(mockClaims) + .setProtectedHeader({ alg: 'HS256' }) + .sign(signingKey); + }); + describe('should transform to type AwsAlbResponse', () => { it('when JWT is valid and identity is resolved successfully', async () => { - jwtMock.mockReturnValueOnce(Promise.resolve({ payload: mockClaims })); - const response = await awsAlbAuthenticator.authenticate( { req: mockRequest }, - { issuer: 'ISSUER_URL', getKey: jest.fn() }, + { + issuer: 'ISSUER_URL', + getKey: jest.fn().mockResolvedValue(signingKey), + }, ); expect(response).toEqual({ result: { @@ -119,27 +130,38 @@ describe('AwsAlbProvider', () => { }); it('JWT is invalid', async () => { - jwtMock.mockImplementationOnce(() => { - throw new Error('bad JWT'); - }); - await expect( awsAlbAuthenticator.authenticate( - { req: mockRequest }, + { req: mockRequestWithInvalidJwt }, { issuer: 'ISSUER_URL', getKey: jest.fn() }, ), ).rejects.toThrow( - 'Exception occurred during JWT processing: Error: bad JWT', + 'Exception occurred during JWT processing: JWSInvalid: Invalid Compact JWS', ); }); it('issuer is missing', async () => { - jwtMock.mockReturnValueOnce({}); + const jwt = await new SignJWT({}) + .setProtectedHeader({ alg: 'HS256' }) + .sign(signingKey); + const req = { + header: jest.fn(name => { + if (name === ALB_JWT_HEADER) { + return jwt; + } else if (name === ALB_ACCESS_TOKEN_HEADER) { + return mockAccessToken; + } + return undefined; + }), + } as unknown as express.Request; await expect( awsAlbAuthenticator.authenticate( - { req: mockRequest }, - { issuer: 'ISSUER_URL', getKey: jest.fn() }, + { req }, + { + issuer: 'ISSUER_URL', + getKey: jest.fn().mockResolvedValue(signingKey), + }, ), ).rejects.toThrow( 'Exception occurred during JWT processing: AuthenticationError: Issuer mismatch on JWT token', @@ -147,14 +169,27 @@ describe('AwsAlbProvider', () => { }); it('issuer is invalid', async () => { - jwtMock.mockReturnValueOnce({ - iss: 'INVALID_ISSUE_URL', - }); + const jwt = await new SignJWT({ iss: 'INVALID_ISSUER_URL' }) + .setProtectedHeader({ alg: 'HS256' }) + .sign(signingKey); + const req = { + header: jest.fn(name => { + if (name === ALB_JWT_HEADER) { + return jwt; + } else if (name === ALB_ACCESS_TOKEN_HEADER) { + return mockAccessToken; + } + return undefined; + }), + } as unknown as express.Request; await expect( awsAlbAuthenticator.authenticate( - { req: mockRequest }, - { issuer: 'ISSUER_URL', getKey: jest.fn() }, + { req }, + { + issuer: 'ISSUER_URL', + getKey: jest.fn().mockResolvedValue(signingKey), + }, ), ).rejects.toThrow( 'Exception occurred during JWT processing: AuthenticationError: Issuer mismatch on JWT token', diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts index 07ad118cea..cb103debb0 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts @@ -1,10 +1,3 @@ -import NodeCache from 'node-cache'; -import { makeProfileInfo, provisionKeyCache } from './helpers'; -import * as crypto from 'crypto'; -import { JWTHeaderParameters } from 'jose'; -import { PassportProfile } from '@backstage/plugin-auth-node'; -import jwtDecoder from 'jwt-decode'; - /* * Copyright 2020 The Backstage Authors * @@ -21,40 +14,47 @@ import jwtDecoder from 'jwt-decode'; * limitations under the License. */ -const mockKey = async () => { - return `-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnuN4LlaJhaUpx+qZFTzYCrSBLk0I -yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== ------END PUBLIC KEY----- -`; -}; +import * as crypto from 'crypto'; +import { JWTHeaderParameters, UnsecuredJWT } from 'jose'; +import NodeCache from 'node-cache'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { PassportProfile } from '@backstage/plugin-auth-node'; +import { makeProfileInfo, provisionKeyCache } from './helpers'; + jest.mock('crypto'); const cryptoMock = crypto as jest.Mocked; -jest.mock('node-fetch', () => ({ - __esModule: true, - default: async () => { - return { - text: async () => { - return mockKey(); - }, - }; - }, -})); - -const jwtMock = jwtDecoder as jest.Mocked; -jest.mock('jwt-decode'); describe('helpers', () => { + const server = setupServer(); + setupRequestMockHandlers(server); + const nodeCache = jest.fn() as unknown as NodeCache; nodeCache.set = jest.fn(); beforeEach(() => { jest.clearAllMocks(); + server.use( + http.get( + 'https://public-keys.auth.elb.eu-west-1.amazonaws.com/kid', + () => + new HttpResponse( + `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnuN4LlaJhaUpx+qZFTzYCrSBLk0I +yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== +-----END PUBLIC KEY----- +`, + ), + ), + ); }); + it('should create a key', () => { const getKey = provisionKeyCache('eu-west-1', nodeCache); expect(getKey).toBeDefined(); }); + it('should return a key from cache', async () => { const getKey = provisionKeyCache('eu-west-1', nodeCache); @@ -65,6 +65,7 @@ describe('helpers', () => { expect(key).toBe('key'); }); + it('should update cache if key is not found', async () => { const getKey = provisionKeyCache('eu-west-1', nodeCache); @@ -77,6 +78,7 @@ describe('helpers', () => { await getKey({ kid: 'kid' } as unknown as JWTHeaderParameters); expect(nodeCache.set).toHaveBeenCalledWith('kid', 'key'); }); + it('should throw error if key is not found', async () => { const getKey = provisionKeyCache('eu-west-1', nodeCache); @@ -87,6 +89,7 @@ describe('helpers', () => { getKey({ kid: 'kid' } as unknown as JWTHeaderParameters), ).rejects.toThrow(); }); + it('should throw if key is not present in request header', async () => { const getKey = provisionKeyCache('eu-west-1', nodeCache); @@ -119,19 +122,19 @@ describe('makeProfileInfo', () => { }; expect(makeProfileInfo(profile, accessToken)).toEqual(result); }); + it('should return profile info from id token', () => { - jwtMock.mockReturnValueOnce({ - email: 'email', - picture: 'picture', - name: 'displayName', - }); const profile = { name: { familyName: 'familyName', givenName: 'givenName', }, } as PassportProfile; - const idToken = 'idToken'; + const idToken = new UnsecuredJWT({ + email: 'email', + picture: 'picture', + name: 'displayName', + }).encode(); const result = { email: 'email', picture: 'picture', diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index d97146bb93..e846b2484e 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import type { PassportProfile } from '@backstage/plugin-auth-node/'; -import { ProfileInfo } from '@backstage/plugin-auth-node'; import { KeyObject } from 'crypto'; -import jwtDecoder from 'jwt-decode'; -import NodeCache from 'node-cache'; import * as crypto from 'crypto'; -import { JWTHeaderParameters } from 'jose'; +import { JWTHeaderParameters, decodeJwt } from 'jose'; +import NodeCache from 'node-cache'; +import fetch from 'node-fetch'; +import { PassportProfile, ProfileInfo } from '@backstage/plugin-auth-node'; import { AuthenticationError } from '@backstage/errors'; export const makeProfileInfo = ( @@ -45,7 +44,11 @@ export const makeProfileInfo = ( if ((!email || !picture || !displayName) && idToken) { try { - const decoded: Record = jwtDecoder(idToken); + const decoded: Record = decodeJwt(idToken) as { + email?: string; + picture?: string; + name?: string; + }; if (!email && decoded.email) { email = decoded.email; } diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 25e0651361..f7494247dc 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -92,7 +92,6 @@ "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", - "@types/jwt-decode": "^3.1.0", "@types/passport-auth0": "^1.0.5", "@types/passport-github2": "^1.2.4", "@types/passport-google-oauth20": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index de0169115f..363823b103 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4677,8 +4677,9 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" express: ^4.18.2 jose: ^4.6.0 - jwt-decode: ^3.1.0 + msw: ^2.0.8 node-cache: ^5.1.2 + node-fetch: ^2.6.7 languageName: unknown linkType: soft @@ -4913,7 +4914,6 @@ __metadata: "@types/cookie-parser": ^1.4.2 "@types/express": ^4.17.6 "@types/express-session": ^1.17.2 - "@types/jwt-decode": ^3.1.0 "@types/passport": ^1.0.3 "@types/passport-auth0": ^1.0.5 "@types/passport-github2": ^1.2.4 @@ -18482,15 +18482,6 @@ __metadata: languageName: node linkType: hard -"@types/jwt-decode@npm:^3.1.0": - version: 3.1.0 - resolution: "@types/jwt-decode@npm:3.1.0" - dependencies: - jwt-decode: "*" - checksum: 82ff0b3826e5d9da48be1f11e16fec96e56dd946995edaa100682202b9b7beb30fb04a353cbabd378d3b13a24241b48a0b662a4f181bae7f758147d92368d930 - languageName: node - linkType: hard - "@types/keyv@npm:*, @types/keyv@npm:^3.1.1": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -32363,13 +32354,6 @@ __metadata: languageName: node linkType: hard -"jwt-decode@npm:*, jwt-decode@npm:^3.1.0": - version: 3.1.2 - resolution: "jwt-decode@npm:3.1.2" - checksum: 20a4b072d44ce3479f42d0d2c8d3dabeb353081ba4982e40b83a779f2459a70be26441be6c160bfc8c3c6eadf9f6380a036fbb06ac5406b5674e35d8c4205eeb - languageName: node - linkType: hard - "kafkajs@npm:^2.0.0": version: 2.2.4 resolution: "kafkajs@npm:2.2.4" From 79062f9c48ffe4b604ebb457d44771ac42fd2b0e Mon Sep 17 00:00:00 2001 From: Adi-Sin Date: Fri, 2 Feb 2024 23:05:47 +0530 Subject: [PATCH 40/52] Update github-codespaces.yaml Update author name Signed-off-by: Adi-Sin --- microsite/data/plugins/github-codespaces.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/github-codespaces.yaml b/microsite/data/plugins/github-codespaces.yaml index de2659c1e1..d846235bd6 100644 --- a/microsite/data/plugins/github-codespaces.yaml +++ b/microsite/data/plugins/github-codespaces.yaml @@ -1,6 +1,6 @@ --- title: GitHub Codespaces -author: Aditya Singhal +author: Aditya Singhal - Lab45 authorUrl: https://github.com/adityasinghal26 category: Development description: Integrates GitHub Codespaces for a Backstage component with the Authenticated User. From 294fab8315a7a26e8a6786b7343da215e2c12644 Mon Sep 17 00:00:00 2001 From: Danyelle AC <90638175+Danyelleac@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:01:50 -0300 Subject: [PATCH 41/52] Update .changeset/fresh-gifts-smile.md Co-authored-by: Sydney Achinger <78113809+squid-ney@users.noreply.github.com> Signed-off-by: Danyelle AC <90638175+Danyelleac@users.noreply.github.com> --- .changeset/fresh-gifts-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fresh-gifts-smile.md b/.changeset/fresh-gifts-smile.md index ffa680bb8e..446e9f3c54 100644 --- a/.changeset/fresh-gifts-smile.md +++ b/.changeset/fresh-gifts-smile.md @@ -2,4 +2,4 @@ '@backstage/plugin-techdocs-module-addons-contrib': patch --- -textsize-fix value label text color +Fixed the value label text color in dark mode for the TextSize addon. From f71352cfe9137d266860603992f6583978315a5d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 29 Jan 2024 11:51:48 +0100 Subject: [PATCH 42/52] align typescript versions to 5.1 + 5.3 Signed-off-by: Patrik Oldsberg --- .changeset/mighty-steaks-shave.md | 5 +++++ microsite/package.json | 2 +- microsite/yarn.lock | 18 +++++++-------- package.json | 2 +- .../src/layout/Sidebar/Page.tsx | 12 +++++----- .../templates/default-app/package.json.hbs | 2 +- plugins/git-release-manager/api-report.md | 16 +++++++------- yarn.lock | 22 +------------------ 8 files changed, 32 insertions(+), 47 deletions(-) create mode 100644 .changeset/mighty-steaks-shave.md diff --git a/.changeset/mighty-steaks-shave.md b/.changeset/mighty-steaks-shave.md new file mode 100644 index 0000000000..b85447e5c0 --- /dev/null +++ b/.changeset/mighty-steaks-shave.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped TypeScript to version `5.3`. diff --git a/microsite/package.json b/microsite/package.json index 53309fb358..d90c455167 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -25,7 +25,7 @@ "@types/webpack-env": "^1.18.0", "js-yaml": "^4.1.0", "prettier": "^2.6.2", - "typescript": "~5.0.0", + "typescript": "~5.1.0", "yaml-loader": "^0.8.0" }, "prettier": "@spotify/prettier-config", diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 50465ec651..4c9f348fe3 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -3907,7 +3907,7 @@ __metadata: react-dom: ^18.0.0 sass: ^1.57.1 swc-loader: ^0.2.3 - typescript: ~5.0.0 + typescript: ~5.1.0 yaml-loader: ^0.8.0 languageName: unknown linkType: soft @@ -11692,23 +11692,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.0.0": - version: 5.0.4 - resolution: "typescript@npm:5.0.4" +"typescript@npm:~5.1.0": + version: 5.1.6 + resolution: "typescript@npm:5.1.6" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 + checksum: b2f2c35096035fe1f5facd1e38922ccb8558996331405eb00a5111cc948b2e733163cc22fab5db46992aba7dd520fff637f2c1df4996ff0e134e77d3249a7350 languageName: node linkType: hard -"typescript@patch:typescript@~5.0.0#~builtin": - version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=a1c5e5" +"typescript@patch:typescript@~5.1.0#~builtin": + version: 5.1.6 + resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=a1c5e5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 6a1fe9a77bb9c5176ead919cc4a1499ee63e46b4e05bf667079f11bf3a8f7887f135aa72460a4c3b016e6e6bb65a822cb8689a6d86cbfe92d22cc9f501f09213 + checksum: 21e88b0a0c0226f9cb9fd25b9626fb05b4c0f3fddac521844a13e1f30beb8f14e90bd409a9ac43c812c5946d714d6e0dee12d5d02dfc1c562c5aacfa1f49b606 languageName: node linkType: hard diff --git a/package.json b/package.json index 1e53b7c00f..6deae7611e 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "semver": "^7.5.3", "shx": "^0.3.2", "ts-node": "^10.4.0", - "typescript": "~5.2.0" + "typescript": "~5.1.0" }, "prettier": "@spotify/prettier-config", "lint-staged": { diff --git a/packages/core-components/src/layout/Sidebar/Page.tsx b/packages/core-components/src/layout/Sidebar/Page.tsx index 09d5bd910c..3d618fc5a0 100644 --- a/packages/core-components/src/layout/Sidebar/Page.tsx +++ b/packages/core-components/src/layout/Sidebar/Page.tsx @@ -33,23 +33,23 @@ import { SidebarPinStateProvider } from './SidebarPinStateContext'; export type SidebarPageClassKey = 'root'; -const useStyles = makeStyles< - Theme, - { sidebarConfig: SidebarConfig; isPinned: boolean } ->( +type StyleProps = { sidebarConfig: SidebarConfig; isPinned: boolean }; + +const useStyles = makeStyles( theme => ({ root: { width: '100%', transition: 'padding-left 0.1s ease-out', isolation: 'isolate', [theme.breakpoints.up('sm')]: { - paddingLeft: props => + paddingLeft: (props: StyleProps) => props.isPinned ? props.sidebarConfig.drawerWidthOpen : props.sidebarConfig.drawerWidthClosed, }, [theme.breakpoints.down('xs')]: { - paddingBottom: props => props.sidebarConfig.mobileSidebarHeight, + paddingBottom: (props: StyleProps) => + props.sidebarConfig.mobileSidebarHeight, }, '@media print': { padding: '0px !important', diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index 40cc8282d9..f2f35360cc 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -39,7 +39,7 @@ "lerna": "^7.3.0", "node-gyp": "^9.0.0", "prettier": "^2.3.2", - "typescript": "~5.2.0" + "typescript": "~5.3.0" }, "resolutions": { "@types/react": "^18", diff --git a/plugins/git-release-manager/api-report.md b/plugins/git-release-manager/api-report.md index d2dd7e909f..3e4c0847a7 100644 --- a/plugins/git-release-manager/api-report.md +++ b/plugins/git-release-manager/api-report.md @@ -317,42 +317,42 @@ function LinearProgressWithLabel(props: { // Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_BRANCH_NAME_CALVER = 'rc/2020.01.01_1'; +const MOCK_RELEASE_BRANCH_NAME_CALVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_BRANCH_NAME_SEMVER = 'rc/1.2.3'; +const MOCK_RELEASE_BRANCH_NAME_SEMVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER = 'rc-2020.01.01_1'; +const MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER = 'rc-1.2.3'; +const MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_NAME_CALVER = 'Version 2020.01.01_1'; +const MOCK_RELEASE_NAME_CALVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_NAME_SEMVER = 'Version 1.2.3'; +const MOCK_RELEASE_NAME_SEMVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_VERSION_TAG_NAME_CALVER = 'version-2020.01.01_1'; +const MOCK_RELEASE_VERSION_TAG_NAME_CALVER: string; // Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const MOCK_RELEASE_VERSION_TAG_NAME_SEMVER = 'version-1.2.3'; +const MOCK_RELEASE_VERSION_TAG_NAME_SEMVER: string; // Warning: (ae-missing-release-tag) "mockBumpedTag" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/yarn.lock b/yarn.lock index 8c0ddcabc2..fa8ea9170c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40134,7 +40134,7 @@ __metadata: semver: ^7.5.3 shx: ^0.3.2 ts-node: ^10.4.0 - typescript: ~5.2.0 + typescript: ~5.1.0 languageName: unknown linkType: soft @@ -43196,16 +43196,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.2.0": - version: 5.2.2 - resolution: "typescript@npm:5.2.2" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c - languageName: node - linkType: hard - "typescript@patch:typescript@~5.0.4#~builtin": version: 5.0.4 resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=a1c5e5" @@ -43226,16 +43216,6 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~5.2.0#~builtin": - version: 5.2.2 - resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=a1c5e5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554 - languageName: node - linkType: hard - "ua-parser-js@npm:^0.7.30": version: 0.7.33 resolution: "ua-parser-js@npm:0.7.33" From ea2b5218868a093fd37d9922c907bdb7077a1f17 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 11:31:32 +0000 Subject: [PATCH 43/52] chore(deps): update dependency @types/jest to v29.5.12 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 d0070ef970..b66ca12848 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18371,12 +18371,12 @@ __metadata: linkType: hard "@types/jest@npm:*, @types/jest@npm:^29.0.0, @types/jest@npm:^29.5.11": - version: 29.5.11 - resolution: "@types/jest@npm:29.5.11" + version: 29.5.12 + resolution: "@types/jest@npm:29.5.12" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: f892a06ec9f0afa9a61cd7fa316ec614e21d4df1ad301b5a837787e046fcb40dfdf7f264a55e813ac6b9b633cb9d366bd5b8d1cea725e84102477b366df23fdd + checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c languageName: node linkType: hard From 0add87ca6a05a6f632cf4474c5bc38e85b38502e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 11:32:01 +0000 Subject: [PATCH 44/52] chore(deps): update dependency @types/react to v18.2.52 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 d0070ef970..d586cee159 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19011,13 +19011,13 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.2.48 - resolution: "@types/react@npm:18.2.48" + version: 18.2.52 + resolution: "@types/react@npm:18.2.52" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: c9ca43ed2995389b7e09492c24e6f911a8439bb8276dd17cc66a2fbebbf0b42daf7b2ad177043256533607c2ca644d7d928fdfce37a67af1f8646d2bac988900 + checksum: 4abc9bd63879e57c3df43a9cacff54c079e21b61ef934d33801e0177c26f582aa7d1d88a0769a740a4fd273168e3b150ff61de23e0fa85d1070e82ddce2b7fd2 languageName: node linkType: hard From 87dea686bfa75d852d84276f32d3f8191dbfd0b9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 3 Feb 2024 12:34:06 +0100 Subject: [PATCH 45/52] auth-backend: refactor to remove internal hardcoded default session expiration Signed-off-by: Patrik Oldsberg --- .../auth-backend/src/lib/session/constants.ts | 19 ----- plugins/auth-backend/src/lib/session/index.ts | 17 ---- .../readBackstageTokenExpiration.test.ts | 77 +++++++++++++++++++ .../service/readBackstageTokenExpiration.ts | 44 +++++++++++ .../auth-backend/src/service/router.test.ts | 67 +--------------- plugins/auth-backend/src/service/router.ts | 31 +------- 6 files changed, 125 insertions(+), 130 deletions(-) delete mode 100644 plugins/auth-backend/src/lib/session/constants.ts delete mode 100644 plugins/auth-backend/src/lib/session/index.ts create mode 100644 plugins/auth-backend/src/service/readBackstageTokenExpiration.test.ts create mode 100644 plugins/auth-backend/src/service/readBackstageTokenExpiration.ts diff --git a/plugins/auth-backend/src/lib/session/constants.ts b/plugins/auth-backend/src/lib/session/constants.ts deleted file mode 100644 index 0d14987ab2..0000000000 --- a/plugins/auth-backend/src/lib/session/constants.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2023 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. - */ - -// BACKSTAGE_SESSION_EXPIRATION the default session expiration time -// TODO: find a less hard-coded way to access this, perhaps by reading it from the configuration. -export const BACKSTAGE_SESSION_EXPIRATION = 3600; diff --git a/plugins/auth-backend/src/lib/session/index.ts b/plugins/auth-backend/src/lib/session/index.ts deleted file mode 100644 index 306d483ae0..0000000000 --- a/plugins/auth-backend/src/lib/session/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 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 { BACKSTAGE_SESSION_EXPIRATION } from './constants'; diff --git a/plugins/auth-backend/src/service/readBackstageTokenExpiration.test.ts b/plugins/auth-backend/src/service/readBackstageTokenExpiration.test.ts new file mode 100644 index 0000000000..e1f863678a --- /dev/null +++ b/plugins/auth-backend/src/service/readBackstageTokenExpiration.test.ts @@ -0,0 +1,77 @@ +/* + * 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 { ConfigReader } from '@backstage/config'; +import { readBackstageTokenExpiration } from './readBackstageTokenExpiration'; + +describe('Test for default backstage token expiry time', () => { + it('Will return default backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + }); + expect(readBackstageTokenExpiration(config)).toBe(3600); + }); + + it('Will return user defined 120 minutes as backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 120 }, + }, + }); + expect(readBackstageTokenExpiration(config)).toBe(7200); + }); + + it('Will return minimum duration of 10 minutes as backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 2 }, + }, + }); + expect(readBackstageTokenExpiration(config)).toBe(600); + }); + + it('Will return user configured value as backstage session expiration', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 20 }, + }, + }); + expect(readBackstageTokenExpiration(config)).toBe(1200); + }); + + it('Will return maximum of 24 hour as backstage session expiration if user configured value is more than a day', () => { + const config = new ConfigReader({ + app: { + baseUrl: 'http://example.com/extra-path', + }, + auth: { + backstageTokenExpiration: { minutes: 1500 }, + }, + }); + expect(readBackstageTokenExpiration(config)).toBe(86400); + }); +}); diff --git a/plugins/auth-backend/src/service/readBackstageTokenExpiration.ts b/plugins/auth-backend/src/service/readBackstageTokenExpiration.ts new file mode 100644 index 0000000000..c687ecdfc5 --- /dev/null +++ b/plugins/auth-backend/src/service/readBackstageTokenExpiration.ts @@ -0,0 +1,44 @@ +/* + * 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 { RootConfigService } from '@backstage/backend-plugin-api'; +import { readDurationFromConfig } from '@backstage/config'; +import { durationToMilliseconds } from '@backstage/types'; + +const TOKEN_EXP_DEFAULT_S = 3600; +const TOKEN_EXP_MIN_S = 600; +const TOKEN_EXP_MAX_S = 86400; + +export function readBackstageTokenExpiration(config: RootConfigService) { + const processingIntervalKey = 'auth.backstageTokenExpiration'; + + if (!config.has(processingIntervalKey)) { + return TOKEN_EXP_DEFAULT_S; + } + + const duration = readDurationFromConfig(config, { + key: processingIntervalKey, + }); + + const durationS = Math.round(durationToMilliseconds(duration) / 1000); + + if (durationS < TOKEN_EXP_MIN_S) { + return TOKEN_EXP_MIN_S; + } else if (durationS > TOKEN_EXP_MAX_S) { + return TOKEN_EXP_MAX_S; + } + return durationS; +} diff --git a/plugins/auth-backend/src/service/router.test.ts b/plugins/auth-backend/src/service/router.test.ts index 8805a60e56..3a1fde881e 100644 --- a/plugins/auth-backend/src/service/router.test.ts +++ b/plugins/auth-backend/src/service/router.test.ts @@ -15,11 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { - createOriginFilter, - getDefaultBackstageTokenExpiryTime, -} from './router'; -import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session'; +import { createOriginFilter } from './router'; describe('Auth origin filtering', () => { const config = new ConfigReader({ @@ -56,64 +52,3 @@ describe('Auth origin filtering', () => { expect(createOriginFilter(config)(origin)).toBeTruthy(); }); }); - -describe('Test for default backstage token expiry time', () => { - it('Will return default backstage session expiration', () => { - const config = new ConfigReader({ - app: { - baseUrl: 'http://example.com/extra-path', - }, - }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe( - BACKSTAGE_SESSION_EXPIRATION, - ); - }); - - it('Will return user defined 120 minutes as backstage session expiration', () => { - const config = new ConfigReader({ - app: { - baseUrl: 'http://example.com/extra-path', - }, - auth: { - backstageTokenExpiration: { minutes: 120 }, - }, - }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe(7200); - }); - - it('Will return minimum duration of 10 minutes as backstage session expiration', () => { - const config = new ConfigReader({ - app: { - baseUrl: 'http://example.com/extra-path', - }, - auth: { - backstageTokenExpiration: { minutes: 2 }, - }, - }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe(600); - }); - - it('Will return user configured value as backstage session expiration', () => { - const config = new ConfigReader({ - app: { - baseUrl: 'http://example.com/extra-path', - }, - auth: { - backstageTokenExpiration: { minutes: 20 }, - }, - }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe(1200); - }); - - it('Will return maximum of 24 hour as backstage session expiration if user configured value is more than a day', () => { - const config = new ConfigReader({ - app: { - baseUrl: 'http://example.com/extra-path', - }, - auth: { - backstageTokenExpiration: { minutes: 1500 }, - }, - }); - expect(getDefaultBackstageTokenExpiryTime(config)).toBe(86400); - }); -}); diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index dddac82c2d..44861207ed 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -36,12 +36,11 @@ import passport from 'passport'; import { Minimatch } from 'minimatch'; import { CatalogAuthResolverContext } from '../lib/resolvers'; import { AuthDatabase } from '../database/AuthDatabase'; -import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session'; +import { readBackstageTokenExpiration } from './readBackstageTokenExpiration'; import { TokenIssuer } from '../identity/types'; import { StaticTokenIssuer } from '../identity/StaticTokenIssuer'; import { StaticKeyStore } from '../identity/StaticKeyStore'; -import { Config, readDurationFromConfig } from '@backstage/config'; -import { durationToMilliseconds } from '@backstage/types'; +import { Config } from '@backstage/config'; /** @public */ export type ProviderFactories = { [s: string]: AuthProviderFactory }; @@ -77,7 +76,7 @@ export async function createRouter( const appUrl = config.getString('app.baseUrl'); const authUrl = await discovery.getExternalBaseUrl('auth'); - const backstageTokenExpiration = getDefaultBackstageTokenExpiryTime(config); + const backstageTokenExpiration = readBackstageTokenExpiration(config); const authDb = AuthDatabase.create(database); const keyStore = await KeyStores.fromConfig(config, { @@ -249,27 +248,3 @@ export function createOriginFilter( return allowedOriginPatterns.some(pattern => pattern.match(origin)); }; } - -/** @internal */ -export function getDefaultBackstageTokenExpiryTime(config: Config) { - const processingIntervalKey = 'auth.backstageTokenExpiration'; - - if (!config.has(processingIntervalKey)) { - return BACKSTAGE_SESSION_EXPIRATION; - } - - const duration = readDurationFromConfig(config, { - key: processingIntervalKey, - }); - - const roundedDuration = Math.round(durationToMilliseconds(duration) / 1000); - - const minSeconds = Math.max(600, roundedDuration); - - const maxSeconds = Math.min(86400, roundedDuration); - - if (roundedDuration < minSeconds) { - return minSeconds - } - return maxSeconds; -} From c6a5c47885409ce2940bde993e66743a2cf175f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 12:00:35 +0000 Subject: [PATCH 46/52] chore(deps): update docker/metadata-action action to v5.5.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/uffizzi-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index 6eac098448..c1b3bc50ea 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -61,7 +61,7 @@ jobs: - name: Docker metadata id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: registry.uffizzi.com/${{ env.UUID_TAG_APP }} tags: type=raw,value=60d From 6bdc749a628f20a7f98473c6f5f730aa0e0a1f63 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 12:00:42 +0000 Subject: [PATCH 47/52] chore(deps): update microsoft/setup-msbuild action to v1.3.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/verify_e2e-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 802247341f..eb9da86c52 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -61,7 +61,7 @@ jobs: python-version: '3.10' - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.3.2 + uses: microsoft/setup-msbuild@v1.3.3 - name: Setup gyp env run: | From f9819a4f9120b0215c6b8283d2efce45e99aa026 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:55:59 +0000 Subject: [PATCH 48/52] chore(deps): update dependency @types/express-serve-static-core to v4.17.43 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 60502016df..cb0d9d01f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18153,14 +18153,14 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.17.42 - resolution: "@types/express-serve-static-core@npm:4.17.42" + version: 4.17.43 + resolution: "@types/express-serve-static-core@npm:4.17.43" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 58273f80fcc94de42691f48e22542e69f0b17863378e3216ce8b782ace012f32241bfeb02a2be837f0e2b4ef96e916979adc30bbfea13f6545bd3ab81b7d2773 + checksum: 08e940cae52eb1388a7b5f61d65f028e783add77d1854243ae920a6a2dfb5febb6acaafbcf38be9d678b0411253b9bc325893c463a93302405f24135664ab1e4 languageName: node linkType: hard From 3a0038f22e85e3e30cdbd576e0906eedff61cbc4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 14:11:47 +0000 Subject: [PATCH 49/52] fix(deps): update dependency @graphiql/react to v0.20.3 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 60502016df..0d5555649d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11402,8 +11402,8 @@ __metadata: linkType: hard "@graphiql/react@npm:^0.20.0, @graphiql/react@npm:^0.20.2": - version: 0.20.2 - resolution: "@graphiql/react@npm:0.20.2" + version: 0.20.3 + resolution: "@graphiql/react@npm:0.20.3" dependencies: "@graphiql/toolkit": ^0.9.1 "@headlessui/react": ^1.7.15 @@ -11424,7 +11424,7 @@ __metadata: graphql: ^15.5.0 || ^16.0.0 react: ^16.8.0 || ^17 || ^18 react-dom: ^16.8.0 || ^17 || ^18 - checksum: 76bd00fd144b1e3044e3239d80fbda49795e5eb41d222da373af11819d06f657a430eff6853e93724134538f3c5e619e0ecf9111b0818fe14569edb290106c84 + checksum: e8b362bd67ff5499c8db64097f9a4050782be53420e27b4c84ad1eba99c9615984257b7a19d0fd9c6f72ce92366321014b04762b400403ee52f53248dd7a8785 languageName: node linkType: hard From f46da34bea3e1c8e6df1a1c3494f165314ea4058 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 15:30:29 +0000 Subject: [PATCH 50/52] fix(deps): update dependency graphiql to v3.1.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2c7f3f3bcd..d74930d0fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11400,7 +11400,7 @@ __metadata: languageName: node linkType: hard -"@graphiql/react@npm:^0.20.0, @graphiql/react@npm:^0.20.2": +"@graphiql/react@npm:^0.20.0, @graphiql/react@npm:^0.20.2, @graphiql/react@npm:^0.20.3": version: 0.20.3 resolution: "@graphiql/react@npm:0.20.3" dependencies: @@ -28702,7 +28702,7 @@ __metadata: languageName: node linkType: hard -"graphiql@npm:3.1.0, graphiql@npm:^3.0.6": +"graphiql@npm:3.1.0": version: 3.1.0 resolution: "graphiql@npm:3.1.0" dependencies: @@ -28718,6 +28718,22 @@ __metadata: languageName: node linkType: hard +"graphiql@npm:^3.0.6": + version: 3.1.1 + resolution: "graphiql@npm:3.1.1" + dependencies: + "@graphiql/react": ^0.20.3 + "@graphiql/toolkit": ^0.9.1 + graphql-language-service: ^5.2.0 + markdown-it: ^12.2.0 + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + checksum: fa0e6a6854b688a80d2d560c07c042c4d63a45ab1ebdb5b56a081a5a2aea6f77b2ef10afb73e071bbb22eb293048a9b72760e91459fe66704afce56271b13ba5 + languageName: node + linkType: hard + "graphlib@npm:^2.1.8": version: 2.1.8 resolution: "graphlib@npm:2.1.8" From c66312a3919ec840185b89d8f9dd47c03ef9b92f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 16:17:44 +0000 Subject: [PATCH 51/52] fix(deps): update dependency react-virtualized-auto-sizer to v1.0.22 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 d74930d0fb..2c26cb1a1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39048,12 +39048,12 @@ __metadata: linkType: hard "react-virtualized-auto-sizer@npm:^1.0.11": - version: 1.0.21 - resolution: "react-virtualized-auto-sizer@npm:1.0.21" + version: 1.0.22 + resolution: "react-virtualized-auto-sizer@npm:1.0.22" peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 - checksum: 9c0929a0363b3b3b10ad65ac57d7562a20966a9c38c28c10dfd296d0a6a3e678319dce2384c5177f43965c2b7f226f5766deffc4b7eaaab0ee7c2cfe0c7d6b48 + checksum: dc3fc29437b7179de71f77e5be3514e8789944132d7eb03f7157f783ec167ad9bebf1d371c135cf74fc5787dfac313a2914a5d23b45e978ae77be36c673342e5 languageName: node linkType: hard From 5fbfcc43ea0cf9ed2e3bb486b930a32f64f01e85 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 17:33:28 +0000 Subject: [PATCH 52/52] fix(deps): update dependency zod-to-json-schema to v3.22.4 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 2c26cb1a1b..748abe6c79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45364,11 +45364,11 @@ __metadata: linkType: hard "zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4": - version: 3.22.3 - resolution: "zod-to-json-schema@npm:3.22.3" + version: 3.22.4 + resolution: "zod-to-json-schema@npm:3.22.4" peerDependencies: zod: ^3.22.4 - checksum: 2747a3d1514f579006939c0edd6a420acae65ad016df223b09c4a542cbc8c0ae61b4d7b391228a211cde973635ed49c47b1449791982f3b32d799319bb174f42 + checksum: 22f89d505cc3d93020de38e4471362fbecd73a8df58017553ad57fb14e69b6f2f88bcdfe9f84b291442ed0654f97344d517af291d23848e43e6e208ee23dac2b languageName: node linkType: hard