diff --git a/lib/models/event.js b/lib/models/event.js index 2e794705c..68e2a8618 100644 --- a/lib/models/event.js +++ b/lib/models/event.js @@ -21,6 +21,7 @@ limitations under the License. * @module models/event */ +var utils = require("../utils"); /** * Enum for event statuses. @@ -202,7 +203,19 @@ module.exports.MatrixEvent.prototype = { this.event.unsigned = {}; } this.event.unsigned.redacted_because = redaction_event; - this.event.content = {}; + + for (var key in utils.keys(this.event)) { + if (!_REDACT_KEEP_KEY_MAP[key]) { + delete this.event[key]; + } + } + + var keeps = _REDACT_KEEP_CONTENT_MAP[this.getType()] || {}; + for (var key in utils.keys(this.event.content)) { + if (!keeps[key]) { + delete this.event.content[key]; + } + } }, /** @@ -214,3 +227,40 @@ module.exports.MatrixEvent.prototype = { return Boolean(this.getUnsigned().redacted_because); }, }; + + +/* http://matrix.org/docs/spec/r0.0.1/client_server.html#redactions says: + * + * the server should strip off any keys not in the following list: + * event_id + * type + * room_id + * user_id + * state_key + * prev_state + * content + * [we keep 'unsigned' as well, since that is created by the local server] + * + * The content object should also be stripped of all keys, unless it is one of one of the following event types: + * m.room.member allows key membership + * m.room.create allows key creator + * m.room.join_rules allows key join_rule + * m.room.power_levels allows keys ban, events, events_default, kick, redact, state_default, users, users_default. + * m.room.aliases allows key aliases + */ +// a map giving the keys we keep when an event is redacted +var _REDACT_KEEP_KEY_MAP = [ + 'event_id', 'type', 'room_id', 'user_id', 'state_key', 'prev_state', 'content', 'unsigned', +].reduce(function(ret, val) { ret[val] = 1; return ret}, {}); + +// a map from event type to the .content keys we keep when an event is redacted +var _REDACT_KEEP_CONTENT_MAP = { + 'm.room.member': {'membership': 1}, + 'm.room.create': {'creator': 1}, + 'm.room.join_rules': {'join_rule': 1}, + 'm.room.power_levels': {'ban': 1, 'events': 1, 'events_default': 1, + 'kick': 1, 'redact': 1, 'state_default': 1, + 'users': 1, 'users_default': 1, + }, + 'm.room.aliases': {'aliases': 1}, +}; diff --git a/lib/models/room.js b/lib/models/room.js index 8efb472b1..0f3fc3943 100644 --- a/lib/models/room.js +++ b/lib/models/room.js @@ -602,6 +602,12 @@ Room.prototype._addLiveEvents = function(events) { if (redactedEvent) { redactedEvent.makeRedacted(events[i]); this.emit("Room.redaction", events[i], this); + + // TODO: we stash user displaynames (among other things) in + // RoomMember objects which are then attached to other events + // (in the sender and target fields). We should get those + // RoomMember objects to update themselves when the events that + // they are based on are changed. } // NB: We continue to add the redaction event to the timeline so