Skip to content

fix(web): handle SSO session expiry behind Cloudflare Access and other proxies - #1438

Merged
s0up4200 merged 8 commits into
autobrr:developfrom
nitrobass24:fix/1105-firefox-sso-detection
Feb 19, 2026
Merged

fix(web): handle SSO session expiry behind Cloudflare Access and other proxies#1438
s0up4200 merged 8 commits into
autobrr:developfrom
nitrobass24:fix/1105-firefox-sso-detection

Conversation

@nitrobass24

@nitrobass24 nitrobass24 commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Builds on #1380

Summary

Testing PR #1380 behind a Cloudflare Access tunnel (qui2.nitrobass24.com) confirmed the Firefox network error detection works, but revealed additional issues specifically when Cloudflare Access returns 401 responses with Content-Type: text/html instead of blocking at the network level. This required several incremental fixes:

1. HTML response recovery for login requests

Extended ssoSafeFetch to also trigger SSO recovery on HTML responses (not just network errors), with bypassGuard for /api/auth/login so the first login attempt always triggers recovery instead of being blocked by a stale guard.

2. Timestamp-based guard cooldown

The sessionStorage recovery guard persisted across page loads, blocking recovery after SSO re-authentication completed. Added a 10-second timestamp cooldown that auto-clears the guard on fresh page loads while still preventing rapid navigation loops.

3. Service worker cache clearing

The PWA service worker serves the cached SPA shell for navigation requests, bypassing the SSO proxy entirely. Before recovery navigation, all SW caches are now cleared so the request falls through to the network. (Unregistering the SW entirely was tried but broke Cloudflare Access's auth flow.)

4. Service worker navigateFallbackDenylist

The root cause of the final issue: Cloudflare Access redirects to /cdn-cgi/access/authorized?nonce=... after authentication, but the SW intercepted this path and failed with FetchEvent.respondWith received an error: TypeError: Load failed. Added /cdn-cgi/ and /.well-known/ to the denylist so SSO callback paths bypass the service worker.

5. SSO recovery toast

With stacked auth (SSO + app login), the first login attempt is consumed by SSO re-authentication. A toast ("SSO session refreshed. Please sign in again.") now appears on the login page after recovery so users understand why they need to enter credentials again.

Test plan

  • Tested end-to-end behind Cloudflare Access tunnel with expired sessions in Safari
  • Verify behavior with Pangolin SSO proxy
  • Verify no regression for non-SSO deployments

Summary by CodeRabbit

  • Documentation

    • Added guidance on SSO proxy and CORS configuration for API requests
    • Added OIDC configuration recommendations for SSO proxy environments
  • Bug Fixes

    • Enhanced authentication error detection and recovery mechanisms
    • Improved handling of network and CORS failures during login flows
  • New Features

    • Added user notification when SSO session recovery completes

s0up4200 and others added 8 commits February 1, 2026 21:42
When behind SSO proxies like Cloudflare Access, expired sessions cause
API calls to return HTML instead of JSON. This extends the existing
network error recovery to also handle HTML responses on API endpoints,
with bypass guard for login requests so recovery always triggers.

Adds /cdn-cgi/ and /.well-known/ to the service worker's
navigateFallbackDenylist so Cloudflare Access auth callbacks are not
intercepted by the SW. Clears SW caches before recovery navigation to
ensure the SSO proxy can intercept the request.

Shows an info toast after SSO recovery so users understand why they
need to sign in again.
@coderabbitai

coderabbitai Bot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds documentation on SSO proxy and CORS behavior, implements robust SSO error detection and recovery mechanisms with session guards and cooldown timing, displays a recovery notification in the Login page, and expands the PWA service worker configuration to exclude SSO/well-known paths from fallback routing.

Changes

Cohort / File(s) Summary
Documentation
documentation/docs/advanced/sso-proxy-cors.md, documentation/docs/configuration/oidc.md
New SSO proxy and CORS guidance page added; OIDC configuration updated to reference SSO proxy documentation and proxy-side CORS configuration.
SSO Recovery Logic
web/src/lib/api.ts
Added SSO recovery guards (SSO_RECOVERY_GUARD_KEY, SSO_RECOVERY_TS_KEY, SSO_RECOVERY_COOLDOWN_MS) with cooldown timing; expanded error detection for network and HTML-response errors; introduced asynchronous attemptSSORecoveryNavigation with cache clearing; updated ssoSafeFetch to detect login requests and trigger recovery navigation on network/HTML errors.
Login UI
web/src/pages/Login.tsx
Added React effect to detect SSO recovery marker in sessionStorage and display informational toast message on mount.
PWA Configuration
web/vite.config.ts
Expanded navigateFallbackDenylist in Vite PWA Workbox config to include /cdn-cgi and /.well-known paths alongside existing /api and /proxy exclusions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

auth, bugfix

Poem

🐰 When SSO proxy guards its gate,
Our fetch attempts to navigate—
With guards and cooldown, clear the way,
A toast appears: "Try once more, okay!" 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective of the changeset: handling SSO session expiry behind proxies like Cloudflare Access, which is the central theme across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
web/src/lib/api.ts (4)

193-201: "cors" and "request failed" substring matches are overly broad.

Line 198: normalized.includes("cors") would match any error message containing the substring "cors" (e.g., hypothetical messages about "discourse" or other unrelated terms). Line 201: "request failed" is similarly generic and could match many non-SSO errors.

Since the guard prevents infinite loops, the blast radius is limited to a single unnecessary recovery navigation. Still, tightening these checks would reduce false positives.

Suggested tightening
-  return normalized.includes("networkerror") ||
-    normalized.includes("network error") ||
-    normalized.includes("failed to fetch") ||
-    normalized.includes("cors request did not succeed") ||
-    normalized.includes("cors") ||
-    normalized.includes("load failed") ||
-    normalized.includes("network request failed") ||
-    normalized.includes("request failed")
+  return normalized.includes("networkerror") ||
+    normalized.includes("network error") ||
+    normalized.includes("failed to fetch") ||
+    normalized.includes("cors request did not succeed") ||
+    normalized.includes("cors error") ||
+    normalized.includes("load failed") ||
+    normalized.includes("network request failed")

224-290: Consider using the Content-Type header alone rather than reading the body stream for ambiguous responses.

The body-sniffing heuristic (reading up to 1KB) is clever, but it adds complexity and latency for edge cases where Content-Type is missing. In practice, SSO proxies that return HTML almost always set text/html in the content type. The existing isSSOHTMLResponse check at Line 225 handles that path.

The body-reading fallback (Lines 247–289) mainly catches responses with no Content-Type header at all. If you want to keep it, the implementation looks correct — the clone() + stream reader + finally cleanup is well-structured.


346-384: Never-resolving promise on navigation is intentional but worth a brief inline comment.

Lines 363 and 373 return new Promise<Response>(() => {}) to suspend the caller while the page navigates. This is a known pattern, but a terse comment would help future readers understand why the promise intentionally never resolves.

Suggested comment
      if (await attemptSSORecoveryNavigation({ bypassGuard: isLoginRequest })) {
+        // Page is navigating away; return a pending promise to halt further processing.
        return new Promise<Response>(() => {})
      }

182-182: Minor formatting nit: missing spaces before ? in ternary expressions.

Line 182 and Line 187 have tightly packed ternaries (e.g., "name" in error? String(...) and error instanceof Error? error.message: typeof error === "string"? error: ""). These are syntactically valid but hard to scan.

Suggested formatting
-  const maybeName = typeof error === "object" && error !== null && "name" in error? String((error as { name?: unknown }).name): ""
+  const maybeName = typeof error === "object" && error !== null && "name" in error ? String((error as { name?: unknown }).name) : ""
...
-  const msg = error instanceof Error? error.message: typeof error === "string"? error: ""
+  const msg = error instanceof Error ? error.message : typeof error === "string" ? error : ""

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@s0up4200
s0up4200 merged commit 25039bc into autobrr:develop Feb 19, 2026
1 check passed
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Feb 22, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.13.1` → `v1.14.0` |

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.14.0`](https://github.com/autobrr/qui/releases/tag/v1.14.0)

[Compare Source](autobrr/qui@v1.13.1...v1.14.0)

#### Changelog

##### New Features

- [`6f8e6ed`](autobrr/qui@6f8e6ed): feat(api): add torrent field endpoint for select all copy ([#&#8203;1477](autobrr/qui#1477)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`2d9b4c7`](autobrr/qui@2d9b4c7): feat(automation): trigger external programs automatically via automation rules ([#&#8203;1284](autobrr/qui#1284)) ([@&#8203;0rkag](https://github.com/0rkag))
- [`32692a4`](autobrr/qui@32692a4): feat(automations): Add the ability to define the move automation with a templated path ([#&#8203;1376](autobrr/qui#1376)) ([@&#8203;ColinHebert](https://github.com/ColinHebert))
- [`61bbeb1`](autobrr/qui@61bbeb1): feat(automations): add Resume action to Automations ([#&#8203;1350](autobrr/qui#1350)) ([@&#8203;cy1der](https://github.com/cy1der))
- [`450b98f`](autobrr/qui@450b98f): feat(automations): grouping + release fields ([#&#8203;1467](autobrr/qui#1467)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`18d4a64`](autobrr/qui@18d4a64): feat(automations): match tracker conditions by display name ([#&#8203;1420](autobrr/qui#1420)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7c67b82`](autobrr/qui@7c67b82): feat(automations): show activity run details ([#&#8203;1385](autobrr/qui#1385)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`177ef4d`](autobrr/qui@177ef4d): feat(crossseed): Multiple hard/reflink dirs ([#&#8203;1289](autobrr/qui#1289)) ([@&#8203;rybertm](https://github.com/rybertm))
- [`a72b673`](autobrr/qui@a72b673): feat(crossseed): gazelle-only OPS/RED ([#&#8203;1436](autobrr/qui#1436)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6a29384`](autobrr/qui@6a29384): feat(crossseed): match bit depth ([#&#8203;1427](autobrr/qui#1427)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c7fd5aa`](autobrr/qui@c7fd5aa): feat(dirscan): add max searchee age filter ([#&#8203;1486](autobrr/qui#1486)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d595a55`](autobrr/qui@d595a55): feat(documentation): add AI doc actions and llms discoverability ([#&#8203;1451](autobrr/qui#1451)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`562ab3f`](autobrr/qui@562ab3f): feat(metrics): add tracker metrics ([#&#8203;1073](autobrr/qui#1073)) ([@&#8203;Winter](https://github.com/Winter))
- [`1b9aa9d`](autobrr/qui@1b9aa9d): feat(notifications): add shoutrrr and notifiarr ([#&#8203;1371](autobrr/qui#1371)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6d1dac7`](autobrr/qui@6d1dac7): feat(pwa): add protocol and file handlers for magnet links and torrent files ([#&#8203;783](autobrr/qui#783)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`42fa501`](autobrr/qui@42fa501): feat(torrents): add unified cross-instance torrent table ([#&#8203;1481](autobrr/qui#1481)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`498eaca`](autobrr/qui@498eaca): feat(ui): show speeds in page title ([#&#8203;1292](autobrr/qui#1292)) ([@&#8203;NoLife141](https://github.com/NoLife141))
- [`94a506e`](autobrr/qui@94a506e): feat(unregistered): nem talalhato ([#&#8203;1483](autobrr/qui#1483)) ([@&#8203;KyleSanderson](https://github.com/KyleSanderson))
- [`8bf366c`](autobrr/qui@8bf366c): feat(web): add logs nav ([#&#8203;1458](autobrr/qui#1458)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`babc88d`](autobrr/qui@babc88d): feat(web): add responsive popover with mobile drawer support ([#&#8203;1398](autobrr/qui#1398)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`06d341b`](autobrr/qui@06d341b): feat(web): add torrent table selection quick wins ([#&#8203;1455](autobrr/qui#1455)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`56fbbec`](autobrr/qui@56fbbec): feat(web): hide selection column ([#&#8203;1460](autobrr/qui#1460)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`46814aa`](autobrr/qui@46814aa): feat(web): qBittorrent autorun preferences ([#&#8203;1430](autobrr/qui#1430)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`342643e`](autobrr/qui@342643e): feat(web): unify instance settings & qbit options dialog ([#&#8203;1257](autobrr/qui#1257)) ([@&#8203;0rkag](https://github.com/0rkag))
- [`e634d01`](autobrr/qui@e634d01): feat: add cross-seed blocklist ([#&#8203;1391](autobrr/qui#1391)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`13aaac8`](autobrr/qui@13aaac8): feat: add dry-run workflows ([#&#8203;1395](autobrr/qui#1395)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f01101d`](autobrr/qui@f01101d): feat: add option to disable built-in authentication ([#&#8203;1464](autobrr/qui#1464)) ([@&#8203;libussa](https://github.com/libussa))
- [`6d1da50`](autobrr/qui@6d1da50): feat: download individual content files from context menu ([#&#8203;1465](autobrr/qui#1465)) ([@&#8203;libussa](https://github.com/libussa))
- [`77e9abf`](autobrr/qui@77e9abf): feat: migrate to dodopayments ([#&#8203;1407](autobrr/qui#1407)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9f6c856`](autobrr/qui@9f6c856): feat: support basic auth for ARR and Torznab ([#&#8203;1442](autobrr/qui#1442)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Bug Fixes

- [`8a06d4b`](autobrr/qui@8a06d4b): fix(api): correct add-torrent OpenAPI param names and add missing fields ([#&#8203;1426](autobrr/qui#1426)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b9a687c`](autobrr/qui@b9a687c): fix(api): honor explicit basic auth clear from URL userinfo ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`948ca67`](autobrr/qui@948ca67): fix(api): tighten CORS/auth routing and base URL joins ([#&#8203;1325](autobrr/qui#1325)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`12bea13`](autobrr/qui@12bea13): fix(automations): improve applied action summaries ([#&#8203;1478](autobrr/qui#1478)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8fe658b`](autobrr/qui@8fe658b): fix(automations): negate regex match for NotContains/NotEqual operators ([#&#8203;1441](autobrr/qui#1441)) ([@&#8203;andresatierf](https://github.com/andresatierf))
- [`8a808eb`](autobrr/qui@8a808eb): fix(automations): respect remove-only tag conditions ([#&#8203;1444](autobrr/qui#1444)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a72715e`](autobrr/qui@a72715e): fix(backups): add failure cooldown and export throttling ([#&#8203;1214](autobrr/qui#1214)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2e75c14`](autobrr/qui@2e75c14): fix(backups): skip exports missing metadata ([#&#8203;1362](autobrr/qui#1362)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5658421`](autobrr/qui@5658421): fix(config): update commented log settings in place ([#&#8203;1402](autobrr/qui#1402)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`62c50c0`](autobrr/qui@62c50c0): fix(crossseed): tighten TV title matching ([#&#8203;1445](autobrr/qui#1445)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`e7cc489`](autobrr/qui@e7cc489): fix(dirscan): prevent immediate requeue after cancel ([#&#8203;1446](autobrr/qui#1446)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`36cbfcf`](autobrr/qui@36cbfcf): fix(docs): avoid mdx jsx parse error ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d8d6f62`](autobrr/qui@d8d6f62): fix(filters): stabilize dense sidebar layout ([#&#8203;1384](autobrr/qui#1384)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b959fc6`](autobrr/qui@b959fc6): fix(orphanscan): NFC-normalize paths to avoid false orphans ([#&#8203;1422](autobrr/qui#1422)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`598e994`](autobrr/qui@598e994): fix(reflink): retry EAGAIN clones ([#&#8203;1360](autobrr/qui#1360)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`aaa5ee0`](autobrr/qui@aaa5ee0): fix(reflinktree): retry transient FICLONE EINVAL and add diagnostics ([#&#8203;1487](autobrr/qui#1487)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`647af31`](autobrr/qui@647af31): fix(rss): enable rules list scrolling ([#&#8203;1359](autobrr/qui#1359)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c356a6f`](autobrr/qui@c356a6f): fix(sync): Optimize torrent sorting and reference management ([#&#8203;1474](autobrr/qui#1474)) ([@&#8203;KyleSanderson](https://github.com/KyleSanderson))
- [`cf4310e`](autobrr/qui@cf4310e): fix(ui): update placeholder text in ArrInstanceForm based on instance type ([#&#8203;1375](autobrr/qui#1375)) ([@&#8203;pashioya](https://github.com/pashioya))
- [`92b6748`](autobrr/qui@92b6748): fix(web): format IPv6 peer addresses and copy IP without port ([#&#8203;1417](autobrr/qui#1417)) ([@&#8203;sleepm](https://github.com/sleepm))
- [`25039bc`](autobrr/qui@25039bc): fix(web): handle SSO session expiry behind Cloudflare Access and other proxies ([#&#8203;1438](autobrr/qui#1438)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`77fe310`](autobrr/qui@77fe310): fix(web): prevent category submenu re-render ([#&#8203;1357](autobrr/qui#1357)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`a42ab1e`](autobrr/qui@a42ab1e): fix(web): raise instance preferences max value from 999 to 99999 ([#&#8203;1311](autobrr/qui#1311)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`540168c`](autobrr/qui@540168c): fix(web): raise virtualization threshold ([#&#8203;1355](autobrr/qui#1355)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`8547dc6`](autobrr/qui@8547dc6): fix(web): remove column filters when column is hidden ([#&#8203;1418](autobrr/qui#1418)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`6b09b8d`](autobrr/qui@6b09b8d): fix(web): remove panel size bounds ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`db4cdc4`](autobrr/qui@db4cdc4): fix(web): show piece size in torrent details ([#&#8203;1365](autobrr/qui#1365)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1f94a06`](autobrr/qui@1f94a06): fix(web): use absolute for scroll-to-top on desktop ([#&#8203;1419](autobrr/qui#1419)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`e31fe3a`](autobrr/qui@e31fe3a): fix: detect tracker health support after qBit upgrade ([#&#8203;909](autobrr/qui#909)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`52f01da`](autobrr/qui@52f01da): fix: disable update indicators when update checks are off ([#&#8203;1364](autobrr/qui#1364)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f7e3fed`](autobrr/qui@f7e3fed): fix: normalize DD+ and DDP file keys ([#&#8203;1456](autobrr/qui#1456)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`d914301`](autobrr/qui@d914301): chore(ci): fire Blacksmith (my wallet screamed) ([#&#8203;1408](autobrr/qui#1408)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b43327d`](autobrr/qui@b43327d): chore(deps): bump the golang group with 2 updates ([#&#8203;1378](autobrr/qui#1378)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`57747bd`](autobrr/qui@57747bd): chore(deps): bump the npm group across 1 directory with 27 updates ([#&#8203;1379](autobrr/qui#1379)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`a43850d`](autobrr/qui@a43850d): chore(docs): add BIMI SVG logo ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`914bede`](autobrr/qui@914bede): chore(funding): add Patreon to FUNDING.yml ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8b76f1e`](autobrr/qui@8b76f1e): docs(automations): clarify tag matching examples ([#&#8203;1457](autobrr/qui#1457)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2994054`](autobrr/qui@2994054): docs(readme): restore concise README ([#&#8203;1452](autobrr/qui#1452)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`51237d4`](autobrr/qui@51237d4): docs: Add configuration reference ([#&#8203;1440](autobrr/qui#1440)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`741462c`](autobrr/qui@741462c): docs: add Windows installation guide ([#&#8203;1463](autobrr/qui#1463)) ([@&#8203;soggy-cr0uton](https://github.com/soggy-cr0uton))
- [`6a11430`](autobrr/qui@6a11430): docs: clarify autobrr filter + apply troubleshooting ([#&#8203;1459](autobrr/qui#1459)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5a2edc2`](autobrr/qui@5a2edc2): docs: update 2 documentation files ([#&#8203;1454](autobrr/qui#1454)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`139ada9`](autobrr/qui@139ada9): docs: update contributing.md ([#&#8203;1470](autobrr/qui#1470)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3909aa1`](autobrr/qui@3909aa1): docs: update docs/features/automations.md ([#&#8203;1447](autobrr/qui#1447)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5dc57ca`](autobrr/qui@5dc57ca): docs: update intro.md ([#&#8203;1453](autobrr/qui#1453)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5d9e986`](autobrr/qui@5d9e986): perf(web): memoize useDateTimeFormatters ([#&#8203;1403](autobrr/qui#1403)) ([@&#8203;jabloink](https://github.com/jabloink))

**Full Changelog**: <autobrr/qui@v1.13.1...v1.14.0>

#### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.14.0`
- `docker pull ghcr.io/autobrr/qui:latest`

#### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNS43IiwidXBkYXRlZEluVmVyIjoiNDMuMjUuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4154
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
@nitrobass24
nitrobass24 deleted the fix/1105-firefox-sso-detection branch February 24, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants