This adds support for listening on a Unix socket for administrative
connections, that then use a simple protocol for communicating with
the service (BouncerServ) as an administrator with a global context.
The wire format used by the Unix socket is IRC, but without
registration or overheads.
Example session:
>>> BOUNCERSERV
<<< 461 * BOUNCERSERV :Not enough parameters
>>> BOUNCERSERV :n s
<<< :gensou FAIL BOUNCERSERV :this command must be run as a user
>>> BOUNCERSERV :u s
<<< :gensou PRIVMSG * :marisa: 2 networks
<<< :gensou PRIVMSG * :alice: 1 networks
<<< :gensou BOUNCERSERV OK
This can be used to disable password authentication for a user.
This is useful to prevent a disabled user account from being
auto-enabled when enable-user-on-auth is on.
Add a new flag to disable users. This can be useful to temporarily
deactivate an account without erasing data.
The user goroutine is kept alive for simplicity's sake. Most of the
infrastructure assumes that each user always has a running goroutine.
A disabled user's goroutine is responsible for sending back an error
to downstream connections, and listening for potential events to
re-enable the account.
This lists all the users of the instances, along with the number
of networks they have.
Limited to 50 users to avoid flooding with thousands of messages
on large instances.
The soju username is immutable. Add a separate nickname setting so
that users can change their nickname for all networks.
References: https://todo.sr.ht/~emersion/soju/110
Most users will connect to their server with `<username>` as their
username in order to configure their upstreams.
Multi-upstream can be unintuitive to them and should not be enabled on
that first connection that is usually used for upstream configuration.
Multi-upstream is instead a power-user feature that should be explicitly
enabled with a specific network suffix.
We reserve the network suffix `*` and use it a special case to mean that
it requests multi-upstream mode.
READ lets downstream clients share information between each other about
what messages have been read by other downstreams.
Each target/entity has an optional corresponding read receipt, which is
stored as a timestamp.
- When a downstream sends:
READ #chan timestamp=2020-01-01T01:23:45.000Z
the read receipt for that target is set to that date
- soju sends READ to downstreams:
- on JOIN, if the client uses the soju.im/read capability
- when the read receipt timestamp is set by any downstream
The read receipt date is clamped by the previous receipt date and the
current time.
Instead of always requiring users to explicitly specify the network
name, guess it from the downstream connection.
Network commands are left as-is because it's not yet clear how to
handle them.