Commit Graph
16 Commits
Author SHA1 Message Date
Claude 9cae430166 additional_directories.sh: fix nested bind-mount problem properly
Root cause: user scopes inside /data/... (the main data bind-mount) mean
any extra mount would nest inside another bind-mount — Docker does not
reliably layer these, so directories appeared in `ls` but were empty
and FileBrowser returned 404.

Fix: detect nested scopes and migrate them to the named volume (fb_users)
before adding any extra mounts.

Migration flow:
- Detects scope is inside /data bind-mount
- Suggests a new scope path in the named volume (e.g. /alice)
- Creates the scope directory via docker exec (no host-side clutter)
- Offers to mount the user's personal files dir as my-files/
- Updates the user's scope in FileBrowser via API PUT /api/users/:id
- Then adds requested extra dirs as non-nested bind-mounts

Also added: let user choose the display name for each added folder
(e.g. mount audiobookshelf but show it as "audiobooks").

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 04:02:03 +00:00
Claude 6d0d72bef5 additional_directories.sh: create host mount-point dirs for nested mounts
When a user's FileBrowser directory lives inside an existing bind-mount
(e.g. /srv/data/users/alice), Docker needs an empty directory at the
host-side equivalent path before it can overlay an inner bind-mount on
top of the outer one.  Without it the inner mount silently fails and
the extra folder never appears.

Now creates the mount-point directory on the host automatically before
adding the compose entry, with a visible note so the user knows a dir
was created.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:46:21 +00:00
Claude 412560aa8f filebrowser: replace manage_users.sh with additional_directories.sh
Symlinks don't work for giving scoped FileBrowser users access to extra
folders — FileBrowser's afero.BasePathFs blocks symlinks that resolve
outside the user's scope directory.

Switch to bind-mount approach: additional_directories.sh edits
docker-compose.yml to add real bind-mount entries for each extra folder,
so FileBrowser sees them as actual subdirectories within the user's root.
No symlinks, no scope-boundary issues.

Features:
- Reads FB_PATH from .env to list available source folders on the host
- Parses docker-compose.yml to show what's already configured per user
- Adds/removes volume entries with a timestamped backup before each edit
- Prompts to restart the container after changes
- Normalises scope paths from the API (handles missing leading slash)

manage_users.sh removed — user CRUD is handled by the FileBrowser web UI.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:29:36 +00:00
Claude c72a20af42 manage_users.sh: strip to directory-access-only tool
Removed all user CRUD (add, delete, rename, passwd, scope change).
The FileBrowser web UI handles those. Script is now focused solely
on adding/removing extra folder shortcuts for users who have a
restricted root directory. Simpler menu, ~half the code.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:06:52 +00:00
Claude c2df116a72 manage_users.sh: don't auto-create user dir, rename scope→directory
- Remove silent mkdir -p when adding extra directories. If the user's
  directory doesn't exist in the container, ask before creating it.
  This avoids creating folders the admin didn't intend.

- Rename all user-facing "scope" text to "directory" throughout:
  prompts, banners, menu labels, column headers, help text, error
  messages. The FileBrowser API field is still called "scope"
  internally, and the CLI subcommand name stays "scope" for compat.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 02:30:53 +00:00
Claude 39c85326e6 filebrowser: named volume for user dirs, rename linked→additional dirs
docker-compose now uses two separate mounts:
  fb_users named volume → /srv      (user home dirs + shortcuts, Docker only)
  FB_PATH bind mount    → /srv/data (actual files, unchanged on host)

User dirs and their shortcuts live entirely in the Docker named volume —
they persist across reboots but never appear on the host filesystem.
Full-access scope is /data; per-user scopes are /alice etc.

manage_users.sh:
- Detect layout: get_data_root() returns /srv/data (new) or /srv (legacy)
  so the script works with both old and new installs automatically
- "Linked directories" renamed to "additional directories" throughout
  (menu labels, prompts, error messages, usage text)
- prompt_add_links → prompt_add_dirs, menu_links → menu_add_dirs
- Available-folder listing and symlink targets use get_data_root()
- Scope examples updated to show /data for full access (new layout)
- Don't offer additional directories when scope is /data (full access)

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 02:23:07 +00:00
Claude 659b3924c0 fix manage_users.sh: strip fields that cause 400 on newer FileBrowser
Removed dateFormat, hideDotfiles, singleClick, and sorting from the
POST /api/users payload — FileBrowser rejects them as invalid data
types on some versions. Only stable fields are now sent.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 01:25:15 +00:00
Claude d591f38acf fix manage_users.sh: show API errors on user creation, fix symlink listing
- User creation was silently failing: api_post used curl -sf (fail on
  HTTP error) with output piped to /dev/null, so set -Eeuo pipefail
  would exit the script with no message. Now captures HTTP status code
  and response body, printing the server's error message on failure.

- Symlink folder listing (? prompt) only searched -type d, missing
  symlinked directories in /srv. Changed to -type d -o -type l so
  all browsable entries appear. Also switched xargs echo to tr for
  a cleaner one-line display.

- mkdir -p and ln -s in docker exec were not checked for errors;
  failures would silently kill the script under set -e. Both now
  show a useful error message and continue/return instead of crashing.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 01:12:43 +00:00
Claude 9ab7979833 manage_users.sh: fix login silently bailing on credential entry
Three fixes in ensure_token:
- Use jq to build the login JSON so special chars in passwords
  (quotes, backslashes, etc.) don't break the raw string interpolation
- Add || true to the curl call so set -e doesn't silently exit on
  connection refused before the response check runs
- Show FileBrowser's actual response on failure so the user can see
  whether it's wrong credentials vs unreachable vs something else

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-08 00:06:21 +00:00
Claude ea1a9cf3b7 manage_users.sh: list folders on demand with ? instead of auto-display
Auto-displaying all top-level dirs could be a wall of text.
Typing ? at the folder prompt lists them on demand instead.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:27:54 +00:00
Claude c71c08ac87 manage_users.sh: show available folders before link prompt
List top-level directories from /srv so the user knows what to type
without having to guess. Subdirs (e.g. documents/shared) still work.
Skip link prompt when scope is / (user already has full access).

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:22:22 +00:00
Claude c584811be4 manage_users.sh: remove /srv from all user-facing prompts
Users think in FileBrowser folder names, not container paths.

- prompt_add_links: prompt now "Folder to add [done]:" with examples
  like "music  photos  documents/shared" — /srv added internally
- list_links: strip /srv prefix from displayed target paths
- menu_links: rename options to "Add folders" / "Remove a folder"
- scope prompts: remove the leading "/" hint (confusing); normalise
  internally instead
- ok message shows "(from path/subdir)" only when link name differs

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:18:50 +00:00
Claude 5fdeff3f9a manage_users.sh: inline link prompts on add/scope-change
- prompt_add_links: shared helper loops asking for /srv paths until
  blank Enter, creates symlinks via docker exec, skips bad paths
- cmd_add: offers linked-dir prompt right after user creation
- cmd_scope: offers linked-dir prompt after a scope change
- menu_links: tighter submenu (list + add loop + remove) replacing
  the old menu_symlinks; called from Modify option 5
- Scope prompts now show the leading / so the user only types the rest
- Note on delete: symlinks on disk survive user deletion (by design)

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:15:12 +00:00
Claude b884d79dd2 manage_users.sh: add linked-directory (symlink) management
New option 5 in the Modify submenu: "Manage linked directories"

- Lists existing symlinks inside the user's scope dir (via docker exec)
- Add: prompts for source path (/srv/...) and a display name, creates
  the symlink inside /srv<scope>/<name> → /srv<source> in the container
- Remove: lists links, prompts for name, refuses to delete non-symlinks
- Warns if source path doesn't exist yet; offers to create anyway
- Auto-detects container name from docker-compose.yml next to the script
- Checks that the container is running before any docker exec calls

This is the recommended workaround for FileBrowser's single-scope
limitation: symlinks inside the scope dir appear as normal folders.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:07:27 +00:00
Claude 141c9115a7 Rewrite manage_users.sh: add interactive menu, fix password nameref bug
- Interactive menu when run with no args (login once, reuse token)
- Modify submenu: change username, password, scope, or toggle admin
- Fix: prompt_password now uses local -n nameref (bash 4.3+) so the
  caller's local variable is actually set; printf -v was writing to
  global scope and being shadowed by the caller's local declaration
- One-shot commands unchanged: list/add/delete/passwd/scope/rename/info
- FileBrowser only supports one scope per user — documented clearly

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:52:42 +00:00
Claude 9c52ac22e1 Fix Caddy routing: use container:port via caddy_net (DoTheEvo pattern)
Undo the host.docker.internal approach from the previous commit — proper
Docker networking routes Caddy to services by container name on the shared
caddy_net, not via the host gateway.

- lib/common.sh: configure_caddy_for_service now accepts either a plain
  port number (localhost:PORT fallback) or container:port (preferred).
  The Caddyfile entry uses the container name for direct Docker DNS routing.
- services/caddy.sh: remove extra_hosts hack; update Caddyfile template
  comments to show container_name:port format
- All service files: update configure_caddy_for_service calls to pass
  container_name:internal_port (e.g. "filebrowser:80", "mealie:9000").
  Services using network_mode:host keep plain port numbers.
- tools/manage_users.sh: new FileBrowser user-management script (deployed
  to ~/docker/filebrowser/ during installation). Manages users via the
  FileBrowser REST API: list, add, delete, passwd, scope, info commands.
  Documents username format (letters/numbers/hyphens/underscores),
  password rules (min 8 chars, letter + number required), and scope path
  convention relative to /srv (= FB_PATH on the host).

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:12:01 +00:00