Issues (159)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

js/script.js (26 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
/*
2
 * Copyright (c) 2015
3
 *
4
 * This file is licensed under the Affero General Public License version 3
5
 * or later.
6
 *
7
 * See the COPYING-README file.
8
 *
9
 */
10
$(function(){
11
	OCA.Activity = OCA.Activity || {};
12
13
	OCA.Activity.Filter = {
14
		filter: undefined,
15
		$navigation: $('#app-navigation'),
16
17
18
		_onPopState: function(params) {
19
			params = _.extend({
20
				filter: 'all'
21
			}, params);
22
23
			this.setFilter(params.filter);
24
		},
25
26
		setFilter: function (filter) {
27
			if (filter === this.filter) {
28
				return;
29
			}
30
31
			this.$navigation.find('a[data-navigation=' + this.filter + ']').parent().removeClass('active');
32
			OCA.Activity.InfinitScrolling.firstKnownId = 0;
33
			OCA.Activity.InfinitScrolling.lastGivenId = 0;
34
35
			this.filter = filter;
36
37
			OCA.Activity.InfinitScrolling.$container.animate({ scrollTop: 0 }, 'slow');
38
			OCA.Activity.InfinitScrolling.$container.children().remove();
39
			$('#emptycontent').addClass('hidden');
40
			$('#no_more_activities').addClass('hidden');
41
			$('#loading_activities').removeClass('hidden');
42
			OCA.Activity.InfinitScrolling.ignoreScroll = 0;
43
44
			this.$navigation.find('a[data-navigation=' + filter + ']').parent().addClass('active');
45
46
			OCA.Activity.InfinitScrolling.prefill();
47
		}
48
	};
49
50
	OCA.Activity.InfinitScrolling = {
51
		ignoreScroll: 0,
52
		$container: $('#container'),
53
		lastDateGroup: null,
54
		$content: $(document),
55
		firstKnownId: 0,
56
		lastGivenId: 0,
57
		activities: {},
58
59
		prefill: function () {
60
			this.ignoreScroll += 1;
61
			if (this.$content.scrollTop() + $(window).height() > this.$container.height() - 100) {
62
				this.ignoreScroll += 1;
63
				this.loadMoreActivities();
64
			}
65
			this.ignoreScroll -= 1;
66
		},
67
68
		onScroll: function () {
69
			if (this.ignoreScroll <= 0
70
				&& this.$content.scrollTop() + $(window).height() > this.$container.height() - 100) {
0 ignored issues
show
There seems to be a bad line break before &&.
Loading history...
71
				this.ignoreScroll = 1;
72
				this.loadMoreActivities();
73
			}
74
		},
75
76
		/**
77
		 * Request a new bunch of activities from the server
78
		 */
79
		loadMoreActivities: function () {
80
			var self = this;
81
82
			$.ajax({
83
				url: OC.linkToOCS('apps/activity/api/v2/activity', 2) + OCA.Activity.Filter.filter + '?format=json&previews=true&since=' + self.lastGivenId,
84
				type: 'GET',
85
				beforeSend: function(xhr) {
86
					xhr.setRequestHeader("Accept-Language", OC.getLocale());
87
				},
88
				success: function(response, status, xhr) {
89
					if (status === 'notmodified') {
90
						self.handleActivitiesCallback([]);
91
						self.saveHeaders(xhr.getAllResponseHeaders());
92
						return;
93
					}
94
95
					self.saveHeaders(xhr.getAllResponseHeaders());
96
					if (typeof response != 'undefined') {
97
						self.handleActivitiesCallback(response.ocs.data);
98
						self.ignoreScroll -= 1;
99
					}
100
				}
101
			});
102
		},
103
104
		/**
105
		 * Read the X-Activity-First-Known and X-Activity-Last-Given headers
106
		 * @param headers
107
		 */
108
		saveHeaders: function(headers) {
109
			var self = this;
110
111
			headers = headers.split("\n");
112
			_.each(headers, function (header) {
113
				var parts = header.split(':');
114
				if (parts[0].toLowerCase() === 'x-activity-first-known') {
115
					self.firstKnownId = parseInt(parts[1].trim(), 10);
116
				} else if (parts[0].toLowerCase() === 'x-activity-last-given') {
117
					self.lastGivenId = parseInt(parts[1].trim(), 10);
118
				}
119
			});
120
		},
121
122
		/**
123
		 * Append activities to the view or display end/no content
124
		 * @param data
125
		 */
126
		handleActivitiesCallback: function (data) {
127
			var numActivities = data.length;
128
129
			if (numActivities > 0) {
130
				for (var i = 0; i < data.length; i++) {
131
					var activity = data[i];
132
					this.appendActivityToContainer(activity);
133
				}
134
135
				// Continue prefill
136
				this.prefill();
137
138
			} else if (this.$container.children().length === 0) {
139
				// First page is empty - No activities :(
140
				var $emptyContent = $('#emptycontent');
141
				$emptyContent.removeClass('hidden');
142
				if (OCA.Activity.Filter.filter == 'all') {
143
					$emptyContent.find('p').text(t('activity', 'This stream will show events like additions, changes & shares'));
144
				} else {
145
					$emptyContent.find('p').text(t('activity', 'There are no events for this filter'));
146
				}
147
				$('#loading_activities').addClass('hidden');
148
				this.ignoreScroll = 1;
149
150
			} else {
151
				// Page is empty - No more activities :(
152
				$('#no_more_activities').removeClass('hidden');
153
				$('#loading_activities').addClass('hidden');
154
				this.ignoreScroll = 1;
155
			}
156
		},
157
158
		appendActivityToContainer: function (activity) {
159
			activity.timestamp = moment(activity.datetime).valueOf();
160
			this.makeSureDateGroupExists(activity.timestamp);
161
162
			this.activities[activity.activity_id] = activity;
163
			this.addActivity(activity);
164
		},
165
166
		makeSureDateGroupExists: function(timestamp) {
167
			var dayOfYear = OC.Util.formatDate(timestamp, 'YYYY-DDD');
168
			var $lastGroup = this.$container.children().last();
169
170
			if ($lastGroup.data('date') !== dayOfYear) {
171
				var dateOfDay = OC.Util.formatDate(timestamp, 'LL'),
172
					displayDate = dateOfDay;
173
174
				var today = OC.Util.formatDate(moment(), 'YYYY-DDD');
175
				if (dayOfYear === today) {
176
					displayDate = t('activity', 'Today');
177
				} else {
178
					var yesterday = OC.Util.formatDate(moment().subtract(1, 'd'), 'YYYY-DDD');
179
180
					if (dayOfYear === yesterday) {
181
						displayDate = t('activity', 'Yesterday');
182
					}
183
				}
184
185
				var content = '<div class="section activity-section group" data-date="' + escapeHTML(dayOfYear) + '">' + "\n"
186
					+'	<h2>'+"\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
187
					+'		<span class="has-tooltip" title="' + escapeHTML(dateOfDay) + '">' + escapeHTML(displayDate) + '</span>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
188
					+'	</h2>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
189
					+'	<div class="boxcontainer">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
190
					+'	</div>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
191
					+'</div>';
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
192
				var $content = $(content);
193
				this.processElements($content);
194
				this.$container.append($content);
195
				this.lastDateGroup = $content;
196
			}
197
		},
198
199
		addActivity: function(activity) {
200
			var subject = activity.subject;
201
			if (activity.subject_rich[0].length > 1) {
202
				subject = OCA.Activity.RichObjectStringParser.parseMessage(activity.subject_rich[0], activity.subject_rich[1]);
203
			}
204
			var message = activity.message;
205
			if (activity.message_rich[0].length > 1) {
206
				message = OCA.Activity.RichObjectStringParser.parseMessage(activity.message_rich[0], activity.message_rich[1]);
207
			}
208
			if (subject.indexOf('<a') >= 0) {
209
				activity.link = '';
210
			}
211
212
			var content = ''
213
				+ '<div class="box" data-activity-id="' + activity.activity_id + '">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
214
				+ '	<div class="messagecontainer">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
215
216
				+ '		<div class="activity-icon">'
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
217
				+ ((activity.icon) ? '			<img src="' + activity.icon + '" alt="" />' : '')
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
218
				+ '		</div>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
219
220
				+ '		<div class="activitysubject">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
221
				+ ((activity.link) ? '			<a href="' + activity.link + '">' + "\n" : '')
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
222
				+ '			' + subject + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
223
				+ ((activity.link) ? '			</a>' + "\n" : '')
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
224
				+ '		</div>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
225
226
				+'		<span class="activitytime has-tooltip live-relative-timestamp" data-timestamp="' + activity.timestamp + '" title="' + escapeHTML(OC.Util.formatDate(activity.timestamp)) + '">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
227
				+ '			' + escapeHTML(OC.Util.relativeModifiedDate(activity.timestamp)) + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
228
				+'		</span>' + "\n";
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
229
230
			if (message) {
231
				content += '<div class="activitymessage">' + "\n"
232
					+ message + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
233
					+'</div>' + "\n";
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
234
			}
235
236
			if (activity.previews && activity.previews.length) {
237
				content += '<div class="activity-previews">';
238
				for (var i = 0; i < activity.previews.length; i++) {
239
					var preview = activity.previews[i];
240
					content += ((preview.link) ? '<a href="' + preview.link + '">' + "\n" : '')
241
						+ '<img class="preview' + ((preview.isMimeTypeIcon) ? ' preview-mimetype-icon' : '') + '" src="' + preview.source + '" alt="' + t('activity', 'Open file') + '" />' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
242
						+ ((preview.link) ? '</a>' + "\n" : '')
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
243
				}
244
				content += '</div>';
245
			}
246
247
			content += '	</div>' + "\n"
248
				+'</div>';
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
249
250
			var $content = $(content);
251
			this.processElements($content);
252
			this.lastDateGroup.append($content);
253
		},
254
255
		processElements: function ($element) {
256
			var self = this;
257
258
			$element.find('.avatar').each(function() {
259
				var element = $(this);
260
				if (element.data('user-display-name')) {
261
					element.avatar(element.data('user'), 21, undefined, false, undefined, element.data('user-display-name'));
262
				} else {
263
					element.avatar(element.data('user'), 21);
264
				}
265
			});
266
267
			$element.find('.avatar-name-wrapper').each(function() {
268
				var element = $(this);
269
				var avatar = element.find('.avatar');
270
				var label = element.find('strong');
271
272
				$.merge(avatar, label).contactsMenu(element.data('user'), 0, element);
273
			});
274
275
			$element.find('.activity-more-link').click(function() {
276
				var $moreElement = $(this),
277
					activityId = $moreElement.closest('.box').data('activity-id'),
278
					$subject = $moreElement.closest('.activitysubject');
279
280
				var activity = self.activities[activityId];
281
				$subject.html(self.parseMessage(activity.subject_prepared, true));
282
				self.processElements($subject);
283
			});
284
285
			$element.find('.has-tooltip').tooltip({
286
				placement: 'bottom'
287
			});
288
		}
289
	};
290
291
	//OCA.Activity.Formatter.setAvatarStatus(OCA.Activity.InfinitScrolling.$container.data('avatars-enabled') === 'yes');
292
	OC.Util.History.addOnPopStateHandler(_.bind(OCA.Activity.Filter._onPopState, OCA.Activity.Filter));
293
	OCA.Activity.Filter.setFilter(OCA.Activity.InfinitScrolling.$container.attr('data-activity-filter'));
294
	OCA.Activity.InfinitScrolling.$content.on('scroll', _.bind(OCA.Activity.InfinitScrolling.onScroll, OCA.Activity.InfinitScrolling));
295
296
	OCA.Activity.Filter.$navigation.find('a[data-navigation]').on('click', function (event) {
297
		var filter = $(this).attr('data-navigation');
298
		if (filter !== OCA.Activity.Filter.filter) {
299
			OC.Util.History.pushState({
300
				filter: filter
301
			});
302
		}
303
		OCA.Activity.Filter.setFilter(filter);
304
		event.preventDefault();
305
	});
306
});
307