diff --git a/syncapi/routing/filter.go b/syncapi/routing/filter.go index baa4d841..cfa059c9 100644 --- a/syncapi/routing/filter.go +++ b/syncapi/routing/filter.go @@ -65,6 +65,7 @@ type filterResponse struct { FilterID string `json:"filter_id"` } +// TODO: asdf //PutFilter implements POST /_matrix/client/r0/user/{userId}/filter func PutFilter( req *http.Request, device *api.Device, syncDB storage.Database, userID string, diff --git a/syncapi/routing/routing.go b/syncapi/routing/routing.go index e2ff2739..71083e7f 100644 --- a/syncapi/routing/routing.go +++ b/syncapi/routing/routing.go @@ -42,6 +42,7 @@ func Setup( r0mux := csMux.PathPrefix("/r0").Subrouter() // TODO: Add AS support for all handlers below. + // asdf r0mux.Handle("/sync", httputil.MakeAuthAPI("sync", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { return srp.OnIncomingSyncRequest(req, device) })).Methods(http.MethodGet, http.MethodOptions) diff --git a/syncapi/storage/shared/syncserver.go b/syncapi/storage/shared/syncserver.go index ba9403a5..4b117ae6 100644 --- a/syncapi/storage/shared/syncserver.go +++ b/syncapi/storage/shared/syncserver.go @@ -762,6 +762,7 @@ func (d *Database) getResponseWithPDUsForCompleteSync( ctx context.Context, res *types.Response, userID string, device userapi.Device, numRecentEventsPerRoom int, + includeLeave bool, ) ( toPos types.StreamingToken, joinedRoomIDs []string, @@ -811,6 +812,9 @@ func (d *Database) getResponseWithPDUsForCompleteSync( if err != nil { return } + + // TODO: Add "leave" rooms. + res.Rooms.Join[roomID] = *jr } diff --git a/syncapi/sync/request.go b/syncapi/sync/request.go index f2f2894b..8e477f76 100644 --- a/syncapi/sync/request.go +++ b/syncapi/sync/request.go @@ -30,11 +30,13 @@ import ( ) const defaultSyncTimeout = time.Duration(0) +const defaultIncludeLeave = false const DefaultTimelineLimit = 20 type filter struct { Room struct { - Timeline struct { + IncludeLeave *bool `json:"include_leave"` + Timeline struct { Limit *int `json:"limit"` } `json:"timeline"` } `json:"room"` @@ -45,6 +47,7 @@ type syncRequest struct { ctx context.Context device userapi.Device limit int + includeLeave bool timeout time.Duration since types.StreamingToken // nil means that no since token was supplied wantFullState bool @@ -64,6 +67,7 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat } } timelineLimit := DefaultTimelineLimit + includeLeave := defaultIncludeLeave // TODO: read from stored filters too filterQuery := req.URL.Query().Get("filter") if filterQuery != "" { @@ -74,6 +78,9 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat if err == nil && f.Room.Timeline.Limit != nil { timelineLimit = *f.Room.Timeline.Limit } + if err == nil && f.Room.IncludeLeave != nil { + includeLeave = *f.Room.IncludeLeave + } } else { // attempt to load the filter ID localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) @@ -84,6 +91,7 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat f, err := syncDB.GetFilter(req.Context(), localpart, filterQuery) if err == nil { timelineLimit = f.Room.Timeline.Limit + includeLeave = f.Room.IncludeLeave } } } @@ -95,6 +103,7 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat since: since, wantFullState: wantFullState, limit: timelineLimit, + includeLeave: includeLeave, log: util.GetLogger(req.Context()), }, nil } diff --git a/syncapi/sync/requestpool.go b/syncapi/sync/requestpool.go index 0751487a..2f65cb5b 100644 --- a/syncapi/sync/requestpool.go +++ b/syncapi/sync/requestpool.go @@ -140,11 +140,12 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *userapi. } logger := util.GetLogger(req.Context()).WithFields(log.Fields{ - "user_id": device.UserID, - "device_id": device.ID, - "since": syncReq.since, - "timeout": syncReq.timeout, - "limit": syncReq.limit, + "user_id": device.UserID, + "device_id": device.ID, + "since": syncReq.since, + "timeout": syncReq.timeout, + "limit": syncReq.limit, + "include_leave": syncReq.includeLeave, }) activeSyncRequests.Inc() @@ -285,7 +286,7 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest, latestPos types.Strea // TODO: handle ignored users if req.since.IsEmpty() { - res, err = rp.db.CompleteSync(req.ctx, res, req.device, req.limit) + res, err = rp.db.CompleteSync(req.ctx, res, req.device, req.limit, req.includeLeave) if err != nil { return res, fmt.Errorf("rp.db.CompleteSync: %w", err) } diff --git a/sytest-whitelist b/sytest-whitelist index cfbe5443..f65c3a53 100644 --- a/sytest-whitelist +++ b/sytest-whitelist @@ -123,6 +123,7 @@ We should see our own leave event when rejecting an invite, even if history_visi Newly left rooms appear in the leave section of gapped sync Previously left rooms don't appear in the leave section of sync Left rooms appear in the leave section of full state sync +Archived rooms only contain history from before the user left Newly banned rooms appear in the leave section of incremental sync Newly banned rooms appear in the leave section of incremental sync local user can join room with version 1