fix: cross-subdomain SSO auto-login for *arr services

- Set Domain=.sami on session + CSRF cookies so browsers send them to all subdomains
- This fixes Caddy forward_auth returning 401 for radarr/sonarr/prowlarr
- Fix login URL concatenation bug (radarr.samilogin -> radarr.sami/login)
- Fix getSetCookie() missing from _httpsFetch/_httpFetch response objects
- Fix array/string handling for set-cookie header in session-handlers fallback
- Refactor csrf-protection to createCSRFMiddleware() factory with cookieDomain support
- Pass renewCSRFToken through middleware deps chain to TOTP route
This commit is contained in:
Coderbot
2026-05-23 16:15:56 -07:00
parent fe0f52ce17
commit 445da9f5fc
7 changed files with 101 additions and 55 deletions
@@ -121,7 +121,7 @@ module.exports = function({ authManager: _authManager, credentialManager: _crede
return null;
}
default:
loginUrl = `${baseUrl}login`;
loginUrl = `${baseUrl.replace(/\/+$/, '')}/login`;
loginBody = `username=${formEncode(username)}&password=${formEncode(password)}&rememberMe=on`;
extraHeaders['Authorization'] = `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;
break;
@@ -168,7 +168,9 @@ module.exports = function({ authManager: _authManager, credentialManager: _crede
const rawCookie = resp.headers.get('set-cookie');
if (rawCookie) {
const cookies = rawCookie.split(/,(?=[^ ])/).map(c => c.split(';')[0].trim()).join('; ');
// headers.get('set-cookie') may return an array (Node http) or string
const cookieStr = Array.isArray(rawCookie) ? rawCookie.join('; ') : rawCookie;
const cookies = cookieStr.split(/,(?=[^ ])/).map(c => c.split(';')[0].trim()).join('; ');
appSessionCache.set(serviceId, { cookies, exp: Date.now() + SESSION_TTL.COOKIE_SESSION });
log.info('auth', 'Auto-login successful (fallback), session cached', { serviceId });
return cookies;