diff --git a/.gitignore b/.gitignore index c1bcf5a4b4..ff544055d5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,12 +3,6 @@ .vscode/ .vsls.json -# @spotify/web-script build output -cjs/ -esm/ -types/ -build/ - # Logs logs *.log diff --git a/CHANGELOG.md b/CHANGELOG.md index b938542b54..8c67eae825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,16 +8,28 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re > Collect changes for the next release below +## v0.1.1-alpha.18 + ### @backstage/catalog-backend -- Fixed an issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. https://github.com/spotify/backstage/pull/1836 +- Fixed an issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. [#1836](https://github.com/spotify/backstage/pull/1836) + +### @backstage/auth-backend + +This version fixes a breakage in CSP policies set by the auth backend. If you're facing trouble with auth in alpha.17, upgrade to alpha.18. + +- OAuth redirect URLs no longer receive the `env` parameter, as it is now passed through state instead. This will likely require a reconfiguration of the OAuth app, where a redirect URL like `http://localhost:7000/auth/google/handler/frame?env=development` should now be configured as `http://localhost:7000/auth/google/handler/frame`. [#1812](https://github.com/spotify/backstage/pull/1812) + +### @backstage/core + +- `SignInPage` props have been changed to receive a list of provider objects instead of simple string identifiers for all but the `'guest'` and `'custom'` providers. This opens up for configuration of custom providers, but may break existing configurations. See [packages/app/src/App.tsx](https://github.com/spotify/backstage/blob/032ba401af36a760efdac41668d7000ccf09bc57/packages/app/src/App.tsx#L36) and [packages/app/src/identityProviders.ts](https://github.com/spotify/backstage/blob/032ba401af36a760efdac41668d7000ccf09bc57/packages/app/src/identityProviders.ts#L24) for how to bring back the existing providers. [#1816](https://github.com/spotify/backstage/pull/1816) ## v0.1.1-alpha.17 ### @backstage/techdocs-backend -- The techdocs backend now requires more configuration to be supplied when creating the router. See [packages/backend/src/plugins/techdocs.ts](https://github.com/spotify/backstage/blob/0201fd9b4a52429519dd59e9184106ba69456deb/packages/backend/src/plugins/techdocs.ts#L42) for an example. https://github.com/spotify/backstage/pull/1736 +- The techdocs backend now requires more configuration to be supplied when creating the router. See [packages/backend/src/plugins/techdocs.ts](https://github.com/spotify/backstage/blob/0201fd9b4a52429519dd59e9184106ba69456deb/packages/backend/src/plugins/techdocs.ts#L42) for an example. [#1736](https://github.com/spotify/backstage/pull/1736) ### @backstage/cli -- The `create-app` command was moved out from the CLI to a standalone package. It's now invoked with `npx @backstage/create-app` instead. https://github.com/spotify/backstage/pull/1745 +- The `create-app` command was moved out from the CLI to a standalone package. It's now invoked with `npx @backstage/create-app` instead. [#1745](https://github.com/spotify/backstage/pull/1745) diff --git a/catalog-info.yaml b/catalog-info.yaml index db16aabd51..86b67f95cd 100644 --- a/catalog-info.yaml +++ b/catalog-info.yaml @@ -5,7 +5,8 @@ metadata: description: | Backstage is an open-source developer portal that puts the developer experience first. annotations: - github.com/project-slug: 'spotify/backstage' + github.com/project-slug: spotify/backstage + backstage.io/github-actions-id: spotify/backstage spec: type: library owner: Spotify diff --git a/docs/README.md b/docs/README.md index 9c25505d10..2bda6a5aaa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -64,6 +64,11 @@ better yet, a pull request. - Publishing - [Open source and NPM](plugins/publishing.md) - [Private/internal (non-open source)](plugins/publish-private.md) + - Configuration + - [Overview](conf/index.md) + - [Reading Configuration](conf/reading.md) + - [Writing Configuration](conf/writing.md) + - [Defining Configuration](conf/defining.md) - Authentication and identity - [Overview](auth/index.md) - [Add auth provider](auth/add-auth-provider.md) diff --git a/docs/conf/defining.md b/docs/conf/defining.md new file mode 100644 index 0000000000..0b15108f43 --- /dev/null +++ b/docs/conf/defining.md @@ -0,0 +1,15 @@ +# Defining Configuration for your Plugin + +There is currently no tooling support or helpers for defining plugin +configuration. But it's on the roadmap. + +Meanwhile, document the config values that you are reading in your plugin +README. + +## Format + +When defining configuration for your plugin, keep keys camelCased and stick to +existing casing conventions such as `baseUrl`. + +It is also usually best to prefer objects over arrays, as it makes it possible +to override individual values using separate files or environment variables. diff --git a/docs/conf/index.md b/docs/conf/index.md new file mode 100644 index 0000000000..af1635d627 --- /dev/null +++ b/docs/conf/index.md @@ -0,0 +1,48 @@ +# Static Configuration in Backstage + +## Summary + +Backstage ships with a flexible configuration system that provides a simple way +to configure Backstage apps and plugins for both local development and +production deployments. It helps get you up and running fast while adapting +Backstage for your specific environment. It also serves as a tool for plugin +authors to use to make it simple to pick up and install a plugin, while still +allowing for customization. + +## Supplying Configuration + +Configuration is stored in `app-config.yaml` files, with support for suffixes +such as `app-config.production.yaml` to override values for specific +environments. The configuration files themselves contain plain YAML, but with +support for loading in secrets from various sources using a `$secret` key. + +It is also possible to supply configuration through environment variables, for +example `APP_CONFIG_app_baseUrl=https://staging.example.com`. However these +should be used sparingly, usually just for temporary overrides during +development or small tweaks to be able to reuse deployment artifacts in +different environments. + +The configuration is shared between the frontend and backend, meaning that +values that are common between the two only needs to be defined once. Such as +the `backend.baseUrl`. + +For more details, see [Writing Configuration](./writing.md). + +## Reading Configuration + +As a plugin developer, you likely end up wanting to define configuration that +you want users of your plugin to supply, as well as reading that configuration +in frontend and backend plugins. For more details, see +[Reading Configuration](./reading.md) and +[Defining Configuration](./defining.md). + +## Further Reading + +More details are provided in dedicated sections of the documentation. + +- [Reading Configuration](./reading.md): How to read configuration in your + plugin. +- [Writing Configuration](./writing.md): How to provide configuration for your + Backstage deployment. +- [Defining Configuration](./defining.md): How to define configuration for users + of your plugin. diff --git a/docs/conf/reading.md b/docs/conf/reading.md new file mode 100644 index 0000000000..9979f0360e --- /dev/null +++ b/docs/conf/reading.md @@ -0,0 +1,128 @@ +# Reading Backstage Configuration + +## Config API + +There's a common configuration API for by both frontend and backend plugins. An +API reference can be found [here](../reference/utility-apis/Config.md). + +The configuration API is tailored towards failing fast in case of missing or bad +config. That's because configuration errors can always be considered programming +mistakes, and will fail deterministically. + +### Type Safety + +The methods for reading primitive values are typed, and validate that type at +runtime. For example `getNumber()` requires the underlying value to be a number, +and there will be no attempt to coerce other types into the desired one. If +`getNumber()` receives a string value, it will throw an error, explaining where +the bad config came from, and what the desired and actual types where. + +### Reading Nested Configuration + +The backing configuration data is a nested JSON structure, meaning there will be +object, within objects, arrays within objects, and so on. There are a couple of +different ways to access nested values when reading configuration, but the +primary one is to use dot-separated paths. + +For example, given the following configuration: + +```yaml +app: + baseUrl: http://localhost:3000 +``` + +We can access the `baseUrl` using `config.getString('app.baseUrl')`. Because of +this syntax, configuration keys are not allowed to contain dots. In fact, +configuration keys are validated using the following RegEx: +`/^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i`. + +Another option of accessing the `baseUrl` value is to create a sub-view of the +configuration, `config.getConfig('app').getString('baseUrl')`. When reading out +single values the dot-path pattern is preferred, but creating sub-views can be +useful for when you want to pass on parts of configuration to be read out by a +separate function. For example, given something like + +```yaml +my-plugin: + items: + a: + title: Item A + path: /a + b: + title: Item B + path: /b +``` + +You can get the list of all items using the `.keys()` method, and then pass on +each sub-view to be handled individually. + +```ts +for (const itemKey of config.keys('my-plugin.items')) { + const itemConfig = config.getConfig(`my-plugin.items`).getConfig(key); + const item = createItemFromConfig(itemConfig); +} +``` + +Another option for iterating through configuration keys is to call +`config.get('my-plugin.items')`, which simply returns the JSON structure for +that position without any validation. This can be handy to use sometimes, +especially if you're passing on config to an external library. There's a clear +benefit to the sub-view approach though, which is that the user will receive +much more detailed and relevant error messages. For example, if +`itemConfig.getString('title')` fails in the above example because a boolean was +supplied, the user will receive an error message with the full path, e.g. +`my-plugin.items.b.title`, as well as the name of the config file with the bad +value. + +Note that no matter what method is used for reading out nested config, the same +merging rules apply. You will always get the same value for any way of accessing +nested config: + +```ts +// Equivalent as long as a.b.c exists and is a string +config.getString('a.b.c'); +config.getConfig('a.b').getString('c'); +config.get('a').b.c; +``` + +### Required vs Optional Configuration + +Reading configuration can be divided into two categories: required, and +optional. When reading optional configuration you use the optional methods such +as `getOptionalString`. These methods will simply return `undefined` if +configuration values are missing, allowing the called to fall back to default +values. The optional methods still validate types however, so receiving a string +in a call to `config.getOptionalNumber` will still throw an error. + +A good pattern for reading optional configuration values is to use the `??` +operator. For example: + +```ts +const title = config.getString('my-plugin.title') ?? 'My Plugin'; +``` + +To read required configuration, simply use the methods without `Optional`, for +example `getString`. These will throw an error if there is no value available. + +## Accessing ConfigApi in Frontend Plugins + +The [ConfigApi](../reference/utility-apis/Config.md) in the frontend is a +[UtilityApi](../api/utility-apis.md). It's accessible as usual via the +`configApiRef` exported from `@backstage/core`. + +Depending on the config api in another API is slightly different though, as the +`ConfigApi` implementation is supplied via the App itself and not instantiated +like other APIs. See +[packages/app/src/apis.ts](https://github.com/spotify/backstage/blob/244eef851f5aa19f91c7c9b5c12d5df95cf482ca/packages/app/src/apis.ts#L66) +for an example of how this wiring is done. + +For standalone plugin setups in `dev/index.ts`, register a factory with a +statically mocked implementation of the config API. Use the `ConfigReader` from +`@backstage/config` to create an instance and register it for the `configApiRef` +from `@backstage/core`. + +## Accessing ConfigApi in Backend Plugins + +In backend plugins the configuration is passed in via options from the main +backend package. See for example +[packages/backend/src/plugins/auth.ts](https://github.com/spotify/backstage/blob/244eef851f5aa19f91c7c9b5c12d5df95cf482ca/packages/backend/src/plugins/auth.ts#L23). diff --git a/docs/conf/writing.md b/docs/conf/writing.md new file mode 100644 index 0000000000..8ab397846d --- /dev/null +++ b/docs/conf/writing.md @@ -0,0 +1,157 @@ +# Writing Backstage Configuration Files + +## File Format + +Configuration is stored in YAML format in `app-config.yaml` files, looking +something like this: + +```yaml +app: + title: Backstage Example App + baseUrl: http://localhost:3000 + +backend: + listen: 0.0.0.0:7000 + baseUrl: http://localhost:7000 + +organization: + name: Spotify + +proxy: + /my/api: + target: https://example.com/api/ + changeOrigin: true + pathRewrite: + ^/proxy/my/api/: / +``` + +Configuration files are typically checked in and stored in the repo that houses +the rest of the Backstage application. + +## Environment Variable Overrides + +Individual configuration values can be overridden using environment variables +prefixed with `APP_CONFIG_`. Everything following that prefix in the environment +variable name will be used as the config key, with `_` replaced by `.`. For +example, to override the `app.baseUrl` value, set the `APP_CONFIG_app_baseUrl` +environment variable to the desired value. + +The value of the environment variable is parsed as JSON, but it will fall back +to being interpreted as a string if it fails to parse. Note that if you for +example want to pass on the string `"false"`, you need to wrap it in double +quotes, e.g. `export APP_CONFIG_example='"false"'`. + +While it may be tempting to use environment variable overrides for supplying a +lot of configuration values, we recommend using them sparingly. Try to stick to +using configuration files, and only use environment variables for things like +reusing deployment artifacts across staging and production environments. + +Note that environment variables work for frontend configuration too. They are +picked up by the serve tasks of `@backstage/cli` for local development, and are +injected by the entrypoint of the nginx container serving the frontend in a +production build. + +## File Resolution + +It is possible to have multiple configuration files, both to support different +environments, but also to define configuration that is local to specific +packages. + +All `app-config.yaml` files inside the monorepo root and package root are +considered, as are files with additional `local` and environment affixes such as +`development`, for example `app-config.local.yaml`, +`app-config.production.yaml`, and `app-config.development.local.yaml`. Which +environment config files are loaded is determined by the `NODE_ENV` environment +variable. Local configuration files are always loaded, but are meant for local +development overrides and should typically be `.gitignore`'d. + +All loaded configuration files are merged together using the following rules: + +- Configurations have different priority, higher priority means you replace + values from configurations with lower priority. +- Primitive values are completely replaced, as are arrays and all of their + contents. +- Objects are merged together deeply, meaning that if any of the included + configs contain a value for a given path, it will be found. + +The priority of the configurations is determined by the following rules, in +order: + +- Configuration from the `APP_CONFIG_` environment variables has the highest + priority, followed by files. +- Files inside package directories have higher priority than those in the root + directory. +- Files with environment affixes have higher priority than ones without. +- Files with the `local` affix have higher priority than ones without. + +## Secrets + +Secrets are supported via a special `$secret` key, which in turn provides a +number of different ways to read in secrets. To load a configuration value as a +secret, supply an object with a single `$secret` key, and within that supply an +object that describes how the secret is loaded. For example, the following will +read the config key `backend.mySecretKey` from the environment variable +`MY_SECRET_KEY`: + +```yaml +backend: + mySecretKey: + $secret: + env: MY_SECRET_KEY +``` + +With the above configuration, calling `config.getString('backend.mySecretKey')` +will return the value of the environment variable `MY_SECRET_KEY` when the +backend started up. All secrets are loaded at startup, so changing the contents +of secret files or environment variables will not be reflected at runtime. + +Note that secrets will never be included in the frontend bundle or development +builds. When loading configuration you have to explicitly enable reading of +secrets, which is only done for the backend configuration. + +As hinted at, secrets can be loaded from a bunch of different sources, and can +be extended with more. Below is a list of the currently supported methods for +loading secrets. + +### Env Secrets + +This reads a secret from an environment variable. For example, the following +config loads the secret from the `MY_SECRET` env var. + +```yaml +$secret: + env: MY_SECRET +``` + +### File Secrets + +This reads a secret from the entire contents of a file. The file path is +relative to the `app-config.yaml` the defines the secrets. For example, the +following reads the contents of `my-secret.txt` relative to the config file +itself: + +```yaml +$secret: + file: ./my-secret.txt +``` + +### Data File Secrets + +This reads secrets from a path within a JSON-like data file. The file path +behaves similar to file secrets, but in addition a `path` is used to point to a +specific value inside the file. Supported file extensions are `.json`, `.yaml`, +and `.yml`. For example, the following would read out `my-secret-key` from +`my-secrets.json`: + +```yaml +$secret: + data: ./my-secrets.json + path: deployment.key + +# my-secrets.json +{ + "deployment": { + "key": "my-secret-key" + } +} +``` diff --git a/lerna.json b/lerna.json index f0ae530062..35f84c54d0 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": ["packages/*", "plugins/*"], "npmClient": "yarn", "useWorkspaces": true, - "version": "0.1.1-alpha.17" + "version": "0.1.1-alpha.18" } diff --git a/mkdocs.yml b/mkdocs.yml index 43e05580d1..2380001203 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -62,6 +62,11 @@ nav: - Publishing: - Open source and NPM: 'plugins/publishing.md' - Private/internal (non-open source): 'plugins/publish-private.md' + - Configuration: + - Overview: 'conf/index.md' + - Reading Configuration: 'conf/reading.md' + - Writing Configuration: 'conf/writing.md' + - Defining Configuration: 'conf/defining.md' - Authentication and identity: - Overview: 'auth/index.md' - Add auth provider: 'auth/add-auth-provider.md' diff --git a/package.json b/package.json index 8574a65958..fa71c19d7c 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "docker-build:all": "yarn tsc && yarn build && yarn docker-build && yarn workspace example-backend build-image", "create-plugin": "backstage-cli create-plugin", "remove-plugin": "backstage-cli remove-plugin", - "release": "if [ \"$(git symbolic-ref --short HEAD)\" = master ]; then echo \"don't try to release master\"; exit 1; else lerna version --no-push; fi", + "release": "if [ \"$(git symbolic-ref --short HEAD)\" = master ]; then echo \"don't try to release master\"; exit 1; else lerna version --no-push --force-publish; fi", "lerna": "lerna", "storybook": "yarn workspace storybook start", "build-storybook": "yarn workspace storybook build-storybook" diff --git a/packages/app/.gitignore b/packages/app/.gitignore deleted file mode 100644 index 567609b123..0000000000 --- a/packages/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/packages/app/package.json b/packages/app/package.json index cca9b6481f..99865a4216 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,26 +1,26 @@ { "name": "example-app", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": true, "dependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/plugin-catalog": "^0.1.1-alpha.17", - "@backstage/plugin-circleci": "^0.1.1-alpha.17", - "@backstage/plugin-explore": "^0.1.1-alpha.17", - "@backstage/plugin-github-actions": "^0.1.1-alpha.17", - "@backstage/plugin-gitops-profiles": "^0.1.1-alpha.17", - "@backstage/plugin-graphiql": "^0.1.1-alpha.17", - "@backstage/plugin-lighthouse": "^0.1.1-alpha.17", - "@backstage/plugin-register-component": "^0.1.1-alpha.17", - "@backstage/plugin-rollbar": "^0.1.1-alpha.17", - "@backstage/plugin-scaffolder": "^0.1.1-alpha.17", - "@backstage/plugin-sentry": "^0.1.1-alpha.17", - "@backstage/plugin-tech-radar": "^0.1.1-alpha.17", - "@backstage/plugin-techdocs": "^0.1.1-alpha.17", - "@backstage/plugin-welcome": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-catalog": "^0.1.1-alpha.18", + "@backstage/plugin-circleci": "^0.1.1-alpha.18", + "@backstage/plugin-explore": "^0.1.1-alpha.18", + "@backstage/plugin-github-actions": "^0.1.1-alpha.18", + "@backstage/plugin-gitops-profiles": "^0.1.1-alpha.18", + "@backstage/plugin-graphiql": "^0.1.1-alpha.18", + "@backstage/plugin-lighthouse": "^0.1.1-alpha.18", + "@backstage/plugin-register-component": "^0.1.1-alpha.18", + "@backstage/plugin-rollbar": "^0.1.1-alpha.18", + "@backstage/plugin-scaffolder": "^0.1.1-alpha.18", + "@backstage/plugin-sentry": "^0.1.1-alpha.18", + "@backstage/plugin-tech-radar": "^0.1.1-alpha.18", + "@backstage/plugin-techdocs": "^0.1.1-alpha.18", + "@backstage/plugin-welcome": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@octokit/rest": "^18.0.0", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 9e9ca1edd0..9a9fdfe5c4 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -19,25 +19,22 @@ import { AlertDisplay, OAuthRequestDialog, SignInPage, - useApi, - configApiRef, } from '@backstage/core'; import React, { FC } from 'react'; import Root from './components/Root'; import * as plugins from './plugins'; import { apis } from './apis'; import { hot } from 'react-hot-loader/root'; +import { providers } from './identityProviders'; const app = createApp({ apis, plugins: Object.values(plugins), components: { SignInPage: props => { - const configApi = useApi(configApiRef); - const providersConfig = configApi.getOptionalConfig('auth.providers'); - const providers = providersConfig?.keys() ?? []; - - return ; + return ( + + ); }, }, }); diff --git a/packages/app/src/identityProviders.ts b/packages/app/src/identityProviders.ts new file mode 100644 index 0000000000..e80b1d6fea --- /dev/null +++ b/packages/app/src/identityProviders.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { + googleAuthApiRef, + gitlabAuthApiRef, + oktaAuthApiRef, + githubAuthApiRef, +} from '@backstage/core'; + +export const providers = [ + { + id: 'google-auth-provider', + title: 'Google', + message: 'Sign In using Google', + apiRef: googleAuthApiRef, + }, + { + id: 'gitlab-auth-provider', + title: 'Gitlab', + message: 'Sign In using Gitlab', + apiRef: gitlabAuthApiRef, + }, + { + id: 'github-auth-provider', + title: 'Github', + message: 'Sign In using Github', + apiRef: githubAuthApiRef, + }, + { + id: 'okta-auth-provider', + title: 'Okta', + message: 'Sign In using Okta', + apiRef: oktaAuthApiRef, + }, +]; diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index d7427500aa..e21d0eb0d7 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/cli-common": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/config-loader": "^0.1.1-alpha.17", + "@backstage/cli-common": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/config-loader": "^0.1.1-alpha.18", "@types/cors": "^2.8.6", "@types/express": "^4.17.6", "compression": "^1.7.4", @@ -44,7 +44,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/compression": "^1.7.0", "@types/http-errors": "^1.6.3", "@types/morgan": "^1.9.0", diff --git a/packages/backend/package.json b/packages/backend/package.json index a144c4d148..6e1bcdaf69 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "dist/index.cjs.js", "types": "src/index.ts", "private": true, @@ -18,18 +18,18 @@ "migrate:create": "knex migrate:make -x ts" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/plugin-auth-backend": "^0.1.1-alpha.17", - "@backstage/plugin-catalog-backend": "^0.1.1-alpha.17", - "@backstage/plugin-graphql-backend": "^0.1.1-alpha.17", - "@backstage/plugin-identity-backend": "^0.1.1-alpha.17", - "@backstage/plugin-proxy-backend": "^0.1.1-alpha.17", - "@backstage/plugin-rollbar-backend": "^0.1.1-alpha.17", - "@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.17", - "@backstage/plugin-sentry-backend": "^0.1.1-alpha.17", - "@backstage/plugin-techdocs-backend": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/plugin-auth-backend": "^0.1.1-alpha.18", + "@backstage/plugin-catalog-backend": "^0.1.1-alpha.18", + "@backstage/plugin-graphql-backend": "^0.1.1-alpha.18", + "@backstage/plugin-identity-backend": "^0.1.1-alpha.18", + "@backstage/plugin-proxy-backend": "^0.1.1-alpha.18", + "@backstage/plugin-rollbar-backend": "^0.1.1-alpha.18", + "@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.18", + "@backstage/plugin-sentry-backend": "^0.1.1-alpha.18", + "@backstage/plugin-techdocs-backend": "^0.1.1-alpha.18", "@octokit/rest": "^18.0.0", "dockerode": "^3.2.0", "express": "^4.17.1", @@ -39,7 +39,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/dockerode": "^2.5.32", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5", diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index e6551bb8a9..248f2765e4 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-model", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/config": "^0.1.1-alpha.18", "@types/json-schema": "^7.0.5", "@types/yup": "^0.28.2", "json-schema": "^0.2.5", @@ -29,7 +29,7 @@ "yup": "^0.29.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "@types/jest": "^26.0.7", "@types/lodash": "^4.14.151", diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index b5d13200cf..092a2a5167 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-common", "description": "Common functionality used by cli, backend, and create-app", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "main": "src/index.ts", "types": "src/index.ts", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/jest": "^26.0.7", "@types/node": "^12.0.0" }, diff --git a/packages/cli/config/eslint.backend.js b/packages/cli/config/eslint.backend.js index a184e6219c..8389f5c508 100644 --- a/packages/cli/config/eslint.backend.js +++ b/packages/cli/config/eslint.backend.js @@ -55,6 +55,16 @@ module.exports = { ], // Avoid cross-package imports 'no-restricted-imports': [2, { patterns: ['**/../../**/*/src/**'] }], + // Avoid default import from winston as it breaks at runtime + 'no-restricted-syntax': [ + 'error', + { + message: + 'Default import from winston is not allowed, import `* as winston` instead.', + selector: + 'ImportDeclaration[source.value="winston"] ImportDefaultSpecifier', + }, + ], }, overrides: [ { diff --git a/packages/cli/package.json b/packages/cli/package.json index e70ac2854c..cc5b3edc9b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public" @@ -29,9 +29,9 @@ "backstage-cli": "bin/backstage-cli" }, "dependencies": { - "@backstage/cli-common": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/config-loader": "^0.1.1-alpha.17", + "@backstage/cli-common": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/config-loader": "^0.1.1-alpha.18", "@hot-loader/react-dom": "^16.13.0", "@lerna/package-graph": "^3.18.5", "@lerna/project": "^3.18.0", diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index eaf8e628a7..a2d7bbbc59 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/config": "^0.1.1-alpha.18", "fs-extra": "^9.0.0", "yaml": "^1.9.2", "yup": "^0.29.1" diff --git a/packages/config/package.json b/packages/config/package.json index 501ffaffad..9c8c81d31b 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", diff --git a/packages/core-api/package.json b/packages/core-api/package.json index 45884a0015..9ce1290a73 100644 --- a/packages/core-api/package.json +++ b/packages/core-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-api", "description": "Internal Core API used by Backstage plugins and apps", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -29,8 +29,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@types/react": "^16.9", @@ -41,8 +41,8 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/test-utils-core": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/test-utils-core": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/packages/core/package.json b/packages/core/package.json index 1ef8300eb8..f75df3f564 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core", "description": "Core API used by Backstage plugins and apps", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/core-api": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/core-api": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -40,7 +40,7 @@ "classnames": "^2.2.6", "clsx": "^1.1.0", "lodash": "^4.17.15", - "material-table": "1.62.x", + "material-table": "1.68.x", "prop-types": "^15.7.2", "rc-progress": "^3.0.0", "react": "^16.12.0", @@ -50,12 +50,12 @@ "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-sparklines": "^1.7.0", - "react-syntax-highlighter": "^12.2.1", + "react-syntax-highlighter": "^13.2.1", "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/packages/core/src/components/Table/Table.tsx b/packages/core/src/components/Table/Table.tsx index 89aa2dce1f..d200b07bc6 100644 --- a/packages/core/src/components/Table/Table.tsx +++ b/packages/core/src/components/Table/Table.tsx @@ -166,7 +166,7 @@ export function Table({ const MTColumns = convertColumns(columns, theme); - const defaultOptions: Options = { + const defaultOptions: Options = { headerStyle: { textTransform: 'uppercase', }, diff --git a/packages/core/src/layout/SignInPage/SignInPage.tsx b/packages/core/src/layout/SignInPage/SignInPage.tsx index 8a1191f442..52a27f190e 100644 --- a/packages/core/src/layout/SignInPage/SignInPage.tsx +++ b/packages/core/src/layout/SignInPage/SignInPage.tsx @@ -21,17 +21,22 @@ import { Content } from '../Content/Content'; import { ContentHeader } from '../ContentHeader/ContentHeader'; import { Grid } from '@material-ui/core'; import { SignInPageProps, useApi, configApiRef } from '@backstage/core-api'; -import { useSignInProviders, SignInProviderId } from './providers'; +import { useSignInProviders, getSignInProviders } from './providers'; +import { IdentityProviders } from './types'; import { Progress } from '../../components/Progress'; export type Props = SignInPageProps & { - providers: SignInProviderId[]; + providers: IdentityProviders; }; -export const SignInPage: FC = ({ onResult, providers }) => { +export const SignInPage: FC = ({ onResult, providers = [] }) => { const configApi = useApi(configApiRef); - const [loading, providerElements] = useSignInProviders(providers, onResult); + const signInProviders = getSignInProviders(providers); + const [loading, providerElements] = useSignInProviders( + signInProviders, + onResult, + ); if (loading) { return ; diff --git a/packages/core/src/layout/SignInPage/githubProvider.tsx b/packages/core/src/layout/SignInPage/commonProvider.tsx similarity index 60% rename from packages/core/src/layout/SignInPage/githubProvider.tsx rename to packages/core/src/layout/SignInPage/commonProvider.tsx index fd7815e7b8..f9611342a2 100644 --- a/packages/core/src/layout/SignInPage/githubProvider.tsx +++ b/packages/core/src/layout/SignInPage/commonProvider.tsx @@ -17,28 +17,34 @@ import React from 'react'; import { Grid, Typography, Button } from '@material-ui/core'; import { InfoCard } from '../InfoCard/InfoCard'; -import { ProviderComponent, ProviderLoader, SignInProvider } from './types'; -import { useApi, githubAuthApiRef, errorApiRef } from '@backstage/core-api'; +import { + ProviderComponent, + ProviderLoader, + SignInProvider, + SignInConfig, +} from './types'; +import { useApi, errorApiRef } from '@backstage/core-api'; -const Component: ProviderComponent = ({ onResult }) => { - const githubAuthApi = useApi(githubAuthApiRef); +const Component: ProviderComponent = ({ config, onResult }) => { + const { apiRef, title, message } = config as SignInConfig; + const authApi = useApi(apiRef); const errorApi = useApi(errorApiRef); const handleLogin = async () => { try { - const identity = await githubAuthApi.getBackstageIdentity({ + const identity = await authApi.getBackstageIdentity({ instantPopup: true, }); - const profile = await githubAuthApi.getProfile(); + const profile = await authApi.getProfile(); onResult({ userId: identity!.id, profile: profile!, getIdToken: () => { - return githubAuthApi.getBackstageIdentity().then(i => i!.idToken); + return authApi.getBackstageIdentity().then(i => i!.idToken); }, logout: async () => { - await githubAuthApi.logout(); + await authApi.logout(); }, }); } catch (error) { @@ -49,23 +55,23 @@ const Component: ProviderComponent = ({ onResult }) => { return ( Sign In } > - Sign In using Github + {message} ); }; -const loader: ProviderLoader = async apis => { - const githubAuthApi = apis.get(githubAuthApiRef)!; +const loader: ProviderLoader = async (apis, apiRef) => { + const authApi = apis.get(apiRef)!; - const identity = await githubAuthApi.getBackstageIdentity({ + const identity = await authApi.getBackstageIdentity({ optional: true, }); @@ -73,17 +79,16 @@ const loader: ProviderLoader = async apis => { return undefined; } - const profile = await githubAuthApi.getProfile(); + const profile = await authApi.getProfile(); return { userId: identity.id, profile: profile!, - getIdToken: () => - githubAuthApi.getBackstageIdentity().then(i => i!.idToken), + getIdToken: () => authApi.getBackstageIdentity().then(i => i!.idToken), logout: async () => { - await githubAuthApi.logout(); + await authApi.logout(); }, }; }; -export const githubProvider: SignInProvider = { Component, loader }; +export const commonProvider: SignInProvider = { Component, loader }; diff --git a/packages/core/src/layout/SignInPage/gitlabProvider.tsx b/packages/core/src/layout/SignInPage/gitlabProvider.tsx deleted file mode 100644 index 5e417cb32d..0000000000 --- a/packages/core/src/layout/SignInPage/gitlabProvider.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 React from 'react'; -import { Grid, Typography, Button } from '@material-ui/core'; -import { InfoCard } from '../InfoCard/InfoCard'; -import { ProviderComponent, ProviderLoader, SignInProvider } from './types'; -import { useApi, gitlabAuthApiRef, errorApiRef } from '@backstage/core-api'; - -const Component: ProviderComponent = ({ onResult }) => { - const gitlabAuthApi = useApi(gitlabAuthApiRef); - const errorApi = useApi(errorApiRef); - - const handleLogin = async () => { - try { - const identity = await gitlabAuthApi.getBackstageIdentity({ - instantPopup: true, - }); - - const profile = await gitlabAuthApi.getProfile(); - onResult({ - userId: identity!.id, - profile: profile!, - getIdToken: () => - gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await gitlabAuthApi.logout(); - }, - }); - } catch (error) { - errorApi.post(error); - } - }; - - return ( - - - Sign In - - } - > - Sign In using Gitlab - - - ); -}; - -const loader: ProviderLoader = async apis => { - const gitlabAuthApi = apis.get(gitlabAuthApiRef)!; - - const identity = await gitlabAuthApi.getBackstageIdentity({ - optional: true, - }); - - if (!identity) { - return undefined; - } - - const profile = await gitlabAuthApi.getProfile(); - - return { - userId: identity.id, - profile: profile!, - getIdToken: () => - gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await gitlabAuthApi.logout(); - }, - }; -}; - -export const gitlabProvider: SignInProvider = { Component, loader }; diff --git a/packages/core/src/layout/SignInPage/googleProvider.tsx b/packages/core/src/layout/SignInPage/googleProvider.tsx deleted file mode 100644 index 632b81ad17..0000000000 --- a/packages/core/src/layout/SignInPage/googleProvider.tsx +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 React from 'react'; -import { Grid, Typography, Button } from '@material-ui/core'; -import { InfoCard } from '../InfoCard/InfoCard'; -import { ProviderComponent, ProviderLoader, SignInProvider } from './types'; -import { useApi, googleAuthApiRef, errorApiRef } from '@backstage/core-api'; - -const Component: ProviderComponent = ({ onResult }) => { - const googleAuthApi = useApi(googleAuthApiRef); - const errorApi = useApi(errorApiRef); - - const handleLogin = async () => { - try { - const identity = await googleAuthApi.getBackstageIdentity({ - instantPopup: true, - }); - - const profile = await googleAuthApi.getProfile(); - - onResult({ - userId: identity!.id, - profile: profile!, - getIdToken: () => - googleAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await googleAuthApi.logout(); - }, - }); - } catch (error) { - errorApi.post(error); - } - }; - - return ( - - - Sign In - - } - > - Sign In using Google - - - ); -}; - -const loader: ProviderLoader = async apis => { - const googleAuthApi = apis.get(googleAuthApiRef)!; - - const identity = await googleAuthApi.getBackstageIdentity({ - optional: true, - }); - - if (!identity) { - return undefined; - } - - const profile = await googleAuthApi.getProfile(); - - return { - userId: identity.id, - profile: profile!, - getIdToken: () => - googleAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await googleAuthApi.logout(); - }, - }; -}; - -export const googleProvider: SignInProvider = { Component, loader }; diff --git a/packages/core/src/layout/SignInPage/oktaProvider.tsx b/packages/core/src/layout/SignInPage/oktaProvider.tsx deleted file mode 100644 index cf15fe5b22..0000000000 --- a/packages/core/src/layout/SignInPage/oktaProvider.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 React from 'react'; -import { Grid, Typography, Button } from '@material-ui/core'; -import { InfoCard } from '../InfoCard/InfoCard'; -import { ProviderComponent, ProviderLoader, SignInProvider } from './types'; -import { - useApi, - oktaAuthApiRef, - errorApiRef, -} from '@backstage/core-api'; - -const Component: ProviderComponent = ({ onResult }) => { - const oktaAuthApi = useApi(oktaAuthApiRef); - const errorApi = useApi(errorApiRef); - - const handleLogin = async () => { - try { - const identity = await oktaAuthApi.getBackstageIdentity({ - instantPopup: true, - }); - - const profile = await oktaAuthApi.getProfile(); - - onResult({ - userId: identity!.id, - profile: profile!, - getIdToken: () => - oktaAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await oktaAuthApi.logout(); - }, - }); - } catch (error) { - errorApi.post(error); - } - }; - - return ( - - - Sign In - - } - > - Sign In using Okta - - - ); -}; - -const loader: ProviderLoader = async apis => { - const oktaAuthApi = apis.get(oktaAuthApiRef)!; - - const identity = await oktaAuthApi.getBackstageIdentity({ - optional: true, - }); - - if (!identity) { - return undefined; - } - - const profile = await oktaAuthApi.getProfile(); - - return { - userId: identity.id, - profile: profile!, - getIdToken: () => - oktaAuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await oktaAuthApi.logout(); - }, - }; -}; - -export const oktaProvider: SignInProvider = { Component, loader }; \ No newline at end of file diff --git a/packages/core/src/layout/SignInPage/providers.tsx b/packages/core/src/layout/SignInPage/providers.tsx index 1eab51e3ee..ff60eba228 100644 --- a/packages/core/src/layout/SignInPage/providers.tsx +++ b/packages/core/src/layout/SignInPage/providers.tsx @@ -15,12 +15,6 @@ */ import React, { useLayoutEffect, useState, useMemo, useCallback } from 'react'; -import { guestProvider } from './guestProvider'; -import { googleProvider } from './googleProvider'; -import { customProvider } from './customProvider'; -import { gitlabProvider } from './gitlabProvider'; -import { oktaProvider } from './oktaProvider'; -import { githubProvider } from './githubProvider'; import { SignInPageProps, SignInResult, @@ -28,24 +22,61 @@ import { useApiHolder, errorApiRef, } from '@backstage/core-api'; -import { SignInProvider } from './types'; +import { SignInConfig, IdentityProviders, SignInProvider } from './types'; +import { commonProvider } from './commonProvider'; +import { guestProvider } from './guestProvider'; +import { customProvider } from './customProvider'; const PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider'; -// Separate list here to avoid exporting internal types -export type SignInProviderId = 'guest' | string; - -const signInProviders: { [id in SignInProviderId]: SignInProvider } = { - guest: guestProvider, - google: googleProvider, - gitlab: gitlabProvider, - oauth2: customProvider, - okta: oktaProvider, - github: githubProvider, +export type SignInProviderType = { + [key: string]: { + components: SignInProvider; + id: string; + config?: SignInConfig; + }; }; +const signInProviders: { [key: string]: SignInProvider } = { + guest: guestProvider, + custom: customProvider, + common: commonProvider, +}; + +function validateIDs(id: string, providers: SignInProviderType): void { + if (id in providers) + throw new Error( + `"${id}" ID is duplicated. IDs of identity providers have to be unique.`, + ); +} + +export function getSignInProviders( + identityProviders: IdentityProviders, +): SignInProviderType { + const providers = identityProviders.reduce( + (acc: SignInProviderType, config) => { + if (typeof config === 'string') { + validateIDs(config, acc); + acc[config] = { components: signInProviders[config], id: config }; + + return acc; + } + + const { id } = config as SignInConfig; + validateIDs(id, acc); + + acc[id] = { components: signInProviders.common, id, config }; + + return acc; + }, + {}, + ); + + return providers; +} + export const useSignInProviders = ( - providers: SignInProviderId[], + providers: SignInProviderType, onResult: SignInPageProps['onResult'], ) => { const errorApi = useApi(errorApiRef); @@ -74,25 +105,26 @@ export const useSignInProviders = ( } // We can't use storageApi here, as it might have a dependency on the IdentityApi - const selectedProvider = localStorage.getItem( + const selectedProviderId = localStorage.getItem( PROVIDER_STORAGE_KEY, - ) as SignInProviderId; + ) as string; // No provider selected, let the user pick one - if (selectedProvider === null) { + if (selectedProviderId === null) { setLoading(false); return undefined; } - const provider = signInProviders[selectedProvider]; + const provider = providers[selectedProviderId]; if (!provider) { setLoading(false); return undefined; } let didCancel = false; - provider - .loader(apiHolder) + + provider.components + .loader(apiHolder, provider.config?.apiRef!) .then(result => { if (didCancel) { return; @@ -119,20 +151,24 @@ export const useSignInProviders = ( // This renders all available sign-in providers const elements = useMemo( () => - providers.map(providerId => { - const provider = signInProviders[providerId]; - if (!provider) { - throw new Error(`Unknown sign-in provider: ${providerId}`); - } - const { Component } = provider; + Object.keys(providers).map(key => { + const provider = providers[key]; + + const { Component } = provider.components; const handleResult = (result: SignInResult) => { - localStorage.setItem(PROVIDER_STORAGE_KEY, providerId); + localStorage.setItem(PROVIDER_STORAGE_KEY, provider.id); handleWrappedResult(result); }; - return ; + return ( + + ); }), [providers, handleWrappedResult], ); diff --git a/packages/core/src/layout/SignInPage/types.ts b/packages/core/src/layout/SignInPage/types.ts index e13cda5ddd..9c501e8095 100644 --- a/packages/core/src/layout/SignInPage/types.ts +++ b/packages/core/src/layout/SignInPage/types.ts @@ -15,12 +15,37 @@ */ import { ComponentType } from 'react'; -import { SignInPageProps, SignInResult, ApiHolder } from '@backstage/core-api'; +import { + SignInPageProps, + SignInResult, + ApiHolder, + ApiRef, + OAuthApi, + ProfileInfoApi, + BackstageIdentityApi, + SessionStateApi, +} from '@backstage/core-api'; -export type ProviderComponent = ComponentType; +export type SignInConfig = { + id: string; + title: string; + message: string; + apiRef: ApiRef< + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi + >; +}; + +export type IdentityProviders = ('guest' | 'custom' | SignInConfig)[]; + +export type ProviderComponent = ComponentType< + SignInPageProps & { config: SignInConfig } +>; export type ProviderLoader = ( apis: ApiHolder, + apiRef: ApiRef< + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi + >, ) => Promise; export type SignInProvider = { diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 0b02c28ef2..56bcfc488a 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public" @@ -25,7 +25,7 @@ "lint": "backstage-cli lint" }, "dependencies": { - "@backstage/cli-common": "^0.1.1-alpha.17", + "@backstage/cli-common": "^0.1.1-alpha.18", "chalk": "^4.0.0", "commander": "^4.1.1", "fs-extra": "^9.0.0", diff --git a/packages/create-app/src/index.ts b/packages/create-app/src/index.ts index d8c0f55572..bb4ac8ae51 100644 --- a/packages/create-app/src/index.ts +++ b/packages/create-app/src/index.ts @@ -15,7 +15,6 @@ */ import program from 'commander'; -import chalk from 'chalk'; import { exitWithError } from './lib/errors'; import { version } from '../package.json'; import createApp from './createApp'; @@ -31,10 +30,6 @@ const main = (argv: string[]) => { ) .action(createApp); - if (!process.argv.slice(2).length) { - program.outputHelp(chalk.yellow); - } - program.parse(argv); }; diff --git a/packages/create-app/templates/default-app/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx b/packages/create-app/templates/default-app/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx index d9ef0524c6..31c1c0f3e2 100644 --- a/packages/create-app/templates/default-app/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx +++ b/packages/create-app/templates/default-app/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx @@ -71,7 +71,7 @@ const WelcomePage: FC<{}> = () => { We suggest you either check out the documentation for{' '} - + creating a plugin {' '} or have a look in the code for the{' '} @@ -90,7 +90,7 @@ const WelcomePage: FC<{}> = () => { backstage.io - + Create a plugin diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index cd563920cf..7eab350990 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/docgen/package.json b/packages/docgen/package.json index b4d3b85213..4b832afdfd 100644 --- a/packages/docgen/package.json +++ b/packages/docgen/package.json @@ -1,7 +1,7 @@ { "name": "docgen", "description": "Tool for generating API Documentation for itself", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": true, "homepage": "https://backstage.io", "repository": { diff --git a/packages/storybook/package.json b/packages/storybook/package.json index cb15512e6c..bbb8743522 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "description": "Storybook build for core package", "private": true, "scripts": { @@ -14,7 +14,7 @@ ] }, "dependencies": { - "@backstage/theme": "^0.1.1-alpha.17" + "@backstage/theme": "^0.1.1-alpha.18" }, "devDependencies": { "@storybook/addon-actions": "^5.3.17", diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 93f3a115e2..2e5d1e3958 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "CLI for running TechDocs locally.", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public" @@ -44,7 +44,7 @@ "ext": "ts" }, "dependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "commander": "^5.1.0", "fs-extra": "^9.0.1", "http-proxy": "^1.18.1", diff --git a/packages/test-utils-core/package.json b/packages/test-utils-core/package.json index 55224b16ed..638513af5c 100644 --- a/packages/test-utils-core/package.json +++ b/packages/test-utils-core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils-core", "description": "Utilities to test Backstage core", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5a4c96d81d..35bbb7d0b0 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/core-api": "^0.1.1-alpha.17", - "@backstage/test-utils-core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/core-api": "^0.1.1-alpha.18", + "@backstage/test-utils-core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", diff --git a/packages/theme/package.json b/packages/theme/package.json index 44b82fa1e4..f4eafa58ff 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "@material-ui/core": "^4.9.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17" + "@backstage/cli": "^0.1.1-alpha.18" }, "files": [ "dist" diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index f413d56fbd..b25c886075 100644 --- a/plugins/auth-backend/README.md +++ b/plugins/auth-backend/README.md @@ -27,6 +27,16 @@ export AUTH_GOOGLE_CLIENT_SECRET=x ### Github +#### Creating a GitHub OAuth application + +Follow this link, [Create new OAuth App](https://github.com/settings/applications/new). + +1. Set Application Name to `backstage-dev` or something along those lines. +1. You can set the Homepage URL to whatever you want to. +1. The Authorization Callback URL should match the redirect URI set in Backstage. + 1. Set this to `http://localhost:7000/auth/github` for local development. + 1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/auth/github` for non-local deployments. + ```bash export AUTH_GITHUB_CLIENT_ID=x export AUTH_GITHUB_CLIENT_SECRET=x diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 30ed41e0ec..65111e599c 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "body-parser": "^1.19.0", "compression": "^1.7.4", @@ -48,7 +48,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/jwt-decode": "2.2.1", diff --git a/plugins/auth-backend/src/lib/EnvironmentHandler.ts b/plugins/auth-backend/src/lib/EnvironmentHandler.ts index 3eab4e793c..fb39ed86b8 100644 --- a/plugins/auth-backend/src/lib/EnvironmentHandler.ts +++ b/plugins/auth-backend/src/lib/EnvironmentHandler.ts @@ -15,7 +15,10 @@ */ import express from 'express'; -import { AuthProviderRouteHandlers } from '../providers/types'; +import { + AuthProviderRouteHandlers, + EnvironmentIdentifierFn, +} from '../providers/types'; export type EnvironmentHandlers = { [key: string]: AuthProviderRouteHandlers; @@ -25,13 +28,14 @@ export class EnvironmentHandler implements AuthProviderRouteHandlers { constructor( private readonly providerId: string, private readonly providers: EnvironmentHandlers, + private readonly envIdentifier: EnvironmentIdentifierFn, ) {} private getProviderForEnv( req: express.Request, res: express.Response, ): AuthProviderRouteHandlers | undefined { - const env = req.query.env?.toString(); + const env: string | undefined = this.envIdentifier(req); if (env && this.providers.hasOwnProperty(env)) { return this.providers[env]; diff --git a/plugins/auth-backend/src/lib/OAuthProvider.test.ts b/plugins/auth-backend/src/lib/OAuthProvider.test.ts index b08d279679..0778b875d0 100644 --- a/plugins/auth-backend/src/lib/OAuthProvider.test.ts +++ b/plugins/auth-backend/src/lib/OAuthProvider.test.ts @@ -21,6 +21,7 @@ import { THOUSAND_DAYS_MS, TEN_MINUTES_MS, verifyNonce, + encodeState, OAuthProvider, } from './OAuthProvider'; import { WebMessageResponse, OAuthProviderHandlers } from '../providers/types'; @@ -43,10 +44,11 @@ const mockResponseData = { describe('OAuthProvider Utils', () => { describe('verifyNonce', () => { it('should throw error if cookie nonce missing', () => { + const state = { nonce: 'NONCE', env: 'development' }; const mockRequest = ({ cookies: {}, query: { - state: 'NONCE', + state: encodeState(state), }, } as unknown) as express.Request; expect(() => { @@ -63,16 +65,17 @@ describe('OAuthProvider Utils', () => { } as unknown) as express.Request; expect(() => { verifyNonce(mockRequest, 'providera'); - }).toThrowError('Auth response is missing state nonce'); + }).toThrowError('Invalid state passed via request'); }); it('should throw error if nonce mismatch', () => { + const state = { nonce: 'NONCEB', env: 'development' }; const mockRequest = ({ cookies: { 'providera-nonce': 'NONCEA', }, query: { - state: 'NONCEB', + state: encodeState(state), }, } as unknown) as express.Request; expect(() => { @@ -81,12 +84,13 @@ describe('OAuthProvider Utils', () => { }); it('should not throw any error if nonce matches', () => { + const state = { nonce: 'NONCE', env: 'development' }; const mockRequest = ({ cookies: { 'providera-nonce': 'NONCE', }, query: { - state: 'NONCE', + state: encodeState(state), }, } as unknown) as express.Request; expect(() => { @@ -217,6 +221,7 @@ describe('OAuthProvider', () => { const mockRequest = ({ query: { scope: 'user', + env: 'development', }, } as unknown) as express.Request; @@ -249,12 +254,13 @@ describe('OAuthProvider', () => { disableRefresh: false, }); + const state = { nonce: 'nonce', env: 'development' }; const mockRequest = ({ cookies: { 'test-provider-nonce': 'nonce', }, query: { - state: 'nonce', + state: encodeState(state), }, } as unknown) as express.Request; diff --git a/plugins/auth-backend/src/lib/OAuthProvider.ts b/plugins/auth-backend/src/lib/OAuthProvider.ts index 9cd496536f..f2b8c8e09c 100644 --- a/plugins/auth-backend/src/lib/OAuthProvider.ts +++ b/plugins/auth-backend/src/lib/OAuthProvider.ts @@ -22,6 +22,7 @@ import { OAuthProviderHandlers, WebMessageResponse, BackstageIdentity, + OAuthState, } from '../providers/types'; import { InputError } from '@backstage/backend-common'; import { TokenIssuer } from '../identity'; @@ -39,14 +40,41 @@ export type Options = { tokenIssuer: TokenIssuer; }; +const readState = (stateString: string): OAuthState => { + const state = Object.fromEntries( + new URLSearchParams(decodeURIComponent(stateString)), + ); + if ( + !state.nonce || + !state.env || + state.nonce?.length === 0 || + state.env?.length === 0 + ) { + throw Error(`Invalid state passed via request`); + } + return { + nonce: state.nonce, + env: state.env, + }; +}; + +export const encodeState = (state: OAuthState): string => { + const searchParams = new URLSearchParams(); + searchParams.append('nonce', state.nonce); + searchParams.append('env', state.env); + + return encodeURIComponent(searchParams.toString()); +}; + export const verifyNonce = (req: express.Request, providerId: string) => { const cookieNonce = req.cookies[`${providerId}-nonce`]; - const stateNonce = req.query.state; + const state: OAuthState = readState(req.query.state?.toString() ?? ''); + const stateNonce = state.nonce; if (!cookieNonce) { throw new Error('Auth response is missing cookie nonce'); } - if (!stateNonce) { + if (stateNonce.length === 0) { throw new Error('Auth response is missing state nonce'); } if (cookieNonce !== stateNonce) { @@ -64,16 +92,19 @@ export const postMessageResponse = ( res.setHeader('Content-Type', 'text/html'); res.setHeader('X-Frame-Options', 'sameorigin'); - res.setHeader('Content-Security-Policy', "script-src 'unsafe-inline'"); // TODO: Make target app origin configurable globally + const script = ` + (window.opener || window.parent).postMessage(JSON.parse(atob('${base64Data}')), '${appOrigin}') + window.close() + `; + const hash = crypto.createHash('sha256').update(script).digest('base64'); + res.setHeader('Content-Security-Policy', `script-src 'sha256-${hash}'`); + res.end(` - + `); @@ -104,6 +135,11 @@ export class OAuthProvider implements AuthProviderRouteHandlers { async start(req: express.Request, res: express.Response): Promise { // retrieve scopes from request const scope = req.query.scope?.toString() ?? ''; + const env = req.query.env?.toString(); + + if (!env) { + throw new InputError('No env provided in request query parameters'); + } if (this.options.persistScopes) { this.setScopesCookie(res, scope); @@ -113,9 +149,12 @@ export class OAuthProvider implements AuthProviderRouteHandlers { // set a nonce cookie before redirecting to oauth provider this.setNonceCookie(res, nonce); + const stateObject = { nonce: nonce, env: env }; + const stateParameter = encodeState(stateObject); + const queryParameters = { scope, - state: nonce, + state: stateParameter, }; const { url, status } = await this.providerHandlers.start( @@ -225,6 +264,19 @@ export class OAuthProvider implements AuthProviderRouteHandlers { } } + identifyEnv(req: express.Request): string | undefined { + const reqEnv = req.query.env?.toString(); + if (reqEnv) { + return reqEnv; + } + const stateParams = req.query.state?.toString(); + if (!stateParams) { + return undefined; + } + const env = readState(stateParams).env; + return env; + } + /** * If the response from the OAuth provider includes a Backstage identity, we * make sure it's populated with all the information we can derive from the user ID. diff --git a/plugins/auth-backend/src/providers/factories.ts b/plugins/auth-backend/src/providers/factories.ts index dcce98a986..701eef81af 100644 --- a/plugins/auth-backend/src/providers/factories.ts +++ b/plugins/auth-backend/src/providers/factories.ts @@ -23,7 +23,11 @@ import { createGoogleProvider } from './google'; import { createOAuth2Provider } from './oauth2'; import { createOktaProvider } from './okta'; import { createSamlProvider } from './saml'; -import { AuthProviderConfig, AuthProviderFactory } from './types'; +import { + AuthProviderConfig, + AuthProviderFactory, + EnvironmentIdentifierFn, +} from './types'; import { Config } from '@backstage/config'; import { EnvironmentHandlers, @@ -54,16 +58,26 @@ export const createAuthProviderRouter = ( const router = Router(); const envs = providerConfig.keys(); const envProviders: EnvironmentHandlers = {}; + let envIdentifier: EnvironmentIdentifierFn | undefined; for (const env of envs) { const envConfig = providerConfig.getConfig(env); const provider = factory(globalConfig, env, envConfig, logger, issuer); if (provider) { envProviders[env] = provider; + envIdentifier = provider.identifyEnv; } } - const handler = new EnvironmentHandler(providerId, envProviders); + if (typeof envIdentifier === 'undefined') { + throw Error(`No envIdentifier provided for '${providerId}'`); + } + + const handler = new EnvironmentHandler( + providerId, + envProviders, + envIdentifier, + ); router.get('/start', handler.start.bind(handler)); router.get('/handler/frame', handler.frameHandler.bind(handler)); diff --git a/plugins/auth-backend/src/providers/github/provider.ts b/plugins/auth-backend/src/providers/github/provider.ts index e9c719ea1c..863cfa9f5a 100644 --- a/plugins/auth-backend/src/providers/github/provider.ts +++ b/plugins/auth-backend/src/providers/github/provider.ts @@ -126,7 +126,7 @@ export class GithubAuthProvider implements OAuthProviderHandlers { export function createGithubProvider( { baseUrl }: AuthProviderConfig, - env: string, + _: string, envConfig: Config, logger: Logger, tokenIssuer: TokenIssuer, @@ -148,7 +148,7 @@ export function createGithubProvider( const userProfileURL = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/api/v3/user` : undefined; - const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`; + const callbackURL = `${baseUrl}/${providerId}/handler/frame`; const opts = { clientID, diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts index c5c546c6f3..22d0bd4f0a 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.ts @@ -133,7 +133,7 @@ export class GitlabAuthProvider implements OAuthProviderHandlers { export function createGitlabProvider( { baseUrl }: AuthProviderConfig, - env: string, + _: string, envConfig: Config, logger: Logger, tokenIssuer: TokenIssuer, @@ -145,7 +145,7 @@ export function createGitlabProvider( const clientSecret = envConfig.getString('clientSecret'); const audience = envConfig.getString('audience'); const baseURL = audience || 'https://gitlab.com'; - const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`; + const callbackURL = `${baseUrl}/${providerId}/handler/frame`; const opts = { clientID, diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index 5749d1465f..b8070949f9 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -145,7 +145,7 @@ export class GoogleAuthProvider implements OAuthProviderHandlers { export function createGoogleProvider( { baseUrl }: AuthProviderConfig, - env: string, + _: string, envConfig: Config, logger: Logger, tokenIssuer: TokenIssuer, @@ -155,7 +155,7 @@ export function createGoogleProvider( const appOrigin = envConfig.getString('appOrigin'); const clientID = envConfig.getString('clientId'); const clientSecret = envConfig.getString('clientSecret'); - const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`; + const callbackURL = `${baseUrl}/${providerId}/handler/frame`; const opts = { clientID, diff --git a/plugins/auth-backend/src/providers/oauth2/provider.ts b/plugins/auth-backend/src/providers/oauth2/provider.ts index 967fd011f0..c03f7c4371 100644 --- a/plugins/auth-backend/src/providers/oauth2/provider.ts +++ b/plugins/auth-backend/src/providers/oauth2/provider.ts @@ -143,7 +143,7 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers { export function createOAuth2Provider( { baseUrl }: AuthProviderConfig, - env: string, + _: string, envConfig: Config, logger: Logger, tokenIssuer: TokenIssuer, @@ -153,7 +153,7 @@ export function createOAuth2Provider( const appOrigin = envConfig.getString('appOrigin'); const clientID = envConfig.getString('clientId'); const clientSecret = envConfig.getString('clientSecret'); - const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`; + const callbackURL = `${baseUrl}/${providerId}/handler/frame`; const authorizationURL = envConfig.getString('authorizationURL'); const tokenURL = envConfig.getString('tokenURL'); diff --git a/plugins/auth-backend/src/providers/okta/provider.ts b/plugins/auth-backend/src/providers/okta/provider.ts index 56e8b1220d..058300cef6 100644 --- a/plugins/auth-backend/src/providers/okta/provider.ts +++ b/plugins/auth-backend/src/providers/okta/provider.ts @@ -165,7 +165,7 @@ export class OktaAuthProvider implements OAuthProviderHandlers { export function createOktaProvider( { baseUrl }: AuthProviderConfig, - env: string, + _: string, envConfig: Config, logger: Logger, tokenIssuer: TokenIssuer, @@ -176,7 +176,7 @@ export function createOktaProvider( const clientID = envConfig.getString('clientId'); const clientSecret = envConfig.getString('clientSecret'); const audience = envConfig.getString('audience'); - const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`; + const callbackURL = `${baseUrl}/${providerId}/handler/frame`; const opts = { audience, diff --git a/plugins/auth-backend/src/providers/saml/provider.ts b/plugins/auth-backend/src/providers/saml/provider.ts index 3ddfba4bb0..1ccee1a9cb 100644 --- a/plugins/auth-backend/src/providers/saml/provider.ts +++ b/plugins/auth-backend/src/providers/saml/provider.ts @@ -106,6 +106,10 @@ export class SamlAuthProvider implements AuthProviderRouteHandlers { async logout(_req: express.Request, res: express.Response): Promise { res.send('noop'); } + + identifyEnv(): string | undefined { + return undefined; + } } type SAMLProviderOptions = { diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index 93d459bb0d..d372fd1b94 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -203,6 +203,15 @@ export interface AuthProviderRouteHandlers { * @param {express.Response} res */ logout?(req: express.Request, res: express.Response): Promise; + + /** + *(Optional) A method to identify the environment Context of the Request + * + *Request + *- contains the environment context information encoded in the request + * @param {express.Request} req + */ + identifyEnv?(req: express.Request): string | undefined; } export type AuthProviderFactory = ( @@ -332,3 +341,14 @@ export type SAMLProviderConfig = { export type SAMLEnvironmentProviderConfig = { [key: string]: SAMLProviderConfig; }; + +export type OAuthState = { + /* A type for the serialized value in the `state` parameter of the OAuth authorization flow + */ + nonce: string; + env: string; +}; + +export type EnvironmentIdentifierFn = ( + req: express.Request, +) => string | undefined; diff --git a/plugins/catalog-backend/migrations/20200807120600_entitySearch.js b/plugins/catalog-backend/migrations/20200807120600_entitySearch.js new file mode 100644 index 0000000000..6e02975f92 --- /dev/null +++ b/plugins/catalog-backend/migrations/20200807120600_entitySearch.js @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex')} knex + */ +exports.up = async function up(knex) { + try { + await knex.schema.alterTable('entities_search', table => { + table.text('value').nullable().alter(); + }); + } catch (e) { + // Sqlite does not support alter column. + } +}; + +/** + * @param {import('knex')} knex + */ +exports.down = async function down(knex) { + try { + await knex.schema.alterTable('entities_search', table => { + table.string('value').nullable().alter(); + }); + } catch (e) { + // Sqlite does not support alter column. + } +}; diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 5d0d957aca..2445ee206e 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "mock-data": "./scripts/mock-data.sh" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/catalog-model": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/catalog-model": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^3.0.3", @@ -39,7 +39,7 @@ "yup": "^0.29.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/lodash": "^4.14.151", "@types/node-fetch": "^2.5.7", "@types/supertest": "^2.0.8", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index d0d9dffa23..a0e69a647d 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,12 +21,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/plugin-github-actions": "^0.1.1-alpha.17", - "@backstage/plugin-scaffolder": "^0.1.1-alpha.17", - "@backstage/plugin-sentry": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-github-actions": "^0.1.1-alpha.18", + "@backstage/plugin-scaffolder": "^0.1.1-alpha.18", + "@backstage/plugin-sentry": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -39,9 +39,9 @@ "swr": "^0.2.2" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.3.0", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 11c75f668d..4fb7a28124 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-circleci", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "postpack": "backstage-cli postpack" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -36,8 +36,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 431e456796..e7783675ae 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -32,9 +32,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/explore/src/components/ExplorePluginPage.tsx b/plugins/explore/src/components/ExplorePluginPage.tsx index c1d36f2544..1752f402be 100644 --- a/plugins/explore/src/components/ExplorePluginPage.tsx +++ b/plugins/explore/src/components/ExplorePluginPage.tsx @@ -88,6 +88,15 @@ const toolsCards = [ image: 'https://miro.medium.com/max/801/1*R28u8gj-hVdDFISoYqPhrQ.png', tags: ['gitops', 'dev'], }, + { + title: 'Rollbar', + description: + 'Error monitoring and crash reporting for agile development and continuous delivery', + url: '/rollbar', + image: + 'https://images.ctfassets.net/cj4mgtttlyx7/4DfiWj9CbuHBi10uWK7JHn/5e94a6c5dbd5d50bdcd8d9e78f88689b/rollbar-seo.png', + tags: ['rollbar', 'monitoring', 'errors'], + }, ]; const ExplorePluginPage: FC<{}> = () => { diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index b9c6523da6..8fcc4591d2 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-actions", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,11 +22,11 @@ "mock-data": "./scripts/mock-data.sh" }, "dependencies": { - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/core-api": "^0.1.1-alpha.17", - "@backstage/plugin-catalog": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/core-api": "^0.1.1-alpha.18", + "@backstage/plugin-catalog": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -39,8 +39,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/github-actions/src/plugin.ts b/plugins/github-actions/src/plugin.ts index 7faee4e624..dbc366bd71 100644 --- a/plugins/github-actions/src/plugin.ts +++ b/plugins/github-actions/src/plugin.ts @@ -23,6 +23,10 @@ export const rootRouteRef = createRouteRef({ path: '/github-actions', title: 'GitHub Actions', }); +export const projectRouteRef = createRouteRef({ + path: '/github-actions/:kind/:optionalNamespaceAndName/', + title: 'GitHub Actions for project', +}); export const buildRouteRef = createRouteRef({ path: '/github-actions/workflow-run/:id', title: 'GitHub Actions Workflow Run', @@ -32,6 +36,7 @@ export const plugin = createPlugin({ id: 'github-actions', register({ router }) { router.addRoute(rootRouteRef, WorkflowRunsPage); + router.addRoute(projectRouteRef, WorkflowRunsPage); router.addRoute(buildRouteRef, WorkflowRunDetailsPage); }, }); diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index b7f541953a..5815386014 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gitops-profiles", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -32,8 +32,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 08984d6f11..a034c14a11 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "private": false, "publishConfig": { "access": "public", @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -43,9 +43,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/graphql/package.json b/plugins/graphql/package.json index f640c6267b..2b6d9a40e7 100644 --- a/plugins/graphql/package.json +++ b/plugins/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-graphql-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,9 +20,9 @@ "mock-data": "./scripts/mock-data.sh" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", - "@backstage/plugin-catalog-graphql": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", + "@backstage/plugin-catalog-graphql": "^0.1.1-alpha.18", "@graphql-modules/core": "^0.7.17", "@types/express": "^4.17.6", "apollo-server": "^2.16.0", @@ -36,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/supertest": "^2.0.8", "eslint-plugin-graphql": "^4.0.0", "msw": "^0.19.5", diff --git a/plugins/identity-backend/package.json b/plugins/identity-backend/package.json index 851391daad..c5c3bffc9b 100644 --- a/plugins/identity-backend/package.json +++ b/plugins/identity-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-identity-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "compression": "^1.7.4", "cors": "^2.8.5", @@ -33,7 +33,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "jest-fetch-mock": "^3.0.3" }, "files": [ diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index b2985b7547..cbf4a77f7e 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-lighthouse", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -33,9 +33,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 5d0b01952a..023fc81cf2 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,8 +19,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^3.0.3", @@ -34,7 +34,7 @@ "yup": "^0.29.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/node-fetch": "^2.5.7", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index 10690dfbdd..085647bc4e 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -15,7 +15,7 @@ */ import { createRouter } from './router'; -import winston from 'winston'; +import * as winston from 'winston'; import { ConfigReader } from '@backstage/config'; import { loadBackendConfig } from '@backstage/backend-common'; diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index 8a33caa0c6..02fd3fe0ed 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-register-component", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,10 +21,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/plugin-catalog": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-catalog": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -36,8 +36,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index dd622a8e22..102e233756 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "axios": "^0.19.2", "camelcase-keys": "^6.2.2", @@ -36,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/supertest": "^2.0.8", "jest-fetch-mock": "^3.0.3", "supertest": "^4.0.2" diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index aacd56e3da..1ca02cb528 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -35,9 +35,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.3.0", diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 135480e6dc..fc956c9832 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,9 +21,9 @@ "mock-data": "./scripts/mock-data.sh" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", "@octokit/rest": "^18.0.0", "@types/dockerode": "^2.5.32", "@types/express": "^4.17.6", @@ -43,7 +43,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@octokit/types": "^5.0.1", "@types/fs-extra": "^9.0.1", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/.github/workflows/build.yml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/.github/workflows/build.yml index e3ca9f44e2..33dd3436d5 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/.github/workflows/build.yml +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/.github/workflows/build.yml @@ -1,6 +1,11 @@ name: Frontend CI -on: [push, pull_request] +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + jobs: build: diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/component-info.yaml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/component-info.yaml index 5f479d9e47..65a77d4a27 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/component-info.yaml +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/component-info.yaml @@ -3,6 +3,9 @@ kind: Component metadata: name: {{cookiecutter.component_id}} description: {{cookiecutter.description}} + annotations: + github.com/project-slug: {{cookiecutter.storePath}} + backstage.io/github-actions-id: {{cookiecutter.storePath}} spec: type: website lifecycle: experimental diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/.github/workflows/build.yml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/.github/workflows/build.yml new file mode 100644 index 0000000000..04e1d10b47 --- /dev/null +++ b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/.github/workflows/build.yml @@ -0,0 +1,21 @@ +name: Java CI with Maven + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Build with Maven + run: mvn -B package --file pom.xml diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/component-info.yaml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/component-info.yaml index f796df8820..15c8fdcfff 100644 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/component-info.yaml +++ b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/{{cookiecutter.component_id}}/component-info.yaml @@ -3,6 +3,9 @@ kind: Component metadata: name: {{cookiecutter.component_id}} description: {{cookiecutter.description}} + annotations: + github.com/project-slug: {{cookiecutter.storePath}} + backstage.io/github-actions-id: {{cookiecutter.storePath}} spec: type: service lifecycle: experimental diff --git a/plugins/scaffolder-backend/scripts/mock-data.sh b/plugins/scaffolder-backend/scripts/mock-data.sh index 8c73ff9378..f18d4b4838 100755 --- a/plugins/scaffolder-backend/scripts/mock-data.sh +++ b/plugins/scaffolder-backend/scripts/mock-data.sh @@ -17,5 +17,5 @@ curl \ --location \ --request POST 'localhost:7000/catalog/locations' \ --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"github\", \"target\": \"https://github.com/benjdlambert/cookiecutter-golang/blob/master/template.yaml\"}" + --data-raw "{\"type\": \"github\", \"target\": \"https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml\"}" echo diff --git a/plugins/scaffolder-backend/src/scaffolder/jobs/logger.ts b/plugins/scaffolder-backend/src/scaffolder/jobs/logger.ts index a35be88832..5e38bd8f2f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/jobs/logger.ts +++ b/plugins/scaffolder-backend/src/scaffolder/jobs/logger.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { PassThrough } from 'stream'; -import winston from 'winston'; +import * as winston from 'winston'; import { JsonValue } from '@backstage/config'; export const makeLogStream = (meta: Record) => { diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 6121a573d8..822a620c8a 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,10 +21,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/plugin-catalog": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-catalog": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,9 +41,9 @@ "swr": "^0.2.2" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/sentry-backend/package.json b/plugins/sentry-backend/package.json index 4c41b1edb7..e199dd2f1d 100644 --- a/plugins/sentry-backend/package.json +++ b/plugins/sentry-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sentry-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", "@types/express": "^4.17.6", "axios": "^0.19.2", "compression": "^1.7.4", @@ -34,7 +34,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "jest-fetch-mock": "^3.0.3" }, "files": [ diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 37dd61cd72..3a6cf54199 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sentry", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,8 +34,8 @@ "timeago.js": "^4.0.2" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 3099a4eb35..b2a7be7341 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-radar", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,9 +21,9 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/test-utils-core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/test-utils-core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -35,8 +35,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/techdocs-backend/.gitignore b/plugins/techdocs-backend/.gitignore index 650853097a..7b4d4ba2e6 100644 --- a/plugins/techdocs-backend/.gitignore +++ b/plugins/techdocs-backend/.gitignore @@ -1,2 +1 @@ static -!src/techdocs/stages/build \ No newline at end of file diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 46463b5a4d..8a5a9fd10a 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,9 +21,9 @@ "mock-data": "./scripts/mock-data.sh" }, "dependencies": { - "@backstage/backend-common": "^0.1.1-alpha.17", - "@backstage/catalog-model": "^0.1.1-alpha.17", - "@backstage/config": "^0.1.1-alpha.17", + "@backstage/backend-common": "^0.1.1-alpha.18", + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/config": "^0.1.1-alpha.18", "@types/dockerode": "^2.5.34", "@types/express": "^4.17.6", "dockerode": "^3.2.1", @@ -35,7 +35,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", "@types/node-fetch": "^2.5.7", "supertest": "^4.0.2" }, diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index accb2e1503..a1b7ddb589 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/test-utils": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -36,8 +36,8 @@ "sanitize-html": "^1.27.0" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index ed45aaad0e..2c0c838de8 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-welcome", - "version": "0.1.1-alpha.17", + "version": "0.1.1-alpha.18", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -21,8 +21,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.1.1-alpha.17", - "@backstage/theme": "^0.1.1-alpha.17", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -32,8 +32,8 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.17", - "@backstage/dev-utils": "^0.1.1-alpha.17", + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx index 272297ed45..3ceb0af58d 100644 --- a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx +++ b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx @@ -113,7 +113,7 @@ const WelcomePage = () => { We suggest you either check out the documentation for{' '} - + creating a plugin {' '} or have a look in the code for the{' '} @@ -135,7 +135,7 @@ const WelcomePage = () => { backstage.io - + Create a plugin diff --git a/yarn.lock b/yarn.lock index a862980d7c..83b287dd4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1938,43 +1938,45 @@ aggregate-error "3.0.1" tslib "~2.0.0" -"@hapi/address@^2.1.2": - version "2.1.4" - resolved "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" - integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== - -"@hapi/formula@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd" - integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA== - -"@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0": - version "8.5.1" - resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" - integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== - -"@hapi/joi@^16.1.8": - version "16.1.8" - resolved "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839" - integrity sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg== +"@hapi/address@^4.0.1": + version "4.1.0" + resolved "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz#d60c5c0d930e77456fdcde2598e77302e2955e1d" + integrity sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ== dependencies: - "@hapi/address" "^2.1.2" - "@hapi/formula" "^1.2.0" - "@hapi/hoek" "^8.2.4" - "@hapi/pinpoint" "^1.0.2" - "@hapi/topo" "^3.1.3" + "@hapi/hoek" "^9.0.0" -"@hapi/pinpoint@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13" - integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ== +"@hapi/formula@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz#edade0619ed58c8e4f164f233cda70211e787128" + integrity sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A== -"@hapi/topo@^3.1.3": - version "3.1.6" - resolved "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" - integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== +"@hapi/hoek@^9.0.0": + version "9.0.4" + resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz#e80ad4e8e8d2adc6c77d985f698447e8628b6010" + integrity sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw== + +"@hapi/joi@^17.1.1": + version "17.1.1" + resolved "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz#9cc8d7e2c2213d1e46708c6260184b447c661350" + integrity sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg== dependencies: - "@hapi/hoek" "^8.3.0" + "@hapi/address" "^4.0.1" + "@hapi/formula" "^2.0.0" + "@hapi/hoek" "^9.0.0" + "@hapi/pinpoint" "^2.0.0" + "@hapi/topo" "^5.0.0" + +"@hapi/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz#805b40d4dbec04fc116a73089494e00f073de8df" + integrity sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw== + +"@hapi/topo@^5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" + integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + dependencies: + "@hapi/hoek" "^9.0.0" "@hot-loader/react-dom@^16.13.0": version "16.13.0" @@ -3262,9 +3264,9 @@ react-lifecycles-compat "^3.0.4" "@rjsf/core@^2.1.0": - version "2.1.0" - resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.1.0.tgz#00130c89959850cc90224fd14c82feaecc2b9dc8" - integrity sha512-2A65RZ3I/RVVNfJUTYUkFs4snX02GHzql6o/KcLBBoG8G8+gr9ZeIi3+JEbe2mOEN02rIPnyJtBkl6C7QajyAw== + version "2.2.2" + resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.2.2.tgz#1ebb6fe47448998f3b54e2dea8d58de8a46014dc" + integrity sha512-4d6DHIiTJEkUq5vyl4LIxLGIYYKKnHcprf94oVchUtGQvRFjNUDFxeFQoyr90oaxcBMs2WDDcCgjcFaKVyfErg== dependencies: "@babel/runtime-corejs2" "^7.8.7" "@types/json-schema" "^7.0.4" @@ -4574,9 +4576,9 @@ integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== "@types/http-errors@^1.6.3": - version "1.6.3" - resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.3.tgz#619a55768eab98299e8f76747339f3373f134e69" - integrity sha512-4KCE/agIcoQ9bIfa4sBxbZdnORzRjIw8JNQPLfqoNv7wQl/8f8mRbW68Q8wBsQFoJkPUHGlQYZ9sqi5WpfGSEQ== + version "1.8.0" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" + integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== "@types/http-proxy-middleware@*": version "0.19.3" @@ -4636,9 +4638,9 @@ pretty-format "^25.2.1" "@types/jquery@^3.3.34": - version "3.3.38" - resolved "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.38.tgz#6385f1e1b30bd2bff55ae8ee75ea42a999cc3608" - integrity sha512-nkDvmx7x/6kDM5guu/YpXkGZ/Xj/IwGiLDdKM99YA5Vag7pjGyTJ8BNUh/6hxEn/sEu5DKtyRgnONJ7EmOoKrA== + version "3.5.1" + resolved "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.1.tgz#cebb057acf5071c40e439f30e840c57a30d406c3" + integrity sha512-Tyctjh56U7eX2b9udu3wG853ASYP0uagChJcQJXLUXEU6C/JiW5qt5dl8ao01VRj1i5pgXPAf8f1mq4+FDLRQg== dependencies: "@types/sizzle" "*" @@ -4647,12 +4649,7 @@ resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== -"@types/json-schema@*", "@types/json-schema@^7.0.3": - version "7.0.4" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== - -"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5": +"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5": version "7.0.5" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== @@ -5449,6 +5446,11 @@ JSONStream@^1.0.4, JSONStream@^1.3.4: jsonparse "^1.2.0" through ">=2.2.7 <3" +abab@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4= + abab@^2.0.0, abab@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" @@ -5467,6 +5469,13 @@ accepts@^1.3.5, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +acorn-globals@^1.0.4: + version "1.0.9" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf" + integrity sha1-VbtemGkVB7dFedBRNBMhfDgMVM8= + dependencies: + acorn "^2.1.0" + acorn-globals@^4.1.0: version "4.3.4" resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" @@ -5498,6 +5507,11 @@ acorn-walk@^7.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== +acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + integrity sha1-q259nYhqrKiwhbwzEreaGYQz8Oc= + acorn@^5.5.3: version "5.7.4" resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" @@ -6629,6 +6643,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base64-arraybuffer@^0.1.5: + version "0.1.5" + resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + base64-js@^1.0.2: version "1.3.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" @@ -7243,6 +7262,16 @@ caniuse-lite@^1.0.30001093: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz#809360df7a5b3458f627aa46b0f6ed6d5239da9a" integrity sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ== +canvg@1.5.3: + version "1.5.3" + resolved "https://registry.npmjs.org/canvg/-/canvg-1.5.3.tgz#aad17915f33368bf8eb80b25d129e3ae922ddc5f" + integrity sha512-7Gn2IuQzvUQWPIuZuFHrzsTM0gkPz2RRT9OcbdmA03jeKk8kltrD8gqUzNX15ghY/4PV5bbe5lmD6yDLDY6Ybg== + dependencies: + jsdom "^8.1.0" + rgbcolor "^1.0.1" + stackblur-canvas "^1.4.1" + xmldom "^0.1.22" + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -7825,9 +7854,9 @@ concat-with-sourcemaps@^1.1.0: source-map "^0.6.1" concurrently@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz#ead55121d08a0fc817085584c123cedec2e08975" - integrity sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw== + version "5.3.0" + resolved "https://registry.npmjs.org/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b" + integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ== dependencies: chalk "^2.4.2" date-fns "^2.0.1" @@ -8070,12 +8099,7 @@ core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.7, core-js@^2.6.5: resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== -core-js@^3.0.1, core-js@^3.0.4: - version "3.6.4" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" - integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== - -core-js@^3.5.0: +core-js@^3.0.1, core-js@^3.0.4, core-js@^3.5.0: version "3.6.5" resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== @@ -8281,6 +8305,13 @@ css-in-js-utils@^2.0.0: hyphenate-style-name "^1.0.2" isobject "^3.0.1" +css-line-break@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/css-line-break/-/css-line-break-1.0.1.tgz#19f2063a33e95fb2831b86446c0b80c188af450a" + integrity sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo= + dependencies: + base64-arraybuffer "^0.1.5" + css-loader@^3.0.0, css-loader@^3.5.3: version "3.6.0" resolved "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" @@ -8480,7 +8511,7 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.37" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: +cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0", "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: version "0.3.8" resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -8490,6 +8521,13 @@ cssom@^0.4.4: resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== +"cssstyle@>= 0.2.34 < 0.3.0": + version "0.2.37" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ= + dependencies: + cssom "0.3.x" + cssstyle@^1.0.0: version "1.4.0" resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" @@ -8643,12 +8681,7 @@ date-fns@^1.27.2: resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== -date-fns@^2.0.0-alpha.27: - version "2.12.0" - resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.12.0.tgz#01754c8a2f3368fc1119cf4625c3dad8c1845ee6" - integrity sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw== - -date-fns@^2.0.1: +date-fns@^2.0.0-alpha.27, date-fns@^2.0.1: version "2.15.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f" integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ== @@ -9600,6 +9633,18 @@ escodegen@^1.14.1, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +escodegen@^1.6.1: + version "1.14.3" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-config-prettier@^6.0.0: version "6.10.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz#7b15e303bf9c956875c948f6b21500e48ded6a7f" @@ -10226,7 +10271,7 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fault@^1.0.2: +fault@^1.0.0, fault@^1.0.2: version "1.0.4" resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== @@ -10332,6 +10377,11 @@ file-loader@^4.2.0: loader-utils "^1.2.3" schema-utils "^2.5.0" +"file-saver@github:eligrey/FileSaver.js#1.3.8": + version "1.3.8" + uid e865e37af9f9947ddcced76b549e27dc45c1cb2e + resolved "https://codeload.github.com/eligrey/FileSaver.js/tar.gz/e865e37af9f9947ddcced76b549e27dc45c1cb2e" + file-system-cache@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" @@ -11532,16 +11582,16 @@ hex-color-regex@^1.1.0: resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +highlight.js@^10.1.1, highlight.js@~10.1.0: + version "10.1.2" + resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.1.2.tgz#c20db951ba1c22c055010648dfffd7b2a968e00c" + integrity sha512-Q39v/Mn5mfBlMff9r+zzA+gWxRsCRKwEMvYTiisLr/XUiFI/4puWt0Ojdko3R3JCNWGdOWaA5g/Yxqa23kC5AA== + highlight.js@~9.13.0: version "9.13.1" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== -highlight.js@~9.15.0, highlight.js@~9.15.1: - version "9.15.10" - resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" - integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw== - history@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/history/-/history-5.0.0.tgz#0cabbb6c4bbf835addb874f8259f6d25101efd08" @@ -11669,6 +11719,13 @@ html-webpack-plugin@^4.0.0-beta.2, html-webpack-plugin@^4.3.0: tapable "^1.1.3" util.promisify "1.0.0" +html2canvas@1.0.0-alpha.12: + version "1.0.0-alpha.12" + resolved "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-alpha.12.tgz#3b1992e3c9b3f56063c35fd620494f37eba88513" + integrity sha1-OxmS48mz9WBjw1/WIElPN+uohRM= + dependencies: + css-line-break "1.0.1" + htmlparser2@^3.3.0: version "3.10.1" resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" @@ -11855,7 +11912,7 @@ hyphenate-style-name@^1.0.2, hyphenate-style-name@^1.0.3: resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== -iconv-lite@0.4.24, iconv-lite@^0.4.21, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.13, iconv-lite@^0.4.21, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -13368,6 +13425,29 @@ jsdom@^16.2.2: ws "^7.2.3" xml-name-validator "^3.0.0" +jsdom@^8.1.0: + version "8.5.0" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-8.5.0.tgz#d4d8f5dbf2768635b62a62823b947cf7071ebc98" + integrity sha1-1Nj12/J2hjW2KmKCO5R89wcevJg= + dependencies: + abab "^1.0.0" + acorn "^2.4.0" + acorn-globals "^1.0.4" + array-equal "^1.0.0" + cssom ">= 0.3.0 < 0.4.0" + cssstyle ">= 0.2.34 < 0.3.0" + escodegen "^1.6.1" + iconv-lite "^0.4.13" + nwmatcher ">= 1.3.7 < 2.0.0" + parse5 "^1.5.1" + request "^2.55.0" + sax "^1.1.4" + symbol-tree ">= 3.1.0 < 4.0.0" + tough-cookie "^2.2.0" + webidl-conversions "^3.0.1" + whatwg-url "^2.0.1" + xml-name-validator ">= 2.0.1 < 3.0.0" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -13506,6 +13586,7 @@ jsonpointer@^4.0.1: resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= +<<<<<<< HEAD jsonwebtoken@^8.1.0: version "8.5.1" resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -13521,6 +13602,24 @@ jsonwebtoken@^8.1.0: lodash.once "^4.0.0" ms "^2.1.1" semver "^5.6.0" +======= +jspdf-autotable@3.5.3: + version "3.5.3" + resolved "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-3.5.3.tgz#2f73adb07f340e7dbf22950e3e6c8bf853991479" + integrity sha512-K+cNWW3x6w0R/1B5m6PYOm6v8CTTDXy/g32lZouc7SuC6zhvzMN2dauhk6dDYxPD0pky0oyPIJFwSJ/tV8PAeg== + +jspdf@1.5.3: + version "1.5.3" + resolved "https://registry.npmjs.org/jspdf/-/jspdf-1.5.3.tgz#5a12c011479defabef5735de55c913060ed219f2" + integrity sha512-J9X76xnncMw+wIqb15HeWfPMqPwYxSpPY8yWPJ7rAZN/ZDzFkjCSZObryCyUe8zbrVRNiuCnIeQteCzMn7GnWw== + dependencies: + canvg "1.5.3" + file-saver "github:eligrey/FileSaver.js#1.3.8" + html2canvas "1.0.0-alpha.12" + omggif "1.0.7" + promise-polyfill "8.1.0" + stackblur-canvas "2.2.0" +>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353 jsprim@^1.2.2: version "1.4.1" @@ -14246,13 +14345,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lowlight@1.12.1: - version "1.12.1" - resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.12.1.tgz#014acf8dd73a370e02ff1cc61debcde3bb1681eb" - integrity sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w== +lowlight@^1.14.0: + version "1.14.0" + resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.14.0.tgz#83ebc143fec0f9e6c0d3deffe01be129ce56b108" + integrity sha512-N2E7zTM7r1CwbzwspPxJvmjAbxljCPThTFawEX2Z7+P3NGrrvY54u8kyU16IY4qWfoVIxY8SYCS8jTkuG7TqYA== dependencies: - fault "^1.0.2" - highlight.js "~9.15.0" + fault "^1.0.0" + highlight.js "~10.1.0" lowlight@~1.11.0: version "1.11.0" @@ -14400,10 +14499,10 @@ markdown-to-jsx@^6.11.4: prop-types "^15.6.2" unquote "^1.1.0" -material-table@1.62.x: - version "1.62.0" - resolved "https://registry.npmjs.org/material-table/-/material-table-1.62.0.tgz#117793ebf16ab0fccbb6f8a670d849a7be0b5995" - integrity sha512-+3tnk32lXtkXeKM7k/hZ82jpSzlXU5CsWXqJHq4Tl0Un7ycjK2Kef6EMPqeE3i58vKNqbIvbrFf/ESH0D/Qwig== +material-table@1.68.x: + version "1.68.0" + resolved "https://registry.npmjs.org/material-table/-/material-table-1.68.0.tgz#275c3d9a885c40ae4bc5a7461c00e877f92397b9" + integrity sha512-dyJJaVsS3m+i6sn71AvYcVdA1P9X1XiUOM2PekfvEeeMtkdQb66oChGkk77ndYi3Ja6j4DovGVNrgeVLwXLZiw== dependencies: "@date-io/date-fns" "^1.1.0" "@material-ui/pickers" "^3.2.2" @@ -14412,6 +14511,8 @@ material-table@1.62.x: debounce "^1.2.0" fast-deep-equal "2.0.1" filefy "0.1.10" + jspdf "1.5.3" + jspdf-autotable "3.5.3" prop-types "^15.6.2" react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" @@ -15442,6 +15543,11 @@ number-is-nan@^1.0.0: resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +"nwmatcher@>= 1.3.7 < 2.0.0": + version "1.4.4" + resolved "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== + nwsapi@^2.0.7, nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -15586,6 +15692,11 @@ octokit-pagination-methods@^1.1.0: resolved "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ== +omggif@1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/omggif/-/omggif-1.0.7.tgz#59d2eecb0263de84635b3feb887c0c9973f1e49d" + integrity sha1-WdLuywJj3oRjWz/riHwMmXPx5J0= + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -15961,7 +16072,23 @@ parse-entities@^1.1.0, parse-entities@^1.1.2: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +<<<<<<< HEAD parse-filepath@1.0.2, parse-filepath@^1.0.1: +======= +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-filepath@^1.0.1: +>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353 version "1.0.2" resolved "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= @@ -16038,6 +16165,11 @@ parse5@5.1.1: resolved "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== +parse5@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" + integrity sha1-m387DeMr543CQBsXVzzK8Pb1nZQ= + parseurl@^1.3.2, parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -17017,6 +17149,7 @@ pretty-hrtime@^1.0.3: resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= +<<<<<<< HEAD prisma-json-schema@0.1.3: version "0.1.3" resolved "https://registry.npmjs.org/prisma-json-schema/-/prisma-json-schema-0.1.3.tgz#6c302db8f464f8b92e8694d3f7dd3f41ac9afcbe" @@ -17050,6 +17183,12 @@ prismjs@^1.8.4: version "1.19.0" resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz#713afbd45c3baca4b321569f2df39e17e729d4dc" integrity sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw== +======= +prismjs@^1.20.0, prismjs@^1.8.4, prismjs@~1.20.0: + version "1.20.0" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03" + integrity sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ== +>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353 optionalDependencies: clipboard "^2.0.0" @@ -17085,6 +17224,11 @@ promise-inflight@^1.0.1: resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.0.tgz#30059da54d1358ce905ac581f287e184aedf995d" + integrity sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA== + promise-polyfill@^8.1.3: version "8.1.3" resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" @@ -17661,9 +17805,9 @@ react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-i integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-lazylog@^4.5.2: - version "4.5.2" - resolved "https://registry.npmjs.org/react-lazylog/-/react-lazylog-4.5.2.tgz#9b66a0997348690f56286f6afcda97ebd0c62b7c" - integrity sha512-XvAjlzs8tzbjmqyEdj8HwW8Kg5nfqZAzIGeeG1incZuhuXQkekIs6nYb3W/GQNxDpA1CowgNUR4UfP+7/C2Ang== + version "4.5.3" + resolved "https://registry.npmjs.org/react-lazylog/-/react-lazylog-4.5.3.tgz#289e24995b5599e75943556ac63f5e2c04d0001e" + integrity sha512-lyov32A/4BqihgXgtNXTHCajXSXkYHPlIEmV8RbYjHIMxCFSnmtdg4kDCI3vATz7dURtiFTvrw5yonHnrS+NNg== dependencies: "@mattiasbuelens/web-streams-polyfill" "^0.2.0" fetch-readablestream "^0.2.0" @@ -17781,16 +17925,16 @@ react-syntax-highlighter@^11.0.2: prismjs "^1.8.4" refractor "^2.4.1" -react-syntax-highlighter@^12.2.1: - version "12.2.1" - resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz#14d78352da1c1c3f93c6698b70ec7c706b83493e" - integrity sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA== +react-syntax-highlighter@^13.2.1: + version "13.2.1" + resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.2.1.tgz#3d5a3b655cd85ce06b9508e0365d01ef9b8560bb" + integrity sha512-O/AF/ll4I3Dp+2WuKbnF5yKG4b1BUncqcpTW6MIBDJPr2eGKqlNGS3Nv+lyCFtAIHx8N+/ktti8qH14Q5VjjcA== dependencies: "@babel/runtime" "^7.3.1" - highlight.js "~9.15.1" - lowlight "1.12.1" - prismjs "^1.8.4" - refractor "^2.4.1" + highlight.js "^10.1.1" + lowlight "^1.14.0" + prismjs "^1.20.0" + refractor "^3.0.0" react-test-renderer@^16.13.1: version "16.13.1" @@ -18098,6 +18242,15 @@ refractor@^2.4.1: parse-entities "^1.1.2" prismjs "~1.17.0" +refractor@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/refractor/-/refractor-3.0.0.tgz#7c8072eaf49dbc1b333e7acc64fb52a1c9b17c75" + integrity sha512-eCGK/oP4VuyW/ERqjMZRZHxl2QsztbkedkYy/SxqE/+Gh1gLaAF17tWIOcVJDiyGhar1NZy/0B9dFef7J0+FDw== + dependencies: + hastscript "^5.0.0" + parse-entities "^2.0.0" + prismjs "~1.20.0" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -18292,9 +18445,9 @@ replace-ext@1.0.0: integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= replace-in-file@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.0.0.tgz#a583be911c4af3ecbf709ca97c48f3f9e7f2b626" - integrity sha512-vMmJekpRgju0GA0UvRxauDbQ645wGXxasVZfw5l5HKk58OlAI1tMmXNcV+YAUKrS/XFdBPla5qgvjI5Tqvshvg== + version "6.1.0" + resolved "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.1.0.tgz#9f9ddd7bb70d6ad231d2ad692e1b646e73d06647" + integrity sha512-URzjyF3nucvejuY13HFd7O+Q6tFJRLKGHLYVvSh+LiZj3gFXzSYGnIkQflnJJulCAI2/RTZaZkpOtdVdW0EhQA== dependencies: chalk "^4.0.0" glob "^7.1.6" @@ -18328,7 +18481,11 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.8: stealthy-require "^1.1.1" tough-cookie "^2.3.3" +<<<<<<< HEAD request@2.88.2, request@^2.85.0, request@^2.87.0, request@^2.88.0, request@^2.88.2: +======= +request@^2.55.0, request@^2.85.0, request@^2.87.0, request@^2.88.0, request@^2.88.2: +>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353 version "2.88.2" resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -18496,6 +18653,11 @@ rgba-regex@^1.0.0: resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rgbcolor@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d" + integrity sha1-1lBezbMEplldom+ktDMHMGd1lF0= + rifm@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be" @@ -18533,11 +18695,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: inherits "^2.0.1" rollup-plugin-dts@^1.4.6: - version "1.4.7" - resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-1.4.7.tgz#6255147ac777314c0725a1efcb42df10fe282243" - integrity sha512-QkunbJ96yUNkW95k/Vd6SdTjCbWSG0rMVUtpHSCwfg078Z7vbDaBnfz/gkSqR5h8WFMxoccBT4aodHm6387Jvg== + version "1.4.10" + resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-1.4.10.tgz#0373c4284a2ba4d2d72df69c289271a816bc2736" + integrity sha512-bL6MBXc8lK7D5b/tYbHaglxs4ZxMQTQilGA6Xm9KQBEj4h9ZwIDlAsvDooGjJ/cOw23r3POTRtSCEyTHxtzHJg== optionalDependencies: - "@babel/code-frame" "^7.8.3" + "@babel/code-frame" "^7.10.4" rollup-plugin-esbuild@^2.0.0: version "2.3.0" @@ -18659,14 +18821,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.3, rxjs@^6.5.4, rxjs@^6.5.5: - version "6.5.5" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" - integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== - dependencies: - tslib "^1.9.0" - -rxjs@^6.5.2: +rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.3, rxjs@^6.5.5: version "6.6.0" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84" integrity sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg== @@ -18739,7 +18894,7 @@ sanitize-html@^1.27.0: srcset "^2.0.1" xtend "^4.0.1" -sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: +sax@>=0.6.0, sax@^1.1.4, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -19470,6 +19625,16 @@ stack-utils@^2.0.2: dependencies: escape-string-regexp "^2.0.0" +stackblur-canvas@2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.2.0.tgz#cacc5924a0744b3e183eb2e6c1d8559c1a17c26e" + integrity sha512-5Gf8dtlf8k6NbLzuly2NkGrkS/Ahh+I5VUjO7TnFizdJtgpfpLLEdQlLe9umbcnZlitU84kfYjXE67xlSXfhfQ== + +stackblur-canvas@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-1.4.1.tgz#849aa6f94b272ff26f6471fa4130ed1f7e47955b" + integrity sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs= + stackframe@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71" @@ -19493,9 +19658,9 @@ stacktrace-js@^2.0.0: stacktrace-gps "^3.0.4" start-server-and-test@^1.10.11: - version "1.11.0" - resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.0.tgz#1b1a83d062b0028ee6e296bb4e0231f2d8b2f4af" - integrity sha512-FhkJFYL/lvbd0tKWvbxWNWjtFtq3Zpa09QDjA8EUH88AsgNL4hkAAKYNmbac+fFM8/GIZoJ1Mj4mm3SMI0X1bA== + version "1.11.2" + resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.2.tgz#9144b7b6f25197148f159f261ae80119afbb17d5" + integrity sha512-rk1zS5WQvdbc8slE5hPtzfji1dFSnBAfm+vSjToZNrBvozHJvuAG80xE5u8N4tQjg3Ej1Crjc19J++r28HGJgg== dependencies: bluebird "3.7.2" check-more-types "2.24.0" @@ -19503,7 +19668,7 @@ start-server-and-test@^1.10.11: execa "3.4.0" lazy-ass "1.6.0" ps-tree "1.2.0" - wait-on "4.0.0" + wait-on "5.1.0" start-server-webpack-plugin@^2.2.5: version "2.2.5" @@ -20001,7 +20166,7 @@ symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -symbol-tree@^3.2.2, symbol-tree@^3.2.4: +"symbol-tree@>= 3.1.0 < 4.0.0", symbol-tree@^3.2.2, symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -20421,7 +20586,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: +tough-cookie@^2.2.0, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -20452,6 +20617,11 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -21249,17 +21419,16 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" -wait-on@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/wait-on/-/wait-on-4.0.0.tgz#4d7e4485ca759968897fd3b0cc50720c0b4ca959" - integrity sha512-QrW3J8LzS5ADPfD9Rx5S6KJck66xkqyiFKQs9jmUTkIhiEOmkzU7WRZc+MjsnmkrgjitS2xQ4bb13hnlQnKBUQ== +wait-on@5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/wait-on/-/wait-on-5.1.0.tgz#b697f21c6fea0908b9c7ad6ed56ace4736768b66" + integrity sha512-JM0kgaE+V0nCDvSl72iM05W8NDt2E2M56WC5mzR7M+T+k6xjt2yYpyom+xA8RasSunFGzbxIpAXbVzXqtweAnA== dependencies: - "@hapi/joi" "^16.1.8" - lodash "^4.17.15" - minimist "^1.2.0" - request "^2.88.0" - request-promise-native "^1.0.8" - rxjs "^6.5.4" + "@hapi/joi" "^17.1.1" + axios "^0.19.2" + lodash "^4.17.19" + minimist "^1.2.5" + rxjs "^6.5.5" walker@^1.0.7, walker@~1.0.5: version "1.0.7" @@ -21298,6 +21467,11 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0, webidl-conversions@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -21489,6 +21663,14 @@ whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-2.0.1.tgz#5396b2043f020ee6f704d9c45ea8519e724de659" + integrity sha1-U5ayBD8CDub3BNnEXqhRnnJN5lk= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^6.4.1: version "6.5.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" @@ -21771,6 +21953,11 @@ xml-encryption@^1.0.0: xmldom "~0.1.15" xpath "0.0.27" +"xml-name-validator@>= 2.0.1 < 3.0.0": + version "2.0.1" + resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" + integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -21799,7 +21986,7 @@ xmldom@0.1.27: resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= -xmldom@0.1.x, xmldom@~0.1.15: +xmldom@0.1.x, xmldom@^0.1.22, xmldom@~0.1.15: version "0.1.31" resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==