feat(auth): add WorkOS and Keycloak SSO providers (rebased) #220

Merged
jason.woltje merged 2 commits from fix/p8-001-sso-rebase into main 2026-03-21 12:57:08 +00:00
Showing only changes of commit 8b261710dd - Show all commits

View File

@@ -62,6 +62,13 @@ function buildAuthentikConfig(env: EnvMap): GenericOidcProviderConfig | null {
const clientId = readEnv(env, 'AUTHENTIK_CLIENT_ID');
const clientSecret = readEnv(env, 'AUTHENTIK_CLIENT_SECRET');
const fields = [issuer, clientId, clientSecret];
const presentCount = fields.filter(Boolean).length;
if (presentCount > 0 && presentCount < fields.length) {
throw new Error(
'@mosaic/auth: Authentik SSO requires AUTHENTIK_ISSUER, AUTHENTIK_CLIENT_ID, AUTHENTIK_CLIENT_SECRET.',
);
}
if (!issuer || !clientId || !clientSecret) {
return null;
}
@@ -86,6 +93,13 @@ function buildWorkosConfig(env: EnvMap): GenericOidcProviderConfig | null {
const clientId = readEnv(env, 'WORKOS_CLIENT_ID');
const clientSecret = readEnv(env, 'WORKOS_CLIENT_SECRET');
const fields = [issuer, clientId, clientSecret];
const presentCount = fields.filter(Boolean).length;
if (presentCount > 0 && presentCount < fields.length) {
throw new Error(
'@mosaic/auth: WorkOS SSO requires WORKOS_ISSUER, WORKOS_CLIENT_ID, WORKOS_CLIENT_SECRET.',
);
}
if (!issuer || !clientId || !clientSecret) {
return null;
}
@@ -105,10 +119,25 @@ function buildWorkosConfig(env: EnvMap): GenericOidcProviderConfig | null {
}
function buildKeycloakConfig(env: EnvMap): GenericOidcProviderConfig | null {
const issuer = readEnv(env, 'KEYCLOAK_ISSUER');
const explicitIssuer = readEnv(env, 'KEYCLOAK_ISSUER');
const keycloakUrl = readEnv(env, 'KEYCLOAK_URL');
const keycloakRealm = readEnv(env, 'KEYCLOAK_REALM');
const clientId = readEnv(env, 'KEYCLOAK_CLIENT_ID');
const clientSecret = readEnv(env, 'KEYCLOAK_CLIENT_SECRET');
// Derive issuer from KEYCLOAK_URL + KEYCLOAK_REALM if KEYCLOAK_ISSUER not set
const issuer =
explicitIssuer ??
(keycloakUrl && keycloakRealm
? `${keycloakUrl.replace(/\/$/, '')}/realms/${keycloakRealm}`
: undefined);
const anySet = !!(issuer || clientId || clientSecret);
if (anySet && (!issuer || !clientId || !clientSecret)) {
throw new Error(
'@mosaic/auth: Keycloak SSO requires KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET, KEYCLOAK_ISSUER.',
);
}
if (!issuer || !clientId || !clientSecret) {
return null;
}