From 986fc6471c62da1214671d4bfc8037eeca37c18c Mon Sep 17 00:00:00 2001 From: Paul Fitzpatrick Date: Wed, 8 May 2024 15:33:16 -0400 Subject: [PATCH] some more robustness to APP_HOME_URL misconfiguration for boot page --- app/client/models/AppModel.ts | 47 +++++++++++++++++++++++++++++++++-- app/server/lib/BootProbes.ts | 1 - test/nbrowser/AdminPanel.ts | 11 ++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/app/client/models/AppModel.ts b/app/client/models/AppModel.ts index 82613e48..52afed69 100644 --- a/app/client/models/AppModel.ts +++ b/app/client/models/AppModel.ts @@ -527,10 +527,53 @@ export function getOrgNameOrGuest(org: Organization|null, user: FullUser|null) { return getOrgName(org); } -export function getHomeUrl(): string { +/** + * If we don't know what the home URL is, the top level of the site + * we are on may work. This should always work for single-server installs + * that don't encode organization information in domains. Even for other + * cases, this should be a good enough home URL for many purposes, it + * just may still have some organization information encoded in it from + * the domain that could influence results that might be supposed to be + * organization-neutral. + */ +export function getFallbackHomeUrl(): string { const {host, protocol} = window.location; + return `${protocol}//${host}`; +} + +/** + * Get the official home URL sent to us from the back end. + */ +export function getConfiguredHomeUrl(): string { const gristConfig: any = (window as any).gristConfig; - return (gristConfig && gristConfig.homeUrl) || `${protocol}//${host}`; + return (gristConfig && gristConfig.homeUrl) || getFallbackHomeUrl(); +} + +/** + * Get the home URL, using fallback if on admin or boot page rather + * than trusting back end configuration. + */ +export function getPreferredHomeUrl(): string|undefined { + const gristUrl = urlState().state.get(); + const url = new URL(window.location.href); + if (gristUrl.adminPanel || url.pathname.startsWith('/boot/')) { + // On the admin panel, we cannot trust configuration much. + // Access the API via relative URLs. This should be reliable for + // admin panel purposes. Couldn't we just always do this? Maybe! + // I think it could require adjustments for calls that are meant + // to be site-neutral if the domain has an org encoded in it? + // But that's doable... + // + // Likewise for boot page, we can't trust config. + // TODO: remove boot page, once admin page is accessible in some + // way with broken auth. + return getFallbackHomeUrl(); + } + return getConfiguredHomeUrl(); +} + +export function getHomeUrl(): string { + return getPreferredHomeUrl() || getConfiguredHomeUrl(); } export function newUserAPIImpl(): UserAPIImpl { diff --git a/app/server/lib/BootProbes.ts b/app/server/lib/BootProbes.ts index 242ab0d8..31a72766 100644 --- a/app/server/lib/BootProbes.ts +++ b/app/server/lib/BootProbes.ts @@ -171,7 +171,6 @@ const _bootProbe: Probe = { const details: Record = { bootKeySet: server.hasBoot(), }; - console.log(details); if (!server.hasBoot()) { return { success: true, details }; } diff --git a/test/nbrowser/AdminPanel.ts b/test/nbrowser/AdminPanel.ts index 762bd929..7cfcd78a 100644 --- a/test/nbrowser/AdminPanel.ts +++ b/test/nbrowser/AdminPanel.ts @@ -328,6 +328,17 @@ describe('AdminPanel', function() { }); assert.isNotEmpty(fakeServer.payload.installationId); }); + + it('should survive APP_HOME_URL misconfiguration', async function() { + // TODO: this works in theory, but admin page is in practice hard + // to access unless other pages work (e.g. to log in). So falling + // back on boot page for now. + process.env.APP_HOME_URL = 'http://misconfigured.invalid'; + process.env.GRIST_BOOT_KEY = 'zig'; + await server.restart(true); + await driver.get(`${server.getHost()}/boot/zig`); + await waitForAdminPanel(); + }); }); async function assertTelemetryLevel(level: TelemetryLevel) {