mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
Merge branch 'master' into query-key-backup
This commit is contained in:
commit
60af5bee47
66 changed files with 488 additions and 441 deletions
|
@ -89,7 +89,7 @@ We are prioritising features that will benefit single-user homeservers first (e.
|
||||||
than features that massive deployments may be interested in (User Directory, OpenID, Guests, Admin APIs, AS API).
|
than features that massive deployments may be interested in (User Directory, OpenID, Guests, Admin APIs, AS API).
|
||||||
This means Dendrite supports amongst others:
|
This means Dendrite supports amongst others:
|
||||||
- Core room functionality (creating rooms, invites, auth rules)
|
- Core room functionality (creating rooms, invites, auth rules)
|
||||||
- Federation in rooms v1-v6
|
- Federation in rooms v1-v7
|
||||||
- Backfilling locally and via federation
|
- Backfilling locally and via federation
|
||||||
- Accounts, Profiles and Devices
|
- Accounts, Profiles and Devices
|
||||||
- Published room lists
|
- Published room lists
|
||||||
|
|
|
@ -152,219 +152,219 @@ jon Joining room twice is idempotent
|
||||||
syn New room members see their own join event
|
syn New room members see their own join event
|
||||||
v1s New room members see existing users' presence in room initialSync
|
v1s New room members see existing users' presence in room initialSync
|
||||||
syn Existing members see new members' join events
|
syn Existing members see new members' join events
|
||||||
syn Existing members see new members' presence
|
pre Existing members see new members' presence
|
||||||
v1s All room members see all room members' presence in global initialSync
|
v1s All room members see all room members' presence in global initialSync
|
||||||
f,jon Remote users can join room by alias
|
f,jon Remote users can join room by alias
|
||||||
syn New room members see their own join event
|
syn New room members see their own join event
|
||||||
v1s New room members see existing members' presence in room initialSync
|
v1s New room members see existing members' presence in room initialSync
|
||||||
syn Existing members see new members' join events
|
syn Existing members see new members' join events
|
||||||
syn Existing members see new member's presence
|
pre Existing members see new member's presence
|
||||||
v1s New room members see first user's profile information in global initialSync
|
v1s New room members see first user's profile information in global initialSync
|
||||||
v1s New room members see first user's profile information in per-room initialSync
|
v1s New room members see first user's profile information in per-room initialSync
|
||||||
f,jon Remote users may not join unfederated rooms
|
f,jon Remote users may not join unfederated rooms
|
||||||
syn Local room members see posted message events
|
syn Local room members see posted message events
|
||||||
v1s Fetching eventstream a second time doesn't yield the message again
|
v1s Fetching eventstream a second time doesn't yield the message again
|
||||||
syn Local non-members don't see posted message events
|
syn Local non-members don't see posted message events
|
||||||
get Local room members can get room messages
|
get Local room members can get room messages
|
||||||
f,syn Remote room members also see posted message events
|
f,syn Remote room members also see posted message events
|
||||||
f,get Remote room members can get room messages
|
f,get Remote room members can get room messages
|
||||||
get Message history can be paginated
|
get Message history can be paginated
|
||||||
f,get Message history can be paginated over federation
|
f,get Message history can be paginated over federation
|
||||||
eph Ephemeral messages received from clients are correctly expired
|
eph Ephemeral messages received from clients are correctly expired
|
||||||
ali Room aliases can contain Unicode
|
ali Room aliases can contain Unicode
|
||||||
f,ali Remote room alias queries can handle Unicode
|
f,ali Remote room alias queries can handle Unicode
|
||||||
ali Canonical alias can be set
|
ali Canonical alias can be set
|
||||||
ali Canonical alias can include alt_aliases
|
ali Canonical alias can include alt_aliases
|
||||||
ali Regular users can add and delete aliases in the default room configuration
|
ali Regular users can add and delete aliases in the default room configuration
|
||||||
ali Regular users can add and delete aliases when m.room.aliases is restricted
|
ali Regular users can add and delete aliases when m.room.aliases is restricted
|
||||||
ali Deleting a non-existent alias should return a 404
|
ali Deleting a non-existent alias should return a 404
|
||||||
ali Users can't delete other's aliases
|
ali Users can't delete other's aliases
|
||||||
ali Users with sufficient power-level can delete other's aliases
|
ali Users with sufficient power-level can delete other's aliases
|
||||||
ali Can delete canonical alias
|
ali Can delete canonical alias
|
||||||
ali Alias creators can delete alias with no ops
|
ali Alias creators can delete alias with no ops
|
||||||
ali Alias creators can delete canonical alias with no ops
|
ali Alias creators can delete canonical alias with no ops
|
||||||
msc Only room members can list aliases of a room
|
msc Only room members can list aliases of a room
|
||||||
inv Can invite users to invite-only rooms
|
inv Can invite users to invite-only rooms
|
||||||
inv Uninvited users cannot join the room
|
inv Uninvited users cannot join the room
|
||||||
inv Invited user can reject invite
|
inv Invited user can reject invite
|
||||||
f,inv Invited user can reject invite over federation
|
f,inv Invited user can reject invite over federation
|
||||||
f,inv Invited user can reject invite over federation several times
|
f,inv Invited user can reject invite over federation several times
|
||||||
inv Invited user can reject invite for empty room
|
inv Invited user can reject invite for empty room
|
||||||
f,inv Invited user can reject invite over federation for empty room
|
f,inv Invited user can reject invite over federation for empty room
|
||||||
inv Invited user can reject local invite after originator leaves
|
inv Invited user can reject local invite after originator leaves
|
||||||
inv Invited user can see room metadata
|
inv Invited user can see room metadata
|
||||||
f,inv Remote invited user can see room metadata
|
f,inv Remote invited user can see room metadata
|
||||||
inv Users cannot invite themselves to a room
|
inv Users cannot invite themselves to a room
|
||||||
inv Users cannot invite a user that is already in the room
|
inv Users cannot invite a user that is already in the room
|
||||||
ban Banned user is kicked and may not rejoin until unbanned
|
ban Banned user is kicked and may not rejoin until unbanned
|
||||||
f,ban Remote banned user is kicked and may not rejoin until unbanned
|
f,ban Remote banned user is kicked and may not rejoin until unbanned
|
||||||
ban 'ban' event respects room powerlevel
|
ban 'ban' event respects room powerlevel
|
||||||
plv setting 'm.room.name' respects room powerlevel
|
plv setting 'm.room.name' respects room powerlevel
|
||||||
plv setting 'm.room.power_levels' respects room powerlevel (2 subtests)
|
plv setting 'm.room.power_levels' respects room powerlevel (2 subtests)
|
||||||
plv Unprivileged users can set m.room.topic if it only needs level 0
|
plv Unprivileged users can set m.room.topic if it only needs level 0
|
||||||
plv Users cannot set ban powerlevel higher than their own (2 subtests)
|
plv Users cannot set ban powerlevel higher than their own (2 subtests)
|
||||||
plv Users cannot set kick powerlevel higher than their own (2 subtests)
|
plv Users cannot set kick powerlevel higher than their own (2 subtests)
|
||||||
plv Users cannot set redact powerlevel higher than their own (2 subtests)
|
plv Users cannot set redact powerlevel higher than their own (2 subtests)
|
||||||
v1s Check that event streams started after a client joined a room work (SYT-1)
|
v1s Check that event streams started after a client joined a room work (SYT-1)
|
||||||
v1s Event stream catches up fully after many messages
|
v1s Event stream catches up fully after many messages
|
||||||
xxx POST /rooms/:room_id/redact/:event_id as power user redacts message
|
xxx POST /rooms/:room_id/redact/:event_id as power user redacts message
|
||||||
xxx POST /rooms/:room_id/redact/:event_id as original message sender redacts message
|
xxx POST /rooms/:room_id/redact/:event_id as original message sender redacts message
|
||||||
xxx POST /rooms/:room_id/redact/:event_id as random user does not redact message
|
xxx POST /rooms/:room_id/redact/:event_id as random user does not redact message
|
||||||
xxx POST /redact disallows redaction of event in different room
|
xxx POST /redact disallows redaction of event in different room
|
||||||
xxx Redaction of a redaction redacts the redaction reason
|
xxx Redaction of a redaction redacts the redaction reason
|
||||||
v1s A departed room is still included in /initialSync (SPEC-216)
|
v1s A departed room is still included in /initialSync (SPEC-216)
|
||||||
v1s Can get rooms/{roomId}/initialSync for a departed room (SPEC-216)
|
v1s Can get rooms/{roomId}/initialSync for a departed room (SPEC-216)
|
||||||
rst Can get rooms/{roomId}/state for a departed room (SPEC-216)
|
rst Can get rooms/{roomId}/state for a departed room (SPEC-216)
|
||||||
mem Can get rooms/{roomId}/members for a departed room (SPEC-216)
|
mem Can get rooms/{roomId}/members for a departed room (SPEC-216)
|
||||||
get Can get rooms/{roomId}/messages for a departed room (SPEC-216)
|
get Can get rooms/{roomId}/messages for a departed room (SPEC-216)
|
||||||
rst Can get 'm.room.name' state for a departed room (SPEC-216)
|
rst Can get 'm.room.name' state for a departed room (SPEC-216)
|
||||||
syn Getting messages going forward is limited for a departed room (SPEC-216)
|
syn Getting messages going forward is limited for a departed room (SPEC-216)
|
||||||
3pd Can invite existing 3pid
|
3pd Can invite existing 3pid
|
||||||
3pd Can invite existing 3pid with no ops into a private room
|
3pd Can invite existing 3pid with no ops into a private room
|
||||||
3pd Can invite existing 3pid in createRoom
|
3pd Can invite existing 3pid in createRoom
|
||||||
3pd Can invite unbound 3pid
|
3pd Can invite unbound 3pid
|
||||||
f,3pd Can invite unbound 3pid over federation
|
f,3pd Can invite unbound 3pid over federation
|
||||||
3pd Can invite unbound 3pid with no ops into a private room
|
3pd Can invite unbound 3pid with no ops into a private room
|
||||||
f,3pd Can invite unbound 3pid over federation with no ops into a private room
|
f,3pd Can invite unbound 3pid over federation with no ops into a private room
|
||||||
f,3pd Can invite unbound 3pid over federation with users from both servers
|
f,3pd Can invite unbound 3pid over federation with users from both servers
|
||||||
3pd Can accept unbound 3pid invite after inviter leaves
|
3pd Can accept unbound 3pid invite after inviter leaves
|
||||||
3pd Can accept third party invite with /join
|
3pd Can accept third party invite with /join
|
||||||
3pd 3pid invite join with wrong but valid signature are rejected
|
3pd 3pid invite join with wrong but valid signature are rejected
|
||||||
3pd 3pid invite join valid signature but revoked keys are rejected
|
3pd 3pid invite join valid signature but revoked keys are rejected
|
||||||
3pd 3pid invite join valid signature but unreachable ID server are rejected
|
3pd 3pid invite join valid signature but unreachable ID server are rejected
|
||||||
gst Guest user cannot call /events globally
|
gst Guest user cannot call /events globally
|
||||||
gst Guest users can join guest_access rooms
|
gst Guest users can join guest_access rooms
|
||||||
gst Guest users can send messages to guest_access rooms if joined
|
gst Guest users can send messages to guest_access rooms if joined
|
||||||
gst Guest user calling /events doesn't tightloop
|
gst Guest user calling /events doesn't tightloop
|
||||||
gst Guest users are kicked from guest_access rooms on revocation of guest_access
|
gst Guest users are kicked from guest_access rooms on revocation of guest_access
|
||||||
gst Guest user can set display names
|
gst Guest user can set display names
|
||||||
gst Guest users are kicked from guest_access rooms on revocation of guest_access over federation
|
gst Guest users are kicked from guest_access rooms on revocation of guest_access over federation
|
||||||
gst Guest user can upgrade to fully featured user
|
gst Guest user can upgrade to fully featured user
|
||||||
gst Guest user cannot upgrade other users
|
gst Guest user cannot upgrade other users
|
||||||
pub GET /publicRooms lists rooms
|
pub GET /publicRooms lists rooms
|
||||||
pub GET /publicRooms includes avatar URLs
|
pub GET /publicRooms includes avatar URLs
|
||||||
gst Guest users can accept invites to private rooms over federation
|
gst Guest users can accept invites to private rooms over federation
|
||||||
gst Guest users denied access over federation if guest access prohibited
|
gst Guest users denied access over federation if guest access prohibited
|
||||||
mem Room members can override their displayname on a room-specific basis
|
mem Room members can override their displayname on a room-specific basis
|
||||||
mem Room members can join a room with an overridden displayname
|
mem Room members can join a room with an overridden displayname
|
||||||
mem Users cannot kick users from a room they are not in
|
mem Users cannot kick users from a room they are not in
|
||||||
mem Users cannot kick users who have already left a room
|
mem Users cannot kick users who have already left a room
|
||||||
typ Typing notification sent to local room members
|
typ Typing notification sent to local room members
|
||||||
f,typ Typing notifications also sent to remote room members
|
f,typ Typing notifications also sent to remote room members
|
||||||
typ Typing can be explicitly stopped
|
typ Typing can be explicitly stopped
|
||||||
rct Read receipts are visible to /initialSync
|
rct Read receipts are visible to /initialSync
|
||||||
rct Read receipts are sent as events
|
rct Read receipts are sent as events
|
||||||
rct Receipts must be m.read
|
rct Receipts must be m.read
|
||||||
pro displayname updates affect room member events
|
pro displayname updates affect room member events
|
||||||
pro avatar_url updates affect room member events
|
pro avatar_url updates affect room member events
|
||||||
gst m.room.history_visibility == "world_readable" allows/forbids appropriately for Guest users
|
gst m.room.history_visibility == "world_readable" allows/forbids appropriately for Guest users
|
||||||
gst m.room.history_visibility == "shared" allows/forbids appropriately for Guest users
|
gst m.room.history_visibility == "shared" allows/forbids appropriately for Guest users
|
||||||
gst m.room.history_visibility == "invited" allows/forbids appropriately for Guest users
|
gst m.room.history_visibility == "invited" allows/forbids appropriately for Guest users
|
||||||
gst m.room.history_visibility == "joined" allows/forbids appropriately for Guest users
|
gst m.room.history_visibility == "joined" allows/forbids appropriately for Guest users
|
||||||
gst m.room.history_visibility == "default" allows/forbids appropriately for Guest users
|
gst m.room.history_visibility == "default" allows/forbids appropriately for Guest users
|
||||||
gst Guest non-joined user cannot call /events on shared room
|
gst Guest non-joined user cannot call /events on shared room
|
||||||
gst Guest non-joined user cannot call /events on invited room
|
gst Guest non-joined user cannot call /events on invited room
|
||||||
gst Guest non-joined user cannot call /events on joined room
|
gst Guest non-joined user cannot call /events on joined room
|
||||||
gst Guest non-joined user cannot call /events on default room
|
gst Guest non-joined user cannot call /events on default room
|
||||||
gst Guest non-joined user can call /events on world_readable room
|
gst Guest non-joined user can call /events on world_readable room
|
||||||
gst Guest non-joined users can get state for world_readable rooms
|
gst Guest non-joined users can get state for world_readable rooms
|
||||||
gst Guest non-joined users can get individual state for world_readable rooms
|
gst Guest non-joined users can get individual state for world_readable rooms
|
||||||
gst Guest non-joined users cannot room initalSync for non-world_readable rooms
|
gst Guest non-joined users cannot room initalSync for non-world_readable rooms
|
||||||
gst Guest non-joined users can room initialSync for world_readable rooms
|
gst Guest non-joined users can room initialSync for world_readable rooms
|
||||||
gst Guest non-joined users can get individual state for world_readable rooms after leaving
|
gst Guest non-joined users can get individual state for world_readable rooms after leaving
|
||||||
gst Guest non-joined users cannot send messages to guest_access rooms if not joined
|
gst Guest non-joined users cannot send messages to guest_access rooms if not joined
|
||||||
gst Guest users can sync from world_readable guest_access rooms if joined
|
gst Guest users can sync from world_readable guest_access rooms if joined
|
||||||
gst Guest users can sync from shared guest_access rooms if joined
|
gst Guest users can sync from shared guest_access rooms if joined
|
||||||
gst Guest users can sync from invited guest_access rooms if joined
|
gst Guest users can sync from invited guest_access rooms if joined
|
||||||
gst Guest users can sync from joined guest_access rooms if joined
|
gst Guest users can sync from joined guest_access rooms if joined
|
||||||
gst Guest users can sync from default guest_access rooms if joined
|
gst Guest users can sync from default guest_access rooms if joined
|
||||||
ath m.room.history_visibility == "world_readable" allows/forbids appropriately for Real users
|
ath m.room.history_visibility == "world_readable" allows/forbids appropriately for Real users
|
||||||
ath m.room.history_visibility == "shared" allows/forbids appropriately for Real users
|
ath m.room.history_visibility == "shared" allows/forbids appropriately for Real users
|
||||||
ath m.room.history_visibility == "invited" allows/forbids appropriately for Real users
|
ath m.room.history_visibility == "invited" allows/forbids appropriately for Real users
|
||||||
ath m.room.history_visibility == "joined" allows/forbids appropriately for Real users
|
ath m.room.history_visibility == "joined" allows/forbids appropriately for Real users
|
||||||
ath m.room.history_visibility == "default" allows/forbids appropriately for Real users
|
ath m.room.history_visibility == "default" allows/forbids appropriately for Real users
|
||||||
ath Real non-joined user cannot call /events on shared room
|
ath Real non-joined user cannot call /events on shared room
|
||||||
ath Real non-joined user cannot call /events on invited room
|
ath Real non-joined user cannot call /events on invited room
|
||||||
ath Real non-joined user cannot call /events on joined room
|
ath Real non-joined user cannot call /events on joined room
|
||||||
ath Real non-joined user cannot call /events on default room
|
ath Real non-joined user cannot call /events on default room
|
||||||
ath Real non-joined user can call /events on world_readable room
|
ath Real non-joined user can call /events on world_readable room
|
||||||
ath Real non-joined users can get state for world_readable rooms
|
ath Real non-joined users can get state for world_readable rooms
|
||||||
ath Real non-joined users can get individual state for world_readable rooms
|
ath Real non-joined users can get individual state for world_readable rooms
|
||||||
ath Real non-joined users cannot room initalSync for non-world_readable rooms
|
ath Real non-joined users cannot room initalSync for non-world_readable rooms
|
||||||
ath Real non-joined users can room initialSync for world_readable rooms
|
ath Real non-joined users can room initialSync for world_readable rooms
|
||||||
ath Real non-joined users can get individual state for world_readable rooms after leaving
|
ath Real non-joined users can get individual state for world_readable rooms after leaving
|
||||||
ath Real non-joined users cannot send messages to guest_access rooms if not joined
|
ath Real non-joined users cannot send messages to guest_access rooms if not joined
|
||||||
ath Real users can sync from world_readable guest_access rooms if joined
|
ath Real users can sync from world_readable guest_access rooms if joined
|
||||||
ath Real users can sync from shared guest_access rooms if joined
|
ath Real users can sync from shared guest_access rooms if joined
|
||||||
ath Real users can sync from invited guest_access rooms if joined
|
ath Real users can sync from invited guest_access rooms if joined
|
||||||
ath Real users can sync from joined guest_access rooms if joined
|
ath Real users can sync from joined guest_access rooms if joined
|
||||||
ath Real users can sync from default guest_access rooms if joined
|
ath Real users can sync from default guest_access rooms if joined
|
||||||
ath Only see history_visibility changes on boundaries
|
ath Only see history_visibility changes on boundaries
|
||||||
f,ath Backfill works correctly with history visibility set to joined
|
f,ath Backfill works correctly with history visibility set to joined
|
||||||
fgt Forgotten room messages cannot be paginated
|
fgt Forgotten room messages cannot be paginated
|
||||||
fgt Forgetting room does not show up in v2 /sync
|
fgt Forgetting room does not show up in v2 /sync
|
||||||
fgt Can forget room you've been kicked from
|
fgt Can forget room you've been kicked from
|
||||||
fgt Can't forget room you're still in
|
fgt Can't forget room you're still in
|
||||||
fgt Can re-join room if re-invited
|
fgt Can re-join room if re-invited
|
||||||
ath Only original members of the room can see messages from erased users
|
ath Only original members of the room can see messages from erased users
|
||||||
mem /joined_rooms returns only joined rooms
|
mem /joined_rooms returns only joined rooms
|
||||||
mem /joined_members return joined members
|
mem /joined_members return joined members
|
||||||
ctx /context/ on joined room works
|
ctx /context/ on joined room works
|
||||||
ctx /context/ on non world readable room does not work
|
ctx /context/ on non world readable room does not work
|
||||||
ctx /context/ returns correct number of events
|
ctx /context/ returns correct number of events
|
||||||
ctx /context/ with lazy_load_members filter works
|
ctx /context/ with lazy_load_members filter works
|
||||||
get /event/ on joined room works
|
get /event/ on joined room works
|
||||||
get /event/ on non world readable room does not work
|
get /event/ on non world readable room does not work
|
||||||
get /event/ does not allow access to events before the user joined
|
get /event/ does not allow access to events before the user joined
|
||||||
mem Can get rooms/{roomId}/members
|
mem Can get rooms/{roomId}/members
|
||||||
mem Can get rooms/{roomId}/members at a given point
|
mem Can get rooms/{roomId}/members at a given point
|
||||||
mem Can filter rooms/{roomId}/members
|
mem Can filter rooms/{roomId}/members
|
||||||
upg /upgrade creates a new room
|
upg /upgrade creates a new room
|
||||||
upg /upgrade should preserve room visibility for public rooms
|
upg /upgrade should preserve room visibility for public rooms
|
||||||
upg /upgrade should preserve room visibility for private rooms
|
upg /upgrade should preserve room visibility for private rooms
|
||||||
upg /upgrade copies >100 power levels to the new room
|
upg /upgrade copies >100 power levels to the new room
|
||||||
upg /upgrade copies the power levels to the new room
|
upg /upgrade copies the power levels to the new room
|
||||||
upg /upgrade preserves the power level of the upgrading user in old and new rooms
|
upg /upgrade preserves the power level of the upgrading user in old and new rooms
|
||||||
upg /upgrade copies important state to the new room
|
upg /upgrade copies important state to the new room
|
||||||
upg /upgrade copies ban events to the new room
|
upg /upgrade copies ban events to the new room
|
||||||
upg local user has push rules copied to upgraded room
|
upg local user has push rules copied to upgraded room
|
||||||
f,upg remote user has push rules copied to upgraded room
|
f,upg remote user has push rules copied to upgraded room
|
||||||
upg /upgrade moves aliases to the new room
|
upg /upgrade moves aliases to the new room
|
||||||
upg /upgrade moves remote aliases to the new room
|
upg /upgrade moves remote aliases to the new room
|
||||||
upg /upgrade preserves direct room state
|
upg /upgrade preserves direct room state
|
||||||
upg /upgrade preserves room federation ability
|
upg /upgrade preserves room federation ability
|
||||||
upg /upgrade restricts power levels in the old room
|
upg /upgrade restricts power levels in the old room
|
||||||
upg /upgrade restricts power levels in the old room when the old PLs are unusual
|
upg /upgrade restricts power levels in the old room when the old PLs are unusual
|
||||||
upg /upgrade to an unknown version is rejected
|
upg /upgrade to an unknown version is rejected
|
||||||
upg /upgrade is rejected if the user can't send state events
|
upg /upgrade is rejected if the user can't send state events
|
||||||
upg /upgrade of a bogus room fails gracefully
|
upg /upgrade of a bogus room fails gracefully
|
||||||
upg Cannot send tombstone event that points to the same room
|
upg Cannot send tombstone event that points to the same room
|
||||||
f,upg Local and remote users' homeservers remove a room from their public directory on upgrade
|
f,upg Local and remote users' homeservers remove a room from their public directory on upgrade
|
||||||
rst Name/topic keys are correct
|
rst Name/topic keys are correct
|
||||||
f,pub Can get remote public room list
|
f,pub Can get remote public room list
|
||||||
pub Can paginate public room list
|
pub Can paginate public room list
|
||||||
pub Can search public room list
|
pub Can search public room list
|
||||||
syn Can create filter
|
syn Can create filter
|
||||||
syn Can download filter
|
syn Can download filter
|
||||||
syn Can sync
|
syn Can sync
|
||||||
syn Can sync a joined room
|
syn Can sync a joined room
|
||||||
syn Full state sync includes joined rooms
|
syn Full state sync includes joined rooms
|
||||||
syn Newly joined room is included in an incremental sync
|
syn Newly joined room is included in an incremental sync
|
||||||
syn Newly joined room has correct timeline in incremental sync
|
syn Newly joined room has correct timeline in incremental sync
|
||||||
syn Newly joined room includes presence in incremental sync
|
pre Newly joined room includes presence in incremental sync
|
||||||
syn Get presence for newly joined members in incremental sync
|
pre Get presence for newly joined members in incremental sync
|
||||||
syn Can sync a room with a single message
|
syn Can sync a room with a single message
|
||||||
syn Can sync a room with a message with a transaction id
|
syn Can sync a room with a message with a transaction id
|
||||||
syn A message sent after an initial sync appears in the timeline of an incremental sync.
|
syn A message sent after an initial sync appears in the timeline of an incremental sync.
|
||||||
syn A filtered timeline reaches its limit
|
syn A filtered timeline reaches its limit
|
||||||
syn Syncing a new room with a large timeline limit isn't limited
|
syn Syncing a new room with a large timeline limit isn't limited
|
||||||
syn A full_state incremental update returns only recent timeline
|
syn A full_state incremental update returns only recent timeline
|
||||||
syn A prev_batch token can be used in the v1 messages API
|
syn A prev_batch token can be used in the v1 messages API
|
||||||
syn A next_batch token can be used in the v1 messages API
|
syn A next_batch token can be used in the v1 messages API
|
||||||
syn A prev_batch token from incremental sync can be used in the v1 messages API
|
syn A prev_batch token from incremental sync can be used in the v1 messages API
|
||||||
syn User sees their own presence in a sync
|
pre User sees their own presence in a sync
|
||||||
syn User is offline if they set_presence=offline in their sync
|
pre User is offline if they set_presence=offline in their sync
|
||||||
syn User sees updates to presence from other users in the incremental sync.
|
pre User sees updates to presence from other users in the incremental sync.
|
||||||
syn State is included in the timeline in the initial sync
|
syn State is included in the timeline in the initial sync
|
||||||
f,syn State from remote users is included in the state in the initial sync
|
f,syn State from remote users is included in the state in the initial sync
|
||||||
syn Changes to state are included in an incremental sync
|
syn Changes to state are included in an incremental sync
|
||||||
|
|
|
@ -52,6 +52,10 @@ global:
|
||||||
# considered valid by other homeservers.
|
# considered valid by other homeservers.
|
||||||
key_validity_period: 168h0m0s
|
key_validity_period: 168h0m0s
|
||||||
|
|
||||||
|
# The server name to delegate server-server communications to, with optional port
|
||||||
|
# e.g. localhost:443
|
||||||
|
well_known_server_name: ""
|
||||||
|
|
||||||
# Lists of domains that the server will trust as identity servers to verify third
|
# Lists of domains that the server will trust as identity servers to verify third
|
||||||
# party identifiers such as phone numbers and email addresses.
|
# party identifiers such as phone numbers and email addresses.
|
||||||
trusted_third_party_id_servers:
|
trusted_third_party_id_servers:
|
||||||
|
|
|
@ -40,7 +40,6 @@ import (
|
||||||
"golang.org/x/net/http2/h2c"
|
"golang.org/x/net/http2/h2c"
|
||||||
|
|
||||||
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
||||||
"github.com/matrix-org/pinecone/router"
|
|
||||||
pineconeRouter "github.com/matrix-org/pinecone/router"
|
pineconeRouter "github.com/matrix-org/pinecone/router"
|
||||||
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
||||||
"github.com/matrix-org/pinecone/types"
|
"github.com/matrix-org/pinecone/types"
|
||||||
|
@ -106,7 +105,7 @@ func (m *DendriteMonolith) SetStaticPeer(uri string) {
|
||||||
func (m *DendriteMonolith) DisconnectType(peertype int) {
|
func (m *DendriteMonolith) DisconnectType(peertype int) {
|
||||||
for _, p := range m.PineconeRouter.Peers() {
|
for _, p := range m.PineconeRouter.Peers() {
|
||||||
if peertype == p.PeerType {
|
if peertype == p.PeerType {
|
||||||
_ = m.PineconeRouter.Disconnect(types.SwitchPortID(p.Port), nil)
|
m.PineconeRouter.Disconnect(types.SwitchPortID(p.Port), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,13 +113,13 @@ func (m *DendriteMonolith) DisconnectType(peertype int) {
|
||||||
func (m *DendriteMonolith) DisconnectZone(zone string) {
|
func (m *DendriteMonolith) DisconnectZone(zone string) {
|
||||||
for _, p := range m.PineconeRouter.Peers() {
|
for _, p := range m.PineconeRouter.Peers() {
|
||||||
if zone == p.Zone {
|
if zone == p.Zone {
|
||||||
_ = m.PineconeRouter.Disconnect(types.SwitchPortID(p.Port), nil)
|
m.PineconeRouter.Disconnect(types.SwitchPortID(p.Port), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DendriteMonolith) DisconnectPort(port int) error {
|
func (m *DendriteMonolith) DisconnectPort(port int) {
|
||||||
return m.PineconeRouter.Disconnect(types.SwitchPortID(port), nil)
|
m.PineconeRouter.Disconnect(types.SwitchPortID(port), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DendriteMonolith) Conduit(zone string, peertype int) (*Conduit, error) {
|
func (m *DendriteMonolith) Conduit(zone string, peertype int) (*Conduit, error) {
|
||||||
|
@ -133,7 +132,7 @@ func (m *DendriteMonolith) Conduit(zone string, peertype int) (*Conduit, error)
|
||||||
for i := 1; i <= 10; i++ {
|
for i := 1; i <= 10; i++ {
|
||||||
logrus.Errorf("Attempting authenticated connect (attempt %d)", i)
|
logrus.Errorf("Attempting authenticated connect (attempt %d)", i)
|
||||||
var err error
|
var err error
|
||||||
conduit.port, err = m.PineconeRouter.AuthenticatedConnect(l, zone, peertype)
|
conduit.port, err = m.PineconeRouter.AuthenticatedConnect(l, zone, peertype, true)
|
||||||
switch err {
|
switch err {
|
||||||
case io.ErrClosedPipe:
|
case io.ErrClosedPipe:
|
||||||
logrus.Errorf("Authenticated connect failed due to closed pipe (attempt %d)", i)
|
logrus.Errorf("Authenticated connect failed due to closed pipe (attempt %d)", i)
|
||||||
|
@ -196,7 +195,7 @@ func (m *DendriteMonolith) RegisterDevice(localpart, deviceID string) (string, e
|
||||||
|
|
||||||
func (m *DendriteMonolith) staticPeerConnect() {
|
func (m *DendriteMonolith) staticPeerConnect() {
|
||||||
attempt := func() {
|
attempt := func() {
|
||||||
if m.PineconeRouter.PeerCount(router.PeerTypeRemote) == 0 {
|
if m.PineconeRouter.PeerCount(pineconeRouter.PeerTypeRemote) == 0 {
|
||||||
m.staticPeerMutex.RLock()
|
m.staticPeerMutex.RLock()
|
||||||
uri := m.staticPeerURI
|
uri := m.staticPeerURI
|
||||||
m.staticPeerMutex.RUnlock()
|
m.staticPeerMutex.RUnlock()
|
||||||
|
@ -254,7 +253,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
logrus.SetOutput(BindLogger{})
|
logrus.SetOutput(BindLogger{})
|
||||||
|
|
||||||
logger := log.New(os.Stdout, "PINECONE: ", 0)
|
logger := log.New(os.Stdout, "PINECONE: ", 0)
|
||||||
m.PineconeRouter = pineconeRouter.NewRouter(logger, "dendrite", sk, pk, nil)
|
m.PineconeRouter = pineconeRouter.NewRouter(logger, sk, false)
|
||||||
m.PineconeQUIC = pineconeSessions.NewSessions(logger, m.PineconeRouter)
|
m.PineconeQUIC = pineconeSessions.NewSessions(logger, m.PineconeRouter)
|
||||||
m.PineconeMulticast = pineconeMulticast.NewMulticast(logger, m.PineconeRouter)
|
m.PineconeMulticast = pineconeMulticast.NewMulticast(logger, m.PineconeRouter)
|
||||||
|
|
||||||
|
@ -333,6 +332,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -156,6 +156,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,7 +32,7 @@ func ParseTSParam(req *http.Request) (time.Time, error) {
|
||||||
// The parameter exists, parse into a Time object
|
// The parameter exists, parse into a Time object
|
||||||
ts, err := strconv.ParseInt(tsStr, 10, 64)
|
ts, err := strconv.ParseInt(tsStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, fmt.Errorf("Param 'ts' is no valid int (%s)", err.Error())
|
return time.Time{}, fmt.Errorf("param 'ts' is no valid int (%s)", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return time.Unix(ts/1000, 0), nil
|
return time.Unix(ts/1000, 0), nil
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
@ -50,18 +49,18 @@ type devicesDeleteJSON struct {
|
||||||
|
|
||||||
// GetDeviceByID handles /devices/{deviceID}
|
// GetDeviceByID handles /devices/{deviceID}
|
||||||
func GetDeviceByID(
|
func GetDeviceByID(
|
||||||
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
req *http.Request, userAPI api.UserInternalAPI, device *api.Device,
|
||||||
deviceID string,
|
deviceID string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
var queryRes userapi.QueryDevicesResponse
|
var queryRes api.QueryDevicesResponse
|
||||||
err := userAPI.QueryDevices(req.Context(), &userapi.QueryDevicesRequest{
|
err := userAPI.QueryDevices(req.Context(), &api.QueryDevicesRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("QueryDevices failed")
|
util.GetLogger(req.Context()).WithError(err).Error("QueryDevices failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
var targetDevice *userapi.Device
|
var targetDevice *api.Device
|
||||||
for _, device := range queryRes.Devices {
|
for _, device := range queryRes.Devices {
|
||||||
if device.ID == deviceID {
|
if device.ID == deviceID {
|
||||||
targetDevice = &device
|
targetDevice = &device
|
||||||
|
@ -88,10 +87,10 @@ func GetDeviceByID(
|
||||||
|
|
||||||
// GetDevicesByLocalpart handles /devices
|
// GetDevicesByLocalpart handles /devices
|
||||||
func GetDevicesByLocalpart(
|
func GetDevicesByLocalpart(
|
||||||
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
req *http.Request, userAPI api.UserInternalAPI, device *api.Device,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
var queryRes userapi.QueryDevicesResponse
|
var queryRes api.QueryDevicesResponse
|
||||||
err := userAPI.QueryDevices(req.Context(), &userapi.QueryDevicesRequest{
|
err := userAPI.QueryDevices(req.Context(), &api.QueryDevicesRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
|
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
@ -115,7 +114,7 @@ func DirectoryRoom(
|
||||||
// SetLocalAlias implements PUT /directory/room/{roomAlias}
|
// SetLocalAlias implements PUT /directory/room/{roomAlias}
|
||||||
func SetLocalAlias(
|
func SetLocalAlias(
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
device *api.Device,
|
device *userapi.Device,
|
||||||
alias string,
|
alias string,
|
||||||
cfg *config.ClientAPI,
|
cfg *config.ClientAPI,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
|
@ -192,7 +191,7 @@ func SetLocalAlias(
|
||||||
// RemoveLocalAlias implements DELETE /directory/room/{roomAlias}
|
// RemoveLocalAlias implements DELETE /directory/room/{roomAlias}
|
||||||
func RemoveLocalAlias(
|
func RemoveLocalAlias(
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
device *api.Device,
|
device *userapi.Device,
|
||||||
alias string,
|
alias string,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
|
|
|
@ -19,16 +19,15 @@ import (
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logout handles POST /logout
|
// Logout handles POST /logout
|
||||||
func Logout(
|
func Logout(
|
||||||
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
req *http.Request, userAPI api.UserInternalAPI, device *api.Device,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
var performRes userapi.PerformDeviceDeletionResponse
|
var performRes api.PerformDeviceDeletionResponse
|
||||||
err := userAPI.PerformDeviceDeletion(req.Context(), &userapi.PerformDeviceDeletionRequest{
|
err := userAPI.PerformDeviceDeletion(req.Context(), &api.PerformDeviceDeletionRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
DeviceIDs: []string{device.ID},
|
DeviceIDs: []string{device.ID},
|
||||||
}, &performRes)
|
}, &performRes)
|
||||||
|
@ -45,10 +44,10 @@ func Logout(
|
||||||
|
|
||||||
// LogoutAll handles POST /logout/all
|
// LogoutAll handles POST /logout/all
|
||||||
func LogoutAll(
|
func LogoutAll(
|
||||||
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
req *http.Request, userAPI api.UserInternalAPI, device *api.Device,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
var performRes userapi.PerformDeviceDeletionResponse
|
var performRes api.PerformDeviceDeletionResponse
|
||||||
err := userAPI.PerformDeviceDeletion(req.Context(), &userapi.PerformDeviceDeletionRequest{
|
err := userAPI.PerformDeviceDeletion(req.Context(), &api.PerformDeviceDeletionRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
DeviceIDs: nil,
|
DeviceIDs: nil,
|
||||||
}, &performRes)
|
}, &performRes)
|
||||||
|
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/clientapi/threepid"
|
"github.com/matrix-org/dendrite/clientapi/threepid"
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
@ -107,7 +106,7 @@ func sendMembership(ctx context.Context, accountDB accounts.Database, device *us
|
||||||
|
|
||||||
if err = roomserverAPI.SendEvents(
|
if err = roomserverAPI.SendEvents(
|
||||||
ctx, rsAPI,
|
ctx, rsAPI,
|
||||||
api.KindNew,
|
roomserverAPI.KindNew,
|
||||||
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
|
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
|
||||||
cfg.Matrix.ServerName,
|
cfg.Matrix.ServerName,
|
||||||
nil,
|
nil,
|
||||||
|
@ -328,11 +327,11 @@ func loadProfile(
|
||||||
return profile, err
|
return profile, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractRequestData(req *http.Request, roomID string, rsAPI api.RoomserverInternalAPI) (
|
func extractRequestData(req *http.Request, roomID string, rsAPI roomserverAPI.RoomserverInternalAPI) (
|
||||||
body *threepid.MembershipRequest, evTime time.Time, roomVer gomatrixserverlib.RoomVersion, resErr *util.JSONResponse,
|
body *threepid.MembershipRequest, evTime time.Time, roomVer gomatrixserverlib.RoomVersion, resErr *util.JSONResponse,
|
||||||
) {
|
) {
|
||||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
verReq := roomserverAPI.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
verRes := roomserverAPI.QueryRoomVersionForRoomResponse{}
|
||||||
if err := rsAPI.QueryRoomVersionForRoom(req.Context(), &verReq, &verRes); err != nil {
|
if err := rsAPI.QueryRoomVersionForRoom(req.Context(), &verReq, &verRes); err != nil {
|
||||||
resErr = &util.JSONResponse{
|
resErr = &util.JSONResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
|
@ -402,13 +401,13 @@ func checkAndProcessThreepid(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkMemberInRoom(ctx context.Context, rsAPI api.RoomserverInternalAPI, userID, roomID string) *util.JSONResponse {
|
func checkMemberInRoom(ctx context.Context, rsAPI roomserverAPI.RoomserverInternalAPI, userID, roomID string) *util.JSONResponse {
|
||||||
tuple := gomatrixserverlib.StateKeyTuple{
|
tuple := gomatrixserverlib.StateKeyTuple{
|
||||||
EventType: gomatrixserverlib.MRoomMember,
|
EventType: gomatrixserverlib.MRoomMember,
|
||||||
StateKey: userID,
|
StateKey: userID,
|
||||||
}
|
}
|
||||||
var membershipRes api.QueryCurrentStateResponse
|
var membershipRes roomserverAPI.QueryCurrentStateResponse
|
||||||
err := rsAPI.QueryCurrentState(ctx, &api.QueryCurrentStateRequest{
|
err := rsAPI.QueryCurrentState(ctx, &roomserverAPI.QueryCurrentStateRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
StateTuples: []gomatrixserverlib.StateKeyTuple{tuple},
|
StateTuples: []gomatrixserverlib.StateKeyTuple{tuple},
|
||||||
}, &membershipRes)
|
}, &membershipRes)
|
||||||
|
@ -445,8 +444,8 @@ func SendForget(
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
logger := util.GetLogger(ctx).WithField("roomID", roomID).WithField("userID", device.UserID)
|
logger := util.GetLogger(ctx).WithField("roomID", roomID).WithField("userID", device.UserID)
|
||||||
var membershipRes api.QueryMembershipForUserResponse
|
var membershipRes roomserverAPI.QueryMembershipForUserResponse
|
||||||
membershipReq := api.QueryMembershipForUserRequest{
|
membershipReq := roomserverAPI.QueryMembershipForUserRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
}
|
}
|
||||||
|
@ -468,11 +467,11 @@ func SendForget(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request := api.PerformForgetRequest{
|
request := roomserverAPI.PerformForgetRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
}
|
}
|
||||||
response := api.PerformForgetResponse{}
|
response := roomserverAPI.PerformForgetResponse{}
|
||||||
if err := rsAPI.PerformForget(ctx, &request, &response); err != nil {
|
if err := rsAPI.PerformForget(ctx, &request, &response); err != nil {
|
||||||
logger.WithError(err).Error("PerformForget: unable to forget room")
|
logger.WithError(err).Error("PerformForget: unable to forget room")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
|
||||||
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
@ -29,7 +28,7 @@ type newPasswordAuth struct {
|
||||||
|
|
||||||
func Password(
|
func Password(
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
userAPI userapi.UserInternalAPI,
|
userAPI api.UserInternalAPI,
|
||||||
accountDB accounts.Database,
|
accountDB accounts.Database,
|
||||||
device *api.Device,
|
device *api.Device,
|
||||||
cfg *config.ClientAPI,
|
cfg *config.ClientAPI,
|
||||||
|
@ -90,11 +89,11 @@ func Password(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the user API to perform the password change.
|
// Ask the user API to perform the password change.
|
||||||
passwordReq := &userapi.PerformPasswordUpdateRequest{
|
passwordReq := &api.PerformPasswordUpdateRequest{
|
||||||
Localpart: localpart,
|
Localpart: localpart,
|
||||||
Password: r.NewPassword,
|
Password: r.NewPassword,
|
||||||
}
|
}
|
||||||
passwordRes := &userapi.PerformPasswordUpdateResponse{}
|
passwordRes := &api.PerformPasswordUpdateResponse{}
|
||||||
if err := userAPI.PerformPasswordUpdate(req.Context(), passwordReq, passwordRes); err != nil {
|
if err := userAPI.PerformPasswordUpdate(req.Context(), passwordReq, passwordRes); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("PerformPasswordUpdate failed")
|
util.GetLogger(req.Context()).WithError(err).Error("PerformPasswordUpdate failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
@ -107,12 +106,12 @@ func Password(
|
||||||
// If the request asks us to log out all other devices then
|
// If the request asks us to log out all other devices then
|
||||||
// ask the user API to do that.
|
// ask the user API to do that.
|
||||||
if r.LogoutDevices {
|
if r.LogoutDevices {
|
||||||
logoutReq := &userapi.PerformDeviceDeletionRequest{
|
logoutReq := &api.PerformDeviceDeletionRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
DeviceIDs: nil,
|
DeviceIDs: nil,
|
||||||
ExceptDeviceID: device.ID,
|
ExceptDeviceID: device.ID,
|
||||||
}
|
}
|
||||||
logoutRes := &userapi.PerformDeviceDeletionResponse{}
|
logoutRes := &api.PerformDeviceDeletionResponse{}
|
||||||
if err := userAPI.PerformDeviceDeletion(req.Context(), logoutReq, logoutRes); err != nil {
|
if err := userAPI.PerformDeviceDeletion(req.Context(), logoutReq, logoutRes); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("PerformDeviceDeletion failed")
|
util.GetLogger(req.Context()).WithError(err).Error("PerformDeviceDeletion failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
@ -113,7 +112,7 @@ func SendRedaction(
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryRes api.QueryLatestEventsAndStateResponse
|
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
|
||||||
e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||||
if err == eventutil.ErrRoomNoExists {
|
if err == eventutil.ErrRoomNoExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
@ -121,7 +120,7 @@ func SendRedaction(
|
||||||
JSON: jsonerror.NotFound("Room does not exist"),
|
JSON: jsonerror.NotFound("Room does not exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, api.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, cfg.Matrix.ServerName, nil); err != nil {
|
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, cfg.Matrix.ServerName, nil); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
|
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,18 +68,18 @@ func (r *SharedSecretRegistration) IsValidMacLogin(
|
||||||
) (bool, error) {
|
) (bool, error) {
|
||||||
// Check that shared secret registration isn't disabled.
|
// Check that shared secret registration isn't disabled.
|
||||||
if r.sharedSecret == "" {
|
if r.sharedSecret == "" {
|
||||||
return false, errors.New("Shared secret registration is disabled")
|
return false, errors.New("shared secret registration is disabled")
|
||||||
}
|
}
|
||||||
if !r.validNonce(nonce) {
|
if !r.validNonce(nonce) {
|
||||||
return false, fmt.Errorf("Incorrect or expired nonce: %s", nonce)
|
return false, fmt.Errorf("incorrect or expired nonce: %s", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that username/password don't contain the HMAC delimiters.
|
// Check that username/password don't contain the HMAC delimiters.
|
||||||
if strings.Contains(username, "\x00") {
|
if strings.Contains(username, "\x00") {
|
||||||
return false, errors.New("Username contains invalid character")
|
return false, errors.New("username contains invalid character")
|
||||||
}
|
}
|
||||||
if strings.Contains(password, "\x00") {
|
if strings.Contains(password, "\x00") {
|
||||||
return false, errors.New("Password contains invalid character")
|
return false, errors.New("password contains invalid character")
|
||||||
}
|
}
|
||||||
|
|
||||||
adminString := "notadmin"
|
adminString := "notadmin"
|
||||||
|
|
|
@ -81,7 +81,7 @@ func CreateSession(
|
||||||
|
|
||||||
// Error if the status isn't OK
|
// Error if the status isn't OK
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return "", fmt.Errorf("Could not create a session on the server %s", req.IDServer)
|
return "", fmt.Errorf("could not create a session on the server %s", req.IDServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the SID from the response and return it
|
// Extract the SID from the response and return it
|
||||||
|
@ -168,7 +168,7 @@ func PublishAssociation(creds Credentials, userID string, cfg *config.ClientAPI)
|
||||||
|
|
||||||
// Error if the status isn't OK
|
// Error if the status isn't OK
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("Could not publish the association on the server %s", creds.IDServer)
|
return fmt.Errorf("could not publish the association on the server %s", creds.IDServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -31,11 +31,11 @@ func ParseUsernameParam(usernameParam string, expectedServerName *gomatrixserver
|
||||||
lp, domain, err := gomatrixserverlib.SplitID('@', usernameParam)
|
lp, domain, err := gomatrixserverlib.SplitID('@', usernameParam)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Invalid username")
|
return "", errors.New("invalid username")
|
||||||
}
|
}
|
||||||
|
|
||||||
if expectedServerName != nil && domain != *expectedServerName {
|
if expectedServerName != nil && domain != *expectedServerName {
|
||||||
return "", errors.New("User ID does not belong to this server")
|
return "", errors.New("user ID does not belong to this server")
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart = lp
|
localpart = lp
|
||||||
|
|
|
@ -198,6 +198,7 @@ func main() {
|
||||||
base.Base.PublicClientAPIMux,
|
base.Base.PublicClientAPIMux,
|
||||||
base.Base.PublicFederationAPIMux,
|
base.Base.PublicFederationAPIMux,
|
||||||
base.Base.PublicKeyAPIMux,
|
base.Base.PublicKeyAPIMux,
|
||||||
|
base.Base.PublicWellKnownAPIMux,
|
||||||
base.Base.PublicMediaAPIMux,
|
base.Base.PublicMediaAPIMux,
|
||||||
base.Base.SynapseAdminMux,
|
base.Base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,7 +34,7 @@ func ConnectToPeer(pRouter *pineconeRouter.Router, peer string) error {
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return fmt.Errorf("failed to wrap connection")
|
return fmt.Errorf("failed to wrap connection")
|
||||||
}
|
}
|
||||||
_, err := pRouter.AuthenticatedConnect(parent, "static", pineconeRouter.PeerTypeRemote)
|
_, err := pRouter.AuthenticatedConnect(parent, "static", pineconeRouter.PeerTypeRemote, true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ import (
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
||||||
"github.com/matrix-org/pinecone/router"
|
|
||||||
pineconeRouter "github.com/matrix-org/pinecone/router"
|
pineconeRouter "github.com/matrix-org/pinecone/router"
|
||||||
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := log.New(os.Stdout, "", 0)
|
logger := log.New(os.Stdout, "", 0)
|
||||||
pRouter := pineconeRouter.NewRouter(logger, "dendrite", sk, pk, nil)
|
pRouter := pineconeRouter.NewRouter(logger, sk, false)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
listener, err := net.Listen("tcp", *instanceListen)
|
listener, err := net.Listen("tcp", *instanceListen)
|
||||||
|
@ -109,7 +108,7 @@ func main() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
port, err := pRouter.AuthenticatedConnect(conn, "", pineconeRouter.PeerTypeRemote)
|
port, err := pRouter.AuthenticatedConnect(conn, "", pineconeRouter.PeerTypeRemote, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Error("pSwitch.AuthenticatedConnect failed")
|
logrus.WithError(err).Error("pSwitch.AuthenticatedConnect failed")
|
||||||
continue
|
continue
|
||||||
|
@ -125,7 +124,7 @@ func main() {
|
||||||
|
|
||||||
connectToStaticPeer := func() {
|
connectToStaticPeer := func() {
|
||||||
attempt := func() {
|
attempt := func() {
|
||||||
if pRouter.PeerCount(router.PeerTypeRemote) == 0 {
|
if pRouter.PeerCount(pineconeRouter.PeerTypeRemote) == 0 {
|
||||||
uri := *instancePeer
|
uri := *instancePeer
|
||||||
if uri == "" {
|
if uri == "" {
|
||||||
return
|
return
|
||||||
|
@ -211,6 +210,7 @@ func main() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
@ -231,7 +231,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn := conn.WrapWebSocketConn(c)
|
conn := conn.WrapWebSocketConn(c)
|
||||||
if _, err = pRouter.AuthenticatedConnect(conn, "websocket", pineconeRouter.PeerTypeRemote); err != nil {
|
if _, err = pRouter.AuthenticatedConnect(conn, "websocket", pineconeRouter.PeerTypeRemote, true); err != nil {
|
||||||
logrus.WithError(err).Error("Failed to connect WebSocket peer to Pinecone switch")
|
logrus.WithError(err).Error("Failed to connect WebSocket peer to Pinecone switch")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -50,11 +50,9 @@ func NewPineconeRoomProvider(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PineconeRoomProvider) Rooms() []gomatrixserverlib.PublicRoom {
|
func (p *PineconeRoomProvider) Rooms() []gomatrixserverlib.PublicRoom {
|
||||||
known := p.r.KnownNodes()
|
|
||||||
//known = append(known, p.s.Sessions()...)
|
|
||||||
list := []gomatrixserverlib.ServerName{}
|
list := []gomatrixserverlib.ServerName{}
|
||||||
for _, k := range known {
|
for _, k := range p.r.Peers() {
|
||||||
list = append(list, gomatrixserverlib.ServerName(k.String()))
|
list = append(list, gomatrixserverlib.ServerName(k.PublicKey))
|
||||||
}
|
}
|
||||||
return bulkFetchPublicRoomsFromServers(context.Background(), p.fedClient, list)
|
return bulkFetchPublicRoomsFromServers(context.Background(), p.fedClient, list)
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,7 @@ func main() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -170,6 +170,7 @@ func main() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,7 +30,7 @@ func FederationAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
|
||||||
keyAPI := base.KeyServerHTTPClient()
|
keyAPI := base.KeyServerHTTPClient()
|
||||||
|
|
||||||
federationapi.AddPublicRoutes(
|
federationapi.AddPublicRoutes(
|
||||||
base.PublicFederationAPIMux, base.PublicKeyAPIMux,
|
base.PublicFederationAPIMux, base.PublicKeyAPIMux, base.PublicWellKnownAPIMux,
|
||||||
&base.Cfg.FederationAPI, userAPI, federation, keyRing,
|
&base.Cfg.FederationAPI, userAPI, federation, keyRing,
|
||||||
rsAPI, fsAPI, base.EDUServerClient(), keyAPI,
|
rsAPI, fsAPI, base.EDUServerClient(), keyAPI,
|
||||||
&base.Cfg.MSCs, nil,
|
&base.Cfg.MSCs, nil,
|
||||||
|
|
|
@ -148,7 +148,7 @@ func buildDendrite(httpClient *http.Client, dockerClient *client.Client, tmpDir,
|
||||||
// add top level Dockerfile
|
// add top level Dockerfile
|
||||||
err = ioutil.WriteFile(path.Join(*flagHead, "Dockerfile"), []byte(Dockerfile), os.ModePerm)
|
err = ioutil.WriteFile(path.Join(*flagHead, "Dockerfile"), []byte(Dockerfile), os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Custom HEAD: failed to inject /Dockerfile: %w", err)
|
return "", fmt.Errorf("custom HEAD: failed to inject /Dockerfile: %w", err)
|
||||||
}
|
}
|
||||||
// now tarball it
|
// now tarball it
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build wasm
|
||||||
// +build wasm
|
// +build wasm
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
@ -155,7 +156,7 @@ func startup() {
|
||||||
pk := sk.Public().(ed25519.PublicKey)
|
pk := sk.Public().(ed25519.PublicKey)
|
||||||
|
|
||||||
logger := log.New(os.Stdout, "", 0)
|
logger := log.New(os.Stdout, "", 0)
|
||||||
pRouter := pineconeRouter.NewRouter(logger, "dendrite", sk, pk, nil)
|
pRouter := pineconeRouter.NewRouter(logger, sk, false)
|
||||||
pSessions := pineconeSessions.NewSessions(logger, pRouter)
|
pSessions := pineconeSessions.NewSessions(logger, pRouter)
|
||||||
|
|
||||||
cfg := &config.Dendrite{}
|
cfg := &config.Dendrite{}
|
||||||
|
@ -221,6 +222,7 @@ func startup() {
|
||||||
base.PublicClientAPIMux,
|
base.PublicClientAPIMux,
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
|
base.PublicWellKnownAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
base.SynapseAdminMux,
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,16 +5,35 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defaultsForCI := flag.Bool("ci", false, "sane defaults for CI testing")
|
defaultsForCI := flag.Bool("ci", false, "sane defaults for CI testing")
|
||||||
|
serverName := flag.String("server", "", "The domain name of the server if not 'localhost'")
|
||||||
|
dbURI := flag.String("db", "", "The DB URI to use for all components if not SQLite files")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
cfg := &config.Dendrite{}
|
cfg := &config.Dendrite{}
|
||||||
cfg.Defaults()
|
cfg.Defaults()
|
||||||
|
if *serverName != "" {
|
||||||
|
cfg.Global.ServerName = gomatrixserverlib.ServerName(*serverName)
|
||||||
|
}
|
||||||
|
if *dbURI != "" {
|
||||||
|
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.FederationSender.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.MSCs.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.MediaAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.RoomServer.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.SyncAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
}
|
||||||
cfg.Global.TrustedIDServers = []string{
|
cfg.Global.TrustedIDServers = []string{
|
||||||
"matrix.org",
|
"matrix.org",
|
||||||
"vector.im",
|
"vector.im",
|
||||||
|
|
|
@ -54,6 +54,10 @@ global:
|
||||||
# considered valid by other homeservers.
|
# considered valid by other homeservers.
|
||||||
key_validity_period: 168h0m0s
|
key_validity_period: 168h0m0s
|
||||||
|
|
||||||
|
# The server name to delegate server-server communications to, with optional port
|
||||||
|
# e.g. localhost:443
|
||||||
|
well_known_server_name: ""
|
||||||
|
|
||||||
# Lists of domains that the server will trust as identity servers to verify third
|
# Lists of domains that the server will trust as identity servers to verify third
|
||||||
# party identifiers such as phone numbers and email addresses.
|
# party identifiers such as phone numbers and email addresses.
|
||||||
trusted_third_party_id_servers:
|
trusted_third_party_id_servers:
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
|
|
||||||
// AddPublicRoutes sets up and registers HTTP handlers on the base API muxes for the FederationAPI component.
|
// AddPublicRoutes sets up and registers HTTP handlers on the base API muxes for the FederationAPI component.
|
||||||
func AddPublicRoutes(
|
func AddPublicRoutes(
|
||||||
fedRouter, keyRouter *mux.Router,
|
fedRouter, keyRouter, wellKnownRouter *mux.Router,
|
||||||
cfg *config.FederationAPI,
|
cfg *config.FederationAPI,
|
||||||
userAPI userapi.UserInternalAPI,
|
userAPI userapi.UserInternalAPI,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
|
@ -43,7 +43,7 @@ func AddPublicRoutes(
|
||||||
servers federationAPI.ServersInRoomProvider,
|
servers federationAPI.ServersInRoomProvider,
|
||||||
) {
|
) {
|
||||||
routing.Setup(
|
routing.Setup(
|
||||||
fedRouter, keyRouter, cfg, rsAPI,
|
fedRouter, keyRouter, wellKnownRouter, cfg, rsAPI,
|
||||||
eduAPI, federationSenderAPI, keyRing,
|
eduAPI, federationSenderAPI, keyRing,
|
||||||
federation, userAPI, keyAPI, mscCfg,
|
federation, userAPI, keyAPI, mscCfg,
|
||||||
servers,
|
servers,
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
fsAPI := base.FederationSenderHTTPClient()
|
||||||
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
|
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
|
||||||
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
|
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
|
||||||
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
|
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, base.PublicWellKnownAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
|
||||||
baseURL, cancel := test.ListenAndServe(t, base.PublicFederationAPIMux, true)
|
baseURL, cancel := test.ListenAndServe(t, base.PublicFederationAPIMux, true)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))
|
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))
|
||||||
|
|
|
@ -30,6 +30,7 @@ import (
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup registers HTTP handlers with the given ServeMux.
|
// Setup registers HTTP handlers with the given ServeMux.
|
||||||
|
@ -41,7 +42,7 @@ import (
|
||||||
// applied:
|
// applied:
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func Setup(
|
func Setup(
|
||||||
fedMux, keyMux *mux.Router,
|
fedMux, keyMux, wkMux *mux.Router,
|
||||||
cfg *config.FederationAPI,
|
cfg *config.FederationAPI,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
eduAPI eduserverAPI.EDUServerInputAPI,
|
eduAPI eduserverAPI.EDUServerInputAPI,
|
||||||
|
@ -85,6 +86,21 @@ func Setup(
|
||||||
return NotaryKeys(req, cfg, fsAPI, pkReq)
|
return NotaryKeys(req, cfg, fsAPI, pkReq)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if cfg.Matrix.WellKnownServerName != "" {
|
||||||
|
logrus.Infof("Setting m.server as %s at /.well-known/matrix/server", cfg.Matrix.WellKnownServerName)
|
||||||
|
wkMux.Handle("/server", httputil.MakeExternalAPI("wellknown", func(req *http.Request) util.JSONResponse {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: struct {
|
||||||
|
ServerName string `json:"m.server"`
|
||||||
|
}{
|
||||||
|
ServerName: cfg.Matrix.WellKnownServerName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore the {keyID} argument as we only have a single server key so we always
|
// Ignore the {keyID} argument as we only have a single server key so we always
|
||||||
// return that key.
|
// return that key.
|
||||||
// Even if we had more than one server key, we would probably still ignore the
|
// Even if we had more than one server key, we would probably still ignore the
|
||||||
|
|
|
@ -306,7 +306,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err = gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
|
if err = event.VerifyEventSignatures(ctx, t.keys); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
|
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
|
||||||
results[event.EventID()] = gomatrixserverlib.PDUResult{
|
results[event.EventID()] = gomatrixserverlib.PDUResult{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
@ -345,7 +345,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
|
||||||
}
|
}
|
||||||
|
|
||||||
if c := len(results); c > 0 {
|
if c := len(results); c > 0 {
|
||||||
util.GetLogger(ctx).Infof("Processed %d PDUs from transaction %q", c, t.TransactionID)
|
util.GetLogger(ctx).Infof("Processed %d PDUs from %v in transaction %q", c, t.Origin, t.TransactionID)
|
||||||
}
|
}
|
||||||
return &gomatrixserverlib.RespSend{PDUs: results}, nil
|
return &gomatrixserverlib.RespSend{PDUs: results}, nil
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ withNextEvent:
|
||||||
}
|
}
|
||||||
|
|
||||||
if missing := len(missingAuthEvents); missing > 0 {
|
if missing := len(missingAuthEvents); missing > 0 {
|
||||||
return fmt.Errorf("Event refers to %d auth_events which we failed to fetch", missing)
|
return fmt.Errorf("event refers to %d auth_events which we failed to fetch", missing)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1358,7 @@ func (t *txnReq) lookupEvent(ctx context.Context, roomVersion gomatrixserverlib.
|
||||||
util.GetLogger(ctx).WithField("event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(servers))
|
util.GetLogger(ctx).WithField("event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(servers))
|
||||||
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(servers))
|
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(servers))
|
||||||
}
|
}
|
||||||
if err := gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
|
if err := event.VerifyEventSignatures(ctx, t.keys); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
|
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
|
||||||
return nil, verifySigError{event.EventID(), err}
|
return nil, verifySigError{event.EventID(), err}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup/process"
|
"github.com/matrix-org/dendrite/setup/process"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// KeyChangeConsumer consumes events that originate in key server.
|
// KeyChangeConsumer consumes events that originate in key server.
|
||||||
|
@ -82,7 +81,7 @@ func (t *KeyChangeConsumer) Start() error {
|
||||||
func (t *KeyChangeConsumer) onMessage(msg *sarama.ConsumerMessage) error {
|
func (t *KeyChangeConsumer) onMessage(msg *sarama.ConsumerMessage) error {
|
||||||
var m api.DeviceMessage
|
var m api.DeviceMessage
|
||||||
if err := json.Unmarshal(msg.Value, &m); err != nil {
|
if err := json.Unmarshal(msg.Value, &m); err != nil {
|
||||||
log.WithError(err).Errorf("failed to read device message from key change topic")
|
logrus.WithError(err).Errorf("failed to read device message from key change topic")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch m.Type {
|
switch m.Type {
|
||||||
|
@ -96,7 +95,7 @@ func (t *KeyChangeConsumer) onMessage(msg *sarama.ConsumerMessage) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) error {
|
func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) error {
|
||||||
logger := log.WithField("user_id", m.UserID)
|
logger := logrus.WithField("user_id", m.UserID)
|
||||||
|
|
||||||
// only send key change events which originated from us
|
// only send key change events which originated from us
|
||||||
_, originServerName, err := gomatrixserverlib.SplitID('@', m.UserID)
|
_, originServerName, err := gomatrixserverlib.SplitID('@', m.UserID)
|
||||||
|
@ -142,7 +141,7 @@ func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Sending device list update message to %q", destinations)
|
logrus.Infof("Sending device list update message to %q", destinations)
|
||||||
return t.queues.SendEDU(edu, t.serverName, destinations)
|
return t.queues.SendEDU(edu, t.serverName, destinations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +157,7 @@ func (t *KeyChangeConsumer) onCrossSigningMessage(m api.DeviceMessage) error {
|
||||||
// end up parroting information we received from other servers.
|
// end up parroting information we received from other servers.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
logger := log.WithField("user_id", output.UserID)
|
logger := logrus.WithField("user_id", output.UserID)
|
||||||
|
|
||||||
var queryRes roomserverAPI.QueryRoomsForUserResponse
|
var queryRes roomserverAPI.QueryRoomsForUserResponse
|
||||||
err = t.rsAPI.QueryRoomsForUser(context.Background(), &roomserverAPI.QueryRoomsForUserRequest{
|
err = t.rsAPI.QueryRoomsForUser(context.Background(), &roomserverAPI.QueryRoomsForUserRequest{
|
||||||
|
|
|
@ -409,7 +409,7 @@ func (r *FederationSenderInternalAPI) performOutboundPeekUsingServer(
|
||||||
return fmt.Errorf("sanityCheckAuthChain: %w", err)
|
return fmt.Errorf("sanityCheckAuthChain: %w", err)
|
||||||
}
|
}
|
||||||
if err = respState.Check(ctx, r.keyRing, federatedAuthProvider(ctx, r.federation, r.keyRing, serverName)); err != nil {
|
if err = respState.Check(ctx, r.keyRing, federatedAuthProvider(ctx, r.federation, r.keyRing, serverName)); err != nil {
|
||||||
return fmt.Errorf("Error checking state returned from peeking: %w", err)
|
return fmt.Errorf("error checking state returned from peeking: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've got this far, the remote server is peeking.
|
// If we've got this far, the remote server is peeking.
|
||||||
|
@ -523,7 +523,7 @@ func (r *FederationSenderInternalAPI) PerformLeave(
|
||||||
|
|
||||||
// If we reach here then we didn't complete a leave for some reason.
|
// If we reach here then we didn't complete a leave for some reason.
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"Failed to leave room %q through %d server(s)",
|
"failed to leave room %q through %d server(s)",
|
||||||
request.RoomID, len(request.ServerNames),
|
request.RoomID, len(request.ServerNames),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -713,14 +713,8 @@ func federatedAuthProvider(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the signatures of the event.
|
// Check the signatures of the event.
|
||||||
if res, err := gomatrixserverlib.VerifyEventSignatures(ctx, []*gomatrixserverlib.Event{ev}, keyRing); err != nil {
|
if err := ev.VerifyEventSignatures(ctx, keyRing); err != nil {
|
||||||
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
|
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
|
||||||
} else {
|
|
||||||
for _, err := range res {
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the event is OK then add it to the results and the retry map.
|
// If the event is OK then add it to the results and the retry map.
|
||||||
|
|
|
@ -29,7 +29,6 @@ import (
|
||||||
"github.com/matrix-org/gomatrix"
|
"github.com/matrix-org/gomatrix"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ type destinationQueue struct {
|
||||||
// start sending events to that destination.
|
// start sending events to that destination.
|
||||||
func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, receipt *shared.Receipt) {
|
func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, receipt *shared.Receipt) {
|
||||||
if event == nil {
|
if event == nil {
|
||||||
log.Errorf("attempt to send nil PDU with destination %q", oq.destination)
|
logrus.Errorf("attempt to send nil PDU with destination %q", oq.destination)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Create a database entry that associates the given PDU NID with
|
// Create a database entry that associates the given PDU NID with
|
||||||
|
@ -84,7 +83,7 @@ func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, re
|
||||||
oq.destination, // the destination server name
|
oq.destination, // the destination server name
|
||||||
receipt, // NIDs from federationsender_queue_json table
|
receipt, // NIDs from federationsender_queue_json table
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.WithError(err).Errorf("failed to associate PDU %q with destination %q", event.EventID(), oq.destination)
|
logrus.WithError(err).Errorf("failed to associate PDU %q with destination %q", event.EventID(), oq.destination)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Check if the destination is blacklisted. If it isn't then wake
|
// Check if the destination is blacklisted. If it isn't then wake
|
||||||
|
@ -116,7 +115,7 @@ func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, re
|
||||||
// start sending events to that destination.
|
// start sending events to that destination.
|
||||||
func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *shared.Receipt) {
|
func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *shared.Receipt) {
|
||||||
if event == nil {
|
if event == nil {
|
||||||
log.Errorf("attempt to send nil EDU with destination %q", oq.destination)
|
logrus.Errorf("attempt to send nil EDU with destination %q", oq.destination)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Create a database entry that associates the given PDU NID with
|
// Create a database entry that associates the given PDU NID with
|
||||||
|
@ -127,7 +126,7 @@ func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *share
|
||||||
oq.destination, // the destination server name
|
oq.destination, // the destination server name
|
||||||
receipt, // NIDs from federationsender_queue_json table
|
receipt, // NIDs from federationsender_queue_json table
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.WithError(err).Errorf("failed to associate EDU with destination %q", oq.destination)
|
logrus.WithError(err).Errorf("failed to associate EDU with destination %q", oq.destination)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Check if the destination is blacklisted. If it isn't then wake
|
// Check if the destination is blacklisted. If it isn't then wake
|
||||||
|
@ -281,7 +280,7 @@ func (oq *destinationQueue) backgroundSend() {
|
||||||
// It's been suggested that we should give up because the backoff
|
// It's been suggested that we should give up because the backoff
|
||||||
// has exceeded a maximum allowable value. Clean up the in-memory
|
// has exceeded a maximum allowable value. Clean up the in-memory
|
||||||
// buffers at this point. The PDU clean-up is already on a defer.
|
// buffers at this point. The PDU clean-up is already on a defer.
|
||||||
log.Warnf("Blacklisting %q due to exceeding backoff threshold", oq.destination)
|
logrus.Warnf("Blacklisting %q due to exceeding backoff threshold", oq.destination)
|
||||||
oq.pendingMutex.Lock()
|
oq.pendingMutex.Lock()
|
||||||
for i := range oq.pendingPDUs {
|
for i := range oq.pendingPDUs {
|
||||||
oq.pendingPDUs[i] = nil
|
oq.pendingPDUs[i] = nil
|
||||||
|
@ -298,7 +297,7 @@ func (oq *destinationQueue) backgroundSend() {
|
||||||
// We haven't backed off yet, so wait for the suggested amount of
|
// We haven't backed off yet, so wait for the suggested amount of
|
||||||
// time.
|
// time.
|
||||||
duration := time.Until(*until)
|
duration := time.Until(*until)
|
||||||
log.Warnf("Backing off %q for %s", oq.destination, duration)
|
logrus.Warnf("Backing off %q for %s", oq.destination, duration)
|
||||||
oq.backingOff.Store(true)
|
oq.backingOff.Store(true)
|
||||||
destinationQueueBackingOff.Inc()
|
destinationQueueBackingOff.Inc()
|
||||||
select {
|
select {
|
||||||
|
@ -421,13 +420,13 @@ func (oq *destinationQueue) nextTransaction(
|
||||||
if pduReceipts != nil {
|
if pduReceipts != nil {
|
||||||
//logrus.Infof("Cleaning PDUs %q", pduReceipt.String())
|
//logrus.Infof("Cleaning PDUs %q", pduReceipt.String())
|
||||||
if err = oq.db.CleanPDUs(context.Background(), oq.destination, pduReceipts); err != nil {
|
if err = oq.db.CleanPDUs(context.Background(), oq.destination, pduReceipts); err != nil {
|
||||||
log.WithError(err).Errorf("Failed to clean PDUs for server %q", t.Destination)
|
logrus.WithError(err).Errorf("Failed to clean PDUs for server %q", t.Destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if eduReceipts != nil {
|
if eduReceipts != nil {
|
||||||
//logrus.Infof("Cleaning EDUs %q", eduReceipt.String())
|
//logrus.Infof("Cleaning EDUs %q", eduReceipt.String())
|
||||||
if err = oq.db.CleanEDUs(context.Background(), oq.destination, eduReceipts); err != nil {
|
if err = oq.db.CleanEDUs(context.Background(), oq.destination, eduReceipts); err != nil {
|
||||||
log.WithError(err).Errorf("Failed to clean EDUs for server %q", t.Destination)
|
logrus.WithError(err).Errorf("Failed to clean EDUs for server %q", t.Destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reset the transaction ID.
|
// Reset the transaction ID.
|
||||||
|
@ -440,9 +439,9 @@ func (oq *destinationQueue) nextTransaction(
|
||||||
// will retry again, subject to backoff.
|
// will retry again, subject to backoff.
|
||||||
return false, 0, 0, err
|
return false, 0, 0, err
|
||||||
default:
|
default:
|
||||||
log.WithFields(log.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"destination": oq.destination,
|
"destination": oq.destination,
|
||||||
log.ErrorKey: err,
|
logrus.ErrorKey: err,
|
||||||
}).Debugf("Failed to send transaction %q", t.TransactionID)
|
}).Debugf("Failed to send transaction %q", t.TransactionID)
|
||||||
return false, 0, 0, err
|
return false, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
17
go.mod
17
go.mod
|
@ -7,7 +7,7 @@ require (
|
||||||
github.com/Masterminds/semver/v3 v3.1.1
|
github.com/Masterminds/semver/v3 v3.1.1
|
||||||
github.com/Shopify/sarama v1.29.1
|
github.com/Shopify/sarama v1.29.1
|
||||||
github.com/codeclysm/extract v2.2.0+incompatible
|
github.com/codeclysm/extract v2.2.0+incompatible
|
||||||
github.com/containerd/containerd v1.5.5 // indirect
|
github.com/containerd/containerd v1.5.7 // indirect
|
||||||
github.com/docker/docker v20.10.7+incompatible
|
github.com/docker/docker v20.10.7+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/getsentry/sentry-go v0.11.0
|
github.com/getsentry/sentry-go v0.11.0
|
||||||
|
@ -27,13 +27,13 @@ require (
|
||||||
github.com/libp2p/go-libp2p-pubsub v0.4.1
|
github.com/libp2p/go-libp2p-pubsub v0.4.1
|
||||||
github.com/libp2p/go-libp2p-record v0.1.3
|
github.com/libp2p/go-libp2p-record v0.1.3
|
||||||
github.com/lucas-clemente/quic-go v0.22.0
|
github.com/lucas-clemente/quic-go v0.22.0
|
||||||
github.com/matrix-org/dugong v0.0.0-20210603171012-8379174dca81
|
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
||||||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
|
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
|
||||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d
|
github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210817115641-f9416ac1a723
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20211102101113-5e02b64e5312
|
||||||
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0
|
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0
|
||||||
github.com/matrix-org/pinecone v0.0.0-20210819150600-e692df1a5c42
|
github.com/matrix-org/pinecone v0.0.0-20211022090602-08a50945ac89
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
||||||
github.com/mattn/go-sqlite3 v1.14.8
|
github.com/mattn/go-sqlite3 v1.14.8
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
|
@ -46,17 +46,16 @@ require (
|
||||||
github.com/pressly/goose v2.7.0+incompatible
|
github.com/pressly/goose v2.7.0+incompatible
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/tidwall/gjson v1.8.1
|
github.com/tidwall/gjson v1.9.3
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
|
||||||
github.com/tidwall/sjson v1.1.7
|
github.com/tidwall/sjson v1.1.7
|
||||||
github.com/uber/jaeger-client-go v2.29.1+incompatible
|
github.com/uber/jaeger-client-go v2.29.1+incompatible
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||||
github.com/yggdrasil-network/yggdrasil-go v0.4.1-0.20210715083903-52309d094c00
|
github.com/yggdrasil-network/yggdrasil-go v0.4.1-0.20210715083903-52309d094c00
|
||||||
go.uber.org/atomic v1.9.0
|
go.uber.org/atomic v1.9.0
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||||
|
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
|
||||||
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554
|
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985
|
golang.org/x/net v0.0.0-20210927181540-4e4d966f7476
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
|
||||||
gopkg.in/h2non/bimg.v1 v1.1.5
|
gopkg.in/h2non/bimg.v1 v1.1.5
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
|
54
go.sum
54
go.sum
|
@ -77,7 +77,7 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
|
||||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||||
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||||
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
||||||
github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
|
@ -116,9 +116,7 @@ github.com/anacrolix/missinggo v1.1.2-0.20190815015349-b888af804467/go.mod h1:MB
|
||||||
github.com/anacrolix/missinggo v1.2.1 h1:0IE3TqX5y5D0IxeMwTyIgqdDew4QrzcXaaEnJQyjHvw=
|
github.com/anacrolix/missinggo v1.2.1 h1:0IE3TqX5y5D0IxeMwTyIgqdDew4QrzcXaaEnJQyjHvw=
|
||||||
github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y=
|
github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y=
|
||||||
github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5urunoLS0Cbvb4V0uMQ=
|
github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5urunoLS0Cbvb4V0uMQ=
|
||||||
github.com/anacrolix/sync v0.2.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
|
|
||||||
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
|
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
|
||||||
github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNaBJ2Dk=
|
|
||||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
@ -219,8 +217,8 @@ github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo
|
||||||
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
||||||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||||
github.com/containerd/containerd v1.5.5 h1:q1gxsZsGZ8ddVe98yO6pR21b5xQSMiR61lD0W96pgQo=
|
github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM=
|
||||||
github.com/containerd/containerd v1.5.5/go.mod h1:oSTh0QpT1w6jYcGmbiSbxv9OSQYaa88mPyWIuU79zyo=
|
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
|
@ -577,6 +575,7 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
||||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
|
@ -985,8 +984,8 @@ github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+
|
||||||
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
|
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
|
||||||
github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E=
|
github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E=
|
||||||
github.com/masterzen/xmlpath v0.0.0-20140218185901-13f4951698ad/go.mod h1:A0zPC53iKKKcXYxr4ROjpQRQ5FgJXtelNdSmHHuq/tY=
|
github.com/masterzen/xmlpath v0.0.0-20140218185901-13f4951698ad/go.mod h1:A0zPC53iKKKcXYxr4ROjpQRQ5FgJXtelNdSmHHuq/tY=
|
||||||
github.com/matrix-org/dugong v0.0.0-20210603171012-8379174dca81 h1:lHNIqMZ77Y++RbHuR4eSehyv6KUKb2sJ8Gdfro4P5f4=
|
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e h1:DP5RC0Z3XdyBEW5dKt8YPeN6vZbm6OzVaGVp7f1BQRM=
|
||||||
github.com/matrix-org/dugong v0.0.0-20210603171012-8379174dca81/go.mod h1:NgPCr+UavRGH6n5jmdX8DuqFZ4JiCWIJoZiuhTRLSUg=
|
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e/go.mod h1:NgPCr+UavRGH6n5jmdX8DuqFZ4JiCWIJoZiuhTRLSUg=
|
||||||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 h1:eqE5OnGx9ZMWmrRbD3KF/3KtTunw0iQulI7YxOIdxo4=
|
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 h1:eqE5OnGx9ZMWmrRbD3KF/3KtTunw0iQulI7YxOIdxo4=
|
||||||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4/go.mod h1:3WluEZ9QXSwU30tWYqktnpC1x9mwZKx1r8uAv8Iq+a4=
|
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4/go.mod h1:3WluEZ9QXSwU30tWYqktnpC1x9mwZKx1r8uAv8Iq+a4=
|
||||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d h1:mGhPVaTht5NViFN/UpdrIlRApmH2FWcVaKUH5MdBKiY=
|
github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d h1:mGhPVaTht5NViFN/UpdrIlRApmH2FWcVaKUH5MdBKiY=
|
||||||
|
@ -994,12 +993,12 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d/go.mod h1
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210817115641-f9416ac1a723 h1:b8cyR4aYv9Lmf1lKgASJ+PFSp/GBv8ZFgb/O42ZXLGA=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20211102101113-5e02b64e5312 h1:of3kbkOrjE8793Vsni8ofxMSy/vpO1SB+ZkHSfv4wrs=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210817115641-f9416ac1a723/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20211102101113-5e02b64e5312/go.mod h1:rB8tBUUUo1rzUqpzklRDSooxZ6YMhoaEPx4SO5fGeUc=
|
||||||
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0 h1:HZCzy4oVzz55e+cOMiX/JtSF2UOY1evBl2raaE7ACcU=
|
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0 h1:HZCzy4oVzz55e+cOMiX/JtSF2UOY1evBl2raaE7ACcU=
|
||||||
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
|
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20210819150600-e692df1a5c42 h1:ZO39w5Kbq9Aw3uHHT5QjFR2kpVHxuJxHD3zOhmU5BVI=
|
github.com/matrix-org/pinecone v0.0.0-20211022090602-08a50945ac89 h1:6JkIymZ1vxfI0shSpg6gNPTJaF4/95Evy34slPVZGKM=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20210819150600-e692df1a5c42/go.mod h1:CVlrvs1R5iz7Omy2GqAjJJKbACn07GZgUq1Gli18FYE=
|
github.com/matrix-org/pinecone v0.0.0-20211022090602-08a50945ac89/go.mod h1:r6dsL+ylE0yXe/7zh8y/Bdh6aBYI1r+u4yZni9A4iyk=
|
||||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||||
|
@ -1034,6 +1033,7 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex
|
||||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||||
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||||
github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
||||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
|
@ -1192,7 +1192,7 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
|
||||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||||
github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
|
@ -1366,15 +1366,12 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
|
||||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||||
github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU=
|
github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=
|
||||||
github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
|
||||||
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
|
||||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
@ -1501,6 +1498,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
@ -1517,8 +1515,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
||||||
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -1531,7 +1529,10 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
|
||||||
|
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
@ -1606,8 +1607,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
|
golang.org/x/net v0.0.0-20210927181540-4e4d966f7476 h1:s5hu7bTnLKswvidgtqc4GwsW83m9LZu8UAqzmWOZtI4=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -1662,6 +1663,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -1713,8 +1715,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||||
|
@ -1757,6 +1759,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
@ -1791,6 +1794,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
|
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
|
||||||
|
golang.zx2c4.com/wireguard v0.0.0-20210927201915-bb745b2ea326/go.mod h1:SDoazCvdy7RDjBPNEMBwrXhomlmtG7svs8mgwWEqtVI=
|
||||||
golang.zx2c4.com/wireguard/windows v0.3.14/go.mod h1:3P4IEAsb+BjlKZmpUXgy74c0iX9AVwwr3WcVJ8nPgME=
|
golang.zx2c4.com/wireguard/windows v0.3.14/go.mod h1:3P4IEAsb+BjlKZmpUXgy74c0iX9AVwwr3WcVJ8nPgME=
|
||||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
|
|
||||||
// ErrRoomNoExists is returned when trying to lookup the state of a room that
|
// ErrRoomNoExists is returned when trying to lookup the state of a room that
|
||||||
// doesn't exist
|
// doesn't exist
|
||||||
var ErrRoomNoExists = errors.New("Room does not exist")
|
var ErrRoomNoExists = errors.New("room does not exist")
|
||||||
|
|
||||||
// QueryAndBuildEvent builds a Matrix event using the event builder and roomserver query
|
// QueryAndBuildEvent builds a Matrix event using the event builder and roomserver query
|
||||||
// API client provided. If also fills roomserver query API response (if provided)
|
// API client provided. If also fills roomserver query API response (if provided)
|
||||||
|
|
|
@ -77,9 +77,9 @@ func PostJSON(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if msgerr := json.NewDecoder(res.Body).Decode(&errorBody); msgerr == nil {
|
if msgerr := json.NewDecoder(res.Body).Decode(&errorBody); msgerr == nil {
|
||||||
return fmt.Errorf("Internal API: %d from %s: %s", res.StatusCode, apiURL, errorBody.Message)
|
return fmt.Errorf("internal API: %d from %s: %s", res.StatusCode, apiURL, errorBody.Message)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Internal API: %d from %s", res.StatusCode, apiURL)
|
return fmt.Errorf("internal API: %d from %s", res.StatusCode, apiURL)
|
||||||
}
|
}
|
||||||
return json.NewDecoder(res.Body).Decode(response)
|
return json.NewDecoder(res.Body).Decode(response)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,5 +19,6 @@ const (
|
||||||
PublicFederationPathPrefix = "/_matrix/federation/"
|
PublicFederationPathPrefix = "/_matrix/federation/"
|
||||||
PublicKeyPathPrefix = "/_matrix/key/"
|
PublicKeyPathPrefix = "/_matrix/key/"
|
||||||
PublicMediaPathPrefix = "/_matrix/media/"
|
PublicMediaPathPrefix = "/_matrix/media/"
|
||||||
|
PublicWellKnownPrefix = "/.well-known/matrix/"
|
||||||
InternalPathPrefix = "/api/"
|
InternalPathPrefix = "/api/"
|
||||||
)
|
)
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (m *Migrations) RunDeltas(db *sql.DB, props *config.DatabaseOptions) error
|
||||||
minVer := int64(0)
|
minVer := int64(0)
|
||||||
migrations, err := m.collect(minVer, maxVer)
|
migrations, err := m.collect(minVer, maxVer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("RunDeltas: Failed to collect migrations: %w", err)
|
return fmt.Errorf("runDeltas: Failed to collect migrations: %w", err)
|
||||||
}
|
}
|
||||||
if props.ConnectionString.IsPostgres() {
|
if props.ConnectionString.IsPostgres() {
|
||||||
if err = goose.SetDialect("postgres"); err != nil {
|
if err = goose.SetDialect("postgres"); err != nil {
|
||||||
|
@ -57,12 +57,12 @@ func (m *Migrations) RunDeltas(db *sql.DB, props *config.DatabaseOptions) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Unknown connection string: %s", props.ConnectionString)
|
return fmt.Errorf("unknown connection string: %s", props.ConnectionString)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
current, err := goose.EnsureDBVersion(db)
|
current, err := goose.EnsureDBVersion(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("RunDeltas: Failed to EnsureDBVersion: %w", err)
|
return fmt.Errorf("runDeltas: Failed to EnsureDBVersion: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
next, err := migrations.Next(current)
|
next, err := migrations.Next(current)
|
||||||
|
@ -71,11 +71,11 @@ func (m *Migrations) RunDeltas(db *sql.DB, props *config.DatabaseOptions) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("RunDeltas: Failed to load next migration to %+v : %w", next, err)
|
return fmt.Errorf("runDeltas: Failed to load next migration to %+v : %w", next, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = next.Up(db); err != nil {
|
if err = next.Up(db); err != nil {
|
||||||
return fmt.Errorf("RunDeltas: Failed run migration: %w", err)
|
return fmt.Errorf("runDeltas: Failed run migration: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrUserExists is returned if a username already exists in the database.
|
// ErrUserExists is returned if a username already exists in the database.
|
||||||
var ErrUserExists = errors.New("Username already exists")
|
var ErrUserExists = errors.New("username already exists")
|
||||||
|
|
||||||
// A Transaction is something that can be committed or rolledback.
|
// A Transaction is something that can be committed or rolledback.
|
||||||
type Transaction interface {
|
type Transaction interface {
|
||||||
|
|
|
@ -37,10 +37,10 @@ import (
|
||||||
// For example, if Base64Hash is 'qwerty', the path will be 'q/w/erty/file'.
|
// For example, if Base64Hash is 'qwerty', the path will be 'q/w/erty/file'.
|
||||||
func GetPathFromBase64Hash(base64Hash types.Base64Hash, absBasePath config.Path) (string, error) {
|
func GetPathFromBase64Hash(base64Hash types.Base64Hash, absBasePath config.Path) (string, error) {
|
||||||
if len(base64Hash) < 3 {
|
if len(base64Hash) < 3 {
|
||||||
return "", fmt.Errorf("Invalid filePath (Base64Hash too short - min 3 characters): %q", base64Hash)
|
return "", fmt.Errorf("invalid filePath (Base64Hash too short - min 3 characters): %q", base64Hash)
|
||||||
}
|
}
|
||||||
if len(base64Hash) > 255 {
|
if len(base64Hash) > 255 {
|
||||||
return "", fmt.Errorf("Invalid filePath (Base64Hash too long - max 255 characters): %q", base64Hash)
|
return "", fmt.Errorf("invalid filePath (Base64Hash too long - max 255 characters): %q", base64Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
filePath, err := filepath.Abs(filepath.Join(
|
filePath, err := filepath.Abs(filepath.Join(
|
||||||
|
@ -51,14 +51,14 @@ func GetPathFromBase64Hash(base64Hash types.Base64Hash, absBasePath config.Path)
|
||||||
"file",
|
"file",
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Unable to construct filePath: %w", err)
|
return "", fmt.Errorf("unable to construct filePath: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the absolute absBasePath is a prefix of the absolute filePath
|
// check if the absolute absBasePath is a prefix of the absolute filePath
|
||||||
// if so, no directory escape has occurred and the filePath is valid
|
// if so, no directory escape has occurred and the filePath is valid
|
||||||
// Note: absBasePath is already absolute
|
// Note: absBasePath is already absolute
|
||||||
if !strings.HasPrefix(filePath, string(absBasePath)) {
|
if !strings.HasPrefix(filePath, string(absBasePath)) {
|
||||||
return "", fmt.Errorf("Invalid filePath (not within absBasePath %v): %v", absBasePath, filePath)
|
return "", fmt.Errorf("invalid filePath (not within absBasePath %v): %v", absBasePath, filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return filePath, nil
|
return filePath, nil
|
||||||
|
@ -102,7 +102,7 @@ func MoveFileWithHashCheck(tmpDir types.Path, mediaMetadata *types.MediaMetadata
|
||||||
func RemoveDir(dir types.Path, logger *log.Entry) {
|
func RemoveDir(dir types.Path, logger *log.Entry) {
|
||||||
dirErr := os.RemoveAll(string(dir))
|
dirErr := os.RemoveAll(string(dir))
|
||||||
if dirErr != nil {
|
if dirErr != nil {
|
||||||
logger.WithError(dirErr).WithField("dir", dir).Warn("Failed to remove directory")
|
logger.WithError(dirErr).WithField("dir", dir).Warn("failed to remove directory")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +153,11 @@ func moveFile(src types.Path, dst types.Path) error {
|
||||||
|
|
||||||
err := os.MkdirAll(dstDir, 0770)
|
err := os.MkdirAll(dstDir, 0770)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to make directory: %w", err)
|
return fmt.Errorf("failed to make directory: %w", err)
|
||||||
}
|
}
|
||||||
err = os.Rename(string(src), string(dst))
|
err = os.Rename(string(src), string(dst))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to move directory: %w", err)
|
return fmt.Errorf("failed to move directory: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -165,11 +165,11 @@ func moveFile(src types.Path, dst types.Path) error {
|
||||||
func createTempFileWriter(absBasePath config.Path) (*bufio.Writer, *os.File, types.Path, error) {
|
func createTempFileWriter(absBasePath config.Path) (*bufio.Writer, *os.File, types.Path, error) {
|
||||||
tmpDir, err := createTempDir(absBasePath)
|
tmpDir, err := createTempDir(absBasePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", fmt.Errorf("Failed to create temp dir: %w", err)
|
return nil, nil, "", fmt.Errorf("failed to create temp dir: %w", err)
|
||||||
}
|
}
|
||||||
writer, tmpFile, err := createFileWriter(tmpDir)
|
writer, tmpFile, err := createFileWriter(tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", fmt.Errorf("Failed to create file writer: %w", err)
|
return nil, nil, "", fmt.Errorf("failed to create file writer: %w", err)
|
||||||
}
|
}
|
||||||
return writer, tmpFile, tmpDir, nil
|
return writer, tmpFile, tmpDir, nil
|
||||||
}
|
}
|
||||||
|
@ -178,11 +178,11 @@ func createTempFileWriter(absBasePath config.Path) (*bufio.Writer, *os.File, typ
|
||||||
func createTempDir(baseDirectory config.Path) (types.Path, error) {
|
func createTempDir(baseDirectory config.Path) (types.Path, error) {
|
||||||
baseTmpDir := filepath.Join(string(baseDirectory), "tmp")
|
baseTmpDir := filepath.Join(string(baseDirectory), "tmp")
|
||||||
if err := os.MkdirAll(baseTmpDir, 0770); err != nil {
|
if err := os.MkdirAll(baseTmpDir, 0770); err != nil {
|
||||||
return "", fmt.Errorf("Failed to create base temp dir: %w", err)
|
return "", fmt.Errorf("failed to create base temp dir: %w", err)
|
||||||
}
|
}
|
||||||
tmpDir, err := ioutil.TempDir(baseTmpDir, "")
|
tmpDir, err := ioutil.TempDir(baseTmpDir, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Failed to create temp dir: %w", err)
|
return "", fmt.Errorf("failed to create temp dir: %w", err)
|
||||||
}
|
}
|
||||||
return types.Path(tmpDir), nil
|
return types.Path(tmpDir), nil
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func createFileWriter(directory types.Path) (*bufio.Writer, *os.File, error) {
|
||||||
filePath := filepath.Join(string(directory), "content")
|
filePath := filepath.Join(string(directory), "content")
|
||||||
file, err := os.Create(filePath)
|
file, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Failed to create file: %w", err)
|
return nil, nil, fmt.Errorf("failed to create file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bufio.NewWriter(file), file, nil
|
return bufio.NewWriter(file), file, nil
|
||||||
|
|
|
@ -737,7 +737,7 @@ func (r *downloadRequest) fetchRemoteFile(
|
||||||
return "", false, parseErr
|
return "", false, parseErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if contentLength > int64(maxFileSizeBytes) {
|
if maxFileSizeBytes > 0 && contentLength > int64(maxFileSizeBytes) {
|
||||||
// TODO: Bubble up this as a 413
|
// TODO: Bubble up this as a 413
|
||||||
return "", false, fmt.Errorf("remote file is too large (%v > %v bytes)", contentLength, maxFileSizeBytes)
|
return "", false, fmt.Errorf("remote file is too large (%v > %v bytes)", contentLength, maxFileSizeBytes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,10 @@ import (
|
||||||
|
|
||||||
// Imported for png codec
|
// Imported for png codec
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
|
|
||||||
|
// Imported for webp codec
|
||||||
|
_ "golang.org/x/image/webp"
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ func (r *Inviter) PerformInvite(
|
||||||
targetUserID := *event.StateKey()
|
targetUserID := *event.StateKey()
|
||||||
info, err := r.DB.RoomInfo(ctx, roomID)
|
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to load RoomInfo: %w", err)
|
return nil, fmt.Errorf("failed to load RoomInfo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
|
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
|
||||||
rsAPI "github.com/matrix-org/dendrite/roomserver/api"
|
rsAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||||
|
@ -49,17 +48,17 @@ type Joiner struct {
|
||||||
// PerformJoin handles joining matrix rooms, including over federation by talking to the federationsender.
|
// PerformJoin handles joining matrix rooms, including over federation by talking to the federationsender.
|
||||||
func (r *Joiner) PerformJoin(
|
func (r *Joiner) PerformJoin(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
res *api.PerformJoinResponse,
|
res *rsAPI.PerformJoinResponse,
|
||||||
) {
|
) {
|
||||||
roomID, joinedVia, err := r.performJoin(ctx, req)
|
roomID, joinedVia, err := r.performJoin(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sentry.CaptureException(err)
|
sentry.CaptureException(err)
|
||||||
perr, ok := err.(*api.PerformError)
|
perr, ok := err.(*rsAPI.PerformError)
|
||||||
if ok {
|
if ok {
|
||||||
res.Error = perr
|
res.Error = perr
|
||||||
} else {
|
} else {
|
||||||
res.Error = &api.PerformError{
|
res.Error = &rsAPI.PerformError{
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,18 +69,18 @@ func (r *Joiner) PerformJoin(
|
||||||
|
|
||||||
func (r *Joiner) performJoin(
|
func (r *Joiner) performJoin(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
) (string, gomatrixserverlib.ServerName, error) {
|
) (string, gomatrixserverlib.ServerName, error) {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if domain != r.Cfg.Matrix.ServerName {
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,20 +90,20 @@ func (r *Joiner) performJoin(
|
||||||
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
||||||
return r.performJoinRoomByAlias(ctx, req)
|
return r.performJoinRoomByAlias(ctx, req)
|
||||||
}
|
}
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("Room ID or alias %q is invalid", req.RoomIDOrAlias),
|
Msg: fmt.Sprintf("Room ID or alias %q is invalid", req.RoomIDOrAlias),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Joiner) performJoinRoomByAlias(
|
func (r *Joiner) performJoinRoomByAlias(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
) (string, gomatrixserverlib.ServerName, error) {
|
) (string, gomatrixserverlib.ServerName, error) {
|
||||||
// Get the domain part of the room alias.
|
// Get the domain part of the room alias.
|
||||||
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("Alias %q is not in the correct format", req.RoomIDOrAlias)
|
return "", "", fmt.Errorf("alias %q is not in the correct format", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
req.ServerNames = append(req.ServerNames, domain)
|
req.ServerNames = append(req.ServerNames, domain)
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ func (r *Joiner) performJoinRoomByAlias(
|
||||||
err = r.FSAPI.PerformDirectoryLookup(ctx, &dirReq, &dirRes)
|
err = r.FSAPI.PerformDirectoryLookup(ctx, &dirReq, &dirRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Errorf("error looking up alias %q", req.RoomIDOrAlias)
|
logrus.WithError(err).Errorf("error looking up alias %q", req.RoomIDOrAlias)
|
||||||
return "", "", fmt.Errorf("Looking up alias %q over federation failed: %w", req.RoomIDOrAlias, err)
|
return "", "", fmt.Errorf("looking up alias %q over federation failed: %w", req.RoomIDOrAlias, err)
|
||||||
}
|
}
|
||||||
roomID = dirRes.RoomID
|
roomID = dirRes.RoomID
|
||||||
req.ServerNames = append(req.ServerNames, dirRes.ServerNames...)
|
req.ServerNames = append(req.ServerNames, dirRes.ServerNames...)
|
||||||
|
@ -135,14 +134,14 @@ func (r *Joiner) performJoinRoomByAlias(
|
||||||
// Otherwise, look up if we know this room alias locally.
|
// Otherwise, look up if we know this room alias locally.
|
||||||
err = r.RSAPI.GetRoomIDForAlias(ctx, &getRoomReq, &getRoomRes)
|
err = r.RSAPI.GetRoomIDForAlias(ctx, &getRoomReq, &getRoomRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("Lookup room alias %q failed: %w", req.RoomIDOrAlias, err)
|
return "", "", fmt.Errorf("lookup room alias %q failed: %w", req.RoomIDOrAlias, err)
|
||||||
}
|
}
|
||||||
roomID = getRoomRes.RoomID
|
roomID = getRoomRes.RoomID
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the room ID is empty then we failed to look up the alias.
|
// If the room ID is empty then we failed to look up the alias.
|
||||||
if roomID == "" {
|
if roomID == "" {
|
||||||
return "", "", fmt.Errorf("Alias %q not found", req.RoomIDOrAlias)
|
return "", "", fmt.Errorf("alias %q not found", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we do, then pluck out the room ID and continue the join.
|
// If we do, then pluck out the room ID and continue the join.
|
||||||
|
@ -153,7 +152,7 @@ func (r *Joiner) performJoinRoomByAlias(
|
||||||
// TODO: Break this function up a bit
|
// TODO: Break this function up a bit
|
||||||
func (r *Joiner) performJoinRoomByID(
|
func (r *Joiner) performJoinRoomByID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
) (string, gomatrixserverlib.ServerName, error) {
|
) (string, gomatrixserverlib.ServerName, error) {
|
||||||
// The original client request ?server_name=... may include this HS so filter that out so we
|
// The original client request ?server_name=... may include this HS so filter that out so we
|
||||||
// don't attempt to make_join with ourselves
|
// don't attempt to make_join with ourselves
|
||||||
|
@ -168,8 +167,8 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// Get the domain part of the room ID.
|
// Get the domain part of the room ID.
|
||||||
_, domain, err := gomatrixserverlib.SplitID('!', req.RoomIDOrAlias)
|
_, domain, err := gomatrixserverlib.SplitID('!', req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("Room ID %q is invalid: %s", req.RoomIDOrAlias, err),
|
Msg: fmt.Sprintf("Room ID %q is invalid: %s", req.RoomIDOrAlias, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,10 +206,10 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
|
|
||||||
// Force a federated join if we aren't in the room and we've been
|
// Force a federated join if we aren't in the room and we've been
|
||||||
// given some server names to try joining by.
|
// given some server names to try joining by.
|
||||||
inRoomReq := &api.QueryServerJoinedToRoomRequest{
|
inRoomReq := &rsAPI.QueryServerJoinedToRoomRequest{
|
||||||
RoomID: req.RoomIDOrAlias,
|
RoomID: req.RoomIDOrAlias,
|
||||||
}
|
}
|
||||||
inRoomRes := &api.QueryServerJoinedToRoomResponse{}
|
inRoomRes := &rsAPI.QueryServerJoinedToRoomResponse{}
|
||||||
if err = r.Queryer.QueryServerJoinedToRoom(ctx, inRoomReq, inRoomRes); err != nil {
|
if err = r.Queryer.QueryServerJoinedToRoom(ctx, inRoomReq, inRoomRes); err != nil {
|
||||||
return "", "", fmt.Errorf("r.Queryer.QueryServerJoinedToRoom: %w", err)
|
return "", "", fmt.Errorf("r.Queryer.QueryServerJoinedToRoom: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -267,21 +266,21 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// If we haven't already joined the room then send an event
|
// If we haven't already joined the room then send an event
|
||||||
// into the room changing our membership status.
|
// into the room changing our membership status.
|
||||||
if !alreadyJoined {
|
if !alreadyJoined {
|
||||||
inputReq := api.InputRoomEventsRequest{
|
inputReq := rsAPI.InputRoomEventsRequest{
|
||||||
InputRoomEvents: []api.InputRoomEvent{
|
InputRoomEvents: []rsAPI.InputRoomEvent{
|
||||||
{
|
{
|
||||||
Kind: api.KindNew,
|
Kind: rsAPI.KindNew,
|
||||||
Event: event.Headered(buildRes.RoomVersion),
|
Event: event.Headered(buildRes.RoomVersion),
|
||||||
AuthEventIDs: event.AuthEventIDs(),
|
AuthEventIDs: event.AuthEventIDs(),
|
||||||
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
inputRes := api.InputRoomEventsResponse{}
|
inputRes := rsAPI.InputRoomEventsResponse{}
|
||||||
r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes)
|
r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes)
|
||||||
if err = inputRes.Err(); err != nil {
|
if err = inputRes.Err(); err != nil {
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorNotAllowed,
|
Code: rsAPI.PerformErrorNotAllowed,
|
||||||
Msg: fmt.Sprintf("InputRoomEvents auth failed: %s", err),
|
Msg: fmt.Sprintf("InputRoomEvents auth failed: %s", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,9 +295,9 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// Otherwise we'll try a federated join as normal, since it's quite
|
// Otherwise we'll try a federated join as normal, since it's quite
|
||||||
// possible that the room still exists on other servers.
|
// possible that the room still exists on other servers.
|
||||||
if len(req.ServerNames) == 0 {
|
if len(req.ServerNames) == 0 {
|
||||||
return "", "", &api.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrorNoRoom,
|
Code: rsAPI.PerformErrorNoRoom,
|
||||||
Msg: fmt.Sprintf("Room ID %q does not exist", req.RoomIDOrAlias),
|
Msg: fmt.Sprintf("room ID %q does not exist", req.RoomIDOrAlias),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +308,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Something else went wrong.
|
// Something else went wrong.
|
||||||
return "", "", fmt.Errorf("Error joining local room: %q", err)
|
return "", "", fmt.Errorf("error joining local room: %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// By this point, if req.RoomIDOrAlias contained an alias, then
|
// By this point, if req.RoomIDOrAlias contained an alias, then
|
||||||
|
@ -321,7 +320,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
|
|
||||||
func (r *Joiner) performFederatedJoinRoomByID(
|
func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
) (gomatrixserverlib.ServerName, error) {
|
) (gomatrixserverlib.ServerName, error) {
|
||||||
// Try joining by all of the supplied server names.
|
// Try joining by all of the supplied server names.
|
||||||
fedReq := fsAPI.PerformJoinRequest{
|
fedReq := fsAPI.PerformJoinRequest{
|
||||||
|
@ -333,8 +332,8 @@ func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
fedRes := fsAPI.PerformJoinResponse{}
|
fedRes := fsAPI.PerformJoinResponse{}
|
||||||
r.FSAPI.PerformJoin(ctx, &fedReq, &fedRes)
|
r.FSAPI.PerformJoin(ctx, &fedReq, &fedRes)
|
||||||
if fedRes.LastError != nil {
|
if fedRes.LastError != nil {
|
||||||
return "", &api.PerformError{
|
return "", &rsAPI.PerformError{
|
||||||
Code: api.PerformErrRemote,
|
Code: rsAPI.PerformErrRemote,
|
||||||
Msg: fedRes.LastError.Message,
|
Msg: fedRes.LastError.Message,
|
||||||
RemoteCode: fedRes.LastError.Code,
|
RemoteCode: fedRes.LastError.Code,
|
||||||
}
|
}
|
||||||
|
@ -344,7 +343,7 @@ func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
|
|
||||||
func buildEvent(
|
func buildEvent(
|
||||||
ctx context.Context, db storage.Database, cfg *config.Global, builder *gomatrixserverlib.EventBuilder,
|
ctx context.Context, db storage.Database, cfg *config.Global, builder *gomatrixserverlib.EventBuilder,
|
||||||
) (*gomatrixserverlib.HeaderedEvent, *api.QueryLatestEventsAndStateResponse, error) {
|
) (*gomatrixserverlib.HeaderedEvent, *rsAPI.QueryLatestEventsAndStateResponse, error) {
|
||||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
return nil, nil, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||||
|
@ -354,8 +353,8 @@ func buildEvent(
|
||||||
return nil, nil, errors.New("expecting state tuples for event builder, got none")
|
return nil, nil, errors.New("expecting state tuples for event builder, got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryRes api.QueryLatestEventsAndStateResponse
|
var queryRes rsAPI.QueryLatestEventsAndStateResponse
|
||||||
err = helpers.QueryLatestEventsAndState(ctx, db, &api.QueryLatestEventsAndStateRequest{
|
err = helpers.QueryLatestEventsAndState(ctx, db, &rsAPI.QueryLatestEventsAndStateRequest{
|
||||||
RoomID: builder.RoomID,
|
RoomID: builder.RoomID,
|
||||||
StateToFetch: eventsNeeded.Tuples(),
|
StateToFetch: eventsNeeded.Tuples(),
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
|
|
|
@ -45,15 +45,15 @@ func (r *Leaver) PerformLeave(
|
||||||
) ([]api.OutputEvent, error) {
|
) ([]api.OutputEvent, error) {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Supplied user ID %q in incorrect format", req.UserID)
|
return nil, fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if domain != r.Cfg.Matrix.ServerName {
|
||||||
return nil, fmt.Errorf("User %q does not belong to this homeserver", req.UserID)
|
return nil, fmt.Errorf("user %q does not belong to this homeserver", req.UserID)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(req.RoomID, "!") {
|
if strings.HasPrefix(req.RoomID, "!") {
|
||||||
return r.performLeaveRoomByID(ctx, req, res)
|
return r.performLeaveRoomByID(ctx, req, res)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("Room ID %q is invalid", req.RoomID)
|
return nil, fmt.Errorf("room ID %q is invalid", req.RoomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Leaver) performLeaveRoomByID(
|
func (r *Leaver) performLeaveRoomByID(
|
||||||
|
@ -68,7 +68,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
var host gomatrixserverlib.ServerName
|
var host gomatrixserverlib.ServerName
|
||||||
_, host, err = gomatrixserverlib.SplitID('@', senderUser)
|
_, host, err = gomatrixserverlib.SplitID('@', senderUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Sender %q is invalid", senderUser)
|
return nil, fmt.Errorf("sender %q is invalid", senderUser)
|
||||||
}
|
}
|
||||||
if host != r.Cfg.Matrix.ServerName {
|
if host != r.Cfg.Matrix.ServerName {
|
||||||
return r.performFederatedRejectInvite(ctx, req, res, senderUser, eventID)
|
return r.performFederatedRejectInvite(ctx, req, res, senderUser, eventID)
|
||||||
|
@ -91,19 +91,19 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !latestRes.RoomExists {
|
if !latestRes.RoomExists {
|
||||||
return nil, fmt.Errorf("Room %q does not exist", req.RoomID)
|
return nil, fmt.Errorf("room %q does not exist", req.RoomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now let's see if the user is in the room.
|
// Now let's see if the user is in the room.
|
||||||
if len(latestRes.StateEvents) == 0 {
|
if len(latestRes.StateEvents) == 0 {
|
||||||
return nil, fmt.Errorf("User %q is not a member of room %q", req.UserID, req.RoomID)
|
return nil, fmt.Errorf("user %q is not a member of room %q", req.UserID, req.RoomID)
|
||||||
}
|
}
|
||||||
membership, err := latestRes.StateEvents[0].Membership()
|
membership, err := latestRes.StateEvents[0].Membership()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error getting membership: %w", err)
|
return nil, fmt.Errorf("error getting membership: %w", err)
|
||||||
}
|
}
|
||||||
if membership != gomatrixserverlib.Join && membership != gomatrixserverlib.Invite {
|
if membership != gomatrixserverlib.Join && membership != gomatrixserverlib.Invite {
|
||||||
return nil, fmt.Errorf("User %q is not joined to the room (membership is %q)", req.UserID, membership)
|
return nil, fmt.Errorf("user %q is not joined to the room (membership is %q)", req.UserID, membership)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the template for the leave event.
|
// Prepare the template for the leave event.
|
||||||
|
@ -161,7 +161,7 @@ func (r *Leaver) performFederatedRejectInvite(
|
||||||
) ([]api.OutputEvent, error) {
|
) ([]api.OutputEvent, error) {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('@', senderUser)
|
_, domain, err := gomatrixserverlib.SplitID('@', senderUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("User ID %q invalid: %w", senderUser, err)
|
return nil, fmt.Errorf("user ID %q invalid: %w", senderUser, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the federation sender to perform a federated leave for us.
|
// Ask the federation sender to perform a federated leave for us.
|
||||||
|
|
|
@ -96,7 +96,7 @@ func (r *Peeker) performPeekRoomByAlias(
|
||||||
// Get the domain part of the room alias.
|
// Get the domain part of the room alias.
|
||||||
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Alias %q is not in the correct format", req.RoomIDOrAlias)
|
return "", fmt.Errorf("alias %q is not in the correct format", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
req.ServerNames = append(req.ServerNames, domain)
|
req.ServerNames = append(req.ServerNames, domain)
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ func (r *Peeker) performPeekRoomByAlias(
|
||||||
err = r.FSAPI.PerformDirectoryLookup(ctx, &dirReq, &dirRes)
|
err = r.FSAPI.PerformDirectoryLookup(ctx, &dirReq, &dirRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Errorf("error looking up alias %q", req.RoomIDOrAlias)
|
logrus.WithError(err).Errorf("error looking up alias %q", req.RoomIDOrAlias)
|
||||||
return "", fmt.Errorf("Looking up alias %q over federation failed: %w", req.RoomIDOrAlias, err)
|
return "", fmt.Errorf("looking up alias %q over federation failed: %w", req.RoomIDOrAlias, err)
|
||||||
}
|
}
|
||||||
roomID = dirRes.RoomID
|
roomID = dirRes.RoomID
|
||||||
req.ServerNames = append(req.ServerNames, dirRes.ServerNames...)
|
req.ServerNames = append(req.ServerNames, dirRes.ServerNames...)
|
||||||
|
@ -122,13 +122,13 @@ func (r *Peeker) performPeekRoomByAlias(
|
||||||
// Otherwise, look up if we know this room alias locally.
|
// Otherwise, look up if we know this room alias locally.
|
||||||
roomID, err = r.DB.GetRoomIDForAlias(ctx, req.RoomIDOrAlias)
|
roomID, err = r.DB.GetRoomIDForAlias(ctx, req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Lookup room alias %q failed: %w", req.RoomIDOrAlias, err)
|
return "", fmt.Errorf("lookup room alias %q failed: %w", req.RoomIDOrAlias, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the room ID is empty then we failed to look up the alias.
|
// If the room ID is empty then we failed to look up the alias.
|
||||||
if roomID == "" {
|
if roomID == "" {
|
||||||
return "", fmt.Errorf("Alias %q not found", req.RoomIDOrAlias)
|
return "", fmt.Errorf("alias %q not found", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we do, then pluck out the room ID and continue the peek.
|
// If we do, then pluck out the room ID and continue the peek.
|
||||||
|
|
|
@ -71,7 +71,7 @@ func (v *StateResolution) LoadStateAtSnapshot(
|
||||||
if !ok {
|
if !ok {
|
||||||
// This should only get hit if the database is corrupt.
|
// This should only get hit if the database is corrupt.
|
||||||
// It should be impossible for an event to reference a NID that doesn't exist
|
// It should be impossible for an event to reference a NID that doesn't exist
|
||||||
panic(fmt.Errorf("Corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
panic(fmt.Errorf("corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
||||||
}
|
}
|
||||||
fullState = append(fullState, entries...)
|
fullState = append(fullState, entries...)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ func (v *StateResolution) LoadCombinedStateAfterEvents(
|
||||||
if !ok {
|
if !ok {
|
||||||
// This should only get hit if the database is corrupt.
|
// This should only get hit if the database is corrupt.
|
||||||
// It should be impossible for an event to reference a NID that doesn't exist
|
// It should be impossible for an event to reference a NID that doesn't exist
|
||||||
panic(fmt.Errorf("Corrupt DB: Missing state snapshot numeric ID %d", prevState.BeforeStateSnapshotNID))
|
panic(fmt.Errorf("corrupt DB: Missing state snapshot numeric ID %d", prevState.BeforeStateSnapshotNID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine all the state entries for this snapshot.
|
// Combine all the state entries for this snapshot.
|
||||||
|
@ -157,7 +157,7 @@ func (v *StateResolution) LoadCombinedStateAfterEvents(
|
||||||
if !ok {
|
if !ok {
|
||||||
// This should only get hit if the database is corrupt.
|
// This should only get hit if the database is corrupt.
|
||||||
// It should be impossible for an event to reference a NID that doesn't exist
|
// It should be impossible for an event to reference a NID that doesn't exist
|
||||||
panic(fmt.Errorf("Corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
panic(fmt.Errorf("corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
||||||
}
|
}
|
||||||
fullState = append(fullState, entries...)
|
fullState = append(fullState, entries...)
|
||||||
}
|
}
|
||||||
|
@ -757,7 +757,7 @@ func (v *StateResolution) resolveConflictsV1(
|
||||||
for _, resolvedEvent := range resolvedEvents {
|
for _, resolvedEvent := range resolvedEvents {
|
||||||
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("Missing state entry for event ID %q", resolvedEvent.EventID()))
|
panic(fmt.Errorf("missing state entry for event ID %q", resolvedEvent.EventID()))
|
||||||
}
|
}
|
||||||
notConflicted = append(notConflicted, entry)
|
notConflicted = append(notConflicted, entry)
|
||||||
}
|
}
|
||||||
|
@ -880,7 +880,7 @@ func (v *StateResolution) resolveConflictsV2(
|
||||||
for _, resolvedEvent := range resolvedEvents {
|
for _, resolvedEvent := range resolvedEvents {
|
||||||
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("Missing state entry for event ID %q", resolvedEvent.EventID()))
|
panic(fmt.Errorf("missing state entry for event ID %q", resolvedEvent.EventID()))
|
||||||
}
|
}
|
||||||
notConflicted = append(notConflicted, entry)
|
notConflicted = append(notConflicted, entry)
|
||||||
}
|
}
|
||||||
|
@ -958,7 +958,7 @@ func (v *StateResolution) loadStateEvents(
|
||||||
for _, entry := range eventEntries {
|
for _, entry := range eventEntries {
|
||||||
event, ok := eventMap(events).lookup(entry.EventNID)
|
event, ok := eventMap(events).lookup(entry.EventNID)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("Corrupt DB: Missing event numeric ID %d", entry.EventNID))
|
panic(fmt.Errorf("corrupt DB: Missing event numeric ID %d", entry.EventNID))
|
||||||
}
|
}
|
||||||
result = append(result, event.Event)
|
result = append(result, event.Event)
|
||||||
eventIDMap[event.Event.EventID()] = entry
|
eventIDMap[event.Event.EventID()] = entry
|
||||||
|
|
|
@ -220,7 +220,6 @@ func UpStateBlocksRefactor(tx *sql.Tx) error {
|
||||||
index := stateSnapshotData{snapshot.StateSnapshotNID, snapshot.RoomNID}
|
index := stateSnapshotData{snapshot.StateSnapshotNID, snapshot.RoomNID}
|
||||||
newsnapshots[index] = append(newsnapshots[index], blocknid)
|
newsnapshots[index] = append(newsnapshots[index], blocknid)
|
||||||
}
|
}
|
||||||
|
|
||||||
for snapshotdata, newblocks := range newsnapshots {
|
for snapshotdata, newblocks := range newsnapshots {
|
||||||
var newblocksarray pq.Int64Array
|
var newblocksarray pq.Int64Array
|
||||||
for _, b := range newblocks {
|
for _, b := range newblocks {
|
||||||
|
@ -229,11 +228,11 @@ func UpStateBlocksRefactor(tx *sql.Tx) error {
|
||||||
|
|
||||||
var newNID types.StateSnapshotNID
|
var newNID types.StateSnapshotNID
|
||||||
err = tx.QueryRow(`
|
err = tx.QueryRow(`
|
||||||
INSERT INTO roomserver_state_snapshots (state_snapshot_hash, room_nid, state_block_nids)
|
INSERT INTO roomserver_state_snapshots (state_snapshot_hash, room_nid, state_block_nids)
|
||||||
VALUES ($1, $2, $3)
|
VALUES ($1, $2, $3)
|
||||||
ON CONFLICT (state_snapshot_hash) DO UPDATE SET room_nid=$2
|
ON CONFLICT (state_snapshot_hash) DO UPDATE SET room_nid=$2
|
||||||
RETURNING state_snapshot_nid
|
RETURNING state_snapshot_nid
|
||||||
`, newblocks.Hash(), snapshotdata.RoomNID, newblocksarray).Scan(&newNID)
|
`, newblocks.Hash(), snapshotdata.RoomNID, newblocksarray).Scan(&newNID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("tx.QueryRow.Scan (insert new snapshot): %w", err)
|
return fmt.Errorf("tx.QueryRow.Scan (insert new snapshot): %w", err)
|
||||||
}
|
}
|
||||||
|
@ -252,16 +251,49 @@ func UpStateBlocksRefactor(tx *sql.Tx) error {
|
||||||
// If we do, this is a problem if Dendrite tries to load the snapshot as it will not exist
|
// If we do, this is a problem if Dendrite tries to load the snapshot as it will not exist
|
||||||
// in roomserver_state_snapshots
|
// in roomserver_state_snapshots
|
||||||
var count int64
|
var count int64
|
||||||
|
|
||||||
if err = tx.QueryRow(`SELECT COUNT(*) FROM roomserver_events WHERE state_snapshot_nid < $1 AND state_snapshot_nid != 0`, maxsnapshotid).Scan(&count); err != nil {
|
if err = tx.QueryRow(`SELECT COUNT(*) FROM roomserver_events WHERE state_snapshot_nid < $1 AND state_snapshot_nid != 0`, maxsnapshotid).Scan(&count); err != nil {
|
||||||
return fmt.Errorf("assertion query failed: %s", err)
|
return fmt.Errorf("assertion query failed: %s", err)
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
var debugEventID, debugRoomID string
|
||||||
|
var debugEventTypeNID, debugStateKeyNID, debugSnapNID, debugDepth int64
|
||||||
|
err = tx.QueryRow(
|
||||||
|
`SELECT event_id, event_type_nid, event_state_key_nid, roomserver_events.state_snapshot_nid, depth, room_id FROM roomserver_events
|
||||||
|
JOIN roomserver_rooms ON roomserver_rooms.room_nid = roomserver_events.room_nid WHERE roomserver_events.state_snapshot_nid < $1 AND roomserver_events.state_snapshot_nid != 0`, maxsnapshotid,
|
||||||
|
).Scan(&debugEventID, &debugEventTypeNID, &debugStateKeyNID, &debugSnapNID, &debugDepth, &debugRoomID)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("cannot extract debug info: %v", err)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf(
|
||||||
|
"Affected row: event_id=%v room_id=%v type=%v state_key=%v snapshot=%v depth=%v",
|
||||||
|
debugEventID, debugRoomID, debugEventTypeNID, debugStateKeyNID, debugSnapNID, debugDepth,
|
||||||
|
)
|
||||||
|
logrus.Errorf("To fix this manually, run this query first then retry the migration: "+
|
||||||
|
"UPDATE roomserver_events SET state_snapshot_nid=0 WHERE event_id='%v'", debugEventID)
|
||||||
|
}
|
||||||
return fmt.Errorf("%d events exist in roomserver_events which have not been converted to a new state_snapshot_nid; this is a bug, please report", count)
|
return fmt.Errorf("%d events exist in roomserver_events which have not been converted to a new state_snapshot_nid; this is a bug, please report", count)
|
||||||
}
|
}
|
||||||
if err = tx.QueryRow(`SELECT COUNT(*) FROM roomserver_rooms WHERE state_snapshot_nid < $1 AND state_snapshot_nid != 0`, maxsnapshotid).Scan(&count); err != nil {
|
if err = tx.QueryRow(`SELECT COUNT(*) FROM roomserver_rooms WHERE state_snapshot_nid < $1 AND state_snapshot_nid != 0`, maxsnapshotid).Scan(&count); err != nil {
|
||||||
return fmt.Errorf("assertion query failed: %s", err)
|
return fmt.Errorf("assertion query failed: %s", err)
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
var debugRoomID string
|
||||||
|
var debugSnapNID, debugLastEventNID int64
|
||||||
|
err = tx.QueryRow(
|
||||||
|
`SELECT room_id, state_snapshot_nid, last_event_sent_nid FROM roomserver_rooms WHERE state_snapshot_nid < $1 AND state_snapshot_nid != 0`, maxsnapshotid,
|
||||||
|
).Scan(&debugRoomID, &debugSnapNID, &debugLastEventNID)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("cannot extract debug info: %v", err)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf(
|
||||||
|
"Affected row: room_id=%v snapshot=%v last_sent=%v",
|
||||||
|
debugRoomID, debugSnapNID, debugLastEventNID,
|
||||||
|
)
|
||||||
|
logrus.Errorf("To fix this manually, run this query first then retry the migration: "+
|
||||||
|
"UPDATE roomserver_rooms SET state_snapshot_nid=0 WHERE room_id='%v'", debugRoomID)
|
||||||
|
logrus.Errorf("Running this UPDATE will cause the room in question to become unavailable on this server. Leave and re-join the room afterwards.")
|
||||||
|
}
|
||||||
return fmt.Errorf("%d rooms exist in roomserver_rooms which have not been converted to a new state_snapshot_nid; this is a bug, please report", count)
|
return fmt.Errorf("%d rooms exist in roomserver_rooms which have not been converted to a new state_snapshot_nid; this is a bug, please report", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1136,7 +1136,7 @@ func (d *Database) loadStateAtSnapshot(
|
||||||
if !ok {
|
if !ok {
|
||||||
// This should only get hit if the database is corrupt.
|
// This should only get hit if the database is corrupt.
|
||||||
// It should be impossible for an event to reference a NID that doesn't exist
|
// It should be impossible for an event to reference a NID that doesn't exist
|
||||||
panic(fmt.Errorf("Corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
panic(fmt.Errorf("corrupt DB: Missing state block numeric ID %d", stateBlockNID))
|
||||||
}
|
}
|
||||||
fullState = append(fullState, entries...)
|
fullState = append(fullState, entries...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ type BaseDendrite struct {
|
||||||
PublicFederationAPIMux *mux.Router
|
PublicFederationAPIMux *mux.Router
|
||||||
PublicKeyAPIMux *mux.Router
|
PublicKeyAPIMux *mux.Router
|
||||||
PublicMediaAPIMux *mux.Router
|
PublicMediaAPIMux *mux.Router
|
||||||
|
PublicWellKnownAPIMux *mux.Router
|
||||||
InternalAPIMux *mux.Router
|
InternalAPIMux *mux.Router
|
||||||
SynapseAdminMux *mux.Router
|
SynapseAdminMux *mux.Router
|
||||||
UseHTTPAPIs bool
|
UseHTTPAPIs bool
|
||||||
|
@ -198,6 +199,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
|
||||||
PublicFederationAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicFederationPathPrefix).Subrouter().UseEncodedPath(),
|
PublicFederationAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicFederationPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
PublicKeyAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicKeyPathPrefix).Subrouter().UseEncodedPath(),
|
PublicKeyAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicKeyPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
PublicMediaAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicMediaPathPrefix).Subrouter().UseEncodedPath(),
|
PublicMediaAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicMediaPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
|
PublicWellKnownAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicWellKnownPrefix).Subrouter().UseEncodedPath(),
|
||||||
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
SynapseAdminMux: mux.NewRouter().SkipClean(true).PathPrefix("/_synapse/").Subrouter().UseEncodedPath(),
|
SynapseAdminMux: mux.NewRouter().SkipClean(true).PathPrefix("/_synapse/").Subrouter().UseEncodedPath(),
|
||||||
apiHttpClient: &apiClient,
|
apiHttpClient: &apiClient,
|
||||||
|
@ -394,6 +396,7 @@ func (b *BaseDendrite) SetupAndServeHTTP(
|
||||||
}
|
}
|
||||||
externalRouter.PathPrefix("/_synapse/").Handler(b.SynapseAdminMux)
|
externalRouter.PathPrefix("/_synapse/").Handler(b.SynapseAdminMux)
|
||||||
externalRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(b.PublicMediaAPIMux)
|
externalRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(b.PublicMediaAPIMux)
|
||||||
|
externalRouter.PathPrefix(httputil.PublicWellKnownPrefix).Handler(b.PublicWellKnownAPIMux)
|
||||||
|
|
||||||
if internalAddr != NoListener && internalAddr != externalAddr {
|
if internalAddr != NoListener && internalAddr != externalAddr {
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -34,6 +34,9 @@ type Global struct {
|
||||||
// Defaults to 24 hours.
|
// Defaults to 24 hours.
|
||||||
KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
|
KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
|
||||||
|
|
||||||
|
// The server name to delegate server-server communications to, with optional port
|
||||||
|
WellKnownServerName string `yaml:"well_known_server_name"`
|
||||||
|
|
||||||
// Disables federation. Dendrite will not be able to make any outbound HTTP requests
|
// Disables federation. Dendrite will not be able to make any outbound HTTP requests
|
||||||
// to other servers and the federation API will not be exposed.
|
// to other servers and the federation API will not be exposed.
|
||||||
DisableFederation bool `yaml:"disable_federation"`
|
DisableFederation bool `yaml:"disable_federation"`
|
||||||
|
|
|
@ -39,6 +39,7 @@ global:
|
||||||
private_key: matrix_key.pem
|
private_key: matrix_key.pem
|
||||||
key_id: ed25519:auto
|
key_id: ed25519:auto
|
||||||
key_validity_period: 168h0m0s
|
key_validity_period: 168h0m0s
|
||||||
|
well_known_server_name: "localhost:443"
|
||||||
trusted_third_party_id_servers:
|
trusted_third_party_id_servers:
|
||||||
- matrix.org
|
- matrix.org
|
||||||
- vector.im
|
- vector.im
|
||||||
|
|
|
@ -57,7 +57,7 @@ type Monolith struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddAllPublicRoutes attaches all public paths to the given router
|
// AddAllPublicRoutes attaches all public paths to the given router
|
||||||
func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ssMux, keyMux, mediaMux, synapseMux *mux.Router) {
|
func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ssMux, keyMux, wkMux, mediaMux, synapseMux *mux.Router) {
|
||||||
clientapi.AddPublicRoutes(
|
clientapi.AddPublicRoutes(
|
||||||
csMux, synapseMux, &m.Config.ClientAPI, m.AccountDB,
|
csMux, synapseMux, &m.Config.ClientAPI, m.AccountDB,
|
||||||
m.FedClient, m.RoomserverAPI,
|
m.FedClient, m.RoomserverAPI,
|
||||||
|
@ -66,7 +66,7 @@ func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ss
|
||||||
&m.Config.MSCs,
|
&m.Config.MSCs,
|
||||||
)
|
)
|
||||||
federationapi.AddPublicRoutes(
|
federationapi.AddPublicRoutes(
|
||||||
ssMux, keyMux, &m.Config.FederationAPI, m.UserAPI, m.FedClient,
|
ssMux, keyMux, wkMux, &m.Config.FederationAPI, m.UserAPI, m.FedClient,
|
||||||
m.KeyRing, m.RoomserverAPI, m.FederationSenderAPI,
|
m.KeyRing, m.RoomserverAPI, m.FederationSenderAPI,
|
||||||
m.EDUInternalAPI, m.KeyAPI, &m.Config.MSCs, nil,
|
m.EDUInternalAPI, m.KeyAPI, &m.Config.MSCs, nil,
|
||||||
)
|
)
|
||||||
|
|
|
@ -98,7 +98,7 @@ func Enable(
|
||||||
) error {
|
) error {
|
||||||
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot enable MSC2836: %w", err)
|
return fmt.Errorf("cannot enable MSC2836: %w", err)
|
||||||
}
|
}
|
||||||
hooks.Enable()
|
hooks.Enable()
|
||||||
hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) {
|
hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ func Enable(
|
||||||
) error {
|
) error {
|
||||||
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot enable MSC2946: %w", err)
|
return fmt.Errorf("cannot enable MSC2946: %w", err)
|
||||||
}
|
}
|
||||||
hooks.Enable()
|
hooks.Enable()
|
||||||
hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) {
|
hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OutputKeyChangeEventConsumer consumes events that originated in the key server.
|
// OutputKeyChangeEventConsumer consumes events that originated in the key server.
|
||||||
|
@ -128,7 +127,7 @@ func (s *OutputKeyChangeEventConsumer) onDeviceKeyMessage(m api.DeviceMessage, o
|
||||||
UserID: output.UserID,
|
UserID: output.UserID,
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("syncapi: failed to QuerySharedUsers for key change event from key server")
|
logrus.WithError(err).Error("syncapi: failed to QuerySharedUsers for key change event from key server")
|
||||||
sentry.CaptureException(err)
|
sentry.CaptureException(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -155,7 +154,7 @@ func (s *OutputKeyChangeEventConsumer) onCrossSigningMessage(m api.DeviceMessage
|
||||||
UserID: output.UserID,
|
UserID: output.UserID,
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("syncapi: failed to QuerySharedUsers for key change event from key server")
|
logrus.WithError(err).Error("syncapi: failed to QuerySharedUsers for key change event from key server")
|
||||||
sentry.CaptureException(err)
|
sentry.CaptureException(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
"github.com/matrix-org/dendrite/keyserver/api"
|
|
||||||
keyapi "github.com/matrix-org/dendrite/keyserver/api"
|
keyapi "github.com/matrix-org/dendrite/keyserver/api"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
|
@ -31,8 +30,8 @@ const DeviceListLogName = "dl"
|
||||||
|
|
||||||
// DeviceOTKCounts adds one-time key counts to the /sync response
|
// DeviceOTKCounts adds one-time key counts to the /sync response
|
||||||
func DeviceOTKCounts(ctx context.Context, keyAPI keyapi.KeyInternalAPI, userID, deviceID string, res *types.Response) error {
|
func DeviceOTKCounts(ctx context.Context, keyAPI keyapi.KeyInternalAPI, userID, deviceID string, res *types.Response) error {
|
||||||
var queryRes api.QueryOneTimeKeysResponse
|
var queryRes keyapi.QueryOneTimeKeysResponse
|
||||||
keyAPI.QueryOneTimeKeys(ctx, &api.QueryOneTimeKeysRequest{
|
keyAPI.QueryOneTimeKeys(ctx, &keyapi.QueryOneTimeKeysRequest{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
DeviceID: deviceID,
|
DeviceID: deviceID,
|
||||||
}, &queryRes)
|
}, &queryRes)
|
||||||
|
@ -81,8 +80,8 @@ func DeviceListCatchup(
|
||||||
if toLog := to; toLog.Partition == partition && toLog.Offset > 0 {
|
if toLog := to; toLog.Partition == partition && toLog.Offset > 0 {
|
||||||
toOffset = toLog.Offset
|
toOffset = toLog.Offset
|
||||||
}
|
}
|
||||||
var queryRes api.QueryKeyChangesResponse
|
var queryRes keyapi.QueryKeyChangesResponse
|
||||||
keyAPI.QueryKeyChanges(ctx, &api.QueryKeyChangesRequest{
|
keyAPI.QueryKeyChanges(ctx, &keyapi.QueryKeyChangesRequest{
|
||||||
Partition: partition,
|
Partition: partition,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
ToOffset: toOffset,
|
ToOffset: toOffset,
|
||||||
|
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database is a temporary struct until we have made syncserver.go the same for both pq/sqlite
|
// Database is a temporary struct until we have made syncserver.go the same for both pq/sqlite
|
||||||
|
@ -309,7 +308,7 @@ func (d *Database) StreamEventsToEvents(device *userapi.Device, in []types.Strea
|
||||||
"transaction_id", in[i].TransactionID.TransactionID,
|
"transaction_id", in[i].TransactionID.TransactionID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"event_id": out[i].EventID(),
|
"event_id": out[i].EventID(),
|
||||||
}).WithError(err).Warnf("Failed to add transaction ID to event")
|
}).WithError(err).Warnf("Failed to add transaction ID to event")
|
||||||
}
|
}
|
||||||
|
@ -529,7 +528,7 @@ func (d *Database) RedactEvent(ctx context.Context, redactedEventID string, reda
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(redactedEvents) == 0 {
|
if len(redactedEvents) == 0 {
|
||||||
log.WithField("event_id", redactedEventID).WithField("redaction_event", redactedBecause.EventID()).Warnf("missing redacted event for redaction")
|
logrus.WithField("event_id", redactedEventID).WithField("redaction_event", redactedBecause.EventID()).Warnf("missing redacted event for redaction")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
eventToRedact := redactedEvents[0].Unwrap()
|
eventToRedact := redactedEvents[0].Unwrap()
|
||||||
|
@ -645,7 +644,7 @@ func (d *Database) fetchMissingStateEvents(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(stateEvents) != len(missing) {
|
if len(stateEvents) != len(missing) {
|
||||||
log.WithContext(ctx).Warnf("Failed to map all event IDs to events (got %d, wanted %d)", len(stateEvents), len(missing))
|
logrus.WithContext(ctx).Warnf("Failed to map all event IDs to events (got %d, wanted %d)", len(stateEvents), len(missing))
|
||||||
|
|
||||||
// TODO: Why is this happening? It's probably the roomserver. Uncomment
|
// TODO: Why is this happening? It's probably the roomserver. Uncomment
|
||||||
// this error again when we work out what it is and fix it, otherwise we
|
// this error again when we work out what it is and fix it, otherwise we
|
||||||
|
|
|
@ -29,10 +29,10 @@ var (
|
||||||
// ErrInvalidSyncTokenType is returned when an attempt at creating a
|
// ErrInvalidSyncTokenType is returned when an attempt at creating a
|
||||||
// new instance of SyncToken with an invalid type (i.e. neither "s"
|
// new instance of SyncToken with an invalid type (i.e. neither "s"
|
||||||
// nor "t").
|
// nor "t").
|
||||||
ErrInvalidSyncTokenType = fmt.Errorf("Sync token has an unknown prefix (should be either s or t)")
|
ErrInvalidSyncTokenType = fmt.Errorf("sync token has an unknown prefix (should be either s or t)")
|
||||||
// ErrInvalidSyncTokenLen is returned when the pagination token is an
|
// ErrInvalidSyncTokenLen is returned when the pagination token is an
|
||||||
// invalid length
|
// invalid length
|
||||||
ErrInvalidSyncTokenLen = fmt.Errorf("Sync token has an invalid length")
|
ErrInvalidSyncTokenLen = fmt.Errorf("sync token has an invalid length")
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateDelta struct {
|
type StateDelta struct {
|
||||||
|
|
|
@ -1,52 +1,9 @@
|
||||||
# Blacklisted due to flakiness
|
|
||||||
Remote users can join room by alias
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
POST /login can log in as a user with just the local part of the id
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
avatar_url updates affect room member events
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
displayname updates affect room member events
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
Room members can override their displayname on a room-specific basis
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
Alias creators can delete alias with no ops
|
|
||||||
|
|
||||||
# Blacklisted because matrix-org/dendrite#847 might have broken it but we're not
|
|
||||||
# really sure and we need it pretty badly anyway
|
|
||||||
Real non-joined users can get individual state for world_readable rooms after leaving
|
|
||||||
|
|
||||||
# Blacklisted until matrix-org/dendrite#862 is reverted due to Riot bug
|
# Blacklisted until matrix-org/dendrite#862 is reverted due to Riot bug
|
||||||
Latest account data appears in v2 /sync
|
Latest account data appears in v2 /sync
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
Outbound federation can backfill events
|
|
||||||
|
|
||||||
# Blacklisted due to alias work on Synapse
|
|
||||||
Alias creators can delete canonical alias with no ops
|
|
||||||
|
|
||||||
# Blacklisted because we need to implement v2 invite endpoints for room versions
|
|
||||||
# to be supported (currently fails with M_UNSUPPORTED_ROOM_VERSION)
|
|
||||||
Inbound federation rejects invites which are not signed by the sender
|
|
||||||
|
|
||||||
# Blacklisted because we don't support ignores yet
|
# Blacklisted because we don't support ignores yet
|
||||||
Ignore invite in incremental sync
|
Ignore invite in incremental sync
|
||||||
|
|
||||||
# Blacklisted because this test calls /r0/events which we don't implement
|
|
||||||
New room members see their own join event
|
|
||||||
Existing members see new members' join events
|
|
||||||
|
|
||||||
# See https://github.com/matrix-org/sytest/pull/901
|
|
||||||
Remote invited user can see room metadata
|
|
||||||
|
|
||||||
# We don't implement soft-failed events yet, but because the /send response is vague,
|
|
||||||
# this test thinks it's all fine...
|
|
||||||
Inbound federation accepts a second soft-failed event
|
|
||||||
|
|
||||||
# Relies on a rejected PL event which will never be accepted into the DAG
|
# Relies on a rejected PL event which will never be accepted into the DAG
|
||||||
# Caused by https://github.com/matrix-org/sytest/pull/911
|
# Caused by https://github.com/matrix-org/sytest/pull/911
|
||||||
Outbound federation requests missing prev_events and then asks for /state_ids and resolves the state
|
Outbound federation requests missing prev_events and then asks for /state_ids and resolves the state
|
||||||
|
@ -59,21 +16,21 @@ Invited user can reject local invite after originator leaves
|
||||||
Invited user can reject invite for empty room
|
Invited user can reject invite for empty room
|
||||||
If user leaves room, remote user changes device and rejoins we see update in /sync and /keys/changes
|
If user leaves room, remote user changes device and rejoins we see update in /sync and /keys/changes
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
A prev_batch token from incremental sync can be used in the v1 messages API
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
# Blacklisted due to flakiness
|
||||||
Forgotten room messages cannot be paginated
|
Forgotten room messages cannot be paginated
|
||||||
|
|
||||||
# Blacklisted due to flakiness
|
|
||||||
Can re-join room if re-invited
|
|
||||||
|
|
||||||
# Blacklisted due to flakiness after #1774
|
# Blacklisted due to flakiness after #1774
|
||||||
Local device key changes get to remote servers with correct prev_id
|
Local device key changes get to remote servers with correct prev_id
|
||||||
|
|
||||||
# Flakey
|
# Flakey
|
||||||
Local device key changes appear in /keys/changes
|
Local device key changes appear in /keys/changes
|
||||||
|
Device list doesn't change if remote server is down
|
||||||
|
If a device list update goes missing, the server resyncs on the next one
|
||||||
|
|
||||||
# we don't support groups
|
# we don't support groups
|
||||||
Remove group category
|
Remove group category
|
||||||
Remove group role
|
Remove group role
|
||||||
|
|
||||||
|
# See https://github.com/matrix-org/sytest/pull/1142
|
||||||
|
Device list doesn't change if remote server is down
|
||||||
|
If a device list update goes missing, the server resyncs on the next one
|
||||||
|
|
|
@ -136,7 +136,6 @@ query for user with no keys returns empty key dict
|
||||||
Can claim one time key using POST
|
Can claim one time key using POST
|
||||||
Can claim remote one time key using POST
|
Can claim remote one time key using POST
|
||||||
Local device key changes appear in v2 /sync
|
Local device key changes appear in v2 /sync
|
||||||
Local device key changes appear in /keys/changes
|
|
||||||
New users appear in /keys/changes
|
New users appear in /keys/changes
|
||||||
Local delete device changes appear in v2 /sync
|
Local delete device changes appear in v2 /sync
|
||||||
Local new device changes appear in v2 /sync
|
Local new device changes appear in v2 /sync
|
||||||
|
@ -556,3 +555,19 @@ Fails to upload self-signing key without master key
|
||||||
can fetch self-signing keys over federation
|
can fetch self-signing keys over federation
|
||||||
Changing master key notifies local users
|
Changing master key notifies local users
|
||||||
Changing user-signing key notifies local users
|
Changing user-signing key notifies local users
|
||||||
|
Inbound federation correctly handles soft failed events as extremities
|
||||||
|
User can create and send/receive messages in a room with version 7
|
||||||
|
local user can join room with version 7
|
||||||
|
User can invite local user to room with version 7
|
||||||
|
remote user can join room with version 7
|
||||||
|
User can invite remote user to room with version 7
|
||||||
|
Remote user can backfill in a room with version 7
|
||||||
|
Can reject invites over federation for rooms with version 7
|
||||||
|
Can receive redactions from regular users over federation in room version 7
|
||||||
|
Federation publicRoom Name/topic keys are correct
|
||||||
|
Remote invited user can see room metadata
|
||||||
|
Can re-join room if re-invited
|
||||||
|
A prev_batch token from incremental sync can be used in the v1 messages API
|
||||||
|
Inbound federation rejects invites which are not signed by the sender
|
||||||
|
Invited user can reject invite over federation several times
|
||||||
|
Test that we can be reinvited to a room we created
|
||||||
|
|
|
@ -177,10 +177,10 @@ func (a *UserInternalAPI) deviceListUpdate(userID string, deviceIDs []string) er
|
||||||
DeviceKeys: deviceKeys,
|
DeviceKeys: deviceKeys,
|
||||||
}, &uploadRes)
|
}, &uploadRes)
|
||||||
if uploadRes.Error != nil {
|
if uploadRes.Error != nil {
|
||||||
return fmt.Errorf("Failed to delete device keys: %v", uploadRes.Error)
|
return fmt.Errorf("failed to delete device keys: %v", uploadRes.Error)
|
||||||
}
|
}
|
||||||
if len(uploadRes.KeyErrors) > 0 {
|
if len(uploadRes.KeyErrors) > 0 {
|
||||||
return fmt.Errorf("Failed to delete device keys, key errors: %+v", uploadRes.KeyErrors)
|
return fmt.Errorf("failed to delete device keys, key errors: %+v", uploadRes.KeyErrors)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -242,10 +242,10 @@ func (a *UserInternalAPI) PerformDeviceUpdate(ctx context.Context, req *api.Perf
|
||||||
OnlyDisplayNameUpdates: true,
|
OnlyDisplayNameUpdates: true,
|
||||||
}, &uploadRes)
|
}, &uploadRes)
|
||||||
if uploadRes.Error != nil {
|
if uploadRes.Error != nil {
|
||||||
return fmt.Errorf("Failed to update device key display name: %v", uploadRes.Error)
|
return fmt.Errorf("failed to update device key display name: %v", uploadRes.Error)
|
||||||
}
|
}
|
||||||
if len(uploadRes.KeyErrors) > 0 {
|
if len(uploadRes.KeyErrors) > 0 {
|
||||||
return fmt.Errorf("Failed to update device key display name, key errors: %+v", uploadRes.KeyErrors)
|
return fmt.Errorf("failed to update device key display name, key errors: %+v", uploadRes.KeyErrors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -67,4 +67,4 @@ type Database interface {
|
||||||
|
|
||||||
// Err3PIDInUse is the error returned when trying to save an association involving
|
// Err3PIDInUse is the error returned when trying to save an association involving
|
||||||
// a third-party identifier which is already associated to a local user.
|
// a third-party identifier which is already associated to a local user.
|
||||||
var Err3PIDInUse = errors.New("This third-party identifier is already in use")
|
var Err3PIDInUse = errors.New("this third-party identifier is already in use")
|
||||||
|
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/dendrite/userapi/storage/accounts/postgres/deltas"
|
"github.com/matrix-org/dendrite/userapi/storage/accounts/postgres/deltas"
|
||||||
_ "github.com/matrix-org/dendrite/userapi/storage/accounts/postgres/deltas"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ func (d *Database) hashPassword(plaintext string) (hash string, err error) {
|
||||||
|
|
||||||
// Err3PIDInUse is the error returned when trying to save an association involving
|
// Err3PIDInUse is the error returned when trying to save an association involving
|
||||||
// a third-party identifier which is already associated to a local user.
|
// a third-party identifier which is already associated to a local user.
|
||||||
var Err3PIDInUse = errors.New("This third-party identifier is already in use")
|
var Err3PIDInUse = errors.New("this third-party identifier is already in use")
|
||||||
|
|
||||||
// SaveThreePIDAssociation saves the association between a third party identifier
|
// SaveThreePIDAssociation saves the association between a third party identifier
|
||||||
// and a local Matrix user (identified by the user's ID's local part).
|
// and a local Matrix user (identified by the user's ID's local part).
|
||||||
|
|
|
@ -304,7 +304,7 @@ func (d *Database) hashPassword(plaintext string) (hash string, err error) {
|
||||||
|
|
||||||
// Err3PIDInUse is the error returned when trying to save an association involving
|
// Err3PIDInUse is the error returned when trying to save an association involving
|
||||||
// a third-party identifier which is already associated to a local user.
|
// a third-party identifier which is already associated to a local user.
|
||||||
var Err3PIDInUse = errors.New("This third-party identifier is already in use")
|
var Err3PIDInUse = errors.New("this third-party identifier is already in use")
|
||||||
|
|
||||||
// SaveThreePIDAssociation saves the association between a third party identifier
|
// SaveThreePIDAssociation saves the association between a third party identifier
|
||||||
// and a local Matrix user (identified by the user's ID's local part).
|
// and a local Matrix user (identified by the user's ID's local part).
|
||||||
|
|
Loading…
Reference in a new issue