Compare commits

..

10 Commits

Author SHA1 Message Date
Alexandre
8984e64ca0 Add sub_filter for '/auth' in ingress.conf 2026-08-18 09:58:52 +02:00
Alexandre
76770b181c Update ingress.conf 2026-08-18 09:58:10 +02:00
dependabot[bot]
2b6e07040f Bump anthropics/claude-code-action from 1.0.187 to 1.0.193 (#2984)
Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.187 to 1.0.193.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](1623c36729...9d7150bc8a)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.193
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-18 08:43:45 +02:00
dependabot[bot]
680386525f Bump EndBug/add-and-commit from 10 to 11 (#2985)
Bumps [EndBug/add-and-commit](https://github.com/endbug/add-and-commit) from 10 to 11.
- [Release notes](https://github.com/endbug/add-and-commit/releases)
- [Commits](https://github.com/endbug/add-and-commit/compare/v10...v11)

---
updated-dependencies:
- dependency-name: EndBug/add-and-commit
  dependency-version: '11'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-18 08:43:31 +02:00
github-actions
20a2f997c9 GitHub bot: changelog [nobuild] 2026-08-17 16:43:17 +00:00
Alexandre
15de5e3a39 fix(seerr): add trailing slash to ingress root-link rewrites (#2976)
Seerr's Discover link is href="/". nginx rewrote it to the bare ingress
entry, but Home Assistant only routes ingress on
"/api/hassio_ingress/{token}/{path:.*}", so a URL without the trailing
slash matches no route and Home Assistant answers its own plain-text
"404: Not Found" before the request reaches the add-on.

Closes #2975

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:35:14 +02:00
Pol Montanera
232e697301 Fix FileBrowser Quantum direct web access (#2979)
* Fix FileBrowser Quantum direct web access

* fix(filebrowser_quantum): make direct ip:port access actually work

ports: {8080/tcp: 8071} alone (as originally proposed) publishes the app's
own port, but FileBrowser Quantum's server.baseURL is set at boot to the
Supervisor ingress-entry path (an opaque, per-install hash), so the app only
serves correctly under that exact path -- a bare port publish gives an
unreachable page, per alexbelgium's own analysis on #2978.

Add a second, dedicated nginx vhost (direct.conf) that proxies a fixed public
path (/filebrowser_quantum/) onto the same ingress-entry baseURL the existing
ingress vhost already targets, instead of changing the app's baseURL itself.
This leaves the ingress vhost, and therefore Ingress access, completely
unchanged -- only the new vhost is new surface area. config.yaml now
publishes the new vhost's internal port (8072) to host 8071, not the app's
own 8080 directly.

Co-authored-by: polmonta <polmonta05@gmail.com>

---------

Co-authored-by: polmonta <polmonta05@gmail.com>
Co-authored-by: alexbelgium <alexandre.pary@gmail.com>
2026-08-17 18:32:48 +02:00
Alexandre
53ad396e5b fix(claude_desktop): sign-in persistence broke again — safeStorage patcher didn't handle bundles without a use-strict directive (#2983)
* fix(claude_desktop): patch safeStorage on bundles without a use-strict directive

The v1.37 safeStorage patcher only knew how to inject its plaintext-encryption
opt-in after a leading "use strict" directive in Claude Desktop's main bundle,
and refused to patch anything else. Confirmed live: Claude Desktop 1.30096.1's
main bundle no longer opens with that directive (bare IIFE instead), so the
patch has been silently refusing to run on every boot and sessions stopped
persisting across restarts again, with the same "Encryption not available"
warning documented in SIGN_IN.md before v1.37.

applyPatch() now falls back to prepending the opt-in as the bundle's first
statement when no directive is found, after skipping any leading BOM,
hashbang, or banner comment so a directive hidden behind a comment is still
protected rather than pushed out of position zero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(claude_desktop): scan the full directive prologue, not just line 0

Addresses two Codex review findings on PR #2983:

1. skipPrologue()'s //-comment scan only recognized "\n" as a line
   terminator. A comment ending in CR-only or U+2028/U+2029 (all valid
   ECMAScript LineTerminators) made it swallow the rest of the file as
   "still the comment", landing the patch after the bundle's last
   statement instead of before it. Reproduced with
   `// banner\r"use strict";(function(){})();`.

2. applyPatch() only checked whether the very first statement was
   literally "use strict". A directive prologue can hold more than one
   string-literal statement, and "use strict" only has to appear
   somewhere in it, not first; prepending ahead of an earlier directive
   pushed the whole prologue out of first-statement position and
   silently dropped strict mode. Reproduced with
   `"use custom";"use strict";(...)`.

Replaced the single-directive check with scanDirectivePrologue(), which
walks every leading string-literal-only statement and inserts right
after the full prologue (or at the same position when there is none).
skipPrologue/applyPatch split into skipBomAndHashbang +
skipWhitespaceAndComments + scanDirectivePrologue accordingly.

Verified: both findings reproduced against the pre-fix code and no
longer occur; 13-case regression suite covering the original edge cases
plus both findings all pass; re-run against the live production
app.asar still patches successfully and idempotently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 18:31:20 +02:00
Alexandre
bcdd972c2f Revert "docs(filebrowser_quantum): stop advertising direct access on port 807…" (#2982)
This reverts commit 65233d1291.
2026-08-17 07:57:24 +02:00
Alexandre
65233d1291 docs(filebrowser_quantum): stop advertising direct access on port 8071 (#2981)
config.yaml declares ingress_port: 8071 but no ports: key, so nothing is
published to the host network. ingress_port is the internal port the
Supervisor ingress proxy connects to on the add-on's private IP, and Home
Assistant only renders the Network card for add-ons that declare ports:.
Direct access at <your-ip>:8071 has therefore never worked; the README was
carried over from the sibling filebrowser add-on, which does declare
ports: 8080/tcp: 8071.

Correct the three README claims rather than publishing a port, since the
app is configured with server.baseURL set to the ingress entry and would
not serve correctly on a plain published port without further work.

Closes #2978

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 07:55:10 +02:00
26 changed files with 233 additions and 45 deletions

View File

@@ -228,7 +228,7 @@ jobs:
echo "... done"
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "GitHub bot : README updated"
default_author: github_actions

View File

@@ -125,7 +125,7 @@ jobs:
- name: Analyse and fix
if: steps.batch.outputs.count != '0'
uses: anthropics/claude-code-action@1623c36729ac1cd5895198cded705a287de7db79 # v1
uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Skip the OIDC -> Claude App token exchange. The scheduled path

View File

@@ -237,7 +237,7 @@ jobs:
# Get stars evolution
wget -S -O .github/starsevol.svg "https://api.star-history.com/svg?repos=alexbelgium/hassio-addons&type=Date" || true
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "GitHub bot : graphs updated"
default_author: github_actions

View File

@@ -64,7 +64,7 @@ jobs:
fetch-depth: 1
- name: Run Claude Code
uses: anthropics/claude-code-action@1623c36729ac1cd5895198cded705a287de7db79 # v1
uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# AI_PR_TOKEN, not GITHUB_TOKEN, so a PR Claude opens triggers CI.

View File

@@ -135,7 +135,7 @@ jobs:
- name: Execute the plan
if: steps.bundle.outputs.has_plan == 'true'
uses: anthropics/claude-code-action@1623c36729ac1cd5895198cded705a287de7db79 # v1
uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Skip the OIDC -> Claude App token exchange, which 401s whenever

View File

@@ -59,7 +59,7 @@ jobs:
# Remove issues list
rm issueslist
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "Github bot : issues linked to readme"
default_author: github_actions

View File

@@ -166,7 +166,7 @@ jobs:
id: classify
if: github.event_name != 'issue_comment' || steps.claim.outputs.go == 'true'
continue-on-error: true
uses: anthropics/claude-code-action@1623c36729ac1cd5895198cded705a287de7db79 # v1
uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Without this the action falls back to the OIDC -> Claude App token

View File

@@ -79,7 +79,7 @@ jobs:
- name: Address CodeRabbit comments
if: steps.claim.outputs.go == 'true'
uses: anthropics/claude-code-action@1623c36729ac1cd5895198cded705a287de7db79 # v1
uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Skip the OIDC -> Claude App token exchange, which 401s whenever

View File

@@ -95,7 +95,7 @@ jobs:
- name: Commit sanitize changes
id: sanitize_commit
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
commit: -u
message: "GitHub bot: sanitize (spaces + LF endings) & chmod [nobuild]"
@@ -410,7 +410,7 @@ jobs:
done
- name: Commit changelog changes
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
commit: -u
message: "GitHub bot: changelog [nobuild]"

View File

@@ -18,7 +18,7 @@ jobs:
uses: erclu/check-crlf@v1
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "Github bot : CRLF corrected"
default_author: github_actions
@@ -50,7 +50,7 @@ jobs:
dos2unix -k "$f"
done
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "Github bot : CRLF corrected"
default_author: github_actions

View File

@@ -31,7 +31,7 @@ jobs:
- name: Commit if needed
if: steps.calibre.outputs.markdown != ''
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
message: "Github bot : image compressed"
default_author: github_actions

View File

@@ -109,7 +109,7 @@ jobs:
#TOTAL3="$(awk '{SUM+=$2}END{print SUM}' Stats)"
- name: Commit if needed
uses: EndBug/add-and-commit@v10
uses: EndBug/add-and-commit@v11
with:
default_author: github_actions
message : "Github bot : stats updated"

View File

@@ -49,6 +49,7 @@ server {
sub_filter `/asset `%%ingress_entry%%/asset;
sub_filter "'/asset" "'%%ingress_entry%%/asset";
sub_filter \"/asset \"%%ingress_entry%%/asset;
sub_filter \"/auth \"%%ingress_entry%%/auth;
sub_filter window.location.origin} window.location.origin}%%ingress_entry%%;
}
}

View File

@@ -49,6 +49,7 @@ server {
sub_filter `/asset `%%ingress_entry%%/asset;
sub_filter "'/asset" "'%%ingress_entry%%/asset";
sub_filter \"/asset \"%%ingress_entry%%/asset;
sub_filter \"/auth \"%%ingress_entry%%/auth;
sub_filter window.location.origin} window.location.origin}%%ingress_entry%%;
}
}

View File

@@ -1,4 +1,25 @@
## 07308545.1 (17-08-2026)
- Minor bugs fixed
## 07308543.1 (17-08-2026)
- Fix the "For your security, sign in again" prompt recurring on every restart again. The v1.37
`safeStorage` patch (`86-claude_safestorage.sh` / `claude-safestorage-patch.js`) only knew how
to inject its opt-in after a leading `"use strict"` directive in the app's main bundle, and
refused to patch anything else. Confirmed live on the running add-on (Claude Desktop
1.30096.1): the shipped main bundle (`.vite/build/index.pre.js`) no longer opens with a
`"use strict"` directive at all — it now opens directly with a bare IIFE — so the patcher has
been silently refusing to patch on every boot, `safeStorage.isEncryptionAvailable()` stayed
`false`, and the app's own log kept showing `Encryption not available, returning empty env
vars` exactly as before v1.37. `applyPatch()` now falls back to inserting the opt-in as the
bundle's first real statement when no directive is present, skipping past any leading BOM,
hashbang, or banner comment first so a directive hidden behind a comment is still found and
protected rather than pushed out of position zero. Verified by copying the live production
`app.asar` and running the patcher against it directly: the previously-refused bundle now
patches successfully, the marker lands correctly, a second run reports "Already patched", and
targeted unit tests cover the bare-IIFE, comment-hidden-directive, hashbang, and
unterminated-comment cases.
- One-time step after upgrading, same as v1.37: the previously-stored session is already stale,
so complete one sign-in from a computer; it then persists across restarts.
## 07308545 (2026-08-15)
- Update to latest version from aaddrick/claude-desktop-debian (changelog : https://github.com/aaddrick/claude-desktop-debian/releases)
- Upstream tag : v3.2.2+claude1.30096.1

View File

@@ -13,8 +13,10 @@ streamed desktop.
offline until a fresh sign-in was done from a computer). v1.35 switched to
`--password-store=basic` plus a cont-init script that re-syncs the persistent openbox
`autostart` from the image on every boot — **but that flag alone does nothing**, and the bug
survived it untouched. Actually fixed in v1.37, which adds the application-side opt-in the
`basic` backend requires; see "Why v1.35 did not work" below.
survived it untouched. v1.37 added the application-side opt-in the `basic` backend requires;
see "Why v1.35 did not work" below. That patcher then regressed silently when upstream's
bundle output changed shape — fixed again in 07308543.1; see "Why v1.37 stopped working"
below.
- **Planned only:** Problem A (in-desktop browser for OAuth) is intentionally not implemented.
The image ships no browser; complete the login with the user-side workaround below.
@@ -170,10 +172,40 @@ The third row is the one that matters: it is the restart survival this add-on ne
reaches upgrades, not just fresh installs.
4. `gnome-keyring` stays out of the Dockerfile.
### Why v1.37 stopped working
`claude-safestorage-patch.js` only knew how to inject its opt-in *after* a leading
`"use strict"` directive in the app's main bundle, and refused to patch (leaving the app
unpatched and the session un-persisted) if that directive wasn't there. Confirmed live on the
running add-on: Claude Desktop 1.30096.1's main bundle (`.vite/build/index.pre.js`) no longer
opens with a `"use strict"` directive — it now opens directly with a bare IIFE
(`(function(){try{var e=typeof window...`). Upstream's build output changed shape at some point
after v1.37 shipped, the patcher's one injection point stopped existing, and it had been
silently refusing to patch on every boot since — the app's `main.log` kept showing exactly the
same `Encryption not available, returning empty env vars` warning documented above, and the
session went back to not surviving restarts.
`applyPatch()` now falls back to inserting the opt-in as the bundle's first real statement when
no `"use strict"` directive is found, rather than refusing outright. It skips past any leading
BOM, hashbang, or banner comment first (`skipPrologue()`), so a directive hidden behind a
comment is still found and protected instead of being pushed out of the first-statement
position by a naive prepend — Vite/esbuild banners commonly put a license comment ahead of the
directive. A bundle with no directive at all has nothing to protect, so prepending the opt-in
there is unconditionally safe: the injected code is a complete `try{}catch(e){}` statement, and
a statement can never merge with what follows it via ASI the way a bare expression could.
Verified by copying the live production `app.asar` and running the patcher against it directly
(outside the container's boot sequence): the previously-refused bundle now patches
successfully, the marker lands at the front of the main entry, a second run correctly reports
"Already patched" (idempotent), and unit tests cover the bare-IIFE, comment-hidden-directive,
hashbang, and unterminated-comment cases.
### One-time step after upgrading
The previously-stored session is already stale. Complete **one** sign-in from a computer
(mobile still can't finish the OAuth flow itself, per Problem A) — the session then persists
normally and dispatch stays online regardless of which device connects first afterward.
normally and dispatch stays online regardless of which device connects first afterward. This
applies again after the 07308543.1 fix above, since the affected sessions were never persisted
in the first place.
---
@@ -185,7 +217,10 @@ normally and dispatch stays online regardless of which device connects first aft
- `claude_desktop/rootfs/etc/cont-init.d/86-claude_safestorage.sh` and
`claude_desktop/rootfs/usr/local/bin/claude-safestorage-patch.js` — new in v1.37; the
app-side `safeStorage` opt-in that makes `--password-store=basic` actually take effect.
`claude-safestorage-patch.js` updated again in 07308543.1 to also patch bundles with no
leading `"use strict"` directive, and to look past leading comments/hashbang when deciding
whether one is present.
- `claude_desktop/Dockerfile` — corrected stale comment (gnome-keyring is not installed).
- `claude_desktop/CHANGELOG.md` / `config.yaml` — v1.35, then v1.37.
- `claude_desktop/CHANGELOG.md` / `config.yaml` — v1.35, then v1.37, then 07308543.1.
Problem A (in-desktop browser for OAuth) remains planned-only; not touched by this change.

View File

@@ -136,5 +136,5 @@ schema:
slug: claude_desktop
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "07308545"
version: "07308545.1"
video: true

View File

@@ -128,24 +128,98 @@ function integrityOf(buf, blockSize) {
return { algorithm: 'SHA256', hash: sha256(buf), blockSize, blocks };
}
/* Insert the opt-in after the bundle's leading "use strict" directive. It must go *after* it: a
* directive prologue only takes effect as the very first statement, so prepending would silently
* drop the whole main process out of strict mode.
// Any of the four ECMAScript LineTerminator code points — not just "\n". A //-comment or an ASI
// boundary ends at the first of these, and using a bare "\n" search for that would let a CR- or
// U+2028/U+2029-terminated line swallow real code as "still the comment/still on this line" and
// misplace the insertion point deep inside the bundle instead of before it.
const LINE_TERMINATOR = /[\n\r\u2028\u2029]/;
/* Skip a leading BOM and hashbang line. Only meaningful at byte 0 — called once, before any
* directive scanning. */
function skipBomAndHashbang(source) {
let i = source.charCodeAt(0) === 0xfeff ? 1 : 0; // BOM
if (source.startsWith('#!', i)) {
const m = LINE_TERMINATOR.exec(source.slice(i));
i += m ? m.index + 1 : source.length - i;
}
return i;
}
/* Skip whitespace and comments starting at i. Returns the next index, or -1 for an unterminated
* block comment (caller refuses rather than guesses). */
function skipWhitespaceAndComments(source, i) {
for (;;) {
const rest = source.slice(i);
const ws = /^\s+/.exec(rest);
if (ws) {
i += ws[0].length;
continue;
}
if (rest.startsWith('//')) {
const m = LINE_TERMINATOR.exec(rest);
i += m ? m.index + 1 : rest.length;
continue;
}
if (rest.startsWith('/*')) {
const end = rest.indexOf('*/');
if (end === -1) return -1;
i += end + 2;
continue;
}
return i;
}
}
// A single-line string literal: no raw line terminator in its content (a real one would need an
// escaped line continuation, which this deliberately doesn't special-case — failing to match
// just means the prologue scan below stops there, which is always safe, see applyPatch).
const STRING_LITERAL = /^(['"])(?:\\.|(?!\1)[^\\\n\r\u2028\u2029])*\1/;
/* Scan the bundle's full leading directive prologue: every consecutive ExpressionStatement made
* of nothing but a string literal, per how ECMAScript directives actually work. A directive
* prologue can hold more than one entry, and "use strict" only has to appear *somewhere* in it,
* not first — so this treats every leading directive as needing protection, not just one
* specifically named "use strict". Returns the index right after the full prologue (which is
* also correct as "no prologue, insert here" when there wasn't one), or -1 when a leading string
* literal isn't cleanly terminated as its own statement — ambiguous whether it's a directive at
* all, refused rather than guessed at. */
function scanDirectivePrologue(source, start) {
let i = start;
for (;;) {
const next = skipWhitespaceAndComments(source, i);
if (next === -1) return -1;
const rest = source.slice(next);
const m = STRING_LITERAL.exec(rest);
if (!m) return next; // not a directive; prologue (possibly empty) ends here
const after = rest.slice(m[0].length);
if (after[0] === ';') {
i = next + m[0].length + 1;
} else if (after === '' || LINE_TERMINATOR.test(after[0])) {
i = next + m[0].length;
} else {
return -1; // "use strict" + x and friends: not unambiguously a directive
}
}
}
/* Insert the opt-in right after the bundle's full leading directive prologue (BOM/hashbang, then
* any run of string-literal-only statements — "use strict" among them if present). It must go
* *after* the whole prologue, not just after the first entry: a directive prologue only takes
* effect when its members are the very first statements, so inserting between two of them, or
* ahead of all of them, would silently drop the file out of strict mode just as surely as
* inserting ahead of a lone "use strict" would.
*
* Returns null — meaning "refuse to patch" — for anything that is not unambiguously a directive.
* `"use strict" + x` is an expression, not a directive, and injecting into it would produce a
* syntax error, so the directive is only accepted when it is terminated by its own semicolon, a
* line break, or end of input. */
* When there is no prologue at all (observed from Claude Desktop 1.30096.1 onward, whose main
* entry opens with a bare IIFE instead), there is nothing to preserve: PATCH lands at the same
* position anyway, as the file's first real statement. A `try{}catch(e){}` statement can never
* merge with whatever follows via ASI — unlike a bare expression, a statement is not a valid
* left-hand side for anything a following token could continue — so this is unconditionally
* safe once placed after any banner comment / hashbang / directive prologue. */
function applyPatch(source) {
const m = /^\s*(['"])use strict\1(;?)/.exec(source);
if (!m) return null;
const rest = source.slice(m[0].length);
const terminated = m[2] === ';' || rest === '' || /^[\r\n]/.test(rest);
if (!terminated) return null;
// Supply the terminator when the directive relied on ASI; without it the injected code would
// continue the string-literal expression instead of following it.
const sep = m[2] === ';' ? '' : ';';
return source.slice(0, m[0].length) + sep + PATCH + rest;
const start = skipBomAndHashbang(source);
const end = scanDirectivePrologue(source, start);
if (end === -1) return null;
return source.slice(0, end) + PATCH + source.slice(end);
}
function writeAll(fd, buf) {
@@ -203,7 +277,7 @@ function main() {
const patchedSource = applyPatch(original);
if (patchedSource === null) {
fail(`${mainRel} does not begin with a recognized "use strict" directive; refusing to patch`);
fail(`${mainRel} opens with an ambiguous "use strict"-like string literal; refusing to patch`);
}
const patched = Buffer.from(patchedSource, 'utf8');

View File

@@ -1,7 +1,10 @@
## 1.5.1.1 (2026-08-17)
- Documentation: the add-on is Ingress-only and does not publish port 8071, so the README no longer advertises direct access at `<your-ip>:8071`
## 1.5.1.1 (2026-08-16)
- Expose the web UI on host port 8071, reachable at `<your-ip>:8071`
(redirects to `/filebrowser_quantum/`). Direct access is served by a new,
separate nginx vhost that proxies to the same backend Ingress already uses;
Ingress itself, and the app's own base URL, are unchanged.
## 1.5.1 (2026-08-08)
- Update to latest version from gtsteffaniak/filebrowser (changelog : https://github.com/gtsteffaniak/filebrowser/releases)

View File

@@ -42,11 +42,11 @@ comparison to installing any other Home Assistant add-on.
1. Click the `Save` button to store your configuration.
1. Start the add-on.
1. Check the logs of the add-on to see if everything went well.
1. Access the web UI through the Home Assistant sidebar.
1. Access the web UI through the sidebar or at `<your-ip>:8071/filebrowser_quantum/`.
## Configuration
The web UI is reached through the Home Assistant sidebar (Ingress). This add-on does not publish a port on your network, so it has no **Network** section in its configuration page and is not reachable at `<your-ip>:8071`.
The web UI can be found at `<your-ip>:8071` (redirects to `/filebrowser_quantum/`) or through the Home Assistant sidebar when using Ingress.
**Default credentials:**
- Username: `admin`
@@ -69,7 +69,7 @@ The web UI is reached through the Home Assistant sidebar (Ingress). This add-on
## Setup
1. Start the add-on and wait for it to initialize.
1. Access the web interface through the Home Assistant sidebar.
1. Access the web interface through the Home Assistant sidebar or at `<your-ip>:8071`.
1. Log in using the default credentials:
- Username: `admin`
- Password: `admin`

View File

@@ -97,6 +97,10 @@ options:
default_user_scope: "/"
panel_admin: false
panel_icon: mdi:file-search
ports:
8072/tcp: 8071
ports_description:
8072/tcp: Web UI port
privileged:
- SYS_ADMIN
- DAC_READ_SEARCH

View File

@@ -43,6 +43,13 @@ declare ingress_interface
declare ingress_port
#declare keyfile
# The app's own baseURL is always the Supervisor ingress-entry path — this is
# unchanged from before. FileBrowser Quantum has no known "ignore baseURL for
# routing" leniency the way classic filebrowser's app does, so ingress access
# is left completely untouched here. Direct ip:port access is handled below by
# a second, separate nginx vhost (direct.conf) that rewrites a fixed public
# path onto this same ingress-entry baseURL, instead of changing the baseURL
# itself.
FB_BASEURL=$(bashio::addon.ingress_entry)
export FB_BASEURL
@@ -59,6 +66,15 @@ sed -i "s|%%protocol%%|${ADDON_PROTOCOL}|g" /etc/nginx/servers/ingress.conf
sed -i "s|%%port%%|${ingress_port}|g" /etc/nginx/servers/ingress.conf
sed -i "s|%%interface%%|${ingress_interface}|g" /etc/nginx/servers/ingress.conf
sed -i "s|%%subpath%%|${FB_BASEURL}/|g" /etc/nginx/servers/ingress.conf
# --- Direct ip:port access (separate from ingress, see comment above) ---
# Publishes a second nginx vhost on a fixed internal port (published to the
# host as 8071 via config.yaml's `ports:`), at a fixed public path
# (/filebrowser_quantum/), that proxies to the same backend the ingress vhost
# uses. This keeps the app's own baseURL, and therefore ingress, unchanged.
sed -i "s|%%protocol%%|${ADDON_PROTOCOL}|g" /etc/nginx/servers/direct.conf
sed -i "s|%%subpath%%|${FB_BASEURL}/|g" /etc/nginx/servers/direct.conf
mkdir -p /var/log/nginx && touch /var/log/nginx/error.log
############################

View File

@@ -0,0 +1,24 @@
server {
listen 0.0.0.0:8072 default_server;
include /etc/nginx/includes/server_params.conf;
include /etc/nginx/includes/proxy_params.conf;
client_max_body_size 0;
location = / {
return 302 /filebrowser_quantum/;
}
location = /filebrowser_quantum {
return 301 /filebrowser_quantum/;
}
location /filebrowser_quantum/ {
add_header Access-Control-Allow-Origin *;
proxy_connect_timeout 30m;
proxy_send_timeout 30m;
proxy_read_timeout 30m;
proxy_pass %%protocol%%://backend%%subpath%%;
}
}

View File

@@ -1,4 +1,8 @@
## 3.4.1.1 (2026-08-16)
- Fixed `404: Not Found` when clicking **Discover** in the sidebar through ingress (#2975). Seerr's Discover link points at `/`, which nginx rewrote to the ingress entry without a trailing slash; Home Assistant only routes ingress on `/api/hassio_ingress/<token>/…`, so the request was rejected by Home Assistant before reaching the add-on. Only ingress was affected; the directly published port 5055 always worked.
## 3.4.1 (2026-08-01)
- Update to latest version from seerr-team/seerr (changelog : https://github.com/seerr-team/seerr/releases)
## 3.3.0.1 (2026-07-28)

View File

@@ -96,4 +96,4 @@ schema:
slug: seerr
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/seerr
version: "3.4.1"
version: "3.4.1.1"

View File

@@ -46,9 +46,14 @@ server {
# Do not rewrite every response type blindly.
sub_filter_types text/html application/javascript text/javascript application/json;
sub_filter 'href="/"' 'href="$app"';
# The trailing slash is required: Home Assistant routes ingress on
# "/api/hassio_ingress/{token}/{path:.*}", so the bare entry without it
# matches no route and Home Assistant answers its own plain-text
# "404: Not Found" before the request ever reaches this add-on. Seerr's
# Discover link is href="/", so without the slash every click on it 404s.
sub_filter 'href="/"' 'href="$app/"';
sub_filter 'href="/login"' 'href="$app/login"';
sub_filter 'href:"/"' 'href:"$app"';
sub_filter 'href:"/"' 'href:"$app/"';
sub_filter '\/_next' '%%ingress_entry_escaped%%\/_next';
sub_filter '/_next' '$app/_next';
sub_filter '/api/v1' '$app/api/v1';