sc-idp/lib/oidc/discovery.js
2026-06-01 16:40:54 -05:00

43 lines
1.7 KiB
JavaScript

// OIDC discovery document + issuer derivation.
//
// The issuer MUST exactly equal the URL prefix a relying party used to fetch
// /.well-known/openid-configuration. We prefer the tenant's configured base_url
// (the trustworthy source); otherwise we fall back to the request scheme+host.
//
// SECURITY: the request-host fallback is vulnerable to Host-header injection
// (an attacker forging Host could poison the advertised issuer/endpoints).
// base_url should be set in any multi-tenant or proxied deployment; the
// fallback exists for single-tenant localhost/dev. This is revisited in the
// multi-tenancy phase (validate host against the tenant's known domains).
const constants = require("../constants");
const issuerForReq = (req) => {
let base = "";
try {
const { getState } = require("@saltcorn/data/db/state");
const configured = getState().getConfig("base_url", "");
if (configured) {
base = configured;
}
} catch (e) {
// getState unavailable; fall back to request-derived host
}
if (!base) {
base = req.protocol + "://" + req.get("host");
// eslint-disable-next-line no-console
console.warn(`[${constants.PLUGIN_NAME}] base_url not set; deriving issuer from request Host (${base}). Set base_url to prevent Host-header issuer poisoning.`);
}
base = base.replace(/\/+$/, "");
return base + constants.IDP_BASE_PATH;
};
// NOTE: the discovery document and JWKS are now generated and served by
// oidc-provider itself (see oidc/provider.js + oidc/routes.js); we only keep the
// issuer derivation here, which feeds the Provider's issuer.
module.exports = {
issuerForReq
};