diff --git a/CHANGELOG.md b/CHANGELOG.md index f78e789..4ee0fbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Changes 10/5/2025 v1.3.14 + +fix(admin): OIDC optional by default; validate only when enabled (fixes #44) + +- AdminModel::updateConfig now enforces OIDC fields only if disableOIDCLogin=false +- AdminModel::getConfig defaults disableOIDCLogin=true and guarantees OIDC keys +- AdminController default loginOptions sets disableOIDCLogin=true; CSRF via header or body +- Normalize file perms to 0664 after write + ## Changes 10/4/2025 v1.3.13 fix(scanner): resolve dirs via CLI/env/constants; write per-item JSON; skip trash diff --git a/src/controllers/AdminController.php b/src/controllers/AdminController.php index 997b1d3..855ad1d 100644 --- a/src/controllers/AdminController.php +++ b/src/controllers/AdminController.php @@ -150,7 +150,7 @@ class AdminController exit; } $headersArr = array_change_key_case(getallheaders(), CASE_LOWER); - $receivedToken = trim($headersArr['x-csrf-token'] ?? ''); + $receivedToken = trim($headersArr['x-csrf-token'] ?? ($_POST['csrfToken'] ?? '')); if (!isset($_SESSION['csrf_token']) || $receivedToken !== $_SESSION['csrf_token']) { http_response_code(403); echo json_encode(['error' => 'Invalid CSRF token.']); @@ -180,7 +180,7 @@ class AdminController $merged['loginOptions'] = $existing['loginOptions'] ?? [ 'disableFormLogin' => false, 'disableBasicAuth' => false, - 'disableOIDCLogin'=> false, + 'disableOIDCLogin'=> true, 'authBypass' => false, 'authHeaderName' => 'X-Remote-User' ]; diff --git a/src/models/AdminModel.php b/src/models/AdminModel.php index a8eec7b..509052e 100644 --- a/src/models/AdminModel.php +++ b/src/models/AdminModel.php @@ -35,14 +35,19 @@ class AdminModel */ public static function updateConfig(array $configUpdate): array { - // Validate required OIDC configuration keys. - if ( - empty($configUpdate['oidc']['providerUrl']) || - empty($configUpdate['oidc']['clientId']) || - empty($configUpdate['oidc']['clientSecret']) || - empty($configUpdate['oidc']['redirectUri']) - ) { - return ["error" => "Incomplete OIDC configuration."]; + // New: only enforce OIDC fields when OIDC is enabled + $oidcDisabled = isset($configUpdate['loginOptions']['disableOIDCLogin']) + ? (bool)$configUpdate['loginOptions']['disableOIDCLogin'] + : true; // default to disabled when not present + + if (!$oidcDisabled) { + $oidc = $configUpdate['oidc'] ?? []; + $required = ['providerUrl','clientId','clientSecret','redirectUri']; + foreach ($required as $k) { + if (empty($oidc[$k]) || !is_string($oidc[$k])) { + return ["error" => "Incomplete OIDC configuration (enable OIDC requires providerUrl, clientId, clientSecret, redirectUri)."]; + } + } } // Ensure enableWebDAV flag is boolean (default to false if missing) @@ -111,6 +116,8 @@ class AdminModel return ["error" => "Failed to update configuration even after cleanup."]; } } + // Best-effort normalize perms for host visibility (user rw, group rw) + @chmod($configFile, 0664); return ["success" => "Configuration updated successfully."]; } @@ -137,17 +144,34 @@ class AdminModel // Normalize login options if missing if (!isset($config['loginOptions'])) { + // migrate legacy top-level flags; default OIDC to true (disabled) $config['loginOptions'] = [ 'disableFormLogin' => isset($config['disableFormLogin']) ? (bool)$config['disableFormLogin'] : false, 'disableBasicAuth' => isset($config['disableBasicAuth']) ? (bool)$config['disableBasicAuth'] : false, - 'disableOIDCLogin' => isset($config['disableOIDCLogin']) ? (bool)$config['disableOIDCLogin'] : false, + 'disableOIDCLogin' => isset($config['disableOIDCLogin']) ? (bool)$config['disableOIDCLogin'] : true, ]; unset($config['disableFormLogin'], $config['disableBasicAuth'], $config['disableOIDCLogin']); } else { - // Ensure proper boolean types - $config['loginOptions']['disableFormLogin'] = (bool)$config['loginOptions']['disableFormLogin']; - $config['loginOptions']['disableBasicAuth'] = (bool)$config['loginOptions']['disableBasicAuth']; - $config['loginOptions']['disableOIDCLogin'] = (bool)$config['loginOptions']['disableOIDCLogin']; + // normalize booleans; default OIDC to true (disabled) if missing + $lo = &$config['loginOptions']; + $lo['disableFormLogin'] = isset($lo['disableFormLogin']) ? (bool)$lo['disableFormLogin'] : false; + $lo['disableBasicAuth'] = isset($lo['disableBasicAuth']) ? (bool)$lo['disableBasicAuth'] : false; + $lo['disableOIDCLogin'] = isset($lo['disableOIDCLogin']) ? (bool)$lo['disableOIDCLogin'] : true; + } + + if (!isset($config['oidc']) || !is_array($config['oidc'])) { + $config['oidc'] = [ + 'providerUrl' => '', + 'clientId' => '', + 'clientSecret' => '', + 'redirectUri' => '', + ]; + } else { + foreach (['providerUrl','clientId','clientSecret','redirectUri'] as $k) { + if (!isset($config['oidc'][$k]) || !is_string($config['oidc'][$k])) { + $config['oidc'][$k] = ''; + } + } } if (!array_key_exists('authBypass', $config['loginOptions'])) { @@ -193,7 +217,7 @@ class AdminModel 'loginOptions' => [ 'disableFormLogin' => false, 'disableBasicAuth' => false, - 'disableOIDCLogin' => false + 'disableOIDCLogin' => true ], 'globalOtpauthUrl' => "", 'enableWebDAV' => false,