fix(oidc): fail clearly when no public base URL is configured

CI exposed that getFrontendBaseUrl() returns '' without FRONTEND_URL or
the general_site_url setting (local runs were masked by backend/.env):
the flow then sent a RELATIVE redirect_uri to the IdP, which surfaced
as an opaque IdP-side error. getRedirectUri now throws OIDC_BAD_CONFIG
with an actionable message (login route maps it to sso_error=config);
the settings GET degrades to an empty redirect_uri instead of 500ing.
The test pins FRONTEND_URL explicitly so it runs identically with and
without a local .env.
This commit is contained in:
Paul Nothaft
2026-07-16 08:59:48 +02:00
parent ed5fc5ad5c
commit ac1838fbd7
3 changed files with 17 additions and 1 deletions
+5 -1
View File
@@ -390,6 +390,10 @@ router.get('/sso', adminAuth, requirePermission('settings.view'), async (req, re
try {
const oidcService = require('../services/oidcService');
const cfg = await oidcService.getOidcConfig();
// No public base URL configured → surface an empty redirect_uri rather
// than failing the whole settings read; the login route refuses to start
// the flow in that state anyway (OIDC_BAD_CONFIG).
const redirectUri = await oidcService.getRedirectUri().catch(() => '');
res.json({
oidc_enabled: cfg.enabled,
oidc_issuer_url: cfg.issuerUrl || '',
@@ -399,7 +403,7 @@ router.get('/sso', adminAuth, requirePermission('settings.view'), async (req, re
oidc_default_role: cfg.defaultRole,
oidc_button_label: cfg.buttonLabel || '',
oidc_scopes: cfg.scopes,
redirect_uri: await oidcService.getRedirectUri(),
redirect_uri: redirectUri,
});
} catch (error) {
logger.error('Failed to read SSO settings', { error: error.message });
+8
View File
@@ -153,6 +153,14 @@ async function getClient(cfg) {
async function getRedirectUri() {
const { getFrontendBaseUrl } = require('../utils/frontendUrl');
const base = (await getFrontendBaseUrl()).replace(/\/$/, '');
if (!base) {
// Without a public base URL the redirect_uri would be relative — the IdP
// would reject it with an opaque error on ITS side. Fail here with a
// clear config message instead.
const err = new Error('FRONTEND_URL (or the general_site_url setting) must be set for SSO');
err.code = 'OIDC_BAD_CONFIG';
throw err;
}
return `${base}/api/auth/admin/sso/callback`;
}