Issues (33)

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/bookmarks.js (1 issue)

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
var bookmarksPage = 0;
2
var bookmarksLoading = false;
3
var dialog;
4
var bookmarksSorting = 'bookmarks_sorting_recent';
5
var fullTags = [];
6
var ajaxCallCount = 0;
7
8
$(document).ready(function () {
9
	getTags();
10
	watchUrlField();
11
	$('#bm_import').change(attachSettingEvent);
12
	$('#add_url').on('keydown keyup change click', watchUrlField);
13
	$('#app-settings').on('click keydown', toggleSettings);
14
	$('#bm_export').click(exportBm);
15
	$('#emptycontent-setting').click(function () {
16
		if (!$('#app-settings').hasClass('open')) {
17
			$('#app-settings').click();
18
		}
19
	});
20
	$('.bookmarks_list').scroll(updateOnBottom).empty();
21
	$('#tag_filter input').tagit({
22
		allowSpaces: true,
23
		availableTags: fullTags,
24
		onTagFinishRemoved: filterTagsChanged,
25
		placeholderText: t('bookmarks', 'Filter by tag')
26
	}).tagit('option', 'onTagAdded', filterTagsChanged);
27
	getBookmarks();
28
});
29
30
function getTags() {
31
	jQuery.ajax({
32
		url: 'tag',
33
		success: function (result) {
34
			fullTags = result;
35
		},
36
		async: false
37
	});
38
}
39
40
var formatString = (function () {
41
	var replacer = function (context) {
42
		return function (s, name) {
43
			return context[name];
44
		};
45
	};
46
47
	return function (input, context) {
48
		return input.replace(/\{(\w+)\}/g, replacer(context));
49
	};
50
})();
51
52
function increaseAjaxCallCount() {
53
	ajaxCallCount++;
54
	if (ajaxCallCount - 1 === 0) {
55
		updateLoadingAnimation();
56
	}
57
}
58
59
function decreaseAjaxCallCount() {
60
	if (ajaxCallCount > 0) {
61
		ajaxCallCount--;
62
		updateLoadingAnimation();
63
	}
64
}
65
66
function updateLoadingAnimation() {
67
	if (ajaxCallCount === 0) {
68
		$('#bookmark_add_submit').removeClass('icon-loading-small');
69
		$('#bookmark_add_submit').addClass('icon-add');
70
	} else {
71
		$('#bookmark_add_submit').removeClass('icon-add');
72
		$('#bookmark_add_submit').addClass('icon-loading-small');
73
	}
74
}
75
76
function watchClickInSetting(e) {
77
	if ($('#app-settings').find($(e.target)).length === 0) {
78
		toggleSettings();
79
	}
80
}
81
82
function checkURL(url) {
83
	if (url.substring(0, 3) === "htt") {
84
		return url;
85
	}
86
	return "http://" + url;
87
}
88
89
function toggleSettings() {
90
	if ($('#app-settings').hasClass('open')) { //Close
91
		$('#app-settings').switchClass("open", "");
92
		$('body').unbind('click', watchClickInSetting);
93
	}
94
	else {
95
		$('#app-settings').switchClass("", "open");
96
		$('body').bind('click', watchClickInSetting);
97
	}
98
}
99
function addFilterTag(event) {
100
	event.preventDefault();
101
	$('#tag_filter input').tagit('createTag', $(this).text());
102
}
103
104
function updateTagsList(tag) {
105
	var html = tmpl("tag_tmpl", tag);
106
	$('.tag_list').append(html);
107
}
108
109
function filterTagsChanged()
110
{
111
	$('#bookmarkFilterTag').val($('#tag_filter input').val());
112
	$('.bookmarks_list').empty();
113
	bookmarksPage = 0;
114
	getBookmarks();
115
}
116
function getBookmarks() {
117
	if (bookmarksLoading) {
118
		//have patience :)
119
		return;
120
	}
121
	increaseAjaxCallCount();
122
	bookmarksLoading = true;
123
	//Update Rel Tags if first page
124
	if (bookmarksPage === 0) {
125
126
		$.ajax({
127
			type: 'GET',
128
			url: 'bookmark',
129
			data: {type: 'rel_tags', tag: $('#bookmarkFilterTag').val(), page: bookmarksPage, sort: bookmarksSorting},
130
			success: function (tags) {
131
				$('.tag_list').empty();
132
				for (var i in tags.data) {
133
					updateTagsList(tags.data[i]);
134
				}
135
				$('.tag_list .tag_edit').click(renameTag);
136
				$('.tag_list .tag_delete').click(deleteTag);
137
				$('.tag_list a.tag').click(addFilterTag);
138
139
140
			}
141
		});
142
	}
143
	$.ajax({
144
		type: 'GET',
145
		url: 'bookmark',
146
		data: {type: 'bookmark', tag: $('#bookmarkFilterTag').val(), page: bookmarksPage, sort: bookmarksSorting},
147
		complete: function () {
148
			decreaseAjaxCallCount();
149
		},
150
		success: function (bookmarks) {
151
			if (bookmarks.data.length) {
152
				bookmarksPage += 1;
153
			}
154
			$('.bookmark_link').unbind('click', recordClick);
155
			$('.bookmark_delete').unbind('click', delBookmark);
156
			$('.bookmark_edit').unbind('click', editBookmark);
157
158
			for (var i in bookmarks.data) {
159
				updateBookmarksList(bookmarks.data[i]);
160
			}
161
			checkEmpty();
162
163
			$('.bookmark_link').click(recordClick);
164
			$('.bookmark_delete').click(delBookmark);
165
			$('.bookmark_edit').click(editBookmark);
166
167
			bookmarksLoading = false;
168
			if (bookmarks.data.length) {
169
				updateOnBottom();
170
			}
171
		}
172
	});
173
}
174
175
function watchUrlField() {
176
	var form = $('#add_form');
177
	var el = $('#add_url');
178
	var button = $('#bookmark_add_submit');
179
	form.unbind('submit');
180
	if (!acceptUrl(el.val())) {
181
		form.bind('submit', function (e) {
182
			e.preventDefault();
183
		});
184
		button.addClass('disabled');
185
	}
186
	else {
187
		button.removeClass('disabled');
188
		form.bind('submit', addBookmark);
189
	}
190
}
191
192
function acceptUrl(url) {
193
	return url.replace(/^\s+/g, '').replace(/\s+$/g, '') !== '';
194
}
195
196
function addBookmark(event) {
197
	event.preventDefault();
198
	var url = $('#add_url').val();
199
	//If trim is empty
200
	if (!acceptUrl(url)) {
201
		return;
202
	}
203
204
	$('#add_url').val('');
205
	var bookmark = {url: url, description: '', title: '', from_own: 0, added_date: new Date()};
206
	increaseAjaxCallCount();
207
	$.ajax({
208
		type: 'POST',
209
		url: 'bookmark',
210
		data: bookmark,
211
		complete: function () {
212
			decreaseAjaxCallCount();
213
		},
214
		success: function (data) {
215
			if (data.status === 'success') {
216
				// First remove old BM if exists
217
				$('.bookmark_single').filterAttr('data-id', data.item.id).remove();
218
219
				var bookmark = $.extend({}, bookmark, data.item);
220
				updateBookmarksList(bookmark, 'prepend');
221
				checkEmpty();
222
				watchUrlField();
223
			}
224
		},
225
		error: function () {
226
			OC.Notification.showTemporary(t('bookmarks', 'Could not add bookmark.'));
227
		}
228
	});
229
}
230
231
function delBookmark() {
232
	var record = $(this).parent().parent();
233
	OC.dialogs.confirm(t('bookmarks', 'Are you sure you want to remove this bookmark?'),
234
			t('bookmarks', 'Warning'), function (answer) {
235
		if (answer) {
236
			$.ajax({
237
				type: 'DELETE',
238
				url: 'bookmark/' + record.data('id'),
239
				success: function (data) {
240
					if (data.status === 'success') {
241
						record.remove();
242
						checkEmpty();
243
					}
244
				}
245
			});
246
		}
247
	});
248
}
249
250
function checkEmpty() {
251
	if ($('.bookmarks_list').children().length === 0) {
252
		$("#emptycontent").show();
253
		$("#bm_export").addClass('disabled');
254
		$('.bookmarks_list').hide();
255
	} else {
256
		$("#emptycontent").hide();
257
		$("#bm_export").removeClass('disabled');
258
		$('.bookmarks_list').show();
259
	}
260
}
261
function editBookmark() {
262
	if ($('.bookmark_single_form').length) {
263
		$('.bookmark_single_form .reset').click();
264
	}
265
	var record = $(this).parent().parent();
266
	var bookmark = record.data('record');
267
	var html = tmpl("item_form_tmpl", bookmark);
268
269
	record.after(html);
270
	record.hide();
271
	var rec_form = record.next().find('form');
272
	rec_form.find('.bookmark_form_tags ul').tagit({
273
		allowSpaces: true,
274
		availableTags: fullTags,
275
		placeholderText: t('bookmarks', 'Tags')
276
	});
277
278
	rec_form.find('.reset').bind('click', cancelBookmark);
279
	rec_form.bind('submit', function (event) {
280
		event.preventDefault();
281
		var form_values = $(this).serialize();
282
		$.ajax({
283
			type: 'PUT',
284
			url: $(this).attr('action') + "/" + this.elements['record_id'].value,
0 ignored issues
show
['record_id'] could be written in dot notation.

You can rewrite this statement in dot notation:

var obj = { };
obj['foo'] = 'bar'; // Bad
obj.foo = 'bar'; // Good
Loading history...
285
			data: form_values,
286
			success: function (data) {
287
				if (data.status === 'success') {
288
					//@TODO : do better reaction than reloading the page
289
					filterTagsChanged();
290
				} else { // On failure
291
					//@TODO : show error message?
292
				}
293
			}
294
		});
295
	});
296
}
297
298
function cancelBookmark(event) {
299
	event.preventDefault();
300
	var rec_form = $(this).closest('form').parent();
301
	rec_form.prev().show();
302
	rec_form.remove();
303
}
304
305
function updateBookmarksList(bookmark, position) {
306
	position = typeof position !== 'undefined' ? position : 'append';
307
	bookmark = $.extend({title: '', description: '', added_date: new Date('now'), tags: []}, bookmark);
308
	var tags = bookmark.tags;
309
	var taglist = '';
310
	for (var i = 0, len = tags.length; i < len; ++i) {
311
		if (tags[i] !== '')
312
			taglist = taglist + '<a class="bookmark_tag" href="#">' + escapeHTML(tags[i]) + '</a> ';
313
	}
314
	if (!hasProtocol(bookmark.url)) {
315
		bookmark.url = 'http://' + bookmark.url;
316
	}
317
318
	if (bookmark.added) {
319
		bookmark.added_date.setTime(parseInt(bookmark.added) * 1000);
320
	}
321
322
	if (!bookmark.title)
323
		bookmark.title = '';
324
325
	var html = tmpl("item_tmpl", bookmark);
326
	if (position === "prepend") {
327
		$('.bookmarks_list').prepend(html);
328
	} else {
329
		$('.bookmarks_list').append(html);
330
	}
331
	var line = $('div[data-id="' + bookmark.id + '"]');
332
	line.data('record', bookmark);
333
	if (taglist !== '') {
334
		line.append('<p class="bookmark_tags">' + taglist + '</p>');
335
	}
336
	line.find('a.bookmark_tag').bind('click', addFilterTag);
337
	line.find('.bookmark_link').click(recordClick);
338
	line.find('.bookmark_delete').click(delBookmark);
339
	line.find('.bookmark_edit').click(editBookmark);
340
341
}
342
343
function updateOnBottom() {
344
	//check wether user is on bottom of the page
345
	var top = $('.bookmarks_list>:last-child').position().top;
346
	var height = $('.bookmarks_list').height();
347
	// use a bit of margin to begin loading before we are really at the
348
	// bottom
349
	if (top < height * 1.2) {
350
		getBookmarks();
351
	}
352
}
353
354
function recordClick() {
355
	$.ajax({
356
		type: 'POST',
357
		url: 'bookmark/click',
358
		data: 'url=' + encodeURIComponent($(this).attr('href'))
359
	});
360
}
361
362
function hasProtocol(url) {
363
	var regexp = /(ftp|http|https|sftp)/;
364
	return regexp.test(url);
365
}
366
367
function renameTag() {
368
	if ($('input[name="tag_new_name"]').length)
369
		return; // Do nothing if a tag is currenlty edited
370
	var tagElement = $(this).closest('li');
371
	tagElement.append('<form><input name="tag_new_name" type="text"></form>');
372
	var form = tagElement.find('form');
373
	//tag_el.find('.tags_actions').hide();
374
	var tagName = tagElement.find('.tag').hide().text();
375
	tagElement.find('input').val(tagName).focus().bind('blur', function () {
376
		form.trigger('submit');
377
	});
378
	form.bind('submit', submitTagName);
379
}
380
381
function submitTagName(event) {
382
	event.preventDefault();
383
	var tagElement = $(this).closest('li');
384
	var newTagName = tagElement.find('input').val();
385
	var oldTagName = tagElement.find('.tag').show().text();
386
	//tag_el.find('.tag_edit').show();
387
	//tag_el.find('.tags_actions').show();
388
	tagElement.find('input').unbind('blur');
389
	tagElement.find('form').unbind('submit').remove();
390
391
	if (newTagName !== oldTagName && newTagName !== '') {
392
		//submit
393
		$.ajax({
394
			type: 'POST',
395
			url: 'tag',
396
			data: {old_name: oldTagName, new_name: newTagName},
397
			success: function (bookmarks) {
398
				if (bookmarks.status === 'success') {
399
					filterTagsChanged();
400
				}
401
			}
402
		});
403
	}
404
}
405
406
function deleteTag() {
407
	var tag_el = $(this).closest('li');
408
	var old_tag_name = tag_el.find('.tag').show().text();
409
	OC.dialogs.confirm(t('bookmarks', 'Are you sure you want to remove this tag from every entry?'),
410
			t('bookmarks', 'Warning'), function (answer) {
411
		if (answer) {
412
			$.ajax({
413
				type: 'DELETE',
414
				url: 'tag',
415
				data: {old_name: old_tag_name},
416
				success: function (bookmarks) {
417
					if (bookmarks.status === 'success') {
418
						filterTagsChanged();
419
					}
420
				}
421
			});
422
		}
423
	});
424
}
425