From 92620013232017a902c11f889a775241fe57f6c1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 11 Mar 2025 14:11:03 +0100 Subject: [PATCH] core-app-api: make fetch auth middleware of discovery config Signed-off-by: Patrik Oldsberg --- .changeset/early-buses-lick.md | 5 +++ ...dentityAuthInjectorFetchMiddleware.test.ts | 45 +++++++++++++++++++ .../IdentityAuthInjectorFetchMiddleware.ts | 26 ++++++++++- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .changeset/early-buses-lick.md diff --git a/.changeset/early-buses-lick.md b/.changeset/early-buses-lick.md new file mode 100644 index 0000000000..6b3650d3b4 --- /dev/null +++ b/.changeset/early-buses-lick.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': minor +--- + +The default auth injection middleware for the `FetchApi` will now also take configuration under `discovery.endpoints` into consideration when deciding whether to include credentials or not. diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts index 50f93444ed..7d18325540 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts @@ -115,4 +115,49 @@ describe('IdentityAuthInjectorFetchMiddleware', () => { ['authorization', 'do-not-clobber'], ]); }); + + describe('.getDiscoveryUrlPrefixes', () => { + it('works with no endpoints', () => { + const config = new ConfigReader({ + backend: { baseUrl: 'https://a.com' }, + }); + expect( + IdentityAuthInjectorFetchMiddleware.getDiscoveryUrlPrefixes(config), + ).toEqual([]); + }); + + it('works with endpoints', () => { + const config = new ConfigReader({ + backend: { baseUrl: 'https://a.com' }, + discovery: { + endpoints: [ + { target: 'https://b.com', plugins: ['p1'] }, + { target: 'https://c.com/{{pluginId}}', plugins: ['p2', 'p3'] }, + { target: { external: 'https://d.com' }, plugins: ['q1'] }, + { + target: { external: 'https://e.com/{{pluginId}}' }, + plugins: ['q2', 'q3'], + }, + { + target: { + external: 'https://{{ pluginId }}.e.com/{{pluginId}}', + }, + plugins: ['q4'], + }, + ], + }, + }); + expect( + IdentityAuthInjectorFetchMiddleware.getDiscoveryUrlPrefixes(config), + ).toEqual([ + 'https://b.com', + 'https://c.com/p2', + 'https://c.com/p3', + 'https://d.com', + 'https://e.com/q2', + 'https://e.com/q3', + 'https://q4.e.com/q4', + ]); + }); + }); }); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts index 6f9733cba1..842f9191eb 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts @@ -45,6 +45,25 @@ export class IdentityAuthInjectorFetchMiddleware implements FetchMiddleware { ); } + /** + * Returns an array of plugin URL prefixes derived from the static `discovery` + * configuration, to be used as `urlPrefixAllowlist` option of {@link create}. + */ + static getDiscoveryUrlPrefixes(config: Config): string[] { + const endpointConfigs = + config.getOptionalConfigArray('discovery.endpoints') || []; + return endpointConfigs.flatMap(c => { + const target = + typeof c.get('target') === 'object' + ? c.getString('target.external') + : c.getString('target'); + const plugins = c.getStringArray('plugins'); + return plugins.map(pluginId => + target.replace(/\{\{\s*pluginId\s*\}\}/g, pluginId), + ); + }); + } + constructor( public readonly identityApi: IdentityApi, public readonly allowUrl: (url: string) => boolean, @@ -87,7 +106,12 @@ function buildMatcher(options: { } else if (options.urlPrefixAllowlist) { return buildPrefixMatcher(options.urlPrefixAllowlist); } else if (options.config) { - return buildPrefixMatcher([options.config.getString('backend.baseUrl')]); + return buildPrefixMatcher([ + options.config.getString('backend.baseUrl'), + ...IdentityAuthInjectorFetchMiddleware.getDiscoveryUrlPrefixes( + options.config, + ), + ]); } return () => false; }