No description
Find a file
2024-08-24 14:15:39 -07:00
.gitea Change license to Apache-2.0 2020-10-18 13:47:52 +02:00
.github/ISSUE_TEMPLATE Shorten more templates 2021-07-18 20:43:21 +00:00
.gitlab Merge branch 'ci-revamp-2022-10' into 'next' 2022-11-02 16:47:48 +00:00
.vscode The procMacro option has long been on by default 2022-12-16 10:12:11 +01:00
complement feat: version checker 2023-07-29 21:53:57 +02:00
debian feat: version checker 2023-07-29 21:53:57 +02:00
docker Update README.md to fix typo & fix compatibility with new versions of docker compose 2023-08-27 02:14:03 +00:00
nix only listen on IPv6 since that's what conduit does 2023-07-21 12:12:37 -07:00
src BROKEN push last changes 2024-08-24 14:15:39 -07:00
tests Complement improvements 2022-10-17 18:41:45 +02:00
.dockerignore fix(ci): Only build in (remote host) docker and switch to glibc 2022-11-02 12:12:48 +01:00
.envrc add nix flake 2022-10-15 19:26:53 -07:00
.gitignore Merge remote-tracking branch 'origin/next' into complement-improvements 2023-01-26 18:19:39 +01:00
.gitlab-ci.yml ci: Fix "0 B" image size display 2023-07-04 21:13:11 +00:00
APPSERVICES.md Pre-0.3 doc adjustments 2022-02-04 18:05:24 +01:00
Cargo.lock BROKEN push last changes 2024-08-24 14:15:39 -07:00
Cargo.toml initial commit for the funny push rules 2023-10-07 13:22:26 -07:00
CODE_OF_CONDUCT.md Add Contributor's Covenant Code of Conduct 2023-01-08 02:44:25 -05:00
conduit-example.toml feat: version checker 2023-07-29 21:53:57 +02:00
DEPLOY.md Merge branch 'msteenhagen-next-patch-18830' into 'next' 2023-08-01 11:23:47 +00:00
Dockerfile chore(ci): Adjust to rust version bumps 2023-06-10 15:35:22 +00:00
flake.lock update flake.lock 2023-07-16 13:37:40 -07:00
flake.nix Revert "only use musl on x86_64" 2023-07-16 13:48:05 -07:00
LICENSE Change license to Apache-2.0 2020-10-18 13:47:52 +02:00
README.md Rework language (WIP) 2023-11-11 03:56:25 -08:00
rustfmt.toml chore: get rid of warnings 2021-03-18 18:33:43 +01:00
TURN.md Move appservice howto into whats-next; again, rename placeholder TURN url 2022-02-04 21:11:50 +01:00

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 p2.counts. 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.

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?

If you want to connect an Appservice to Conduit, take a look at APPSERVICES.md.

How can I contribute?

  1. Look for an issue you would like to work on and make sure it's not assigned to other users
  2. Ask someone to assign the issue to you (comment on the issue or chat in #conduit:fachschaften.org)
  3. Fork the repo and work on the issue.#conduit:fachschaften.org is happy to help :)
  4. 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

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