Skip to content

v3.7.0 — Archives open without unpacking, and a second factor on local accounts

Choose a tag to compare

@cerede2000 cerede2000 released this 16 Sep 20:51
· 359 commits to main since this release

Archives open like folders now, without being unpacked. That is the headline of
3.7.0, and it joins the trash and file versions from 3.6.0 — the three things
this explorer does that the alternatives mostly do not. There is a
comparison table
in the documentation now, checked against each project's own repository rather
than its marketing, and it says where the others are ahead as plainly as where
we are.

Look inside an archive without unpacking it

Open a .zip, .7z, .rar, .iso, .tar or .tar.gz and it opens like a
folder: the entries with their sizes and dates, folders you can go into, and a
trail at the top to walk back. Nothing is written to disk to show it.

  • Read a file inside it. Text and code, Markdown rendered, and the images a
    browser draws on its own. Text stops at 2 MB and an image at 32 MB; past that
    the panel says the size rather than freezing the tab. A camera's raw file and
    a HEIC are not offered, because nothing converts them on this path and a name
    that opens onto a broken image is worse than a name that stayed text.
  • Take part of it out. One entry, or several ticked at once, into the folder
    the archive sits in or into a folder you pick from the same dialog the rest of
    the application uses. A folder stands for everything under it, and nothing is
    ever replaced: a name already held becomes “name (1)”, and the panel says
    which name it landed under.
  • Which formats. Whatever the image's 7-Zip reads — zip, 7z, rar, iso, tar,
    gz, tgz, bz2, xz, cab, wim, cpio, rpm, deb and more. A .tar.gz is two
    archives, so the tar inside is decompressed once into the cache and read from
    there; MAX_BROWSABLE_ARCHIVE_SIZE (2 GB by default) is the point above which
    the answer is to extract the archive instead.
  • A solid .7z is extracted once, on the second read. Measured rather than
    guessed, on a runner with a real 7-Zip: reading the first entry of a
    fifty-megabyte solid archive takes 0.02 s, the last one 1.37 s, and extracting
    the whole thing 1.41 s — so the second read is where a cache pays, and the
    first is left alone.
  • Nothing from inside an archive is ever opened as a page. The server hands
    an entry over as an attachment and tells the browser not to guess its type;
    what the panel shows, it draws itself.

Documentation: Archives

Two-factor on a local account

Without an identity provider — the simplest way to run this, and so the most
common — a password was the whole of what stood in front of somebody's files.
Settings → Two-factor now offers a QR code for any authenticator app, one
code to confirm the phone kept the secret, and ten recovery codes shown once.

  • The password alone opens nothing after that: the sign-in waits for a code, for
    five minutes, and a wrong one counts against the same lockout a wrong password
    does.
  • A code is worth one sign-in and a recovery code one use.
  • The secret is unreadable in app.db, under a key drawn beside it in
    /config/totp-key. Back that file up with the database; losing it costs
    authenticators, not accounts, because recovery codes go on working.
  • An administrator can take it off an account that lost both the phone and the
    paper — the same person who could already reset its password.

Documentation: Admin & Access

Nothing is ever replaced

Every path that writes a file now takes its name by creating it, and steps aside
when something already holds that name: uploads, copies, moves, extractions,
compressions, restores from the trash, restores of a version, and ONLYOFFICE's
“save as”. What arrives takes “name (1)”, and what was there is untouched. A
transfer that fails takes back what it placed and nothing else — a file somebody
saved into a placed folder in the meantime stays.

A restart no longer signs everyone out

Sessions outlive a restart, but the secret they are signed with was drawn again
at every start unless SESSION_SECRET was set. It is kept in
/config/session-secret now, so an upgrade, a crash or a plain restart leaves
everyone signed in. A /config restored without that file signs everyone out
once.

Changing a password ends every other session of the account, on every device,
and the identity provider's sessions with them — the one that made the change
stays, on a new cookie.

Faster with large files, and quieter on disk

  • A text file opens through a GET that answers 304 when nothing changed and
    compresses what it does send, so a large document reaches a browser's cache
    instead of crossing the network again.
  • A long Markdown document renders in slabs rather than freezing the tab, and
    the editor no longer copies the whole document on every keystroke.
  • Space is handed back rather than kept: app.db and sessions.db give back
    what deletions free, thumbnails are swept oldest first, each trash zone keeps
    its newest thousand events, expired ONLYOFFICE keys are purged, and what an
    interrupted upload left behind is removed at start.

Security and dependencies

Every advisory that reached the running container is closed: the Alpine release
whose ffmpeg is patched, the Node and 7-Zip security releases, and the vitest
patch for the mocker path traversal. exifr, unmaintained since 2021, is
replaced by exif-reader, maintained beside sharp; archiver 8 takes glob@8
and inflight out of the image. The build moved to Vite 7 and the browsers it
is built for are now a written decision rather than a default. The published
images are rebuilt every Monday against the day's distribution packages, so a
fix in Alpine reaches them without waiting for a release.

Also in this release

  • Single sign-on says whether it can work before the button is pressed, and
    tells an unreachable provider from an unconfigured one.
  • Dutch, complete.
  • An upload over the size limit no longer leaves the name it asked for behind,
    and multer's refusals answer 400 and 413 rather than 500.
  • Settings and access rules are refused when they cannot be stored, rather than
    half-written or silently corrected.
  • A thumbnail that ffmpeg never finishes is killed rather than held forever.
  • Folder sizes follow chunked uploads, and an operation's own entries are told
    from new ones even when the filesystem reuses an inode number.

What comes next

Three things the comparison says are missing here, in the order they are likely
to arrive:

  • An activity log — who downloaded what, when, from which share. The share
    counters are already in the database; the table, the retention and the page
    are not.
  • Space quotas, which the recursive folder-size index already does the
    counting for.
  • API tokens for scripts, managed per user in the settings. Token minting is
    deliberately disabled today, and a session cookie is what a script uses.

What is deliberately not coming: WebDAV, and storage protocols. NextExplorer
is a file browser, not a server — something you open and use, not something
other software mounts. What it browses is what the container was given: each
/mnt/<Label> is a volume the way a drive is one in Windows Explorer, so an NFS
or SMB share mounted on the host is already in here, without this project
speaking a protocol of its own. Both crosses in the comparison table are owned,
not pending.

Upgrading

Nothing to do. The database migrates itself to schema 21 at the first start —
the two tables two-factor needs — and an older /config is read as it is. Back
up /config (now including totp-key) before upgrading, as always.

ghcr.io/cerede2000/explorer:3.7.0
ghcr.io/cerede2000/explorer:3.7.0-lean