From 394782704ea0c899da0a2d921992f930a5a1338f Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 4 Nov 2024 10:05:40 -0500 Subject: [PATCH 1/6] feat: export middleware from httpRouter entrypoint Signed-off-by: aramissennyeydd --- .../backend-defaults/report-httpRouter.api.md | 41 +++++++++++++++++++ .../{ => http}/createAuthIntegrationRouter.ts | 3 ++ .../createCookieAuthRefreshMiddleware.test.ts | 0 .../createCookieAuthRefreshMiddleware.ts | 0 .../createCredentialsBarrier.test.ts | 0 .../{ => http}/createCredentialsBarrier.ts | 3 ++ .../createLifecycleMiddleware.test.ts | 2 +- .../{ => http}/createLifecycleMiddleware.ts | 4 +- .../src/entrypoints/httpRouter/http/index.ts | 20 +++++++++ .../httpRouter/httpRouterServiceFactory.ts | 10 +++-- .../src/entrypoints/httpRouter/index.ts | 1 + 11 files changed, 77 insertions(+), 7 deletions(-) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createAuthIntegrationRouter.ts (98%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createCookieAuthRefreshMiddleware.test.ts (100%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createCookieAuthRefreshMiddleware.ts (100%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createCredentialsBarrier.test.ts (100%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createCredentialsBarrier.ts (99%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createLifecycleMiddleware.test.ts (96%) rename packages/backend-defaults/src/entrypoints/httpRouter/{ => http}/createLifecycleMiddleware.ts (99%) create mode 100644 packages/backend-defaults/src/entrypoints/httpRouter/http/index.ts diff --git a/packages/backend-defaults/report-httpRouter.api.md b/packages/backend-defaults/report-httpRouter.api.md index 97805bc926..b8587db287 100644 --- a/packages/backend-defaults/report-httpRouter.api.md +++ b/packages/backend-defaults/report-httpRouter.api.md @@ -3,9 +3,43 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; +import express from 'express'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; +import { HttpRouterServiceAuthPolicy } from '@backstage/backend-plugin-api'; +import { HumanDuration } from '@backstage/types'; +import { LifecycleService } from '@backstage/backend-plugin-api'; +import { RequestHandler } from 'express'; +import { RootConfigService } from '@backstage/backend-plugin-api'; +import { Router } from 'express'; import { ServiceFactory } from '@backstage/backend-plugin-api'; +// @public (undocumented) +export function createAuthIntegrationRouter(options: { + auth: AuthService; +}): express.Router; + +// @public +export function createCookieAuthRefreshMiddleware(options: { + auth: AuthService; + httpAuth: HttpAuthService; +}): Router; + +// @public (undocumented) +export function createCredentialsBarrier(options: { + httpAuth: HttpAuthService; + config: RootConfigService; +}): { + middleware: RequestHandler; + addAuthPolicy: (policy: HttpRouterServiceAuthPolicy) => void; +}; + +// @public +export function createLifecycleMiddleware( + options: LifecycleMiddlewareOptions, +): RequestHandler; + // @public export const httpRouterServiceFactory: ServiceFactory< HttpRouterService, @@ -13,5 +47,12 @@ export const httpRouterServiceFactory: ServiceFactory< 'singleton' >; +// @public +export interface LifecycleMiddlewareOptions { + // (undocumented) + lifecycle: LifecycleService; + startupRequestPauseTimeout?: HumanDuration; +} + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createAuthIntegrationRouter.ts similarity index 98% rename from packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createAuthIntegrationRouter.ts index ef36e7ba2d..3d36ef8e34 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createAuthIntegrationRouter.ts @@ -18,6 +18,9 @@ import { AuthService } from '@backstage/backend-plugin-api'; import express from 'express'; import Router from 'express-promise-router'; +/** + * @public + */ export function createAuthIntegrationRouter(options: { auth: AuthService; }): express.Router { diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createCookieAuthRefreshMiddleware.test.ts similarity index 100% rename from packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createCookieAuthRefreshMiddleware.test.ts diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createCookieAuthRefreshMiddleware.ts similarity index 100% rename from packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createCookieAuthRefreshMiddleware.ts diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createCredentialsBarrier.test.ts similarity index 100% rename from packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createCredentialsBarrier.test.ts diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createCredentialsBarrier.ts similarity index 99% rename from packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createCredentialsBarrier.ts index dd6c95ca82..f6332c6d28 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createCredentialsBarrier.ts @@ -36,6 +36,9 @@ export function createPathPolicyPredicate(policyPath: string) { }; } +/** + * @public + */ export function createCredentialsBarrier(options: { httpAuth: HttpAuthService; config: RootConfigService; diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.test.ts similarity index 96% rename from packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.test.ts index 31eecf14bb..3b85c8cb92 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.test.ts @@ -15,7 +15,7 @@ */ import { createLifecycleMiddleware } from './createLifecycleMiddleware'; -import { BackendLifecycleImpl } from '../rootLifecycle/rootLifecycleServiceFactory'; +import { BackendLifecycleImpl } from '../../rootLifecycle/rootLifecycleServiceFactory'; import { mockServices } from '@backstage/backend-test-utils'; import { ServiceUnavailableError } from '@backstage/errors'; diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.ts similarity index 99% rename from packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.ts index 18ff2f0840..3f8ee3ea69 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createLifecycleMiddleware.ts @@ -23,7 +23,7 @@ export const DEFAULT_TIMEOUT = { seconds: 5 }; /** * Options for {@link createLifecycleMiddleware}. - * @internal + * @public */ export interface LifecycleMiddlewareOptions { lifecycle: LifecycleService; @@ -47,7 +47,7 @@ export interface LifecycleMiddlewareOptions { * If the service is shutting down, all requests will be rejected with a * {@link @backstage/errors#ServiceUnavailableError}. * - * @internal + * @public */ export function createLifecycleMiddleware( options: LifecycleMiddlewareOptions, diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/http/index.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/index.ts new file mode 100644 index 0000000000..d31ea74fe8 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { createAuthIntegrationRouter } from './createAuthIntegrationRouter'; +export { createCredentialsBarrier } from './createCredentialsBarrier'; +export { createLifecycleMiddleware } from './createLifecycleMiddleware'; +export type { LifecycleMiddlewareOptions } from './createLifecycleMiddleware'; +export { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware'; diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts index fb2646580b..0557cb636d 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts @@ -21,10 +21,12 @@ import { createServiceFactory, HttpRouterServiceAuthPolicy, } from '@backstage/backend-plugin-api'; -import { createLifecycleMiddleware } from './createLifecycleMiddleware'; -import { createCredentialsBarrier } from './createCredentialsBarrier'; -import { createAuthIntegrationRouter } from './createAuthIntegrationRouter'; -import { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware'; +import { + createLifecycleMiddleware, + createCookieAuthRefreshMiddleware, + createCredentialsBarrier, + createAuthIntegrationRouter, +} from './http'; /** * HTTP route registration for plugins. diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts index 15bced5ef3..fc9752bdc1 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts @@ -15,3 +15,4 @@ */ export { httpRouterServiceFactory } from './httpRouterServiceFactory'; +export * from './http'; From 18a2c006f4f09294fd6069b1b9714cc53b8ad630 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 4 Nov 2024 10:07:06 -0500 Subject: [PATCH 2/6] add changeset Signed-off-by: aramissennyeydd --- .changeset/short-baboons-search.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/short-baboons-search.md diff --git a/.changeset/short-baboons-search.md b/.changeset/short-baboons-search.md new file mode 100644 index 0000000000..9855ad6df7 --- /dev/null +++ b/.changeset/short-baboons-search.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': minor +--- + +All middleware used by the default `coreServices.http` is now exported for use by custom implementations. From c0007a13131cfa80d7b1a1b872a42d1e060f57db Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 4 Nov 2024 10:21:17 -0500 Subject: [PATCH 3/6] fix api report Signed-off-by: aramissennyeydd --- packages/backend-defaults/report-rootHttpRouter.api.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index 3686f25a12..39ce7f12fa 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// /// import { Config } from '@backstage/config'; From dd985eba4f15672c7d26550aade9aa887a367b2d Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 4 Nov 2024 11:00:49 -0500 Subject: [PATCH 4/6] add usage docs Signed-off-by: aramissennyeydd --- .../core-services/http-router.md | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/backend-system/core-services/http-router.md b/docs/backend-system/core-services/http-router.md index 6ab8218c83..eab8ce8560 100644 --- a/docs/backend-system/core-services/http-router.md +++ b/docs/backend-system/core-services/http-router.md @@ -70,4 +70,67 @@ access the incoming credentials. ## Configuring the service -This service does not have any configuration options. +For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation: + +```ts +import { + createLifecycleMiddleware, + createCookieAuthRefreshMiddleware, + createCredentialsBarrier, + createAuthIntegrationRouter, +} from '@backstage/backend-defaults/httpRouter'; +import { createServiceFactory } from '@backstage/backend-plugin-api'; + +const backend = createBackend(); + +backend.add( + createServiceFactory({ + service: coreServices.httpRouter, + initialization: 'always', + deps: { + plugin: coreServices.pluginMetadata, + config: coreServices.rootConfig, + lifecycle: coreServices.lifecycle, + rootHttpRouter: coreServices.rootHttpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + }, + async factory({ + auth, + httpAuth, + config, + plugin, + rootHttpRouter, + lifecycle, + }) { + const router = PromiseRouter(); + + rootHttpRouter.use(`/api/${plugin.getId()}`, router); + + const credentialsBarrier = createCredentialsBarrier({ + httpAuth, + config, + }); + + router.use(createAuthIntegrationRouter({ auth })); + router.use(createLifecycleMiddleware({ lifecycle })); + router.use(credentialsBarrier.middleware); + router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth })); + + // Add a custom healthcheck endpoint for all plugins. + router.use('/health', (_, res) => { + res.status(200); + }); + + return { + use(handler: Handler): void { + router.use(handler); + }, + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { + credentialsBarrier.addAuthPolicy(policy); + }, + }; + }, + }), +); +``` From ce9ee222c6a80817011646c80c708b62084a8068 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 4 Nov 2024 11:03:32 -0500 Subject: [PATCH 5/6] fix api reports Signed-off-by: aramissennyeydd --- packages/backend-defaults/report-httpRouter.api.md | 2 ++ packages/backend-defaults/report-rootHttpRouter.api.md | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/backend-defaults/report-httpRouter.api.md b/packages/backend-defaults/report-httpRouter.api.md index b8587db287..4f6c6f06dc 100644 --- a/packages/backend-defaults/report-httpRouter.api.md +++ b/packages/backend-defaults/report-httpRouter.api.md @@ -3,6 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + import { AuthService } from '@backstage/backend-plugin-api'; import express from 'express'; import { HttpAuthService } from '@backstage/backend-plugin-api'; diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index 39ce7f12fa..3686f25a12 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// /// import { Config } from '@backstage/config'; From 5170ecc2485c4f198dfae5030f67b00f5ac93a8d Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Tue, 5 Nov 2024 09:38:38 -0500 Subject: [PATCH 6/6] add a bit more intro in the docs Signed-off-by: aramissennyeydd --- docs/backend-system/core-services/http-router.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/core-services/http-router.md b/docs/backend-system/core-services/http-router.md index eab8ce8560..c354f4fceb 100644 --- a/docs/backend-system/core-services/http-router.md +++ b/docs/backend-system/core-services/http-router.md @@ -70,7 +70,7 @@ access the incoming credentials. ## Configuring the service -For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation: +For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation, for example - here's how you would add a custom health check route to all plugins: ```ts import {