.gitea | ||
.github/ISSUE_TEMPLATE | ||
.gitlab | ||
.vscode | ||
complement | ||
debian | ||
docker | ||
nix | ||
src | ||
tests | ||
.dockerignore | ||
.envrc | ||
.gitignore | ||
.gitlab-ci.yml | ||
APPSERVICES.md | ||
Cargo.lock | ||
Cargo.toml | ||
CODE_OF_CONDUCT.md | ||
conduit-example.toml | ||
DEPLOY.md | ||
Dockerfile | ||
flake.lock | ||
flake.nix | ||
LICENSE | ||
README.md | ||
rustfmt.toml | ||
TURN.md |
Conduit
The p2 experiment
p2 (aka push v2, or piston) is an experimental push rule parser designed to be faster and flexible-er than the current push rule system!
{
"m.unread": {
"rule": "event.type in ['m.room.message', 'm.room.encrypted', 'm.room.name', 'm.room.topic'] && !('m.new_content' in event.content) && !(event.sender in account_data.'m.ignored_users')",
"actions": [],
"enabled": true
},
"m.highlight": {
"rule": "@'m.unread' && (user_id in event.content.'m.mentions'.user_ids || (event.content.'m.mentions'.room && can_notify('room')))",
"actions": ["notify", "store", "mark"],
"enabled": true
},
"m.notify": {
"rule": "@'m.highlight' || @'m.room' || 'm.direct' in state.'m.purpose'.purposes",
"actions": ["notify"],
"enabled": true
},
"m.invite": {
"rule": "event.type == 'm.room.member' && event.state_key == user_id && event.content.membership == 'invite'",
"actions": ["notify"],
"enabled": true
}
}
what?
p2 is composed of counters, rules, and actions. Each counter has one rule and n actions. In the above config, there are four counters. When a rule matches an event, that counter is incremented.
Actions specify what actions the server should take when a counter is
incremented. Currently, there is notify
for sending a push notification,
store
for storing notifications in a list for later (/notifications
),
and mark
for adding a mark to an event's unsigned content. Perhaps
count
could be split out from counters into its own action later on.
Instead of having a separate set of apis and /sync
field for
notify/highlight counts, p2 takes place entirely in account data. Rules
are specified via the p2.rules
event and unread/notify counts are set
by the server in Update: to fix threads and a few other
issues, counters are moved back into unread_counts. Per-room account
data can override global push rules.p2.counts
.
The rules aren't mean to be machine-edited - make them read from account data instead.
This implementation of p2 takes the ruleset and precompiles it to stack-based bytecode-ish intermediate representation, which is then evaluated on all new events. It lazy loads state events and account data. Most of the code is in a single file currently.
why?
Matrix push rules in their current state are a crime against humanity. They're overengineered, yet aren't able to do things like telling you when a rooms has unread messages. Rules are evaluated in an awful home grown json thing that is not jsonpath nor jsonschema but more limited than either.
All rules go into a single giant mess of an object - per room account data apparently doesn't exist. Rules are split into override/sender/content/room/underride for no rhyme or reason. Want a room to be muted? That rule goes in "override". Want a room to notify for all messages? That rule goes in "rooms"!
Rules are hardcoded to either be notify
or highlight
. There's no way
to make custom/extensible rules, so counters/rules that don't exist in
spec (ie. unread
) can't be implemented or worked around.
why not?
The most obvious reason: this breaks compatibility with everything else in the matrix ecosystem, so it requires forking and modifying clients. This takes varying amounts of effort and can become incompatible or out of sync with upstream.
In terms of implementation, this system is very much a work in progress
and syntax/rules may change and break. The code is a mess, and doesn't
properly handle read receipts nor does it atomically update the
p2.counts
config event. It also isn't very performant in its current
state, needing an extra db lookup for every event to check for marks.
This system requires m.mentions
to be in plaintext, which some people
may not want.
spec?
This is a custom system that exists outside of the official matrix client-server spec. If a version of p2 gets merged into the official spec it would be wonderful, but unfortunately it would be a pipe dream.
rant
Matrix is has so much potential as a general purpose protocol or event an instant messaging protocol, but so many features seem to be poorly designed. There are so many rough edges that it's hard for me to recommend it to anyone who isn't willing to spend a bit of time working around its idiosyncraties.
I strongly believe m.mentions
shouldn't have been encrypted, as a
form of it is functionally required by servers to accurately send
push notifications. It's frustrating that mentions are critical to
push notifications, but are one of the only pieces of metadata that
are encrypted. Unfortunately, mentions probably won't be moved to
plaintext.
I know I should probably be happy that matrix is fixing its chronically
bad plaintext leaks, but this really shouldn't have been done.
On the other hand, state events like name/topic/avatar, which if
encrypted will have difficulties with /hierarchy
or summaries, aren't
as critical or can be worked around. Reactions are also plaintext, though
the reaction keys could be encrypted. Room member nicknames/avatars are
stored as plaintext, assuming they aren't clobbered when a user changes
their global displayname/avatar_url.
All these little things add up to a frustrating experience. Despite all that, I'm very hopeful for matrix and it's probably the best option that exists.
original readme below:
A Matrix homeserver written in Rust
What is Matrix?
Matrix is an open network for secure and decentralized communication. Users from every Matrix homeserver can chat with users from all other Matrix servers. You can even use bridges (also called Matrix appservices) to communicate with users outside of Matrix, like a community on Discord.
What is the goal?
An efficient Matrix homeserver that's easy to set up and just works. You can install it on a mini-computer like the Raspberry Pi to host Matrix for your family, friends or company.
Can I try it out?
Yes! You can test our Conduit instance by opening a Matrix client (https://app.element.io or Element Android for
example) and registering on the conduit.rs
homeserver. The registration token is "for_testing_only". Don't share personal information.
Server hosting for conduit.rs is donated by the Matrix.org Foundation.
What is the current status?
Conduit is Beta, meaning you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.
There are still a few important features missing:
- E2EE emoji comparison over federation (E2EE chat works)
- Outgoing read receipts, typing, presence over federation (incoming works)
Check out the Conduit 1.0 Release Milestone.
How can I deploy my own?
- Simple install (this was tested the most): DEPLOY.md
- Debian package: debian/README.md
- Nix/NixOS: nix/README.md
- Docker: docker/README.md
If you want to connect an Appservice to Conduit, take a look at APPSERVICES.md.
How can I contribute?
- Look for an issue you would like to work on and make sure it's not assigned to other users
- Ask someone to assign the issue to you (comment on the issue or chat in #conduit:fachschaften.org)
- Fork the repo and work on the issue.#conduit:fachschaften.org is happy to help :)
- Submit a MR
Thanks to
Thanks to FUTO, Famedly, Prototype Fund (DLR and German BMBF) and all individuals for financially supporting this project.
Thanks to the contributors to Conduit and all libraries we use, for example:
- Ruma: A clean library for the Matrix Spec in Rust
- axum: A modular web framework
Contact
If you run into any question, feel free to
- Ask us in
#conduit:fachschaften.org
on Matrix - Write an E-Mail to
conduit@koesters.xyz
- Send an direct message to
timokoesters@fachschaften.org
on Matrix - Open an issue on GitLab
Donate
Liberapay: https://liberapay.com/timokoesters/
Bitcoin: bc1qnnykf986tw49ur7wx9rpw2tevpsztvar5x8w4n
Logo
Lightning Bolt Logo: https://github.com/mozilla/fxemoji/blob/gh-pages/svgs/nature/u26A1-bolt.svg
Logo License: https://github.com/mozilla/fxemoji/blob/gh-pages/LICENSE.md