Repository navigation
Releases: kubuno/chat
Release list
v0.1.9
Changed
-
Visual Studio solution versioned with the repository (
Kubuno.Chat.slnx, generated by vskubuno, the naming of
every Kubuno repository): the server is the projectKubuno.Chat.Server, the frontendKubuno.Chat.Web, in
the solution folders Server, Libraries and Frontend, with the shared launch profile "Chat (Kubuno Core + browser)".
The crate and npm names do not change. -
Runs on PostgreSQL, MySQL/MariaDB or SQLite. Chat moves off its
PostgreSQL-only stack onto the runtime-dispatch kubuno-db 0.6.0 foundation:
the same binary connects to whichever engine the administrator names in
[database] engine, read at start-up. All queries were rewritten off the
driver-specific paths —RETURNINGinserts became a Rust-minted id plus a
re-select (MySQL has noRETURNING),ON CONFLICTand case-insensitive
matching go through the dialect layer,= ANY(array)becomes a portable
IN (...),NOW()/make_interval/'-infinity'are computed in Rust and
bound,LEFT JOIN LATERAL(unsupported by MariaDB/SQLite) becomes a
correlated subquery, and every integer read is decoded at a width that holds
on a strict PostgreSQL. Events are published through kubuno-db, which uses
pg_notifyon PostgreSQL and a durable outbox the core polls on the other
engines. The one-time-prekey claim no longer relies onFOR UPDATE SKIP LOCKED; it is a guarded update proven by its affected-row count.
(Cross-schema reads ofcore.users/core.settingsremain PostgreSQL/MySQL
only, as they touch another module's namespace.)
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). -
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. -
Media downloads no longer fail for recipients. The access check read a
SELECT 1probe at a width PostgreSQL rejected, so every non-uploader saw a
database error and a permanent "media unavailable"; the check is now decoded
portably and passes for anyone in the conversation.
Security
-
The real-time connection no longer puts your access token in its URL: it presents a one-minute
signed ticket, fresh at each reconnection. Leaving a meeting page while a provisional conversation is
open now authenticates its clean-up with your session instead of a cookie. Requires a Kubuno core that issues signed tickets (POST /api/v1/auth/tickets) and@kubuno/sdkwith the signed-URL helpers. -
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. -
Database driver updated past an unfixable advisory. The previous line
pulled in an RSA implementation vulnerable to a timing side-channel
(RUSTSEC-2023-0071) for which no fix will ever exist. The new line does not
depend on it at all, and it refuses any SQL string built at run time unless it
has been audited — the queries here were checked and marked. -
Input validation library updated. The version in use carried
RUSTSEC-2024-0421 through its domain-name parser, which accepted Punycode
labels that decode to plain ASCII — a mismatch an attacker can use to make two
different names look like one.
v0.1.8
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.7
Added
- Chat offers its two acts wherever a person is shown. A guest's card on a
calendar event now carries "Chat" and "Start a meeting", performed by this
module. Offered only for someone with an account on this instance: there is
nobody to talk to behind an outside address, and a button that always fails is
worse than an absent one.
Added
- A meeting attached to an event carries that event's title. Renaming it in
the meetings list renames the event too, and renaming the event renames the
meeting — one title in two places instead of two that slowly disagree. Linked
meetings show a small link mark beside their name, so the consequence is
visible before you type. A meeting whose event lets it go (the call was taken
off it, or the event was deleted) keeps its name and becomes its own again;
its link goes on working.
Changed
-
Joining the call from an event opens it in a new tab. The link followed
in place, so reaching the meeting meant abandoning the event you were in the
middle of writing. The call also outlives the visit to the event: it belongs
in a tab of its own. -
The video-call card in an event carries no camera of its own. The row's
gutter already shows this module's mark, and the card says in words who hosts
the call; a camera an inch away was decoration, not information.
Added
-
A meeting room attached to an event you never save no longer survives it.
Adding a video call to an event has to create its room straight away — the
link is what gets saved, so it must already point somewhere. Until now that
room stayed for good, even when the event was abandoned: closing the form
without saving, or taking the call back off it, left an empty meeting in your
list that you never knowingly created. A room created that way is now a draft
and belongs to the form: taking the call off the event or closing the form
deletes it, saving the event keeps it. Reloading the page, closing the tab,
losing the network or crashing needs no cooperation either — the room carries
its own deadline and the server removes it on its own. A draft room never
shows up in anyone's meeting list while it is one, and a room somebody has
already joined or written in is never removed by any of this. -
The Meetings page lets you review and manage each meeting without joining
it. Clicking a meeting used to drop you straight into its call. Now a plain
click opens a details panel on the right instead: the day and time, the member
list, and a plain transcript of everything said in the meeting — so a past
meeting can be read back at a glance. Joining is now an explicit Join
button, which appears on a row on hover and also sits at the bottom of the
panel. -
Meetings can be deleted from the Meetings page. Each row now carries a
delete button (and one in the details panel too), removing the meeting from
your list after a confirmation. Every row also has a right-click / “⋮” context
menu — Join, details, copy link, delete — a starting set we will keep
extending. -
Select several meetings and act on them at once. A checkbox appears on
each row (on hover, or once a selection is under way); Ctrl/Cmd-click toggles
a row and Shift-click extends a range. A toolbar then shows how many are
selected, with Select all, Copy links and Delete — the deletion
asks once for the whole set. -
A meeting's options no longer look forbidden to the person who owns
them. The settings that depend on host management were greyed out until it
was switched on — which reads as "you may not", and a host quite reasonably
asked why they were refused their own meeting. Nothing is greyed now: the
settings can be prepared at any time, and a line under the master switch says
they take effect once it is on. -
A meeting can record itself. Its options gained a second section,
Meeting recordings: the legal warning — recording without everyone's
permission may be illegal — and one choice, "Record this meeting". Ticked,
the room starts recording on its own as soon as someone allowed to record is
in it, and everyone is told as they always were. It starts once per room: a
reconnection does not start a second one, and a host who stopped it on
purpose does not see it start again under them. The consent step did not
disappear — it moved to where the decision is made, under the same warning,
because asking twice for one decision teaches people to dismiss the asking. -
A meeting can run ACTIVITIES, and its host decides who may start one.
An activity is something one person launches and everyone gets — a file put
in front of the room, and whatever other modules come to offer: any module
may register one, and the room lists what it finds. Nothing is hard-wired;
when nothing is registered there is no activities menu rather than an empty
one. The host may reserve launching for themselves. -
The meeting's audio and video have exactly one door, and the host holds
the key. The media never touches a server here — it is exchanged directly
between browsers — so there is one function through which anything else in
this product could obtain it, and the host's setting is checked at that
function rather than by whoever calls it. -
A meeting can be closed to whoever merely holds its link. Its access type
is now a choice: Open — the link is enough, as it has always been — or
Open to trusted people, where only those the host put in the room walk
in. Everyone else is refused by the server, and may ask to join when the host
allows it: they see a page that sends one request and waits, the host sees
them queued inside the meeting and admits or refuses them in one press, and
being admitted puts them in the room there and then. Asking twice is asking
once. Refused twice, they may not ask again — a door that can be knocked
on forever is a way of knocking until someone gives in; from there only the
host adding them opens it. -
A meeting's host can set its rules before it starts. The ⚙ on the event's
meeting card opens the video call options: host management, who may share a
screen, who may send reactions, whether participants may write in the
meeting's chat, and whether the host must arrive before anyone else. Off by
default — the master switch has to be turned on before any of the others
apply, so a meeting stays open unless someone decides otherwise. Only the
host sees the panel, and only the host may save it: the server checks, it
does not merely hide the button. Chat moderation and "host joins first" are
refused by the server; screen sharing and reactions are enforced by the room
itself, because the media travels directly between participants and no
server stands in its path — each switch says which it is. -
A calendar event can carry a Kubuno video call, created in place. When
this module is installed, the video row of the calendar's event editor is
its own, and the row's icon becomes this module's logo: one button creates
the room and attaches its link; the event then
shows a card naming the call, with its full address, a copy button and a ✕
that takes it away — an event holds one call at a time. A link pasted from
elsewhere gets the same card, without the pretence that we host it. The
room is a conversation anyone holding the link may join; it is not deleted
when the link is removed, since an edit may be abandoned and a link already
shared is not cheap to break. -
The meeting's messaging is the conversation itself. It was a bare list of
lines with no author: you could not tell who had written what. It now loads
the history, so someone joining midway reads what was already said, groups
messages by author with a picture, a name and a time, and renders them with
the same component as the rest of the app — attachments, images, polls,
replies, reactions and link previews all work. Files can be attached and
emoji picked without leaving the meeting. -
The meeting shows who is speaking. The tile of whoever has the floor is
outlined in blue, tinted with a faint blue veil, and wears a small badge
whose three bars follow their voice. It is heard from the audio itself, so it
works for everyone in the meeting, and someone whose microphone is off is
never shown as speaking. -
Meetings can be recorded. The person who holds the meeting can start a
recording from the meeting menu. Everyone is told when it starts and stops,
and a red REC indicator with a running time stays visible throughout — a
recording is never silent. The file captures the presentation when someone is
sharing and the participants otherwise, with every voice mixed in, and it is
filed in the recorder's own files when the recording stops, in a "Chat"
folder created on first use — it belongs to whoever made it. Without a files
module to write to, it is posted to the meeting's conversation instead so it
is never lost. It is stopped automatically if the meeting ends, and after two
hours. -
A page follows leaving a meeting. Instead of dropping straight back into
the app, leaving a meeting now leads to a page offering to rejoin it or go to
the home screen, and asking how the audio and video quality was. It returns
home on its own after a minute. The rating is kept, one answer per person and
per meeting, and a later answer replaces the earlier one. -
Ending a meeting is now distinct from leaving it. The host of a meeting —
whoever owns or administers the room — is offered both when they hang up:
leaving lets the others carry on, ending closes the meeting for everyone at
once and the page that follows says so and offers no way back in. Everyone
else simply leaves. -
Host moderation. From the participants panel, a host can mute someone or
remove them from the meeting. A host can only mute: tu...
v0.1.6
Changed
- Theme tokens: two colours for navigation labels (
--color-text-nav,
--color-text-nav-active). Every module carries the same token sheet, so the
values must match across them — whichever bundle loads last would otherwise
win. No visible change inside this module.
Added
- A mini-panel for the shell's right rail: conversations with their unread counts,
to see who is waiting and jump into the thread.
Changed
- 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.