Issues (81)

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 (23 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: $('#app-content'),
55
		firstKnownId: 0,
56
		lastGivenId: 0,
57
		activities: {},
58
59
		prefill: function () {
60
			this.ignoreScroll += 1;
61
			if (this.$content.scrollTop() + this.$content.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 && this.$content.scrollTop() +
70
				this.$content.height() > this.$container.height() - 100) {
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
				url: OC.generateUrl('/apps/activity/api/v2/activity') + '/' + OCA.Activity.Filter.filter + '?format=json&previews=true&since=' + self.lastGivenId,
85
				type: 'GET',
86
				beforeSend: function(xhr) {
87
					xhr.setRequestHeader("Accept-Language", OC.getLocale());
88
				},
89
				success: function(response, status, xhr) {
90
					if (status === 'notmodified') {
91
						self.handleActivitiesCallback([]);
92
						self.saveHeaders(xhr.getAllResponseHeaders());
93
						return;
94
					}
95
96
					self.saveHeaders(xhr.getAllResponseHeaders());
97
					if (typeof response != 'undefined') {
98
						self.handleActivitiesCallback(response.ocs.data);
99
						self.ignoreScroll -= 1;
100
					}
101
				}
102
			});
103
		},
104
105
		/**
106
		 * Read the X-Activity-First-Known and X-Activity-Last-Given headers
107
		 * @param headers
108
		 */
109
		saveHeaders: function(headers) {
110
			var self = this;
111
112
			headers = headers.split("\n");
113
			_.each(headers, function (header) {
114
				var parts = header.split(':');
115
				if (parts[0].toLowerCase() === 'x-activity-first-known') {
116
					self.firstKnownId = parseInt(parts[1].trim(), 10);
117
				} else if (parts[0].toLowerCase() === 'x-activity-last-given') {
118
					self.lastGivenId = parseInt(parts[1].trim(), 10);
119
				}
120
			});
121
		},
122
123
		/**
124
		 * Append activities to the view or display end/no content
125
		 * @param data
126
		 */
127
		handleActivitiesCallback: function (data) {
128
			var numActivities = data.length;
129
130
			if (numActivities > 0) {
131
				for (var i = 0; i < data.length; i++) {
132
					var activity = data[i];
133
					this.appendActivityToContainer(activity);
134
				}
135
136
				// Continue prefill
137
				this.prefill();
138
139
			} else if (this.$container.children().length === 0) {
140
				// First page is empty - No activities :(
141
				var $emptyContent = $('#emptycontent');
142
				$emptyContent.removeClass('hidden');
143
				if (OCA.Activity.Filter.filter == 'all') {
144
					$emptyContent.find('p').text(t('activity', 'This stream will show events like additions, changes & shares'));
145
				} else {
146
					$emptyContent.find('p').text(t('activity', 'There are no events for this filter'));
147
				}
148
				$('#loading_activities').addClass('hidden');
149
				this.ignoreScroll = 1;
150
151
			} else {
152
				// Page is empty - No more activities :(
153
				$('#no_more_activities').removeClass('hidden');
154
				$('#loading_activities').addClass('hidden');
155
				this.ignoreScroll = 1;
156
			}
157
		},
158
159
		appendActivityToContainer: function (activity) {
160
			activity.timestamp = moment(activity.datetime).valueOf();
161
			this.makeSureDateGroupExists(activity.timestamp);
162
163
			this.activities[activity.activity_id] = activity;
164
			this.addActivity(activity);
165
		},
166
167
		makeSureDateGroupExists: function(timestamp) {
168
			var dayOfYear = OC.Util.formatDate(timestamp, 'YYYY-DDD');
169
			var $lastGroup = this.$container.children().last();
170
171
			if ($lastGroup.data('date') !== dayOfYear) {
172
				var dateOfDay = OC.Util.formatDate(timestamp, 'LL'),
173
					displayDate = dateOfDay;
174
175
				var today = OC.Util.formatDate(moment(), 'YYYY-DDD');
176
				if (dayOfYear === today) {
177
					displayDate = t('activity', 'Today');
178
				} else {
179
					var yesterday = OC.Util.formatDate(moment().subtract(1, 'd'), 'YYYY-DDD');
180
181
					if (dayOfYear === yesterday) {
182
						displayDate = t('activity', 'Yesterday');
183
					}
184
				}
185
186
				var content = '<div class="section activity-section group" data-date="' + escapeHTML(dayOfYear) + '">' + "\n"
187
					+'	<h2>'+"\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
188
					+'		<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...
189
					+'	</h2>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
190
					+'	<div class="boxcontainer">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
191
					+'	</div>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
192
					+'</div>';
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
193
				var $content = $(content);
194
				this.processElements($content);
195
				this.$container.append($content);
196
				this.lastDateGroup = $content;
197
			}
198
		},
199
200
		addActivity: function(activity) {
201
			subject = activity.subject_prepared;
202
			var parsedSubject = OCA.Activity.Formatter.parseMessage(subject);
203
204
			if (parsedSubject.indexOf('<a') >= 0) {
205
				activity.link = '';
206
			}
207
208
			var content = ''
209
				+ '<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...
210
				+ '	<div class="messagecontainer">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
211
212
				+ '		<div class="activity-icon ' + ((activity.typeicon) ? escapeHTML(activity.typeicon) + ' svg' : '') + '"></div>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
213
214
				+ '		<div class="activitysubject">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
215
				+ ((activity.link) ? '			<a href="' + activity.link + '">' + "\n" : '')
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
216
				+ '			' + parsedSubject + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
217
				+ ((activity.link) ? '			</a>' + "\n" : '')
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
				+'		<span class="activitytime has-tooltip" title="' + escapeHTML(OC.Util.formatDate(activity.timestamp)) + '">' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
221
				+ '			' + escapeHTML(OC.Util.relativeModifiedDate(activity.timestamp)) + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
222
				+'		</span>' + "\n";
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
223
224
			if (activity.message_prepared) {
225
				content += '<div class="activitymessage">' + "\n"
226
					+ OCA.Activity.Formatter.parseMessage(activity.message_prepared) + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
227
					+'</div>' + "\n";
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
228
			}
229
230
			if (activity.previews && activity.previews.length) {
231
				content += '<br />';
232
				for (var i = 0; i < activity.previews.length; i++) {
233
					var preview = activity.previews[i];
234
					content += ((preview.link) ? '<a href="' + preview.link + '">' + "\n" : '')
235
						+ '<img class="preview' + ((preview.isMimeTypeIcon) ? ' preview-mimetype-icon' : '') + '" src="' + preview.source + '" alt=""/>' + "\n"
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
236
						+ ((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...
237
				}
238
			}
239
240
			content += '	</div>' + "\n"
241
				+'</div>';
0 ignored issues
show
There seems to be a bad line break before +.
Loading history...
242
243
			var $content = $(content);
244
			this.processElements($content);
245
			this.lastDateGroup.append($content);
246
		},
247
248
		processElements: function ($element) {
249
			var self = this;
250
251
			$element.find('.avatar').each(function() {
252
				var element = $(this);
253
				if (element.data('user-display-name')) {
254
					element.avatar(element.data('user'), 28, undefined, false, undefined, element.data('user-display-name'));
255
				} else {
256
					element.avatar(element.data('user'), 28);
257
				}
258
			});
259
260
			$element.find('.activity-more-link').on('click', function() {
261
				var $moreElement = $(this),
262
					activityId = $moreElement.closest('.box').data('activity-id'),
263
					$subject = $moreElement.closest('.activitysubject');
264
265
				var activity = self.activities[activityId];
266
				$subject.html(self.parseMessage(activity.subject_prepared, true));
267
				self.processElements($subject);
268
			});
269
270
			$element.find('.has-tooltip').tooltip({
271
				placement: 'bottom'
272
			});
273
		}
274
	};
275
276
	OCA.Activity.Formatter.setAvatarStatus(OCA.Activity.InfinitScrolling.$container.data('avatars-enabled') === 'yes');
277
	OC.Util.History.addOnPopStateHandler(_.bind(OCA.Activity.Filter._onPopState, OCA.Activity.Filter));
278
	OCA.Activity.Filter.setFilter(OCA.Activity.InfinitScrolling.$container.attr('data-activity-filter'));
279
	OCA.Activity.InfinitScrolling.$content.on('scroll', _.bind(OCA.Activity.InfinitScrolling.onScroll, OCA.Activity.InfinitScrolling));
280
281
	OCA.Activity.Filter.$navigation.find('a[data-navigation]').on('click', function (event) {
282
		var filter = $(this).attr('data-navigation');
283
		if (filter !== OCA.Activity.Filter.filter) {
284
			OC.Util.History.pushState({
285
				filter: filter
286
			});
287
		}
288
		OCA.Activity.Filter.setFilter(filter);
289
		event.preventDefault();
290
	});
291
292
	$('#enable_rss').change(function () {
293
		if (this.checked) {
294
			$('#rssurl').removeClass('hidden');
295
		} else {
296
			$('#rssurl').addClass('hidden');
297
		}
298
		$.post(OC.generateUrl('/apps/activity/settings/feed'), 'enable=' + this.checked, function(response) {
299
			$('#rssurl').val(response.data.rsslink);
300
		});
301
	});
302
303
	$('#rssurl').on('click', function () {
304
		$('#rssurl').select();
305
	});
306
});
307
308