fix(auth): resolve CSP blocking and session refresh loop

Fix two issues causing login loop after successful admin setup:

1. CSP blocking inline styles: The frontend JavaScript dynamically sets
   inline styles (e.g., element.style.display = 'none') for UI state
   management. The CSP header only allowed 'self' for style-src, blocking
   these dynamic styles. Added 'unsafe-inline' to style-src directive.

2. Session refresh 401 errors: The cookie Secure flag defaulted to true
   when OXICLOUD_BASE_URL was not set, causing cookies to not be sent
   over HTTP in Docker deployments. Changed the default to false when
   the base URL is not explicitly set to HTTPS, with clear logging to
   guide users to set OXICLOUD_COOKIE_SECURE=true for production.

Fixes #203
This commit is contained in:
BillionClaw
2026-03-17 06:14:02 +08:00
parent c669c24036
commit 2daee68d20
2 changed files with 28 additions and 16 deletions
+22 -13
View File
@@ -30,8 +30,10 @@ pub const CSRF_HEADER: &str = "x-csrf-token";
/// Resolution order:
/// 1. `OXICLOUD_COOKIE_SECURE=true|false` — explicit override.
/// 2. `OXICLOUD_BASE_URL` starts with `https` → `true`.
/// 3. **Default: `true`** (safe-by-default). Set `OXICLOUD_COOKIE_SECURE=false`
/// explicitly for plain-HTTP development environments.
/// 3. `OXICLOUD_BASE_URL` starts with `http` → `false`.
/// 4. **Default: `false`** for compatibility with HTTP deployments
/// (Docker, local development). Set `OXICLOUD_COOKIE_SECURE=true`
/// explicitly for production HTTPS environments.
fn cookie_secure() -> bool {
if let Ok(v) = std::env::var("OXICLOUD_COOKIE_SECURE") {
let secure = v == "true" || v == "1";
@@ -44,18 +46,25 @@ fn cookie_secure() -> bool {
}
return secure;
}
// Auto-detect from base URL, defaulting to secure when unset
let secure = std::env::var("OXICLOUD_BASE_URL")
.map(|u| u.starts_with("https"))
.unwrap_or(true);
if !secure {
tracing::warn!(
"OXICLOUD_BASE_URL does not start with https — \
cookie Secure flag is OFF. Set OXICLOUD_COOKIE_SECURE=true \
to override if your proxy terminates TLS."
);
// Auto-detect from base URL, defaulting to insecure for compatibility
match std::env::var("OXICLOUD_BASE_URL") {
Ok(url) if url.starts_with("https") => true,
Ok(url) if url.starts_with("http://") => {
tracing::info!(
"OXICLOUD_BASE_URL is HTTP — cookie Secure flag is OFF. \
Set OXICLOUD_COOKIE_SECURE=true to override if your proxy terminates TLS."
);
false
}
_ => {
// Default to false for compatibility with HTTP deployments
tracing::info!(
"OXICLOUD_BASE_URL not set — defaulting to non-secure cookies \
for HTTP compatibility. Set OXICLOUD_COOKIE_SECURE=true for HTTPS deployments."
);
false
}
}
secure
}
/// Build a `Set-Cookie` header value.