@@ -605,6 +605,23 @@ public async Task<List<UniFiDeviceResponse>> GetDevicesAsync(CancellationToken c
605605 {
606606 var response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/device" ) , cancellationToken ) ;
607607
608+ // Handle authentication failures (session expired)
609+ if ( response . StatusCode == HttpStatusCode . Unauthorized ||
610+ response . StatusCode == HttpStatusCode . Forbidden )
611+ {
612+ _logger . LogWarning ( "Got {StatusCode} fetching raw device JSON, re-authenticating..." , response . StatusCode ) ;
613+ _isAuthenticated = false ;
614+
615+ if ( ! await LoginAsync ( cancellationToken ) )
616+ {
617+ _logger . LogError ( "Re-authentication failed while fetching raw device JSON" ) ;
618+ return null ;
619+ }
620+
621+ // Retry with new authentication
622+ response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/device" ) , cancellationToken ) ;
623+ }
624+
608625 if ( response . IsSuccessStatusCode )
609626 {
610627 var json = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
@@ -934,6 +951,23 @@ public async Task<List<UniFiFirewallRule>> GetFirewallRulesAsync(CancellationTok
934951 try
935952 {
936953 var response = await _httpClient ! . GetAsync ( BuildApiPath ( "rest/firewallrule" ) , cancellationToken ) ;
954+
955+ // Handle authentication failures (session expired)
956+ if ( response . StatusCode == HttpStatusCode . Unauthorized ||
957+ response . StatusCode == HttpStatusCode . Forbidden )
958+ {
959+ _logger . LogWarning ( "Got {StatusCode} fetching legacy firewall rules, re-authenticating..." , response . StatusCode ) ;
960+ _isAuthenticated = false ;
961+
962+ if ( ! await LoginAsync ( cancellationToken ) )
963+ {
964+ _logger . LogError ( "Re-authentication failed while fetching legacy firewall rules" ) ;
965+ return null ;
966+ }
967+
968+ response = await _httpClient ! . GetAsync ( BuildApiPath ( "rest/firewallrule" ) , cancellationToken ) ;
969+ }
970+
937971 response . EnsureSuccessStatusCode ( ) ;
938972
939973 var json = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
@@ -1253,6 +1287,22 @@ public async Task<bool> UpdateNetworkConfigAsync(
12531287 {
12541288 var response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/health" ) , cancellationToken ) ;
12551289
1290+ // Handle authentication failures (session expired)
1291+ if ( response . StatusCode == HttpStatusCode . Unauthorized ||
1292+ response . StatusCode == HttpStatusCode . Forbidden )
1293+ {
1294+ _logger . LogWarning ( "Got {StatusCode} fetching site health, re-authenticating..." , response . StatusCode ) ;
1295+ _isAuthenticated = false ;
1296+
1297+ if ( ! await LoginAsync ( cancellationToken ) )
1298+ {
1299+ _logger . LogError ( "Re-authentication failed while fetching site health" ) ;
1300+ return null ;
1301+ }
1302+
1303+ response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/health" ) , cancellationToken ) ;
1304+ }
1305+
12561306 if ( response . IsSuccessStatusCode )
12571307 {
12581308 var json = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
@@ -1432,6 +1482,22 @@ public async Task<bool> UpdateTrafficRouteAsync(
14321482 {
14331483 var response = await _httpClient ! . GetAsync ( BuildApiPath ( "rest/setting" ) , cancellationToken ) ;
14341484
1485+ // Handle authentication failures (session expired)
1486+ if ( response . StatusCode == HttpStatusCode . Unauthorized ||
1487+ response . StatusCode == HttpStatusCode . Forbidden )
1488+ {
1489+ _logger . LogWarning ( "Got {StatusCode} fetching settings, re-authenticating..." , response . StatusCode ) ;
1490+ _isAuthenticated = false ;
1491+
1492+ if ( ! await LoginAsync ( cancellationToken ) )
1493+ {
1494+ _logger . LogError ( "Re-authentication failed while fetching settings" ) ;
1495+ return null ;
1496+ }
1497+
1498+ response = await _httpClient ! . GetAsync ( BuildApiPath ( "rest/setting" ) , cancellationToken ) ;
1499+ }
1500+
14351501 if ( response . IsSuccessStatusCode )
14361502 {
14371503 var json = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
@@ -1461,6 +1527,22 @@ public async Task<bool> UpdateTrafficRouteAsync(
14611527 {
14621528 var response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/current-channel" ) , cancellationToken ) ;
14631529
1530+ // Handle authentication failures (session expired)
1531+ if ( response . StatusCode == HttpStatusCode . Unauthorized ||
1532+ response . StatusCode == HttpStatusCode . Forbidden )
1533+ {
1534+ _logger . LogWarning ( "Got {StatusCode} fetching current channel data, re-authenticating..." , response . StatusCode ) ;
1535+ _isAuthenticated = false ;
1536+
1537+ if ( ! await LoginAsync ( cancellationToken ) )
1538+ {
1539+ _logger . LogError ( "Re-authentication failed while fetching current channel data" ) ;
1540+ return null ;
1541+ }
1542+
1543+ response = await _httpClient ! . GetAsync ( BuildApiPath ( "stat/current-channel" ) , cancellationToken ) ;
1544+ }
1545+
14641546 if ( response . IsSuccessStatusCode )
14651547 {
14661548 var json = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
0 commit comments