File explorer
[admin]
listen = "0.0.0.0:8080"
bearer_token = "changez-moi-en-production"
[api]
enabled = true
prefix = "/api/v1/files"
[api.ui]
enabled = true
path = "/files"
The page is at http://serveur:8080/files.
Options
Both keys are read at startup. All the keys:
Reference [api.ui].
What the page does
The page is a client of the REST file API, and of nothing else. It has
no rights of its own: what the ACL refuses, the API refuses, and the page shows
the server’s detail.
| Action | Request | Right |
|---|---|---|
| sign in | GET <prefix>?rights | - |
| open a folder | GET <folder>?list&offset=&limit=200, then ?rights | list |
| download | POST <file>?ticket, then the returned URL handed to the browser | read |
| upload | HEAD <file> (“Replace file?” if it exists), then a streamed PUT | write |
| new folder | PUT <folder>?mkdir | write |
| rename | POST <path>?rename=<destination> | rename |
| delete | DELETE <path> | delete |
- A button whose right is missing on the current folder is grayed out.
- Requests go one at a time, plus the upload in progress, to stay under
[auth] hash_per_addresswithBasic. - Uploads go one file after the other, with a progress panel (name, percentage, throughput, cancel).
- The list is paginated by 200, sortable by name, size or date, folders first.
- The current folder is in the URL (
#/rapports/2026): back, forward and links work.
Signing in
Username and password (Basic, local user), or “Use a token
instead” (Bearer, a JWT). The credential stays in memory only:
reloading the page signs you out. Only the theme is kept (craft-admin-theme).
Failures count for [api.ban].
Mounts
The page starts at /, the home that GET ?rights returns. A mount at /
shows its home_dir there; mounts under names show the
synthetic root that lists them.
| Entry | Display |
|---|---|
| mount point | storage icon, mount label; opens like a folder |
| synthetic directory | ordinary folder; upload, rename, delete grayed out |
Downloading: the ticket
A browser link carries no Authorization header: the page asks for
a ticket (this file, this user, ten minutes; see
The file API), then the browser
downloads as a stream. During those ten minutes, “Retry” and the browser’s
resume reuse the same URL.
The page’s files are public, under the same CSP as the console; the data goes through the API.
Limits
| Limit | Effect |
|---|---|
| no upload resume | an interrupted upload must be redone; a download restarted after ten minutes needs a new click |
| no preview or editing | no share link, no archive of a folder |
Basic behind a shared address (NAT) | users share hash_per_address; declare the proxy in api.ban.trusted_proxies, or sign in with a JWT |
Interface in English or French (?lang=fr, otherwise the browser’s
language); under 720 px, the actions move into a menu.