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); ?>