diff --git a/data/config.default.php b/data/config.default.php
index 0ec8b93..34f9460 100644
--- a/data/config.default.php
+++ b/data/config.default.php
@@ -615,6 +615,13 @@ $menu2Tags = array(
'menu2', 'tags', 'configurable', 'in', 'data/config.php'
);
+/**
+ * Tag protected from shoulder surfing.
+ * This tag, his children and the associated bookmarks won't appear anywhere unless enabled in the UI.
+ *
+ * @var string
+ */
+$shoulderSurfingProtectedTag = 's_hidden';
/****************************
diff --git a/data/templates/default/toolbar.inc.php b/data/templates/default/toolbar.inc.php
index fb6638d..02ffc59 100644
--- a/data/templates/default/toolbar.inc.php
+++ b/data/templates/default/toolbar.inc.php
@@ -11,14 +11,62 @@ if ($userservice->isLoggedOn() && is_object($currentUser)) {
+
+
+
+
+
()
isAdmin()): ?>
-
+
+
+
+
+
+
diff --git a/data/templates/default/top.inc.php b/data/templates/default/top.inc.php
index 55be4a7..0550d55 100644
--- a/data/templates/default/top.inc.php
+++ b/data/templates/default/top.inc.php
@@ -22,9 +22,11 @@ if (isset($rsschannels)) {
+
+
diff --git a/src/SemanticScuttle/Service/Bookmark.php b/src/SemanticScuttle/Service/Bookmark.php
index 1315350..1c1bc22 100644
--- a/src/SemanticScuttle/Service/Bookmark.php
+++ b/src/SemanticScuttle/Service/Bookmark.php
@@ -733,11 +733,26 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
if (!is_array($tags) && !is_null($tags)) {
$tags = explode('+', trim($tags));
}
-
- $tagcount = count($tags);
- for ($i = 0; $i < $tagcount; $i ++) {
- $tags[$i] = trim($tags[$i]);
+ if (!is_null($tags)) {
+ $tags = array_map('trim', $tags);
}
+ // Remove shoulder surfing protected tags.
+ if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ $shoulderSurfingProtectedTags = $tag2tagservice->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $sId, array());
+ $shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
+ $tags2 = [];
+ foreach ($tags as $tag) {
+ if (! in_array($tag, $shoulderSurfingProtectedTags, true)) {
+ $tags2[] = $tag;
+ }
+ }
+ // If we filtered everything, we stop here and return nothing.
+ if(! empty($tags) && empty($tags2)) {
+ return array();
+ }
+ $tags = $tags2;
+ }
+ $tagcount = count($tags);
// Set up the SQL query.
$query_1 = 'SELECT DISTINCT ';
@@ -899,6 +914,20 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$query_4 .= ' AND B.bHash = "'. $hash .'"';
}
+ // Exclude bookmarks with shoulder surfing protected tags.
+ if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ $query_4 .= ' AND B.bId NOT IN (SELECT DISTINCT B0.bId FROM '.
+ $this->getTableName() .' AS B0, ' . $userservice->getTableName()
+ .' AS U, ' . $b2tservice->getTableName() .' AS T WHERE B0.uId = U.'
+ . $userservice->getFieldName('primary') . $privacy .' AND B0.uId = '
+ . $sId . ' AND (';
+ $count_s = count($shoulderSurfingProtectedTags);
+ for ($i = 0; $i < $count_s - 1; $i++) {
+ $query_4 .= 'T.tag = "'. $shoulderSurfingProtectedTags[$i] .'" OR ';
+ }
+ $query_4 .= 'T.tag = "'. $shoulderSurfingProtectedTags[$count_s - 1] .'")'
+ .' AND T.bId = B0.bId)';
+ }
$query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
@@ -951,6 +980,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$this->db->sql_freeresult($dbresult);
$output = array ('bookmarks' => $bookmarks, 'total' => $total);
+
return $output;
}
diff --git a/src/SemanticScuttle/Service/Bookmark2Tag.php b/src/SemanticScuttle/Service/Bookmark2Tag.php
index a01b5d7..fbb0520 100644
--- a/src/SemanticScuttle/Service/Bookmark2Tag.php
+++ b/src/SemanticScuttle/Service/Bookmark2Tag.php
@@ -329,7 +329,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$query = 'SELECT tag, bId FROM ' . $this->getTableName()
. ' WHERE bId IN (' . implode(',', $bookmarkids) . ')'
- . ' AND LEFT(tag, 7) <> "system:"'
+ . ' AND LEFT(tag, 7) <> "system:"'
. ' ORDER BY id, bId ASC';
if (!($dbresult = $this->db->sql_query($query))) {
@@ -353,7 +353,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
function &getTags($userid = NULL) {
- $userservice =SemanticScuttle_Service_Factory::get('User');
+ $userservice = SemanticScuttle_Service_Factory::get('User');
$logged_on_user = $userservice->getCurrentUserId();
$query = 'SELECT T.tag, COUNT(B.bId) AS bCount FROM '. $GLOBALS['tableprefix'] .'bookmarks AS B INNER JOIN '. $userservice->getTableName() .' AS U ON B.uId = U.'. $userservice->getFieldName('primary') .' INNER JOIN '. $GLOBALS['tableprefix'] .'bookmarks2tags AS T ON B.bId = T.bId';
@@ -366,7 +366,6 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
} else {
$conditions['B.bStatus'] = 0;
}
-
$query .= ' WHERE '. $this->db->sql_build_array('SELECT', $conditions) .' AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC, tag';
if (!($dbresult = $this->db->sql_query($query))) {
@@ -376,9 +375,31 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
- return $output;
+ return $this->filterShoulderSurfingProtectedTags($output);
+ }
+
+ function &filterShoulderSurfingProtectedTags($dboutput) {
+ $userservice = SemanticScuttle_Service_Factory::get('User');
+ if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ $logged_on_user = $userservice->getCurrentUserId();
+ $ttt = SemanticScuttle_Service_Factory::get('Tag2Tag');
+ $shoulderSurfingProtectedTags = $ttt->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $logged_on_user, array());
+ $shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
+ $output = array();
+ foreach ($dboutput as $array) {
+ $flag = 1;
+ foreach ($shoulderSurfingProtectedTags as $tag) {
+ if ($array['tag'] === $tag) {
+ $flag = 0;
+ break;
+ }
+ }
+ if ($flag) {$output[] = $array;}
+ }
+ return $output;
+ }
+ else {return $dboutput;}
}
-
// Returns the tags related to the specified tags; i.e. attached to the same bookmarks
function &getRelatedTags($tags, $for_user = NULL, $logged_on_user = NULL, $limit = 10) {
@@ -423,7 +444,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
- return $output;
+ return $this->filterShoulderSurfingProtectedTags($output);
}
// Returns the most popular tags used for a particular bookmark hash
@@ -453,7 +474,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
- return $output;
+ return $this->filterShoulderSurfingProtectedTags($output);
}
@@ -613,7 +634,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
- return $output;
+ return $this->filterShoulderSurfingProtectedTags($output);
}
diff --git a/src/SemanticScuttle/Service/SearchHistory.php b/src/SemanticScuttle/Service/SearchHistory.php
index ac0b1c7..98c075b 100644
--- a/src/SemanticScuttle/Service/SearchHistory.php
+++ b/src/SemanticScuttle/Service/SearchHistory.php
@@ -151,6 +151,10 @@ class SemanticScuttle_Service_SearchHistory extends SemanticScuttle_DbService
$range = null, $uId = null, $nb = null,
$start = null, $distinct = false, $withResults = false
) {
+ $userservice = SemanticScuttle_Service_Factory::get('User');
+ if ($userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ return array();
+ }
$sql = 'SELECT DISTINCT(shTerms),'
. ' shId, shRange, shNbResults, shDatetime, uId';
$sql.= ' FROM '. $this->getTableName();
diff --git a/src/SemanticScuttle/Service/Tag2Tag.php b/src/SemanticScuttle/Service/Tag2Tag.php
index 9dddc44..e33798a 100644
--- a/src/SemanticScuttle/Service/Tag2Tag.php
+++ b/src/SemanticScuttle/Service/Tag2Tag.php
@@ -318,7 +318,8 @@ class SemanticScuttle_Service_Tag2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
- return $output;
+ $btt = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
+ return $btt->filterShoulderSurfingProtectedTags($output);
}
function getMenuTags($uId) {
@@ -377,6 +378,25 @@ class SemanticScuttle_Service_Tag2Tag extends SemanticScuttle_DbService
$dbres = $this->db->sql_query($query);
$rowset = $this->db->sql_fetchrowset($dbres);
$this->db->sql_freeresult($dbres);
+
+ $userservice = SemanticScuttle_Service_Factory::get('User');
+ if (count($rowset)>0 && ! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ $logged_on_user = $userservice->getCurrentUserId();
+ $shoulderSurfingProtectedTags = $this->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $logged_on_user, array());
+ $shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
+ $output = array();
+ foreach($rowset as $link) {
+ $flag = 1;
+ foreach ($shoulderSurfingProtectedTags as $tag) {
+ if ($link['tag1'] === $tag || $link['tag2'] === $tag) {
+ $flag = 0;
+ break;
+ }
+ }
+ if ($flag) {$output[] = $link;}
+ }
+ $rowset = $output;
+ }
return $rowset;
}
diff --git a/www/about.php b/www/about.php
index 9bd37b0..19ee6df 100644
--- a/www/about.php
+++ b/www/about.php
@@ -22,6 +22,7 @@ require_once 'www-header.php';
$tplVars['pagetitle'] = T_('About');
$tplVars['subtitle'] = T_('About');
+$tplVars['loadjs'] = true;
$templateservice->loadTemplate('about.tpl', $tplVars);
-?>
\ No newline at end of file
+?>
diff --git a/www/ajax/checkpassword.php b/www/ajax/checkpassword.php
new file mode 100644
index 0000000..6bc2d8a
--- /dev/null
+++ b/www/ajax/checkpassword.php
@@ -0,0 +1,33 @@
+isLoggedOn()){
+ $password = $userservice->sanitisePassword($_POST['password']);
+ $username = $currentUser->getUsername();
+ $db = SemanticScuttle_Service_Factory::getDb();
+
+ $query = 'SELECT '. $userservice->getFieldName('primary') .' FROM '. $userservice->getTableName() .' WHERE '. $userservice->getFieldName('username') .' = "'. $db->sql_escape($username) .'" AND '. $userservice->getFieldName('password') .' = "'. $db->sql_escape($password) .'"';
+
+ if (!($dbresult = $db->sql_query($query))) {
+ message_die(
+ GENERAL_ERROR,
+ 'Could not get user',
+ '', __LINE__, __FILE__, $query, $db
+ );
+ echo 'false';
+ }
+ else {
+ $row = $db->sql_fetchrow($dbresult);
+ $db->sql_freeresult($dbresult);
+
+ if ($row) {
+ echo 'true';
+ }
+ else {
+ echo 'false';
+ }
+ }
+}
+else {
+ echo 'false';
+}
+?>
diff --git a/www/ajax/getlinkedtags.php b/www/ajax/getlinkedtags.php
index 9bb3b1f..63b1712 100644
--- a/www/ajax/getlinkedtags.php
+++ b/www/ajax/getlinkedtags.php
@@ -138,4 +138,4 @@ $tagData = assembleLinkedTagData(
SemanticScuttle_Service_Factory::get('Tag2Tag')
);
echo json_encode($tagData);
-?>
\ No newline at end of file
+?>
diff --git a/www/bookmarks.php b/www/bookmarks.php
index 8926f69..c7b08bc 100644
--- a/www/bookmarks.php
+++ b/www/bookmarks.php
@@ -262,20 +262,46 @@ if ($templatename == 'editbookmark.tpl') {
$tplVars['sidebar_blocks'] = array('watchstatus');
if (!$cat) { //user page without tags
- $rssTitle = "My Bookmarks";
+ $rssTitle = "My Bookmarks";
$cat = NULL;
$tplVars['currenttag'] = NULL;
//$tplVars['sidebar_blocks'][] = 'menu2';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'popular';
} else { //pages with tags
- $rssTitle = "Tags" . $catTitle;
+ $rssTitle = "Tags" . $catTitle;
$rssCat = '/'. filter($cat, 'url');
$tplVars['currenttag'] = $cat;
- $tplVars['sidebar_blocks'][] = 'tagactions';
//$tplVars['sidebar_blocks'][] = 'menu2';
- $tplVars['sidebar_blocks'][] = 'linked';
- $tplVars['sidebar_blocks'][] = 'related';
+
+ if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
+ $tag2tagservice = SemanticScuttle_Service_Factory::get('Tag2Tag');
+ $b2tservice = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
+ $alltags = $b2tservice->getTags($currentUserID);
+ $shoulderSurfingProtectedTags = $tag2tagservice->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $currentUserID, array());
+ $shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
+ $flag = 0;
+ if (! in_array($cat, $shoulderSurfingProtectedTags, true)) {
+ foreach ($alltags as $tag) {
+ if ($tag['tag'] === $cat) {
+ $flag = 1;
+ break;
+ }
+
+ }
+ }
+ if ($flag) {
+ $tplVars['sidebar_blocks'][] = 'tagactions';
+ $tplVars['sidebar_blocks'][] = 'linked';
+ $tplVars['sidebar_blocks'][] = 'related';
+ }
+ }
+ else {
+ $tplVars['sidebar_blocks'][] = 'tagactions';
+ $tplVars['sidebar_blocks'][] = 'linked';
+ $tplVars['sidebar_blocks'][] = 'related';
+ }
+
/*$tplVars['sidebar_blocks'][] = 'menu';*/
}
$tplVars['sidebar_blocks'][] = 'menu2';
diff --git a/www/js/jstree-1.0-rc2/jquery.cookie-1.4.1.js b/www/js/jstree-1.0-rc2/jquery.cookie-1.4.1.js
new file mode 100644
index 0000000..c7f3a59
--- /dev/null
+++ b/www/js/jstree-1.0-rc2/jquery.cookie-1.4.1.js
@@ -0,0 +1,117 @@
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2013 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD
+ define(['jquery'], factory);
+ } else if (typeof exports === 'object') {
+ // CommonJS
+ factory(require('jquery'));
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+}(function ($) {
+
+ var pluses = /\+/g;
+
+ function encode(s) {
+ return config.raw ? s : encodeURIComponent(s);
+ }
+
+ function decode(s) {
+ return config.raw ? s : decodeURIComponent(s);
+ }
+
+ function stringifyCookieValue(value) {
+ return encode(config.json ? JSON.stringify(value) : String(value));
+ }
+
+ function parseCookieValue(s) {
+ if (s.indexOf('"') === 0) {
+ // This is a quoted cookie as according to RFC2068, unescape...
+ s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+ }
+
+ try {
+ // Replace server-side written pluses with spaces.
+ // If we can't decode the cookie, ignore it, it's unusable.
+ // If we can't parse the cookie, ignore it, it's unusable.
+ s = decodeURIComponent(s.replace(pluses, ' '));
+ return config.json ? JSON.parse(s) : s;
+ } catch(e) {}
+ }
+
+ function read(s, converter) {
+ var value = config.raw ? s : parseCookieValue(s);
+ return $.isFunction(converter) ? converter(value) : value;
+ }
+
+ var config = $.cookie = function (key, value, options) {
+
+ // Write
+
+ if (value !== undefined && !$.isFunction(value)) {
+ options = $.extend({}, config.defaults, options);
+
+ if (typeof options.expires === 'number') {
+ var days = options.expires, t = options.expires = new Date();
+ t.setTime(+t + days * 864e+5);
+ }
+
+ return (document.cookie = [
+ encode(key), '=', stringifyCookieValue(value),
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+ options.path ? '; path=' + options.path : '',
+ options.domain ? '; domain=' + options.domain : '',
+ options.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // Read
+
+ var result = key ? undefined : {};
+
+ // To prevent the for loop in the first place assign an empty array
+ // in case there are no cookies at all. Also prevents odd result when
+ // calling $.cookie().
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
+
+ for (var i = 0, l = cookies.length; i < l; i++) {
+ var parts = cookies[i].split('=');
+ var name = decode(parts.shift());
+ var cookie = parts.join('=');
+
+ if (key && key === name) {
+ // If second argument (value) is a function it's a converter...
+ result = read(cookie, value);
+ break;
+ }
+
+ // Prevent storing a cookie that we couldn't decode.
+ if (!key && (cookie = read(cookie)) !== undefined) {
+ result[name] = cookie;
+ }
+ }
+
+ return result;
+ };
+
+ config.defaults = {};
+
+ $.removeCookie = function (key, options) {
+ if ($.cookie(key) === undefined) {
+ return false;
+ }
+
+ // Must not alter options, thus extending a fresh object...
+ $.cookie(key, '', $.extend({}, options, { expires: -1 }));
+ return !$.cookie(key);
+ };
+
+}));
diff --git a/www/tag2tagadd.php b/www/tag2tagadd.php
index 3f4af8c..d865a62 100644
--- a/www/tag2tagadd.php
+++ b/www/tag2tagadd.php
@@ -63,7 +63,7 @@ if (POST_CONFIRM != '') {
}
$tplVars['links'] = $tag2tagservice->getLinks($currentUser->getId());
-
+$tplVars['loadjs'] = true;
$tplVars['tag1'] = $tag1;
$tplVars['tag2'] = '';
$tplVars['subtitle'] = T_('Add Tag Link') .': '. $tag1;
diff --git a/www/tag2tagdelete.php b/www/tag2tagdelete.php
index 06fea98..cab32aa 100644
--- a/www/tag2tagdelete.php
+++ b/www/tag2tagdelete.php
@@ -75,7 +75,7 @@ if (POST_CONFIRM) {
}
$tplVars['links'] = $tag2tagservice->getLinks($currentUser->getId());
-
+$tplVars['loadjs'] = true;
$tplVars['tag1'] = $tag1;
$tplVars['tag2'] = $tag2;
$tplVars['subtitle'] = T_('Delete Link Between Tags') .': '. $tag1.' > '.$tag2;
diff --git a/www/tagrename.php b/www/tagrename.php
index 18e26ab..68febec 100644
--- a/www/tagrename.php
+++ b/www/tagrename.php
@@ -73,6 +73,7 @@ if (POST_CONFIRM) {
$tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag;
$tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
$tplVars['old'] = $tag;
+ $tplVars['loadjs'] = true;
}
$templateservice->loadTemplate($template, $tplVars);
?>