-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Implement MSC3391: Removing account data #14242
Description
Add an experimental implementation for MSC3391, which allows users to remove keys from their user and room account data.
TODO
-
Add an off-by-default experimental config option
msc3391_enabledto guard the feature behind. -
Add two unstable endpoints for deleting account data:
-
DELETE /_matrix/client/unstable/org.matrix.msc3391/user/{userId}/account_data/{type} -
DELETE /_matrix/client/unstable/org.matrix.msc3391/user/{userId}/rooms/{roomId}/account_data/{type}- Upon calling the above endpoints, the provided
typeis removed from the user's user/room account data. This should be recorded in theaccount_dataandroom_account_datatables respectively, by setting the content of each to{}. Ensure these entries are not included in initial syncs.
- Upon calling the above endpoints, the provided
-
-
Setting an account data type's content to
{}when callingPUT /_matrix/client/v3/user/{userId}/account_data/{type}andPUT /_matrix/client/v3/user/{userId}/rooms/{roomId}/account_data/{type}will be equivalent to calling theDELETEendpoint for that type. This is for backwards-compatibility with older clients which have used this to effectively "delete" keys in the past. -
Ensure that event entries with a content of
{}appear down/syncafter an account data entry is deleted. -
Add a new table
account_data_unsynced_deletes, which tracks whether a device has seen the deletion. Upon a delete one row for each known user device is added to this table. Upon a device sync'ing the change or hitting theGETendpoint for the data, the relevant row will be removed. Once all devices have seen a deletion, we can delete the key from theaccount_dataorroom_account_datatables. The device that caused the deletion should not have a row inserted.
Theaccount_data_unsynced_deletestable has the following schema:CREATE TABLE IF NOT EXISTS account_data_unsynced_deletes ( -- The stream_id of the delete in `account_data` or `room_account_data`. Note that this value is -- unique across both `account_data` and `room_account_data` tables. stream_id BIGINT NOT NULL, user_id TEXT NOT NULL, // foreign key: users(name) account_data_type TEXT NOT NULL, -- The room ID if this is referring to `room_account_data`. room_id TEXT, // foreign key: rooms(room_id) -- A device ID that has not yet seen this delete. device_id TEXT NOT NULL, // foreign key: devices(device_id) ); -- This will be used to quickly look up a given (room) account_data entry for a given (user_id, device_id) pair CREATE UNIQUE INDEX IF NOT EXISTS account_data_unsynced_deletes_stream_id_user_id_device_id ON account_data_unsynced_deletes(stream_id, user_id, device_id); -- This is CREATE INDEX IF NOT EXISTS account_data_unsynced_deletes_user_id_device_id ON account_data_unsynced_deletes(user_id, device_id);
- /sync needs to delete a row using
(stream_id, user_id, device_id).GETwould use the same. Deleting all rows for a device needs(user_id, device_id).
- Delete entries in
account_data_unsynced_deleteswhen a given device knows that delete has occurred. Either through/syncorGETendpoints. - Deleting a device should remove all relevant rows from the
account_data_unsynced_devicestable. - Write complement tests.