core-app-api: fix to support explicit ports in app baseUrl

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-01-30 13:51:25 +01:00
parent f4761a91df
commit dff4d8ddb1
3 changed files with 43 additions and 26 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-app-api': patch
---
Fixed an issue where an explicit port the frontend base URL could break the app.
@@ -634,6 +634,28 @@ describe('Integration Test', () => {
},
},
],
[
['http://localhost', 'http://localhost'],
{
backend: {
baseUrl: 'http://localhost:80',
},
app: {
baseUrl: 'http://localhost:80',
},
},
],
[
['http://localhost', 'http://localhost'],
{
backend: {
baseUrl: 'http://localhost',
},
app: {
baseUrl: 'http://localhost',
},
},
],
[
['http://localhost/backstage', 'http://localhost/backstage'],
{
@@ -674,7 +696,7 @@ describe('Integration Test', () => {
},
],
])(
'should be %p when %p',
'should be %p when %p (%#)',
async ([expectedAppUrl, expectedBackendUrl], data) => {
const app = new AppManager({
apis: [],
+15 -25
View File
@@ -82,6 +82,17 @@ type CompatiblePlugin =
output(): Array<{ type: 'feature-flag'; name: string }>;
});
/**
* Creates a base URL that uses to the current document origin.
*/
function createLocalBaseUrl(fullUrl: string): string {
const url = new URL(fullUrl);
url.protocol = document.location.protocol;
url.hostname = document.location.hostname;
url.port = document.location.port;
return url.toString().replace(/\/$/, '');
}
function useConfigLoader(
configLoader: AppConfigLoader | undefined,
components: AppComponents,
@@ -121,27 +132,6 @@ function useConfigLoader(
if (config.value?.length) {
const urlConfigReader = ConfigReader.fromConfigs(config.value);
/**
* Return the origin of the given URL.
* @param url An absolute URL.
* @returns The given URL's origin.
* @throws If fullUrl is not a correctly formatted absolute URL.
*/
const getOrigin = (url: string) => new URL(url).origin;
/**
* Resolve an absolute URL as relative to the current document.
* @param fullUrl URL to resolve.
* @returns Absolute URL with origin as the current document origin.
* @throws If fullUrl is not a correctly formatted absolute URL.
*/
const overrideOrigin = (fullUrl: string) => {
return new URL(
fullUrl.replace(getOrigin(fullUrl), ''),
document.location.origin,
).href.replace(/\/$/, '');
};
/**
* Test configs may not define `app.baseUrl` or `backend.baseUrl` and we
* don't want to enforce here.
@@ -155,18 +145,18 @@ function useConfigLoader(
context: 'relative-resolver',
};
if (appBaseUrl && backendBaseUrl) {
const appOrigin = getOrigin(appBaseUrl);
const backendOrigin = getOrigin(backendBaseUrl);
const appOrigin = new URL(appBaseUrl).origin;
const backendOrigin = new URL(backendBaseUrl).origin;
if (appOrigin === backendOrigin) {
const newBackendBaseUrl = overrideOrigin(backendBaseUrl);
const newBackendBaseUrl = createLocalBaseUrl(backendBaseUrl);
if (backendBaseUrl !== newBackendBaseUrl) {
relativeResolverConfig.data.backend = { baseUrl: newBackendBaseUrl };
}
}
}
if (appBaseUrl) {
const newAppBaseUrl = overrideOrigin(appBaseUrl);
const newAppBaseUrl = createLocalBaseUrl(appBaseUrl);
if (appBaseUrl !== newAppBaseUrl) {
relativeResolverConfig.data.app = { baseUrl: newAppBaseUrl };
}