@@ -6,6 +6,13 @@ let uiServiceProxy;
66
77const UI_SERVICE_COOKIE = 'dumb_ui_service' ;
88const ARR_API_SERVICES = new Set ( [ 'radarr' , 'sonarr' , 'lidarr' , 'whisparr' , 'prowlarr' ] ) ;
9+ const ARR_CLIENT_HEADERS = new Set ( [
10+ 'x-prowlarr-client' ,
11+ 'x-sonarr-client' ,
12+ 'x-radarr-client' ,
13+ 'x-lidarr-client' ,
14+ 'x-whisparr-client' ,
15+ ] ) ;
916const WEB_UI_SERVICES = new Set ( [ 'emby' , 'jellyfin' ] ) ;
1017const SEERR_SERVICES = new Set ( [ 'seerr' , 'jellyseerr' , 'overseerr' ] ) ;
1118const REACT_SPA_SERVICES = new Set ( [ ] ) ;
@@ -55,6 +62,12 @@ const getServiceType = (serviceName) => {
5562 if ( ARR_API_SERVICES . has ( normalized ) || WEB_UI_SERVICES . has ( normalized ) || SEERR_SERVICES . has ( normalized ) ) {
5663 return normalized ;
5764 }
65+ // Fallback: handle names like "prowlarr_indexer" or "sonarr_main"
66+ for ( const arrService of ARR_API_SERVICES ) {
67+ if ( normalized && normalized . includes ( arrService ) ) {
68+ return arrService ;
69+ }
70+ }
5871 return null ;
5972} ;
6073
@@ -343,16 +356,6 @@ export default defineEventHandler(async (event) => {
343356 reqUrl . startsWith ( '/_nuxt/' ) ||
344357 ( isHtmlRequest && ! reqUrl . startsWith ( '/ui/' ) && ! reqUrl . startsWith ( '/service/ui/' ) ) ;
345358
346- // If in main app context, clear the cookie immediately
347- if ( isMainAppContext ) {
348- const earlyCookieService = getCookieService ( event . node . req ) ;
349- if ( earlyCookieService ) {
350- const clearCookie = `${ UI_SERVICE_COOKIE } =; Path=/; Max-Age=0; SameSite=Lax` ;
351- event . node . res . setHeader ( 'Set-Cookie' , clearCookie ) ;
352- console . log ( '[Main App Context] Clearing UI cookie:' , reqUrl , 'Referer:' , referer ) ;
353- }
354- }
355-
356359 // Normalize /ui/{service} URLs early - decode and sanitize service names
357360 const uiPathMatch = reqUrl . match ( / ^ \/ u i \/ ( [ ^ / ? ] + ) ( .* ) / ) ;
358361 if ( uiPathMatch ) {
@@ -407,6 +410,10 @@ export default defineEventHandler(async (event) => {
407410 const uiRefererService = getUiServiceFromReferer ( event . node . req ) ;
408411 const pageRefererService = getPageServiceFromReferer ( event . node . req ) ;
409412 const cookieService = getCookieService ( event . node . req ) ;
413+ const reqHeaders = event . node . req . headers || { } ;
414+ const hasArrClientHeader = Object . keys ( reqHeaders ) . some ( ( key ) => ARR_CLIENT_HEADERS . has ( key ) ) ;
415+ const hasArrApiKeyHeader = Boolean ( reqHeaders [ 'x-api-key' ] ) ;
416+ const hasArrApiHeaders = hasArrClientHeader || hasArrApiKeyHeader ;
410417
411418 // Get cached service for this session (helps with timing issue where cookie hasn't updated yet)
412419 const cachedService = sessionId ? sessionServiceCache . get ( sessionId ) : null ;
@@ -512,9 +519,10 @@ export default defineEventHandler(async (event) => {
512519 } else {
513520 const apiService =
514521 uiRefererService ||
515- ( ! isNavigation && arrApiPath && apiRoutingService && apiRoutingServiceType && ARR_API_SERVICES . has ( apiRoutingServiceType )
516- ? apiRoutingService
517- : null ) ;
522+ ( ! isNavigation && arrApiPath && apiRoutingService &&
523+ ( ( apiRoutingServiceType && ARR_API_SERVICES . has ( apiRoutingServiceType ) ) || hasArrApiHeaders )
524+ ? apiRoutingService
525+ : null ) ;
518526 if ( apiService ) {
519527 const target = `/ui/${ apiService } ${ reqUrl } ` ;
520528 event . node . req . url = target ;
0 commit comments