Compare commits

..

12 Commits

Author SHA1 Message Date
alexbelgium
14e377cf2f fix(filebrowser_quantum): drop the doubled status-bar inset in the HA app
2.0 sets viewport-fit=cover and pads its header by env(safe-area-inset-top);
inside the ingress panel HA's toolbar already handles that inset. Rewrite it
to viewport-fit=auto on the ingress listener only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 08:08:40 +02:00
alexbelgium
55c3ad47ad fix(filebrowser_quantum): simplify the healthcheck
Curl the app root: v2 answers 200, or 301 to the baseURL, which curl -f
accepts, so the baseURL no longer has to be read from the config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 08:00:42 +02:00
alexbelgium
a4b6282d23 Revert "fix(filebrowser_quantum): drop panel_admin default flagged by the add-on linter"
Keep panel_admin: true explicit, per maintainer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:50:41 +02:00
alexbelgium
2b0f7b61ad fix(filebrowser_quantum): drop panel_admin default flagged by the add-on linter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:41:28 +02:00
alexbelgium
9aa2c2c749 fix(filebrowser_quantum): keep server.database siblings, sanitize direct XFF
Set only server.database.path (dropping migrateFrom) so user-set keys such
as activity survive, and replace X-Forwarded-For on the published 8071
listener now that FileBrowser trusts proxy headers for login rate limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:40:00 +02:00
alexbelgium
277fdc5679 fix(filebrowser_quantum): ask users to back up before the 2.0 upgrade
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:38:16 +02:00
alexbelgium
49083d7492 docs(filebrowser_quantum): fix CHANGELOG entry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:31:19 +02:00
alexbelgium
5dfff5fe89 fix(filebrowser_quantum): convert 1.x configs in place instead of resetting
Resetting to the v2 default dropped extra sources (breaking shares on them)
and auth/OIDC settings. Both 1.x and 2.0 reject unknown keys, so the keys a
1.5.x config can hold that 2.0 lacks are exactly the settings-struct diff:
move the server http keys under http and drop the removed ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:31:08 +02:00
alexbelgium
28afa07729 fix(filebrowser_quantum): follow the v2 migration guide and upstream healthcheck
Set migrateFrom only until the SQLite database exists, set
http.trustProxyHeaders for the nginx subpath, and check upstream's
${baseURL}health endpoint instead of an nginx-only stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:17:37 +02:00
alexbelgium
7638c594b0 docs(filebrowser_quantum): clarify migrateFrom comment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:12:30 +02:00
alexbelgium
3a94f3c188 fix(filebrowser_quantum): reset 1.x configs to the v2 default on upgrade
Old installs carry a config copied from a 1.x image default, whose
userDefaults layout v2 rejects as unknown fields. Deleting keys one by one
cannot cover every 1.x variant, so back the file up and start from the v2
default, which the script then fills in as on a fresh install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:10:19 +02:00
alexbelgium
c2bbc5b46a fix(filebrowser_quantum): write the v2 config format so 2.0.0 starts
v2 rejects the string server.database, the 1.x server.port/listen/baseURL
keys and the FILEBROWSER_DATABASE variable, so both fresh installs and
upgrades died at startup. Write http.* and server.database.path, and point
migrateFrom at an existing 1.x BoltDB so upstream migrates it on first start.

Fixes #3109

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:06:26 +02:00
3 changed files with 10 additions and 12 deletions

View File

@@ -1,7 +1,4 @@
## 2.0.0.2 (2026-10-11)
- Remove the empty band above the search bar in the Home Assistant app (portrait): 2.0 padded its header for the phone status bar, which HA already does. The top inset is set to 0 on ingress only.
## 2.0.0.1 (2026-10-11)
- ⚠️ **Back up before updating.** FileBrowser 2.0 changes the config format and the database. This add-on converts both automatically, but you should first create a Home Assistant backup of the add-on, or copy `/addon_configs/*filebrowser_quantum*/` (`config.yaml` and `database.db`). Your 1.x `database.db` is left untouched, but downgrading after the migration loses any changes made in 2.0.
- Fix startup on 2.0.0, for fresh installs and upgrades (#3109).
@@ -14,6 +11,7 @@
- Users, shares and settings in `/config/database.db` are migrated to `/config/database.sqlite` on first start.
- `http.trustProxyHeaders` is set to `true`, because the add-on always runs behind nginx on a subpath.
- The container healthcheck now checks FileBrowser directly on port 8080 instead of an nginx stub.
- Remove the empty band above the search bar in the Home Assistant app: 2.0 padded its header for the phone status bar, which HA already does. This applies to ingress only.
- Direct access on port 8071 no longer passes on a client-supplied `X-Forwarded-For`, so the IP-based login lockout cannot be bypassed now that proxy headers are trusted. Ingress keeps the forwarded chain.
## 2.0.0 (2026-10-10)

View File

@@ -117,4 +117,4 @@ schema:
slug: filebrowser_quantum
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2.0.0.2"
version: "2.0.0.1"

View File

@@ -13,12 +13,12 @@ server {
proxy_read_timeout 30m;
proxy_pass %%protocol%%://backend%%subpath%%;
# Three things the ingress panel needs that a plain browser tab does not.
# Two things the ingress panel needs that a plain browser tab does not.
# Both are injected into the page's existing nonce-carrying inline script
# rather than next to <div id="app">: FileBrowser sends
# script-src 'self' 'nonce-<random>', so a standalone inline <script>
# would be blocked. If upstream ever drops that
# window.__pwaDeferredPrompt line the filter stops matching and all three
# window.__pwaDeferredPrompt line the filter stops matching and both
# behaviours revert, which is the state before either fix.
#
# 1. Opening a folder. The tool views (Tools -> File Size Analyzer and
@@ -106,12 +106,12 @@ server {
# links inside a document FileBrowser renders in its own iframe -- the
# pdf viewer, the srcdoc markdown/html preview, OnlyOffice -- because a
# listener on this document never sees another document's clicks.
# 3. The status-bar inset. 2.0 pads its header by env(safe-area-inset-top)
# (--safe-area-top), but inside the Home Assistant app the panel already
# sits below HA's toolbar, which handles that inset, so in portrait it
# was applied twice: an empty band above the search bar. Zero it on
# <html>, which overrides the :root rule; the direct port is untouched.
sub_filter "window.__pwaDeferredPrompt = null;" "window.__pwaDeferredPrompt = null;document.documentElement.style.setProperty('--safe-area-top','0px');(function(){var o=window.open;window.open=function(u,n,f){try{var b=(window.globalVars||{}).baseURL;if(u&&n==='_blank'&&!f&&b){if(b.slice(-1)!=='/')b+='/';var t=new URL(u,location.href);if((t.protocol==='http:'||t.protocol==='https:')&&t.origin===location.origin&&(t.pathname.indexOf(b+'files/')===0||t.pathname.indexOf(b+'public/share/')===0)){location.assign(t.href);return window}}}catch(e){}return o.apply(window,arguments)};document.addEventListener('click',function(e){try{if(e.button||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;var a=e.target&&e.target.closest?e.target.closest('a'):null;if(!a||!a.href)return;var b=(window.globalVars||{}).baseURL;if(!b)return;if(b.slice(-1)!=='/')b+='/';var t=new URL(a.href,location.href);if(t.origin!==location.origin)return;if(!a.hasAttribute('download')&&t.searchParams.get('inline')!=='true'&&(t.pathname===b+'api/resources/download'||t.pathname===b+'public/api/resources/download')){a.download='';a.removeAttribute('target');return}if(a.target==='_blank'&&t.pathname.indexOf(b)===0&&navigator.userAgent.indexOf('Mobile/HomeAssistant')!==-1){a.removeAttribute('target')}}catch(err){}},true)})();";
# 2.0 asks for viewport-fit=cover and pads its header by
# env(safe-area-inset-top). In the Home Assistant app the panel already
# sits below HA's toolbar, which handles that inset, so it was applied
# twice (an empty band above the search bar). The direct port is untouched.
sub_filter "viewport-fit=cover" "viewport-fit=auto";
sub_filter "window.__pwaDeferredPrompt = null;" "window.__pwaDeferredPrompt = null;(function(){var o=window.open;window.open=function(u,n,f){try{var b=(window.globalVars||{}).baseURL;if(u&&n==='_blank'&&!f&&b){if(b.slice(-1)!=='/')b+='/';var t=new URL(u,location.href);if((t.protocol==='http:'||t.protocol==='https:')&&t.origin===location.origin&&(t.pathname.indexOf(b+'files/')===0||t.pathname.indexOf(b+'public/share/')===0)){location.assign(t.href);return window}}}catch(e){}return o.apply(window,arguments)};document.addEventListener('click',function(e){try{if(e.button||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;var a=e.target&&e.target.closest?e.target.closest('a'):null;if(!a||!a.href)return;var b=(window.globalVars||{}).baseURL;if(!b)return;if(b.slice(-1)!=='/')b+='/';var t=new URL(a.href,location.href);if(t.origin!==location.origin)return;if(!a.hasAttribute('download')&&t.searchParams.get('inline')!=='true'&&(t.pathname===b+'api/resources/download'||t.pathname===b+'public/api/resources/download')){a.download='';a.removeAttribute('target');return}if(a.target==='_blank'&&t.pathname.indexOf(b)===0&&navigator.userAgent.indexOf('Mobile/HomeAssistant')!==-1){a.removeAttribute('target')}}catch(err){}},true)})();";
}
}