{"id":106,"date":"2011-01-04T15:09:05","date_gmt":"2011-01-04T14:09:05","guid":{"rendered":"http:\/\/46.105.150.90\/tstnunix\/?p=106"},"modified":"2011-01-04T15:09:05","modified_gmt":"2011-01-04T14:09:05","slug":"reveal-hidden-visitors-on-viadeocom","status":"publish","type":"post","link":"https:\/\/nunix.fr\/?p=106","title":{"rendered":"Reveal hidden visitors on Viadeo.com"},"content":{"rendered":"<p>Viadeo has a feature to reveal who visited your profile&#8230;. but you first have to pay to become a premium user.<\/p>\n<p>But the way viadeo presents us the different profiles \u00ab\u00a0anonymized\u00a0\u00bb (cf picture1) contains a token which identify a profile. To illustrate this tiny breach in their business, I&rsquo;ve created a small script you can launch when browsing the <a href=\"http:\/\/www.viadeo.com\/monreseau\/consultation\/\">viadeo \u00ab\u00a0profile visits view\u00a0\u00bb<\/a>.<\/p>\n<p>Basically it replaces all links on profile cards by the user profile link whereas normally they point to the subscription page. The script also browses for you the different profiles and replace the labels by the real name and job position from your visitor (cf picture 2). Be careful that this latest option creates automated activity for your account and indicates to the profiles being revealed that you have visited them.<\/p>\n<p>\u00a0<\/p>\n<h3>Before :<\/h3>\n<p style=\"text-align: center;\"><figure id=\"attachment_104\" aria-describedby=\"caption-attachment-104\" style=\"width: 621px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"caption size-full wp-image-104\" src=\"http:\/\/46.105.150.90\/tstnunix\/wp-content\/uploads\/2011\/01\/1-subscribe.jpg\" border=\"0\" alt=\"Anonymized profile card for your account's visitors on viadeo.com\" title=\"Anonymized profile card for your account's visitors on viadeo.com\" width=\"621\" height=\"622\" srcset=\"https:\/\/nunix.fr\/wp-content\/uploads\/2011\/01\/1-subscribe.jpg 621w, https:\/\/nunix.fr\/wp-content\/uploads\/2011\/01\/1-subscribe-150x150.jpg 150w, https:\/\/nunix.fr\/wp-content\/uploads\/2011\/01\/1-subscribe-300x300.jpg 300w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption id=\"caption-attachment-104\" class=\"wp-caption-text\">Anonymized profile card for your account&rsquo;s visitors on viadeo.com<\/figcaption><\/figure><\/p>\n<h3 \/>After:  <!--more-->  <\/h3>\n<p>\u00a0<\/p>\n<p style=\"text-align: center;\"><figure id=\"attachment_105\" aria-describedby=\"caption-attachment-105\" style=\"width: 623px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"caption size-full wp-image-105\" src=\"http:\/\/46.105.150.90\/tstnunix\/wp-content\/uploads\/2011\/01\/3-enjoy.jpg\" border=\"0\" alt=\"Pprofile card for your account's visitors revealed!!!\" title=\"Pprofile card for your account's visitors revealed!!!\" width=\"623\" height=\"634\" srcset=\"https:\/\/nunix.fr\/wp-content\/uploads\/2011\/01\/3-enjoy.jpg 623w, https:\/\/nunix.fr\/wp-content\/uploads\/2011\/01\/3-enjoy-295x300.jpg 295w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption id=\"caption-attachment-105\" class=\"wp-caption-text\">Pprofile card for your account&rsquo;s visitors revealed!!!<\/figcaption><\/figure><\/p>\n<p>\u00a0<\/p>\n<p>The user understandable code is below, but I also provide a mini version (cf attachments) you can bookmark in your favorite browser to execute it whenever you are on the viadeo page (correct as long as viadeo doesn&rsquo;t change its systems).<\/p>\n<h3>Code :<\/h3>\n<p>{codecitation class=\u00a0\u00bbbrush: javascript;\u00a0\u00bb}\/*<br \/> Copyright 2010 Gabriel Serme<\/p>\n<p> Licensed under the Apache License, Version 2.0 (the \u00ab\u00a0License\u00a0\u00bb);<br \/> you may not use this file except in compliance with the License.<br \/> You may obtain a copy of the License at<\/p>\n<p> http:\/\/www.apache.org\/licenses\/LICENSE-2.0<\/p>\n<p> Unless required by applicable law or agreed to in writing, software<br \/> distributed under the License is distributed on an \u00ab\u00a0AS IS\u00a0\u00bb BASIS,<br \/> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br \/> See the License for the specific language governing permissions and<br \/> limitations under the License.<br \/>*\/<\/p>\n<p>\/\/Utility functions<\/p>\n<p>function obValsl(ob){var r=[],mx=ob.length;for(var z=0;z<\/p>\n<p>function tags(element, tagName){ return obValsl(element.getElementsByTagName(tagName));};<\/p>\n<p>\u00a0<\/p>\n<p>function getHTTPObject() { if (typeof XMLHttpRequest != &lsquo;undefined&rsquo;) { return new XMLHttpRequest(); } try { return new ActiveXObject(\u00ab\u00a0Msxml2.XMLHTTP\u00a0\u00bb); } catch (e) { try { return new ActiveXObject(\u00ab\u00a0Microsoft.XMLHTTP\u00a0\u00bb); } catch (e) {} } return false; }<\/p>\n<p>\u00a0<\/p>\n<p>\/**<\/p>\n<p>* Change label on a card, to indicate a message<\/p>\n<p>* @parameter card : a user-card from viadeo<\/p>\n<p>* @parameter withName : if true, scrap the name from profile (additional network requetsts)<\/p>\n<p>*\/<\/p>\n<p>function changeLabel (card, message, withName){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/change label<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var label = card.getElementsByClassName(\u00ab\u00a0information\u00a0\u00bb).item(0)<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>.getElementsByClassName(\u00ab\u00a0main\u00a0\u00bb).item(0)<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>.childNodes[0]<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>.childNodes[0];<\/p>\n<p>\u00a0<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>label.innerHTML= message;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (withName === true){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>getNameFromProfile(label, card);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>}<\/p>\n<p>}<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>function getNameFromProfile(elem, card){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var pId = getPidFromCard(card);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (undefined == pId)<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>return;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var http = getHTTPObject();<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>http.open(\u00ab\u00a0GET\u00a0\u00bb, baseUrl + pId, true);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>http.onreadystatechange = function() {<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (http.readyState != 4)<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>return;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/thx to http:\/\/www.anyexample.com\/webdev\/ajax\/ajax_example__get_page_title.xml<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>try { var real_status = http.status; }<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>catch (e) { return; }<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/ status != 200 means that page was not downloaded<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/ error 404 happened or something like this<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (real_status != 200)<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>return;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/ regexp which parses text for value between  ..  tags<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var re_title = new RegExp(\u00ab\u00a0[\\n\\r\\s]*(.*)[\\n\\r\\s]*\u00a0\u00bb, \u00ab\u00a0gmi\u00a0\u00bb);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/ page text<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var content = http.responseText;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var title = re_title.exec(content);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var emsg = \u00a0\u00bb; \/\/ output text<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (title == null) \u00a0\/\/ regexp didn&rsquo;t match<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>return; \/\/we do not change the current label<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>else<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>emsg = title[1];<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/if everything is perfectly fine, we change label<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>elem.innerHTML= emsg;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>}<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>http.send(null);<\/p>\n<p>}<\/p>\n<p>\u00a0<\/p>\n<p>\/**<\/p>\n<p>@return Pid if a picture is present, or undefined<\/p>\n<p>*\/<\/p>\n<p>function getPidFromCard(card){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var src = card.childNodes[0].childNodes[0].childNodes[0];<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (undefined == src){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span> return undefined;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>}<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>src = src.getAttribute(\u00ab\u00a0src\u00a0\u00bb);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var pId = src.substr(src.indexOf(\u00ab\u00a0memberId=\u00a0\u00bb) + \u00ab\u00a0memberId=\u00a0\u00bb.length);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>pId = pId.substr(0,pId.indexOf(\u00ab\u00a0&#038;\u00a0\u00bb));<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>return pId;<\/p>\n<p>}<\/p>\n<p>\u00a0<\/p>\n<p>\/** Starting point *\/<\/p>\n<p>\u00a0<\/p>\n<p>var baseUrl = \u00ab\u00a0http:\/\/www.viadeo.com\/profile\/\u00a0\u00bb;<\/p>\n<p>var a = document.getElementsByClassName(&lsquo;user-card&rsquo;);<\/p>\n<p>\/\/for all cards in the current page<\/p>\n<p>for (var i=0; i<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var card = a.item(i).childNodes[2];<\/p>\n<p>\u00a0<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var pId = getPidFromCard(card);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (undefined == pId){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span> console.log(\u00ab\u00a0Couldn&rsquo;t extract member profile\u00a0\u00bb);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span> continue;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>}<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/change all links from the card, except common contacts<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var links = Array.concat(<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>tags(a.item(i).childNodes[0], \u00ab\u00a0a\u00a0\u00bb),<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>tags(card.childNodes[0], \u00ab\u00a0a\u00a0\u00bb),<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>tags(card.childNodes[1], \u00ab\u00a0a\u00a0\u00bb));<\/p>\n<p><span style=\"white-space: pre;\"> <\/span><\/p>\n<p><span style=\"white-space: pre;\"> <\/span>for (var j=0; j<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var l = links[j];<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>l.setAttribute(\u00ab\u00a0href\u00a0\u00bb, \u00ab\u00a0\/profile\/\u00a0\u00bb + pId);<\/p>\n<p>}<\/p>\n<p>\/\/temporary change label<\/p>\n<p>changeLabel (card, \u00ab\u00a0Wait for name\u00a0\u00bb, false);<\/p>\n<p>}<\/p>\n<p>\u00a0<\/p>\n<p>\/\/at this point, you can already click on picture or label to browse the profile<\/p>\n<p>\/\/second loop, to separate name fetching from simple url replacing<\/p>\n<p>for (var i=0; i<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>var card = a.item(i).childNodes[2];<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>\/\/change label, one per second<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>if (undefined == getPidFromCard(card)){<\/p>\n<p><span style=\"white-space: pre;\"> <\/span> console.log(\u00ab\u00a0Couldn&rsquo;t extract member profile\u00a0\u00bb);<\/p>\n<p><span style=\"white-space: pre;\"> <\/span> continue;<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>}<\/p>\n<p><span style=\"white-space: pre;\"> <\/span>window.setTimeout(changeLabel , 1000*i, card, \u00a0\u00ab\u00a0Wait for name &#8211; \u00a0\u00bb + i, true);<\/p>\n<p>}<\/p>\n<p>{\/codecitation}<\/p>\n<div>{jcomments on}<\/div>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Viadeo has a feature to reveal who visited your profile&#8230;. but you first have to pay to become a premium user. But the way viadeo presents us the different profiles \u00ab\u00a0anonymized\u00a0\u00bb (cf picture1) contains a token which identify a profile. To illustrate this tiny breach in their business, I&rsquo;ve created a small script you can &hellip; <a href=\"https:\/\/nunix.fr\/?p=106\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;Reveal hidden visitors on Viadeo.com&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":104,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-106","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-js"],"_links":{"self":[{"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/posts\/106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nunix.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=106"}],"version-history":[{"count":0,"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nunix.fr\/index.php?rest_route=\/wp\/v2\/media\/104"}],"wp:attachment":[{"href":"https:\/\/nunix.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nunix.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nunix.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}