Commit Graph

450 Commits

Author SHA1 Message Date
Simon Ser
36d6cb19a4 Move authError to auth package
This allows auth backends to customize the error message displayed
to the user.
2023-02-23 22:32:24 +01:00
Simon Ser
8f1f67f1f0 Rate limit Web Push checks
No need to re-check that a Web Push subscription is valid every
time a downstream connects. Mobile devices may reconnect pretty
frequently.

Check at most once a day.
2023-02-18 13:27:13 +01:00
delthas
1ccc7ce6d2 Add a database store for messages
This adds a new config option, `logs db`, which enables storing chat
logs in the soju database.

Regular store options, CHATHISTORY options, and SEARCH operations are
supported, like the fs logs backend.

Messages are stored in a new table, Message. In order to track the list
of targets we have messages for in an optimized manner, another database
is used: MessageTarget.

All new requests are backend by indexes so should be fast even with
hundreds of thousands of messages.

A contrib script is provided for migrating existing logs fs chat logs to
the database. It can be run with eg:

  go run ./contrib/migrate-logs/ logs/ sqlite3:soju.db

Co-authored-by: Simon Ser <contact@emersion.fr>
2023-02-17 14:13:43 +01:00
Simon Ser
47f0dd5b3f downstream: send MSGREFTYPES ISUPPORT
References: https://github.com/ircv3/ircv3-specifications/pull/510
2023-02-13 19:25:42 +01:00
delthas
b920facdff service: Return the error rather than printing it
This enables callers to make the difference between a successful
service call and a failed one.
2023-02-06 15:15:09 +01:00
delthas
d17c7d57f2 service: Enable running service commands without users
This enables support for global service contexts, that are run
independently from a user context.

These contexts are considered to be admin. They only have access
to admin commands, because those are relevant in a global context.
2023-02-06 15:15:09 +01:00
delthas
4bd600c651 service: Store the admin capability independently the user
We can acquire admin contexts independently of the user.

This is mainly for a future commit that will introduce events
without a user.
2023-02-06 15:15:09 +01:00
Simon Ser
b4731cbd71 downstream: only send CHATHISTORY ISUPPORT when supported 2023-02-02 19:36:18 +01:00
Simon Ser
ca2d666056 Auto-create users after external auth when enable-user-on-auth is on 2023-01-30 11:53:01 +01:00
Simon Ser
c79fc0c19e Add support for SASL OAUTHBEARER 2023-01-30 11:53:01 +01:00
Simon Ser
63ca247354 Add infrastructure for external authentication 2023-01-30 11:53:01 +01:00
delthas
e7a06fe208 service: refactor downstreamConn to serviceContext
This will enable running service commands from other contexts.
2023-01-18 15:12:33 +01:00
Simon Ser
59dfa05d13 downstream: set empty CHANTYPES for bouncer connection 2023-01-16 16:46:46 +01:00
Simon Ser
f44e922c42 downstream: use ERR_BADCHANMASK for invalid channel name
It's more appropriate than ERR_NOSUCHCHANNEL.
2022-12-08 15:27:02 +01:00
Simon Ser
6d64c164a7 downstream: check channel name validity on JOIN
Avoid storing garbage in the DB.
2022-12-08 15:25:39 +01:00
Simon Ser
ec2c0685dd Add WHO cache
This adds a new field to upstreams, members, which is a casemapped map
of upstream users known to the soju. The upstream users known to soju
are: self, any monitored user, and any user with whom we share a
channel.

The information stored for each upstream user corresponds to the info
that can be returned by a WHO/WHOX command.

We build the upstream user information both incrementally, capturing
information contained in JOIN and AWAY messages; and with the bulk user
information contained in WHO replies we receive.

This lets us build a user cache that can then be used to return
synthetic WHO responses to later WHO requests by downstreams.

This is useful because some networks (eg Libera) heavily throttle WHO
commands, and without this cache, any downstream connecting would send 1
WHO command per channel, so possibly more than a dozen WHO commands,
which soju then forwarded to the upstream as WHO commands.

With this cache most WHO commands can be cached and avoid sending
WHO commands to the upstream.

In order to cache the "flags" field, we synthetize the field from user
info we get from incremental messages: away status (H/G) and bot status
(B). This could result in incorrect values for proprietary user fields.
Support for the server-operator status (*) is also not supported.

Of note is that it is difficult to obtain a user "connected server"
field incrementally, so clients that want to maximize their WHO cache
hit ratio can use WHOX to only request fields they need, and in
particular not include the server field flag.

Co-authored-by: delthas <delthas@dille.cc>
2022-12-01 15:50:33 +01:00
delthas
ac578823dc Fix clearing webpush targets after any MARKREAD
Previously, we would clear webpush targets after any MARKREAD.

Consider the following scenario (ignore any typos, this is crafted by
hand):

    <<< @time=2020-01-01T00:00:00Z PRIVMSG #foo :hi mark!
    <<< @time=2020-01-02T00:00:00Z PRIVMSG #foo :hi again mark!
    >>> MARKREAD #foo timestamp=2020-01-01T00:00:00Z
    >>> MARKREAD #foo timestamp=2020-01-02T00:00:00Z

The push target was previously cleared on the first MARKREAD, which
means that the second MARKREAD was never broadcast to Firebase, and all
devices would keep the "hi again mark!" notification indefinitely.

This changes the webpush target map so that we store a timestamp of the
last highlight we sent. We only clear the push target when sending a
MARKREAD that is at or after the last message.
2022-11-28 17:55:19 +01:00
delthas
897c21dbb4 Truncate message times to the second when using the FS message store
The FS message store truncates message times to the second.

This means that a message sent out as 2020-01-01T00:00:00.123Z could be
sent later as part of a CHATHISTORY batch as 2020-01-01T00:00:00.000Z,
which could cause issues in clients.

One such issue is a client sending a MARKREAD for
2020-01-01T00:00:00.000Z, with another client considering the
2020-01-01T00:00:00.123Z message it has as unread.

This fixes the issue by truncating all message times to the second when
using the FS message store.
2022-11-28 17:54:13 +01:00
Simon Ser
106d40dcd4 Upgrade to gopkg.in/irc.v4 2022-11-14 12:06:58 +01:00
Simon Ser
ea97b1a9bd Use ratified extended-monitor cap name for needAllDownstreamCaps
Fixes: 6ad3dcc396 ("Use ratified extended-monitor cap name")
2022-11-06 20:39:04 +01:00
Simon Ser
90be9a8ab9 downstream: stop sending HTTP OPTIONS request on WEBPUSH REGISTER
We were sending a test notification later anyways. Let's just do
that to check that the endpoint accepts our messages.
2022-09-30 12:20:07 +02:00
Simon Ser
c3ab11de4e downstream: drop downstreamConn.unmarshalEntity{,Network} 2022-09-26 16:57:05 +02:00
Simon Ser
8a2f544806 downstream: drop downstreamConn.marshalEntity
This is a no-op.
2022-09-26 16:57:05 +02:00
Simon Ser
31957a9ac4 downstream: drop downstreamConn.marshalMessage
It's a no-op.
2022-09-26 16:57:05 +02:00
Simon Ser
25257b8892 downstream: drop downstreamConn.marshalUserPrefix
This is now a no-op.
2022-09-26 16:57:05 +02:00
Simon Ser
00919e9412 downstream: drop downstreamConn.unmarshalText
It's unused.
2022-09-26 16:57:05 +02:00
Simon Ser
eba7aa38d2 downstream: drop downstreamConn.isMultiUpstream
This is now always false.
2022-09-26 16:57:05 +02:00
Simon Ser
1ea3a19403 downstream: refuse to enable multi-upstream mode
References: https://todo.sr.ht/~emersion/soju/125
2022-09-26 16:57:04 +02:00
Simon Ser
c5f6a41d6c downstream: remove outdated Web Push TODO
We already do that.
2022-09-16 18:58:42 +02:00
Simon Ser
bb868eae82 downstream: fix CHATHISTORY LATEST without a bound
Fixes: 5e56cc30c5 ("downstream: fix inverted range in CHATHISTORY LATEST with a timestamp")
2022-09-16 18:55:31 +02:00
Simon Ser
5b10348957 downstream: don't echo back SASL mechanism
Some clients will queue up multiple AUTHENTICATE commands without
waiting for a reply to avoid some roundtrips. However that means
the traffic looks like so:

    AUTHENTICATE <mechanism>
    AUTHENTICATE <base64 blob containing credentials>

soju will fail the first command, and will behave as if no SASL
authentication was in progress when interpreting the second one.
This means we'll echo back the security-sensitive base64 blob to
the client in the error message, which is definitely not great.

Stop doing that.
2022-09-12 21:42:03 +02:00
Simon Ser
f4af7975d3 Pass-through ISUPPORT LINELEN
Can be used by the server to indicate support for a greater message
size limit.
2022-08-28 18:53:41 +02:00
Ember Sawady
57584c08ed Fix NICK on upstreams supporting MONITOR
Previously, uc.network.Network.Nick wasn't successfully updated on
downstream NICK. This would cause soju to immediately switch back to the
old nick when the upstream supported MONITOR, so long as the network had
a nick configured as of initialization.

In addition, stop monitoring our desired nick once we've successfully
switched to it once, in order to not immediately undo server-induced
nick changes.
2022-08-23 09:39:24 +02:00
Petr Ročkai
5e56cc30c5 downstream: fix inverted range in CHATHISTORY LATEST with a timestamp 2022-08-17 19:43:01 +02:00
Simon Ser
6fa8a1f30a downstream: add hard limit on Web Push subscriptions
Each subscription comes with the cost of a HTTP request when
broadcasting a message.
2022-08-17 17:08:23 +02:00
Simon Ser
cffdbc16b4 downstream: break findWebPushSubscription in two functions
We'll use that to count the number of existing subscriptions in
the next commit.
2022-08-17 17:04:11 +02:00
Simon Ser
65f0b2367e Broadcast Web Push subscriptions in a new goroutine 2022-08-17 16:09:12 +02:00
Simon Ser
0ef8b7d4c8 downstream: re-format doc comment with Go 1.19 style
We can use lists now.
2022-08-05 18:37:32 +02:00
Simon Ser
f37aedea79 downstream: reply to INFO 2022-07-14 15:51:26 +02:00
gildarts
48960a2992 database: upgrade bcrypt cost as needed
Closes: https://todo.sr.ht/~emersion/soju/136
2022-07-12 18:52:49 +02:00
Simon Ser
c69ea81999 downstream: fix downstream check for draft/read-marker
`dc` is the source connection, `d` is the destination for the
broadcast.

Fixes: 7e21e79eab ("downstream: fix MARKREAD/READ command name in broadcast")
2022-07-12 17:04:46 +02:00
Simon Ser
1e78e3e4b0 dowstream: remove noop WEBPUSH REGISTER
We still want to update the updated_at column when a client
refreshes the subscription.
2022-07-11 22:54:51 +02:00
Simon Ser
4e683af535 Aggregate AWAY status from all connected clients
Closes: https://todo.sr.ht/~emersion/soju/200
2022-07-11 19:36:12 +02:00
Simon Ser
84188ba644 downstream: relay SETNAME with upstreamConn.SendMessageLabeled
This makes it so any errors are only relayed to this downstream
connection.

The upstream handler for SETNAME handles the broadcasting to all
downstream connections already.
2022-07-08 18:17:24 +02:00
Simon Ser
b1b4541a53 downstream: simplify NICK handling when disconnected 2022-07-08 18:14:10 +02:00
Simon Ser
dc0a847240 Add per-user default nickname
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
2022-07-08 18:01:05 +02:00
Simon Ser
14cbd63412 Send MARKREAD push notifications
Allows clients to dismiss notifications when another client marks
the conversation as read.
2022-07-08 16:55:29 +02:00
Simon Ser
7e21e79eab downstream: fix MARKREAD/READ command name in broadcast
We wouldn't send a MARKREAD message to draft/read-marker downstreams
when receiving a READ command.
2022-07-08 15:17:30 +02:00
Simon Ser
0d44413e85 upstream: drop upstreamConn.nickCM
Removes an unnecessary source of truth.
2022-07-08 14:52:10 +02:00
Simon Ser
e2e3e2731b Fix draft/read-marker entry in permanentDownstreamCaps
Oops.

Fixes: 71d639699e ("Add support for draft/read-marker")
2022-07-01 15:58:11 +02:00