1 | /*
|
2 | Copyright 2016 OpenMarket Ltd
|
3 |
|
4 | Licensed under the Apache License, Version 2.0 (the "License");
|
5 | you may not use this file except in compliance with the License.
|
6 | You may obtain a copy of the License at
|
7 |
|
8 | http://www.apache.org/licenses/LICENSE-2.0
|
9 |
|
10 | Unless required by applicable law or agreed to in writing, software
|
11 | distributed under the License is distributed on an "AS IS" BASIS,
|
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | See the License for the specific language governing permissions and
|
14 | limitations under the License.
|
15 | */
|
16 | ;
|
17 | /**
|
18 | * @module filter-component
|
19 | */
|
20 |
|
21 | /**
|
22 | * Checks if a value matches a given field value, which may be a * terminated
|
23 | * wildcard pattern.
|
24 | * @param {String} actual_value The value to be compared
|
25 | * @param {String} filter_value The filter pattern to be compared
|
26 | * @return {bool} true if the actual_value matches the filter_value
|
27 | */
|
28 |
|
29 | var _keys = require("babel-runtime/core-js/object/keys");
|
30 |
|
31 | var _keys2 = _interopRequireDefault(_keys);
|
32 |
|
33 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
34 |
|
35 | function _matches_wildcard(actual_value, filter_value) {
|
36 | if (filter_value.endsWith("*")) {
|
37 | var type_prefix = filter_value.slice(0, -1);
|
38 | return actual_value.substr(0, type_prefix.length) === type_prefix;
|
39 | } else {
|
40 | return actual_value === filter_value;
|
41 | }
|
42 | }
|
43 |
|
44 | /**
|
45 | * FilterComponent is a section of a Filter definition which defines the
|
46 | * types, rooms, senders filters etc to be applied to a particular type of resource.
|
47 | * This is all ported over from synapse's Filter object.
|
48 | *
|
49 | * N.B. that synapse refers to these as 'Filters', and what js-sdk refers to as
|
50 | * 'Filters' are referred to as 'FilterCollections'.
|
51 | *
|
52 | * @constructor
|
53 | * @param {Object} filter_json the definition of this filter JSON, e.g. { 'contains_url': true }
|
54 | */
|
55 | function FilterComponent(filter_json) {
|
56 | this.filter_json = filter_json;
|
57 |
|
58 | this.types = filter_json.types || null;
|
59 | this.not_types = filter_json.not_types || [];
|
60 |
|
61 | this.rooms = filter_json.rooms || null;
|
62 | this.not_rooms = filter_json.not_rooms || [];
|
63 |
|
64 | this.senders = filter_json.senders || null;
|
65 | this.not_senders = filter_json.not_senders || [];
|
66 |
|
67 | this.contains_url = filter_json.contains_url || null;
|
68 | }
|
69 |
|
70 | /**
|
71 | * Checks with the filter component matches the given event
|
72 | * @param {MatrixEvent} event event to be checked against the filter
|
73 | * @return {bool} true if the event matches the filter
|
74 | */
|
75 | FilterComponent.prototype.check = function (event) {
|
76 | return this._checkFields(event.getRoomId(), event.getSender(), event.getType(), event.getContent() ? event.getContent().url !== undefined : false);
|
77 | };
|
78 |
|
79 | /**
|
80 | * Checks whether the filter component matches the given event fields.
|
81 | * @param {String} room_id the room_id for the event being checked
|
82 | * @param {String} sender the sender of the event being checked
|
83 | * @param {String} event_type the type of the event being checked
|
84 | * @param {String} contains_url whether the event contains a content.url field
|
85 | * @return {bool} true if the event fields match the filter
|
86 | */
|
87 | FilterComponent.prototype._checkFields = function (room_id, sender, event_type, contains_url) {
|
88 | var literal_keys = {
|
89 | "rooms": function rooms(v) {
|
90 | return room_id === v;
|
91 | },
|
92 | "senders": function senders(v) {
|
93 | return sender === v;
|
94 | },
|
95 | "types": function types(v) {
|
96 | return _matches_wildcard(event_type, v);
|
97 | }
|
98 | };
|
99 |
|
100 | var self = this;
|
101 | for (var n = 0; n < (0, _keys2.default)(literal_keys).length; n++) {
|
102 | var name = (0, _keys2.default)(literal_keys)[n];
|
103 | var match_func = literal_keys[name];
|
104 | var not_name = "not_" + name;
|
105 | var disallowed_values = self[not_name];
|
106 | if (disallowed_values.filter(match_func).length > 0) {
|
107 | return false;
|
108 | }
|
109 |
|
110 | var allowed_values = self[name];
|
111 | if (allowed_values) {
|
112 | if (!allowed_values.map(match_func)) {
|
113 | return false;
|
114 | }
|
115 | }
|
116 | }
|
117 |
|
118 | var contains_url_filter = this.filter_json.contains_url;
|
119 | if (contains_url_filter !== undefined) {
|
120 | if (contains_url_filter !== contains_url) {
|
121 | return false;
|
122 | }
|
123 | }
|
124 |
|
125 | return true;
|
126 | };
|
127 |
|
128 | /**
|
129 | * Filters a list of events down to those which match this filter component
|
130 | * @param {MatrixEvent[]} events Events to be checked againt the filter component
|
131 | * @return {MatrixEvent[]} events which matched the filter component
|
132 | */
|
133 | FilterComponent.prototype.filter = function (events) {
|
134 | return events.filter(this.check, this);
|
135 | };
|
136 |
|
137 | /**
|
138 | * Returns the limit field for a given filter component, providing a default of
|
139 | * 10 if none is otherwise specified. Cargo-culted from Synapse.
|
140 | * @return {Number} the limit for this filter component.
|
141 | */
|
142 | FilterComponent.prototype.limit = function () {
|
143 | return this.filter_json.limit !== undefined ? this.filter_json.limit : 10;
|
144 | };
|
145 |
|
146 | /** The FilterComponent class */
|
147 | module.exports = FilterComponent;
|
148 | //# sourceMappingURL=filter-component.js.map |
\ | No newline at end of file |