Repository navigation
Releases
v0.1.12
Changed
- Visual Studio solution versioned with the repository (
Kubuno.Drive.slnx, generated by vskubuno, the naming of
every Kubuno repository): the server is the projectKubuno.Drive.Server, the frontendKubuno.Drive.Web, in
the solution folders Server, Libraries and Frontend, with the shared launch profile "Drive (Kubuno Core + browser)".
The crate and npm names do not change.
Fixed
-
Files kept on the server's local storage are found again on Windows and under symlinked storage
roots (shared storage layer updated to kubuno-storage 0.1.2). -
MariaDB and Oracle MySQL installs use the migrations written for them. The module now runs its
mysql-mariadbormysql-oraclemigration set when the database is MariaDB or Oracle MySQL, instead of the generic MySQL set. -
Drive starts on MySQL and MariaDB again. Migration 2 ("one live file per
name and folder") declared its uniqueness key as aSTOREDgenerated column
overfolder_id, whose foreign key isON DELETE SET NULL; both servers refuse
that (MySQL 8 with error 1215, MariaDB with error 1901), so the module stopped
at start-up. Each server now runs a variant of that migration
(migrations/mysql-oracle/,migrations/mysql-mariadb/) that declares the
columnVIRTUAL— same key, same unique index, same rule. The variants are
recorded under the original checksum, so nothing changes for a database that
already applied the migration. If an earlier start failed on it, delete the
failed row once (DELETE FROM drive._sqlx_migrations WHERE version = 2 AND success = 0) and restart. -
Database migrations keep the same checksum on every OS. The repository now
pins line endings to LF (.gitattributes), so a checkout on Windows no longer
turns SQL migrations, scripts, manifests or sources into CRLF. A database
migrated by a Linux build is therefore no longer refused by a Windows or macOS
build of the same version because its migration checksums differ. -
Merging two folders keeps the trashed files of the merged folder. Moving
or renaming a folder onto a same-named one (with "merge") used to drop the
source folder's trashed files; they now move into the destination and stay in
the trash, restorable, without overwriting anything there. -
Restoring a file whose name is now taken keeps both files. The restored
file comes back under a unique name (report (2).pdf) next to the file that
took its name. -
Storage quota is charged back exactly once when files are deleted for
good. Emptying the trash freed nothing from the quota, and the automatic
trash clean-up and permanent deletes left the space used by version history
counted forever. File and version sizes are now released together, once, and
the version history's stored copies are removed too. On SQLite installations
the quota counter was not updated at all; it now is. -
Renaming or moving a folder keeps every file pointing at its contents,
including files stored under a different name on disk; if the database step
fails, the folder is moved back on disk. -
No more duplicate copies of the same file. Two saves of a new document
arriving together (office drafts, Flow, App, PaintSharp files), or a save
racing the disk scan, could each create a file with the same name in the same
folder, often over one stored copy. A folder can now hold only one live file
per name: a concurrent overwrite updates that file, a concurrent upload gets a
numbered name, and the disk scan skips names already in use. Existing
duplicates are merged on upgrade: the most recently saved copy is kept, the
others' version history, shares, comments, tags, activity and star move to it,
and a duplicate with different contents becomes a version of the kept file —
nothing is deleted.drive:fscklists any that remain (--merge-duplicates). -
Module file registration with "overwrite" no longer deletes the contents it
registers. Re-registering a file at the location just written deleted the
previous record and, with it, those very bytes; the record is now updated in
place. -
Drive builds from a clean checkout again. The lockfile pinned two shared
crates (kubuno-modauth,kubuno-storage) to commits that no longer exist on
GitHub after their tags were moved, so a freshcargo buildcould not fetch
them. The lockfile now points at the commits the tags currently resolve to. -
Drive is fully translated again. English (and other non-French) users saw a
French "Mon Drive" page title and a French "Deux volets" entry, because the
title used a translation key that existed in no language and the two-pane view
had no translations at all. Both are now translated in every supported
language.
Added
- Downloads answer byte-range requests (
206 Partial Content,Accept-Ranges: bytes), so a video
or an audio file can be sought without downloading it again, and a PDF viewer can fetch only the pages
it shows. - Drive now runs on PostgreSQL, MySQL/MariaDB or SQLite. The database engine
is an administrator's choice, set in configuration ([database] engine) and
read at start-up; the same build connects to whichever is named. SQLite needs
no server at all, which turns a single-machine or evaluation install into a
one-line affair. Existing PostgreSQL instances keep working unchanged. - Open Drive in Visual Studio. The repository now ships a ready-made solution
(Kubuno.Drive.slnx) with the server and frontend projects and a launch profile
that starts both, so contributors can build and debug Drive from Visual Studio
without generating the solution first. Per-machine files (obj/,.vs/, user
settings, the local SDK feed) stay out of version control. drive:fsckmaintenance command.kubuno-drive drive:fscklists the
files and versions whose contents are missing from storage and the files that
share one stored copy, account by account (--owner,--json). It changes
nothing unless asked:--split-sharedgives each file its own copy, and
--trash-missingmoves files whose contents are gone to the trash, where
their owner can see them. It exits with code 2 when it finds a problem.
Changed
- File search reworked to behave identically on every database. A file's
name and extracted text are reduced to their word stems (with accents folded)
when the file is indexed, and a query is matched the same way, so a search
returns the same results and the same ranking whichever engine backs the
instance. Approximate "typo" matching on names is no longer offered.
Security
-
The storage rescan is no longer reachable without authentication. The
maintenance route that re-synchronises files on disk with the database (adding
and removing entries) could be triggered by anyone, including through the
public API. It now requires the module's internal secret and is refused to
clients. Internal calls are compared in constant time and refused when the
module has no internal secret configured. -
Thumbnails, previews, the video and audio players, downloads (files, archive members, fonts) and the
image editor no longer rely on the access-token cookie the web client used to keep readable by page
scripts. They load with short-lived signed tickets bound to your session and to the exact file.
Saving from the image editor now uses your session instead of a token read from local storage.
Requires a Kubuno core that issues signed tickets (POST /api/v1/auth/tickets) and@kubuno/sdkwith the signed-URL helpers. -
Deleting a folder for good no longer leaves broken files behind or destroys
other files' contents. A permanent folder delete (Shift+Delete, deleting from
the trash, the WebDAVDELETE, the module and admin APIs) moved the folder's
files to the root of the drive while wiping the folder's directory on disk, so
those files showed up at the root with their contents gone, and any other file
whose bytes happened to live in that directory lost them too. The whole folder
is now deleted consistently — subfolders, files (trashed ones included),
version history and thumbnails — and the bytes are only removed after the
database change is committed and only when no remaining file still uses them. -
Emptying the trash, or deleting a trashed file for good, no longer erases a
live file with the same name. A file uploaded under the name of a trashed
file in the same folder shares its storage location; purging the trashed copy
deleted the live file's contents. Shared contents are now kept. -
A new file no longer takes over the contents of a trashed file with the same
name. Uploading, creating, renaming, moving, copying or restoring a file
under the name of a trashed file in the same folder wrote over the trashed
file's contents, so restoring it brought back the wrong data. Every file now
gets a storage location that no other file or version uses; the name shown in
Drive is unchanged. -
File and folder names can no longer escape their folder. A rename to a
name such as../../other.txt, or a folder name containing\(a path
separator on Windows), could place bytes outside the folder, or even outside
the account's own storage. Such names are now refused. -
Security fixes from the shared database layer (kubuno-db 0.9.0). The
database password can no longer appear in a log through the debug output of
the database settings. A search now keeps at most 16 distinct words (set for the
whole instance by the core's[search] max_terms), so a single request can
no longer overload the database. -
PDF and XML readers updated to patched releases. The PDF text extractor
could be made to overflow the stack by deeply nested objects
(RUSTSEC-2026-0187), and the XML reader could be driven into quadratic time or
unbounded memory by a crafted document (RUSTSEC-2026-0194, RUSTSEC...
v0.1.11
Security
- HTTP/2 layer updated to a patched release.
h2moves from 0.4.15 to
0.4.19, closing a denial of service through unbounded empty DATA frames
(RUSTSEC-2026-0258). - Error library updated to a patched release.
anyhowmoves from 1.0.102
to 1.0.104, closing an unsoundness inError::downcast_mut()
(RUSTSEC-2026-0190). - TLS library updated to a patched release. The pinned
rustlscarried
RUSTSEC-2026-0285 (medium). Every outbound HTTPS connection goes through it.
v0.1.10
Changed
-
This module now installs as a Kubuno package (
.kbpkg) only. Its system
packages (Debian/RPM and the Windows and macOS installers) are no longer
built: the module is distributed as one.kbpkgper platform (Linux, Windows,
macOS) that the Kubuno server installs itself — from the admin console, or
offline withkubuno modules:install <file>.kbpkg. -
The storage client now reaches the files service through the core, not
directly. Editor modules (documents, notes, and the like) talk to file
storage through this crate'sFilesClient. It used to call the files module
on its own port; on a deployment where each module holds only its own derived
secret, that direct call is rejected and file operations fail. The client now
sends every request to the core, which authenticates the caller and forwards
it to the files service on their behalf. Callers pass the core's URL when they
build the client instead of the files service's URL; nothing else about how
they use it changes. This also works unchanged on single-secret deployments. -
Dates are formatted by the platform now, not by a library.
date-fnsis
gone from this module: the shared SDK exposes helpers built onIntl, which is
localised for every language we ship and needs no locale bundle loaded. Call
sites say what a date is FOR —formatDate(d, 'date')— and the platform
decides how to write it, so a reader in Japanese no longer gets a French
layout. Machine formats (keys,<input type="date">values) go through
toISODateand friends, built from local calendar fields so the day cannot
shift near midnight. -
Class names are composed by
cn()from@ui, replacingclsx. One less
dependency for a dozen lines of finished logic; call sites are unchanged. -
The RPM package now names the same maintainer as the Debian one. Its
changelog entry used a placeholder address on a domain the project does not
use; it now matches the maintainer of the.deb, on the project's own domain.
Nothing about what the package installs changes. -
The package maintainer address moved to the project's own domain. The
Debian package'sMaintainerfield now uses an address on the project's own
domain. Nothing about what the package installs changes. -
Security reports now go to an address on the project's own domain. The
address published inSECURITY.mdmoved to that domain; the previous one is
retired. Reporting through GitHub Security Advisories is unaffected. -
The README now opens with the module's logo. The public README on
GitHub now shows the module's designer logo (the same PNG shown as the
browser tab icon and in the applications menu) at the top of the page — the
repository landing now matches the icon a signed-in user sees inside the
platform. The image ships in-repo, under.github/logo.png, so it renders
even when the repo is browsed offline. -
New Drive logo — a blue isometric stack of platters with a white top
face and gold tabs, used as the browser-tab icon and in the applications
menu. It is now raster (PNG) designer artwork. -
Classic window-caption glyphs on the floating audio player. Expand is a
plain square and reduce two overlapping squares, instead of diagonal double
arrows. -
The advanced-search panel and the search bar now stay in sync both ways.
Opening the panel pre-fills the "Contains the words" field with the bar's
current text, and editing that field rewrites the bar's text live (running
the search as you type, exactly like typing in the bar). Drive's search is
plain free text — the other panel fields (type, owner, location, dates…) are
structured filters with no text representation, so they intentionally stay
panel-only. "Reset" now also clears the search bar's text.
Fixed
- Folders whose stored path drifted from their name are repaired on start.
A folder's path is stored, not recomputed on read, and the rename that keeps
it current refuses protected folders — so a protected folder renamed by a raw
database write (as happened to an application's own protected folder during an
earlier rename) kept a path from its old name. Two folders could then claim the
same local path, and desktop sync clients would materialise neither, leaving
files that were present on the server missing on the machine. The drive now
reconciles these paths at startup: it recomputes each folder's path from its
parent and its name and relocates the folder's files one by one, never as a
whole directory, so a file that a neighbouring folder happens to share on disk
is left untouched; where two records point at the very same stored file the
content is copied rather than moved, so neither record breaks. When a folder is
moved off a path it had been sharing, the neighbour that legitimately keeps that
path is re-published as well, so a client that had collapsed the two onto one
local location restores the neighbour's files instead of losing them. The pass
is a no-op on healthy instances and its corrections flow to clients on their
next sync, so the missing files reappear without any manual step.
v0.1.8
Fixed
- The quality gate rejected the font-name reader. A lint introduced with a
newer Rust compiler refused reading UTF-16 name records two bytes at a time
throughchunks_exact; the pair is now read as a fixed-size array, which says
the same thing without indexing.
Fixed
- The package could not be built where
zipis absent. The Windows job of
the continuous integration has nozip, so the Windows package was simply lost
the first time it was attempted — a script failure, not a build failure. The
builder now falls back to 7-Zip, then to PowerShell.
v0.1.7
Added
- Drive now also ships a
.kbpkg— the single package format a Kubuno
server installs by itself, identical on every system. It carries the same
binary, interface and manifest as the.deb, arranged the way the server
expects to find a module on disk, plus aSHA256SUMSso an offline copy can
be checked without the catalogue. Nothing changes for existing installations:
the system packages are still published, and a catalogue that sees both simply
prefers the new one. Drive is the pilot for this format; the other modules
follow once it has proven itself.
Fixed
- A built package could be thrown away instead of published. The job that
attaches a package to the release waited ten minutes for another workflow to
create that release, then gave up with "release never appeared — build.yml
likely failed". The diagnosis was wrong: on a repository whose.debtakes
longer than ten minutes to build, the release simply did not exist yet, and a
package that had built perfectly was discarded. Four modules reached v0.1.6
with packages missing for some systems because of it. The job now creates the
release itself when it is missing, so it no longer depends on another workflow
finishing first.
Added
- Security policy and CI quality gate. A
SECURITY.mddocuments how to
report vulnerabilities, and a CI workflow enforcesclippy -D warnings, a
dependency-vulnerability audit (cargo audit) and the frontend typecheck/tests.
Security
- Drive now authenticates proxied requests from a signed token instead of
trusting plain headers. User routes require a validX-Kubuno-Authtoken
minted by the core with this module's internal secret (seekubuno-modauth),
rather than readingX-Kubuno-User-*headers at face value — which any process
reaching Drive's loopback port could otherwise forge to act as any user.
Changed
- Opening Drive now lands on "Accueil" instead of My Drive. The app's launch
target is its Home hub (/drive/home); My Drive stays at/drive, reachable
from the sidebar and by every existing folder link. - Home screen reworked to stop echoing "Recent". Its file section no longer
replays the opened-file journal; it now surfaces a curated blend — files you
recently modified, starred files, and files recently shared with you —
distinct from Recent. Folders and files render through the shared explorer, so
their cards, view modes, sort bar and context menu are identical to every other
Drive view, and the page now uses the full width. The in-page search box was
removed (the header search already covers it); the quick filter chips stay.
v0.1.6
Added
- "Home" landing screen. A new Accueil entry tops the sidebar (above
"My Drive") and opens a welcome page in the spirit of the major cloud drives:
a centered "Welcome to Drive" banner, a wide search box, quick filter chips
(Type / Owner / Modified date / Location), a Suggested folders row (the
folders you recently worked in) and a Suggested files grid (recently
opened items, with a list/grid toggle and a "See more" link). Typing a query
jumps straight to the results; a chip narrows the whole drive; a card opens
the file in its app or preview, or the folder in the explorer. On phones it
keeps the existing tabbed home. - Remote mounts can be edited. A pencil on each mount opens its settings:
everything but the secrets comes back filled in, and a password left blank
keeps the stored one — correcting a host no longer means retyping credentials. - "List the server's shares" in the SMB form. It asks the server and shows
each share's real name beside its description, which is the distinction that
makes a mount work: a share calledbackupsmay be described as
"Nightly Backups", and entering the description fails with "share not found". - Platform fonts shipped with the module: 20 open-licensed font files (Google Sans
Text, Google Sans, Roboto, Google Sans Flex, Roboto Flex, Inter, DM Mono — variable
where a variable release exists) are embedded in the binary and seeded into
System/Fontsat startup, marked protected: they cannot be deleted, administrators
included. The seed is idempotent and refreshes a seeded file in place when the
embedded binary changed (protected files cannot be replaced through the API, so
corrections can only arrive this way). - Self-hosted font endpoints:
GET /fonts/css2?family=…&display=swap
generates@font-facerules from the actual binaries inSystem/Fonts(family,
weight and stretch ranges read from theirname/fvar/OS-2tables, cached), and
GET /fonts/files/:idserves the bytes with ETag/304 and day-long caching. Both are
unauthenticated on purpose — stylesheet fetches carry no credentials and the surface
only exposes the shared fonts directory. Any font an administrator drops into
System/Fontsbecomes servable the same way. - Fonts explorer: protected fonts show a "Police système" chip and never offer
deletion; the embed page now leads with a<link>/@importto the instance's own
css2 endpoint, the raw@font-facerules remaining as an alternative. - A mini-panel for the shell's right rail: recent and starred files, to reach a
document without leaving what you are writing.
Changed
- New Drive logo.
- Remote storage panel: a floating window instead of a full-height drawer,
so the files being worked on stay visible behind it. It also opens from every
Drive screen now — from a remote mount it used to set nothing on screen until
you navigated back to My Drive. - Provider icons are the official brand marks (Nextcloud, ownCloud, Google
Drive, Dropbox, Windows) in their own colours, instead of emoji that showed
the same cloud for Nextcloud and ownCloud. Protocols without a brand (WebDAV,
SFTP, FTP, NFS) keep a neutral glyph. - Search view: twice as much space between tiles in the icon views, matching
the main explorer. - Selection tick badges no longer sit on file and folder cards.
- The fonts search bar follows the new default background (
#e9eef6). - The dual-pane explorer's splitter is a 5px hairline with a grip pill on hover, like
every other resize handle. - Default application background token aligned with the core (
--body-bg#f8fafd). Only
visible when the module runs standalone: inside the shell the active theme sets it. - Search bar background now comes from the
--color-search-bgtoken (unified at#e9eef6)
rather than a hard-coded colour. - New
--color-viewer-backdroptoken for the full-screen preview backdrop.
Fixed
-
A broken mount advertised itself as "Connected". Its real state and the
reason are now shown on the mount, and browsing it explains what to do rather
than failing silently. -
The Fonts view's toolbar (search, sort, selection bag) had
become unreachable behind the header's magnifying-glass search mode; it is pinned
inline again.